// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
#include <linux/kconfig.h>
#include <linux/kernel.h>
#include <linux/rbtree.h>
#include <linux/types.h>
#include <linux/zalloc.h>
#include <inttypes.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/param.h>
#include <sys/utsname.h>
#include <perf/cpumap.h>
#include <perf/evlist.h>
#include <perf/mmap.h>

#include "debug.h"
#include "dso.h"
#include "env.h"
#include "parse-events.h"
#include "evlist.h"
#include "evsel.h"
#include "thread_map.h"
#include "machine.h"
#include "map.h"
#include "symbol.h"
#include "event.h"
#include "record.h"
#include "util/mmap.h"
#include "util/string2.h"
#include "util/synthetic-events.h"
#include "util/util.h"
#include "thread.h"

#include "tests.h"

#include <linux/ctype.h>

#define BUFSZ	1024
#define READLEN	128

struct tested_section {
	struct rb_node rb_node;
	u64 addr;
	char *path;
};

static bool tested_code_insert_or_exists(const char *path, u64 addr,
					 struct rb_root *tested_sections)
{
	struct rb_node **node = &tested_sections->rb_node;
	struct rb_node *parent = NULL;
	struct tested_section *data;

	while (*node) {
		int cmp;

		parent = *node;
		data = rb_entry(*node, struct tested_section, rb_node);
		cmp = strcmp(path, data->path);
		if (!cmp) {
			if (addr < data->addr)
				cmp = -1;
			else if (addr > data->addr)
				cmp = 1;
			else
				return true; /* already tested */
		}

		if (cmp < 0)
			node = &(*node)->rb_left;
		else
			node = &(*node)->rb_right;
	}

	data = zalloc(sizeof(*data));
	if (!data)
		return true;

	data->addr = addr;
	data->path = strdup(path);
	if (!data->path) {
		free(data);
		return true;
	}
	rb_link_node(&data->rb_node, parent, node);
	rb_insert_color(&data->rb_node, tested_sections);
	return false;
}

static void tested_sections__free(struct rb_root *root)
{
	while (!RB_EMPTY_ROOT(root)) {
		struct rb_node *node = rb_first(root);
		struct tested_section *ts = rb_entry(node,
						     struct tested_section,
						     rb_node);

		rb_erase(node, root);
		free(ts->path);
		free(ts);
	}
}

static size_t read_objdump_chunk(const char **line, unsigned char **buf,
				 size_t *buf_len)
{
	size_t bytes_read = 0;
	unsigned char *chunk_start = *buf;

	/* Read bytes */
	while (*buf_len > 0) {
		char c1, c2;

		/* Get 2 hex digits */
		c1 = *(*line)++;
		if (!isxdigit(c1))
			break;
		c2 = *(*line)++;
		if (!isxdigit(c2))
			break;

		/* Store byte and advance buf */
		**buf = (hex(c1) << 4) | hex(c2);
		(*buf)++;
		(*buf_len)--;
		bytes_read++;

		/* End of chunk? */
		if (isspace(**line))
			break;
	}

	/*
	 * objdump will display raw insn as LE if code endian
	 * is LE and bytes_per_chunk > 1. In that case reverse
	 * the chunk we just read.
	 *
	 * see disassemble_bytes() at binutils/objdump.c for details
	 * how objdump chooses display endian)
	 */
	if (bytes_read > 1 && !host_is_bigendian()) {
		unsigned char *chunk_end = chunk_start + bytes_read - 1;
		unsigned char tmp;

		while (chunk_start < chunk_end) {
			tmp = *chunk_start;
			*chunk_start = *chunk_end;
			*chunk_end = tmp;
			chunk_start++;
			chunk_end--;
		}
	}

	return bytes_read;
}

static size_t read_objdump_line(const char *line, unsigned char *buf,
				size_t buf_len)
{
	const char *p;
	size_t ret, bytes_read = 0;

	/* Skip to a colon */
	p = strchr(line, ':');
	if (!p)
		return 0;
	p++;

	/* Skip initial spaces */
	while (*p) {
		if (!isspace(*p))
			break;
		p++;
	}

	do {
		ret = read_objdump_chunk(&p, &buf, &buf_len);
		bytes_read += ret;
		p++;
	} while (ret > 0);

	/* return number of successfully read bytes */
	return bytes_read;
}

static int read_objdump_output(FILE *f, void *buf, size_t *len, u64 start_addr)
{
	char *line = NULL;
	size_t line_len, off_last = 0;
	ssize_t ret;
	int err = 0;
	u64 addr, last_addr = start_addr;

	while (off_last < *len) {
		size_t off, read_bytes, written_bytes;
		unsigned char tmp[BUFSZ];

		ret = getline(&line, &line_len, f);
		if (feof(f))
			break;
		if (ret < 0) {
			pr_debug("getline failed\n");
			err = -1;
			break;
		}

		/* read objdump data into temporary buffer */
		read_bytes = read_objdump_line(line, tmp, sizeof(tmp));
		if (!read_bytes)
			continue;

		if (sscanf(line, "%"PRIx64, &addr) != 1)
			continue;
		if (addr < last_addr) {
			pr_debug("addr going backwards, read beyond section?\n");
			break;
		}
		last_addr = addr;

		/* copy it from temporary buffer to 'buf' according
		 * to address on current objdump line */
		off = addr - start_addr;
		if (off >= *len)
			break;
		written_bytes = MIN(read_bytes, *len - off);
		memcpy(buf + off, tmp, written_bytes);
		off_last = off + written_bytes;
	}

	/* len returns number of bytes that could not be read */
	*len -= off_last;

	free(line);

	return err;
}

/*
 * Only gets GNU objdump version. Returns 0 for llvm-objdump.
 */
static int objdump_version(void)
{
	size_t line_len;
	char cmd[PATH_MAX * 2];
	char *line = NULL;
	const char *fmt;
	FILE *f;
	int ret;

	int version_tmp, version_num = 0;
	char *version = 0, *token;

	fmt = "%s --version";
	ret = snprintf(cmd, sizeof(cmd), fmt, test_objdump_path);
	if (ret <= 0 || (size_t)ret >= sizeof(cmd))
		return -1;
	/* Ignore objdump errors */
	strcat(cmd, " 2>/dev/null");
	f = popen(cmd, "r");
	if (!f) {
		pr_debug("popen failed\n");
		return -1;
	}
	/* Get first line of objdump --version output */
	ret = getline(&line, &line_len, f);
	pclose(f);
	if (ret < 0) {
		pr_debug("getline failed\n");
		return -1;
	}

	token = strsep(&line, " ");
	if (token != NULL && !strcmp(token, "GNU")) {
		// version is last part of first line of objdump --version output.
		while ((token = strsep(&line, " ")))
			version = token;

		// Convert version into a format we can compare with
		token = strsep(&version, ".");
		version_num = atoi(token);
		if (version_num)
			version_num *= 10000;

		token = strsep(&version, ".");
		version_tmp = atoi(token);
		if (token)
			version_num += version_tmp * 100;

		token = strsep(&version, ".");
		version_tmp = atoi(token);
		if (token)
			version_num += version_tmp;
	}

	return version_num;
}

static int read_via_objdump(const char *filename, u64 addr, void *buf,
			    size_t len)
{
	u64 stop_address = addr + len;
	struct utsname uname_buf;
	char cmd[PATH_MAX * 2];
	const char *fmt;
	FILE *f;
	int ret;

	ret = uname(&uname_buf);
	if (ret) {
		pr_debug("uname failed\n");
		return -1;
	}

	if (!strncmp(uname_buf.machine, "riscv", 5)) {
		int version = objdump_version();

		/* Default to this workaround if version parsing fails */
		if (version < 0 || version > 24100) {
			/*
			 * Starting at riscv objdump version 2.41, dumping in
			 * the middle of an instruction is not supported. riscv
			 * instructions are aligned along 2-byte intervals and
			 * can be either 2-bytes or 4-bytes. This makes it
			 * possible that the stop-address lands in the middle of
			 * a 4-byte instruction. Increase the stop_address by
			 * two to ensure an instruction is not cut in half, but
			 * leave the len as-is so only the expected number of
			 * bytes are collected.
			 */
			stop_address += 2;
		}
	}

	fmt = "%s -z -d --start-address=0x%"PRIx64" --stop-address=0x%"PRIx64" %s";
	ret = snprintf(cmd, sizeof(cmd), fmt, test_objdump_path, addr, stop_address,
		       filename);
	if (ret <= 0 || (size_t)ret >= sizeof(cmd))
		return -1;

	pr_debug("Objdump command is: %s\n", cmd);

	/* Ignore objdump errors */
	strcat(cmd, " 2>/dev/null");

	f = popen(cmd, "r");
	if (!f) {
		pr_debug("popen failed\n");
		return -1;
	}

	ret = read_objdump_output(f, buf, &len, addr);
	if (len) {
		pr_debug("objdump read too few bytes: %zd\n", len);
		if (!ret)
			ret = len;
	}

	pclose(f);

	return ret;
}

static void dump_buf(unsigned char *buf, size_t len)
{
	size_t i;

	for (i = 0; i < len; i++) {
		pr_debug("0x%02x ", buf[i]);
		if (i % 16 == 15)
			pr_debug("\n");
	}
	pr_debug("\n");
}

static int read_object_code(u64 addr, size_t len, u8 cpumode,
			    struct thread *thread,
			    struct rb_root *tested_sections)
{
	struct addr_location al;
	unsigned char buf1[BUFSZ] = {0};
	unsigned char buf2[BUFSZ] = {0};
	size_t ret_len;
	u64 objdump_addr;
	u64 skip_addr;
	const char *objdump_name;
	char decomp_name[KMOD_DECOMP_LEN];
	bool decomp = false;
	int ret, err = 0;
	struct dso *dso;

	pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr);

	addr_location__init(&al);
	if (!thread__find_map(thread, cpumode, addr, &al) || !map__dso(al.map)) {
		if (cpumode == PERF_RECORD_MISC_HYPERVISOR) {
			pr_debug("Hypervisor address can not be resolved - skipping\n");
			goto out;
		}

		pr_debug("thread__find_map failed\n");
		err = -1;
		goto out;
	}
	dso = map__dso(al.map);
	pr_debug("File is: %s\n", dso__long_name(dso));

	if (dso__symtab_type(dso) == DSO_BINARY_TYPE__KALLSYMS && !dso__is_kcore(dso)) {
		pr_debug("Unexpected kernel address - skipping\n");
		goto out;
	}

	/*
	 * Don't retest the same addresses. objdump struggles with kcore - try
	 * each map only once even if the address is different.
	 */
	skip_addr = dso__is_kcore(dso) ? map__start(al.map) : al.addr;
	if (tested_code_insert_or_exists(dso__long_name(dso), skip_addr,
					 tested_sections)) {
		pr_debug("Already tested %s @ %#"PRIx64" - skipping\n",
			 dso__long_name(dso), skip_addr);
		goto out;
	}

	pr_debug("On file address is: %#"PRIx64"\n", al.addr);

	if (len > BUFSZ)
		len = BUFSZ;

	/* Do not go off the map */
	if (addr + len > map__end(al.map))
		len = map__end(al.map) - addr;

	/*
	 * Some architectures (ex: powerpc) have stubs (trampolines) in kernel
	 * modules to manage long jumps. Check if the ip offset falls in stubs
	 * sections for kernel modules. And skip module address after text end
	 */
	if (dso__is_kmod(dso) && al.addr > dso__text_end(dso)) {
		pr_debug("skipping the module address %#"PRIx64" after text end\n", al.addr);
		goto out;
	}

	/* Read the object code using perf */
	ret_len = dso__data_read_offset(dso, maps__machine(thread__maps(thread)),
					al.addr, buf1, len);
	if (ret_len != len) {
		pr_debug("dso__data_read_offset failed\n");
		err = -1;
		goto out;
	}

	/*
	 * Converting addresses for use by objdump requires more information.
	 * map__load() does that.  See map__rip_2objdump() for details.
	 */
	if (map__load(al.map)) {
		err = -1;
		goto out;
	}

	objdump_name = dso__long_name(dso);
	if (dso__needs_decompress(dso)) {
		if (dso__decompress_kmodule_path(dso, objdump_name,
						 decomp_name,
						 sizeof(decomp_name)) < 0) {
			pr_debug("decompression failed\n");
			err = -1;
			goto out;
		}

		/* empty pathname means file wasn't actually compressed */
		if (decomp_name[0] != '\0') {
			decomp = true;
			objdump_name = decomp_name;
		}
	}

	/* Read the object code using objdump */
	objdump_addr = map__rip_2objdump(al.map, al.addr);
	ret = read_via_objdump(objdump_name, objdump_addr, buf2, len);

	if (decomp)
		unlink(objdump_name);

	if (ret > 0) {
		/*
		 * The kernel maps are inaccurate - assume objdump is right in
		 * that case.
		 */
		if (cpumode == PERF_RECORD_MISC_KERNEL ||
		    cpumode == PERF_RECORD_MISC_GUEST_KERNEL) {
			len -= ret;
			if (len) {
				pr_debug("Reducing len to %zu\n", len);
			} else if (dso__is_kcore(dso)) {
				/*
				 * objdump cannot handle very large segments
				 * that may be found in kcore.
				 */
				pr_debug("objdump failed for kcore");
				pr_debug(" - skipping\n");
			} else {
				err = -1;
			}
			goto out;
		}
	}
	if (ret < 0) {
		pr_debug("read_via_objdump failed\n");
		err = -1;
		goto out;
	}

	/* The results should be identical */
	if (memcmp(buf1, buf2, len)) {
		pr_debug("Bytes read differ from those read by objdump\n");
		pr_debug("buf1 (dso):\n");
		dump_buf(buf1, len);
		pr_debug("buf2 (objdump):\n");
		dump_buf(buf2, len);
		err = -1;
		goto out;
	}
	pr_debug("Bytes read match those read by objdump\n");
out:
	addr_location__exit(&al);
	return err;
}

static int process_sample_event(struct machine *machine, struct evlist *evlist,
				union perf_event *event,
				struct rb_root *tested_sections)
{
	struct perf_sample sample;
	struct thread *thread;
	int ret;

	perf_sample__init(&sample, /*all=*/false);
	ret = evlist__parse_sample(evlist, event, &sample);
	if (ret) {
		pr_debug("evlist__parse_sample failed\n");
		ret = -1;
		goto out;
	}

	thread = machine__findnew_thread(machine, sample.pid, sample.tid);
	if (!thread) {
		pr_debug("machine__findnew_thread failed\n");
		ret = -1;
		goto out;
	}

	ret = read_object_code(sample.ip, READLEN, sample.cpumode, thread,
			       tested_sections);
	thread__put(thread);
out:
	perf_sample__exit(&sample);
	return ret;
}

static int process_event(struct machine *machine, struct evlist *evlist,
			 union perf_event *event, struct rb_root *tested_sections)
{
	if (event->header.type == PERF_RECORD_SAMPLE)
		return process_sample_event(machine, evlist, event,
					    tested_sections);

	if (event->header.type == PERF_RECORD_THROTTLE ||
	    event->header.type == PERF_RECORD_UNTHROTTLE)
		return 0;

	if (event->header.type < PERF_RECORD_MAX) {
		int ret;

		ret = machine__process_event(machine, event, NULL);
		if (ret < 0)
			pr_debug("machine__process_event failed, event type %u\n",
				 event->header.type);
		return ret;
	}

	return 0;
}

static int process_events(struct machine *machine, struct evlist *evlist,
			  struct rb_root *tested_sections)
{
	union perf_event *event;
	struct mmap *md;
	int i, ret;

	for (i = 0; i < evlist__core(evlist)->nr_mmaps; i++) {
		md = &evlist__mmap(evlist)[i];
		if (perf_mmap__read_init(&md->core) < 0)
			continue;

		while ((event = perf_mmap__read_event(&md->core)) != NULL) {
			ret = process_event(machine, evlist, event, tested_sections);
			perf_mmap__consume(&md->core);
			if (ret < 0)
				return ret;
		}
		perf_mmap__read_done(&md->core);
	}
	return 0;
}

static int comp(const void *a, const void *b)
{
	return *(int *)a - *(int *)b;
}

static void do_sort_something(void)
{
	int buf[40960], i;

	for (i = 0; i < (int)ARRAY_SIZE(buf); i++)
		buf[i] = ARRAY_SIZE(buf) - i - 1;

	qsort(buf, ARRAY_SIZE(buf), sizeof(int), comp);

	for (i = 0; i < (int)ARRAY_SIZE(buf); i++) {
		if (buf[i] != i) {
			pr_debug("qsort failed\n");
			break;
		}
	}
}

static void sort_something(void)
{
	int i;

	for (i = 0; i < 10; i++)
		do_sort_something();
}

static void syscall_something(void)
{
	int pipefd[2];
	int i;

	for (i = 0; i < 1000; i++) {
		if (pipe(pipefd) < 0) {
			pr_debug("pipe failed\n");
			break;
		}
		close(pipefd[1]);
		close(pipefd[0]);
	}
}

static void fs_something(void)
{
	const char *test_file_name = "temp-perf-code-reading-test-file--";
	FILE *f;
	int i;

	for (i = 0; i < 1000; i++) {
		f = fopen(test_file_name, "w+");
		if (f) {
			fclose(f);
			unlink(test_file_name);
		}
	}
}

static void do_something(void)
{
	fs_something();

	sort_something();

	syscall_something();
}

enum {
	TEST_CODE_READING_OK,
	TEST_CODE_READING_NO_VMLINUX,
	TEST_CODE_READING_NO_KCORE,
	TEST_CODE_READING_NO_ACCESS,
	TEST_CODE_READING_NO_KERNEL_OBJ,
};

static int do_test_code_reading(bool try_kcore)
{
	struct machine *machine;
	struct thread *thread;
	struct record_opts opts = {
		.mmap_pages	     = UINT_MAX,
		.user_freq	     = UINT_MAX,
		.user_interval	     = ULLONG_MAX,
		.freq		     = 500,
		.target		     = {
			.uses_mmap   = true,
		},
	};
	struct rb_root tested_sections = RB_ROOT;
	struct perf_thread_map *threads = NULL;
	struct perf_cpu_map *cpus = NULL;
	struct evlist *evlist = NULL;
	struct evsel *evsel = NULL;
	int err = -1, ret;
	pid_t pid;
	struct map *map;
	bool have_vmlinux, have_kcore;
	struct dso *dso;
	const char *events[] = { "cpu-cycles", "cpu-cycles:u", "cpu-clock", "cpu-clock:u", NULL };
	int evidx = 0;
	struct perf_env host_env;

	pid = getpid();

	perf_env__init(&host_env);
	machine = machine__new_host(&host_env);

	ret = machine__create_kernel_maps(machine);
	if (ret < 0) {
		pr_debug("machine__create_kernel_maps failed\n");
		goto out_err;
	}

	/* Force the use of kallsyms instead of vmlinux to try kcore */
	if (try_kcore)
		symbol_conf.kallsyms_name = "/proc/kallsyms";

	/* Load kernel map */
	map = machine__kernel_map(machine);
	ret = map__load(map);
	if (ret < 0) {
		pr_debug("map__load failed\n");
		goto out_err;
	}
	dso = map__dso(map);
	have_vmlinux = dso__is_vmlinux(dso);
	have_kcore = dso__is_kcore(dso);

	/* 2nd time through we just try kcore */
	if (try_kcore && !have_kcore)
		return TEST_CODE_READING_NO_KCORE;

	/* No point getting kernel events if there is no kernel object */
	if (!have_vmlinux && !have_kcore)
		evidx++;

	threads = thread_map__new_by_tid(pid);
	if (!threads) {
		pr_debug("thread_map__new_by_tid failed\n");
		goto out_err;
	}

	ret = perf_event__synthesize_thread_map(NULL, threads,
						perf_event__process, machine,
						true, false);
	if (ret < 0) {
		pr_debug("perf_event__synthesize_thread_map failed\n");
		goto out_err;
	}

	thread = machine__findnew_thread(machine, pid, pid);
	if (!thread) {
		pr_debug("machine__findnew_thread failed\n");
		goto out_put;
	}

	cpus = perf_cpu_map__new_online_cpus();
	if (!cpus) {
		pr_debug("perf_cpu_map__new failed\n");
		goto out_put;
	}

	while (events[evidx]) {
		const char *str;

		evlist = evlist__new();
		if (!evlist) {
			pr_debug("evlist__new failed\n");
			goto out_put;
		}

		perf_evlist__set_maps(evlist__core(evlist), cpus, threads);

		str = events[evidx];
		pr_debug("Parsing event '%s'\n", str);
		ret = parse_event(evlist, str);
		if (ret < 0) {
			pr_debug("parse_events failed\n");
			goto out_put;
		}

		evlist__config(evlist, &opts, NULL);

		evlist__for_each_entry(evlist, evsel) {
			evsel->core.attr.comm = 1;
			evsel->core.attr.disabled = 1;
			evsel->core.attr.enable_on_exec = 0;
		}

		ret = evlist__open(evlist);
		if (ret < 0) {
			evidx++;

			if (events[evidx] == NULL && verbose > 0) {
				char errbuf[512];
				evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf));
				pr_debug("perf_evlist__open() failed!\n%s\n", errbuf);
			}

			perf_evlist__set_maps(evlist__core(evlist), NULL, NULL);
			evlist__put(evlist);
			evlist = NULL;
			continue;
		}
		break;
	}

	if (events[evidx] == NULL)
		goto out_put;

	ret = evlist__do_mmap(evlist, UINT_MAX);
	if (ret < 0) {
		pr_debug("evlist__mmap failed\n");
		goto out_put;
	}

	evlist__enable(evlist);

	do_something();

	evlist__disable(evlist);

	ret = process_events(machine, evlist, &tested_sections);
	if (ret < 0)
		goto out_put;

	if (!have_vmlinux && !have_kcore && !try_kcore)
		err = TEST_CODE_READING_NO_KERNEL_OBJ;
	else if (!have_vmlinux && !try_kcore)
		err = TEST_CODE_READING_NO_VMLINUX;
	else if (strstr(events[evidx], ":u"))
		err = TEST_CODE_READING_NO_ACCESS;
	else
		err = TEST_CODE_READING_OK;
out_put:
	thread__put(thread);
out_err:
	evlist__put(evlist);
	perf_cpu_map__put(cpus);
	perf_thread_map__put(threads);
	machine__delete(machine);
	perf_env__exit(&host_env);
	tested_sections__free(&tested_sections);

	return err;
}

static int test__code_reading(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
{
	int ret;

	ret = do_test_code_reading(false);
	if (!ret)
		ret = do_test_code_reading(true);

	switch (ret) {
	case TEST_CODE_READING_OK:
		return 0;
	case TEST_CODE_READING_NO_VMLINUX:
		pr_debug("no vmlinux\n");
		return 0;
	case TEST_CODE_READING_NO_KCORE:
		pr_debug("no kcore\n");
		return 0;
	case TEST_CODE_READING_NO_ACCESS:
		pr_debug("no access\n");
		return 0;
	case TEST_CODE_READING_NO_KERNEL_OBJ:
		pr_debug("no kernel obj\n");
		return 0;
	default:
		return -1;
	};
}

DEFINE_SUITE("Object code reading", code_reading);
