// SPDX-License-Identifier: GPL-2.0-only

#include <sys/types.h>
#include <sys/stat.h>
#include <getopt.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>

#include "elf-parse.h"

static Elf_Shdr *check_data_sec;
static Elf_Shdr *tracepoint_data_sec;

static inline void *get_index(void *start, int entsize, int index)
{
	return start + (entsize * index);
}

static int compare_strings(const void *a, const void *b)
{
	const char *av = *(const char **)a;
	const char *bv = *(const char **)b;

	return strcmp(av, bv);
}

struct elf_tracepoint {
	Elf_Ehdr *ehdr;
	const char **array;
	int count;
};

#define REALLOC_SIZE (1 << 10)
#define REALLOC_MASK (REALLOC_SIZE - 1)

static int add_string(const char *str, const char ***vals, int *count)
{
	const char **array = *vals;

	if (!(*count & REALLOC_MASK)) {
		int size = (*count) + REALLOC_SIZE;

		array = realloc(array, sizeof(char *) * size);
		if (!array) {
			fprintf(stderr, "Failed memory allocation\n");
			return -1;
		}
		*vals = array;
	}

	array[(*count)++] = str;
	return 0;
}

/**
 * for_each_shdr_str - iterator that reads strings that are in an ELF section.
 * @len: "int" to hold the length of the current string
 * @ehdr: A pointer to the ehdr of the ELF file
 * @sec: The section that has the strings to iterate on
 *
 * This is a for loop that iterates over all the nul terminated strings
 * that are in a given ELF section. The variable "str" will hold
 * the current string for each iteration and the passed in @len will
 * contain the strlen() of that string.
 */
#define for_each_shdr_str(len, ehdr, sec)				\
	for (const char *str = (void *)(ehdr) + shdr_offset(sec),	\
			*end = str + shdr_size(sec);			\
	     len = strlen(str), str < end;				\
	     str += (len) + 1)


static void make_trace_array(struct elf_tracepoint *etrace)
{
	Elf_Ehdr *ehdr = etrace->ehdr;
	const char **vals = NULL;
	int count = 0;
	int len;

	etrace->array = NULL;

	/*
	 * The __tracepoint_check section is filled with strings of the
	 * names of tracepoints (in tracepoint_strings). Create an array
	 * that points to each string and then sort the array.
	 */
	for_each_shdr_str(len, ehdr, check_data_sec) {
		if (!len)
			continue;
		if (add_string(str, &vals, &count) < 0)
			return;
	}

	/* If CONFIG_TRACEPOINT_VERIFY_USED is not set, there's nothing to do */
	if (!count)
		return;

	qsort(vals, count, sizeof(char *), compare_strings);

	etrace->array = vals;
	etrace->count = count;
}

static int find_event(const char *str, void *array, size_t size)
{
	return bsearch(&str, array, size, sizeof(char *), compare_strings) != NULL;
}

static void check_tracepoints(struct elf_tracepoint *etrace, const char *fname)
{
	Elf_Ehdr *ehdr = etrace->ehdr;
	int len;

	if (!etrace->array)
		return;

	/*
	 * The __tracepoints_strings section holds all the names of the
	 * defined tracepoints. If any of them are not in the
	 * __tracepoint_check_section it means they are not used.
	 */
	for_each_shdr_str(len, ehdr, tracepoint_data_sec) {
		if (!len)
			continue;
		if (!find_event(str, etrace->array, etrace->count)) {
			fprintf(stderr, "warning: tracepoint '%s' is unused", str);
			if (fname)
				fprintf(stderr, " in module %s\n", fname);
			else
				fprintf(stderr, "\n");
		}
	}

	free(etrace->array);
}

static void *tracepoint_check(struct elf_tracepoint *etrace, const char *fname)
{
	make_trace_array(etrace);
	check_tracepoints(etrace, fname);

	return NULL;
}

static int process_tracepoints(bool mod, void *addr, const char *fname)
{
	struct elf_tracepoint etrace = {0};
	Elf_Ehdr *ehdr = addr;
	Elf_Shdr *shdr_start;
	Elf_Shdr *string_sec;
	const char *secstrings;
	unsigned int shnum;
	unsigned int shstrndx;
	int shentsize;
	int idx;
	int done = 2;

	shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
	shentsize = ehdr_shentsize(ehdr);

	shstrndx = ehdr_shstrndx(ehdr);
	if (shstrndx == SHN_XINDEX)
		shstrndx = shdr_link(shdr_start);
	string_sec = get_index(shdr_start, shentsize, shstrndx);
	secstrings = (const char *)ehdr + shdr_offset(string_sec);

	shnum = ehdr_shnum(ehdr);
	if (shnum == SHN_UNDEF)
		shnum = shdr_size(shdr_start);

	for (int i = 0; done && i < shnum; i++) {
		Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);

		idx = shdr_name(shdr);

		/* locate the __tracepoint_check in vmlinux */
		if (!strcmp(secstrings + idx, "__tracepoint_check")) {
			check_data_sec = shdr;
			done--;
		}

		/* locate the __tracepoints_ptrs section in vmlinux */
		if (!strcmp(secstrings + idx, "__tracepoints_strings")) {
			tracepoint_data_sec = shdr;
			done--;
		}
	}

	/*
	 * Modules may not have either section. But if it has one section,
	 * it should have both of them.
	 */
	if (mod && !check_data_sec && !tracepoint_data_sec)
		return 0;

	if (!check_data_sec) {
		if (mod) {
			fprintf(stderr, "warning: Module %s has only unused tracepoints\n", fname);
			/* Do not fail build */
			return 0;
		}
		fprintf(stderr,	"no __tracepoint_check in file: %s\n", fname);
		return -1;
	}

	if (!tracepoint_data_sec) {
		/* A module may reference only exported tracepoints */
		if (mod)
			return 0;
		fprintf(stderr,	"no __tracepoint_strings in file: %s\n", fname);
		return -1;
	}

	if (!mod)
		fname = NULL;

	etrace.ehdr = ehdr;
	tracepoint_check(&etrace, fname);
	return 0;
}

int main(int argc, char *argv[])
{
	int n_error = 0;
	size_t size = 0;
	void *addr = NULL;
	bool mod = false;

	if (argc > 1 && strcmp(argv[1], "--module") == 0) {
		mod = true;
		argc--;
		argv++;
	}

	if (argc < 2) {
		if (mod)
			fprintf(stderr, "usage: tracepoint-update --module module...\n");
		else
			fprintf(stderr, "usage: tracepoint-update vmlinux...\n");
		return 0;
	}

	/* Process each file in turn, allowing deep failure. */
	for (int i = 1; i < argc; i++) {
		addr = elf_map(argv[i], &size, 1 << ET_REL);
		if (!addr) {
			++n_error;
			continue;
		}

		if (process_tracepoints(mod, addr, argv[i]))
			++n_error;

		elf_unmap(addr, size);
	}

	return !!n_error;
}
