// SPDX-License-Identifier: GPL-2.0
#include <linux/compiler.h>
#include <linux/rbtree.h>
#include <inttypes.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include "dso.h"
#include "map.h"
#include "symbol.h"
#include <internal/lib.h> // page_size
#include "tests.h"
#include "debug.h"
#include "machine.h"

#define UM(x) map__unmap_ip(kallsyms_map, (x))

static bool is_ignored_symbol(const char *name, char type)
{
	/* Symbol names that exactly match to the following are ignored.*/
	static const char * const ignored_symbols[] = {
		/*
		 * Symbols which vary between passes. Passes 1 and 2 must have
		 * identical symbol lists. The kallsyms_* symbols below are
		 * only added after pass 1, they would be included in pass 2
		 * when --all-symbols is specified so exclude them to get a
		 * stable symbol list.
		 */
		"kallsyms_offsets",
		"kallsyms_relative_base",
		"kallsyms_num_syms",
		"kallsyms_names",
		"kallsyms_markers",
		"kallsyms_token_table",
		"kallsyms_token_index",
		/* Exclude linker generated symbols which vary between passes */
		"_SDA_BASE_",		/* ppc */
		"_SDA2_BASE_",		/* ppc */
		NULL
	};

	/* Symbol names that begin with the following are ignored.*/
	static const char * const ignored_prefixes[] = {
		"$",			/* local symbols for ARM, MIPS, etc. */
		".L",			/* local labels, .LBB,.Ltmpxxx,.L__unnamed_xx,.LASANPC, etc. */
		"__crc_",		/* modversions */
		"__efistub_",		/* arm64 EFI stub namespace */
		"__kvm_nvhe_$",		/* arm64 local symbols in non-VHE KVM namespace */
		"__kvm_nvhe_.L",	/* arm64 local symbols in non-VHE KVM namespace */
		"__AArch64ADRPThunk_",	/* arm64 lld */
		"__ARMV5PILongThunk_",	/* arm lld */
		"__ARMV7PILongThunk_",
		"__ThumbV7PILongThunk_",
		"__LA25Thunk_",		/* mips lld */
		"__microLA25Thunk_",
		NULL
	};

	/* Symbol names that end with the following are ignored.*/
	static const char * const ignored_suffixes[] = {
		"_from_arm",		/* arm */
		"_from_thumb",		/* arm */
		"_veneer",		/* arm */
		NULL
	};

	/* Symbol names that contain the following are ignored.*/
	static const char * const ignored_matches[] = {
		".long_branch.",	/* ppc stub */
		".plt_branch.",		/* ppc stub */
		NULL
	};

	const char * const *p;

	for (p = ignored_symbols; *p; p++)
		if (!strcmp(name, *p))
			return true;

	for (p = ignored_prefixes; *p; p++)
		if (!strncmp(name, *p, strlen(*p)))
			return true;

	for (p = ignored_suffixes; *p; p++) {
		int l = strlen(name) - strlen(*p);

		if (l >= 0 && !strcmp(name + l, *p))
			return true;
	}

	for (p = ignored_matches; *p; p++) {
		if (strstr(name, *p))
			return true;
	}

	if (type == 'U' || type == 'u')
		return true;
	/* exclude debugging symbols */
	if (type == 'N' || type == 'n')
		return true;

	if (toupper(type) == 'A') {
		/* Keep these useful absolute symbols */
		if (strcmp(name, "__kernel_syscall_via_break") &&
		    strcmp(name, "__kernel_syscall_via_epc") &&
		    strcmp(name, "__kernel_sigtramp") &&
		    strcmp(name, "__gp"))
			return true;
	}

	return false;
}

struct test__vmlinux_matches_kallsyms_cb_args {
	struct machine kallsyms;
	struct map *vmlinux_map;
	bool header_printed;
};

static int test__vmlinux_matches_kallsyms_cb1(struct map *map, void *data)
{
	struct test__vmlinux_matches_kallsyms_cb_args *args = data;
	struct dso *dso = map__dso(map);
	/*
	 * If it is the kernel, kallsyms is always "[kernel.kallsyms]", while
	 * the kernel will have the path for the vmlinux file being used, so use
	 * the short name, less descriptive but the same ("[kernel]" in both
	 * cases.
	 */
	struct map *pair = maps__find_by_name(args->kallsyms.kmaps,
					(dso__kernel(dso) ? dso__short_name(dso) : dso__name(dso)));

	if (pair) {
		map__set_priv(pair);
		map__put(pair);
	} else {
		if (!args->header_printed) {
			pr_info("WARN: Maps only in vmlinux:\n");
			args->header_printed = true;
		}
		map__fprintf(map, stderr);
	}
	return 0;
}

static int test__vmlinux_matches_kallsyms_cb2(struct map *map, void *data)
{
	struct test__vmlinux_matches_kallsyms_cb_args *args = data;
	struct map *pair;
	u64 mem_start = map__unmap_ip(args->vmlinux_map, map__start(map));
	u64 mem_end = map__unmap_ip(args->vmlinux_map, map__end(map));

	pair = maps__find(args->kallsyms.kmaps, mem_start);

	if (pair != NULL && !map__priv(pair) && map__start(pair) == mem_start) {
		struct dso *dso = map__dso(map);

		if (!args->header_printed) {
			pr_info("WARN: Maps in vmlinux with a different name in kallsyms:\n");
			args->header_printed = true;
		}

		pr_info("WARN: %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as",
			map__start(map), map__end(map), map__pgoff(map), dso__name(dso));
		if (mem_end != map__end(pair))
			pr_info(":\nWARN: *%" PRIx64 "-%" PRIx64 " %" PRIx64,
				map__start(pair), map__end(pair), map__pgoff(pair));
		pr_info(" %s\n", dso__name(dso));
		map__set_priv(pair);
	}
	map__put(pair);
	return 0;
}

static int test__vmlinux_matches_kallsyms_cb3(struct map *map, void *data)
{
	struct test__vmlinux_matches_kallsyms_cb_args *args = data;

	if (!map__priv(map)) {
		if (!args->header_printed) {
			pr_info("WARN: Maps only in kallsyms:\n");
			args->header_printed = true;
		}
		map__fprintf(map, stderr);
	}
	return 0;
}

static int test__vmlinux_matches_kallsyms(struct test_suite *test __maybe_unused,
					int subtest __maybe_unused)
{
	int err = TEST_FAIL;
	struct rb_node *nd;
	struct symbol *sym;
	struct map *kallsyms_map;
	struct machine vmlinux;
	struct maps *maps;
	u64 mem_start, mem_end;
	struct test__vmlinux_matches_kallsyms_cb_args args;

	/*
	 * Step 1:
	 *
	 * Init the machines that will hold kernel, modules obtained from
	 * both vmlinux + .ko files and from /proc/kallsyms split by modules.
	 */
	machine__init(&args.kallsyms, "", HOST_KERNEL_ID);
	machine__init(&vmlinux, "", HOST_KERNEL_ID);

	maps = machine__kernel_maps(&vmlinux);

	/*
	 * Step 2:
	 *
	 * Create the kernel maps for kallsyms and the DSO where we will then
	 * load /proc/kallsyms. Also create the modules maps from /proc/modules
	 * and find the .ko files that match them in /lib/modules/`uname -r`/.
	 */
	if (machine__create_kernel_maps(&args.kallsyms) < 0) {
		pr_debug("machine__create_kernel_maps failed");
		err = TEST_SKIP;
		goto out;
	}

	/*
	 * Step 3:
	 *
	 * Load and split /proc/kallsyms into multiple maps, one per module.
	 * Do not use kcore, as this test was designed before kcore support
	 * and has parts that only make sense if using the non-kcore code.
	 * XXX: extend it to stress the kcorre code as well, hint: the list
	 * of modules extracted from /proc/kcore, in its current form, can't
	 * be compacted against the list of modules found in the "vmlinux"
	 * code and with the one got from /proc/modules from the "kallsyms" code.
	 */
	if (machine__load_kallsyms(&args.kallsyms, "/proc/kallsyms") <= 0) {
		pr_debug("machine__load_kallsyms failed");
		err = TEST_SKIP;
		goto out;
	}

	/*
	 * Step 4:
	 *
	 * kallsyms will be internally on demand sorted by name so that we can
	 * find the reference relocation * symbol, i.e. the symbol we will use
	 * to see if the running kernel was relocated by checking if it has the
	 * same value in the vmlinux file we load.
	 */
	kallsyms_map = machine__kernel_map(&args.kallsyms);

	/*
	 * Step 5:
	 *
	 * Now repeat step 2, this time for the vmlinux file we'll auto-locate.
	 */
	if (machine__create_kernel_maps(&vmlinux) < 0) {
		pr_info("machine__create_kernel_maps failed");
		goto out;
	}

	args.vmlinux_map = machine__kernel_map(&vmlinux);

	/*
	 * Step 6:
	 *
	 * Locate a vmlinux file in the vmlinux path that has a buildid that
	 * matches the one of the running kernel.
	 *
	 * While doing that look if we find the ref reloc symbol, if we find it
	 * we'll have its ref_reloc_symbol.unrelocated_addr and then
	 * maps__reloc_vmlinux will notice and set proper ->[un]map_ip routines
	 * to fixup the symbols.
	 */
	if (machine__load_vmlinux_path(&vmlinux) <= 0) {
		pr_info("Couldn't find a vmlinux that matches the kernel running on this machine, skipping test\n");
		err = TEST_SKIP;
		goto out;
	}

	err = 0;
	/*
	 * Step 7:
	 *
	 * Now look at the symbols in the vmlinux DSO and check if we find all of them
	 * in the kallsyms dso. For the ones that are in both, check its names and
	 * end addresses too.
	 */
	map__for_each_symbol(args.vmlinux_map, sym, nd) {
		struct symbol *pair, *first_pair;

		sym  = rb_entry(nd, struct symbol, rb_node);

		if (sym->start == sym->end)
			continue;

		mem_start = map__unmap_ip(args.vmlinux_map, sym->start);
		mem_end = map__unmap_ip(args.vmlinux_map, sym->end);

		first_pair = machine__find_kernel_symbol(&args.kallsyms, mem_start, NULL);
		pair = first_pair;

		if (pair && UM(pair->start) == mem_start) {
next_pair:
			if (arch__compare_symbol_names(sym->name, pair->name) == 0) {
				/*
				 * kallsyms don't have the symbol end, so we
				 * set that by using the next symbol start - 1,
				 * in some cases we get this up to a page
				 * wrong, trace_kmalloc when I was developing
				 * this code was one such example, 2106 bytes
				 * off the real size. More than that and we
				 * _really_ have a problem.
				 */
				s64 skew = mem_end - UM(pair->end);
				if (llabs(skew) >= page_size)
					pr_debug("WARN: %#" PRIx64 ": diff end addr for %s v: %#" PRIx64 " k: %#" PRIx64 "\n",
						 mem_start, sym->name, mem_end,
						 UM(pair->end));

				/*
				 * Do not count this as a failure, because we
				 * could really find a case where it's not
				 * possible to get proper function end from
				 * kallsyms.
				 */
				continue;
			} else {
				pair = machine__find_kernel_symbol_by_name(&args.kallsyms,
									   sym->name, NULL);
				if (pair) {
					if (UM(pair->start) == mem_start)
						goto next_pair;

					pr_debug("WARN: %#" PRIx64 ": diff name v: %s k: %s\n",
						 mem_start, sym->name, pair->name);
				} else {
					pr_debug("WARN: %#" PRIx64 ": diff name v: %s k: %s\n",
						 mem_start, sym->name, first_pair->name);
				}

				continue;
			}
		} else if (mem_start == map__end(args.kallsyms.vmlinux_map)) {
			/*
			 * Ignore aliases to _etext, i.e. to the end of the kernel text area,
			 * such as __indirect_thunk_end.
			 */
			continue;
		} else if (is_ignored_symbol(sym->name, sym->type)) {
			/*
			 * Ignore hidden symbols, see scripts/kallsyms.c for the details
			 */
			continue;
		} else {
			pr_debug("ERR : %#" PRIx64 ": %s not on kallsyms\n",
				 mem_start, sym->name);
		}

		err = -1;
	}

	if (verbose <= 0)
		goto out;

	args.header_printed = false;
	maps__for_each_map(maps, test__vmlinux_matches_kallsyms_cb1, &args);

	args.header_printed = false;
	maps__for_each_map(maps, test__vmlinux_matches_kallsyms_cb2, &args);

	args.header_printed = false;
	maps = machine__kernel_maps(&args.kallsyms);
	maps__for_each_map(maps, test__vmlinux_matches_kallsyms_cb3, &args);

out:
	machine__exit(&args.kallsyms);
	machine__exit(&vmlinux);
	return err;
}

DEFINE_SUITE("vmlinux symtab matches kallsyms", vmlinux_matches_kallsyms);
