scripts/tracepoint-update.c

Source file repositories/reference/linux-study-clean/scripts/tracepoint-update.c

File Facts

System
Linux kernel
Corpus path
scripts/tracepoint-update.c
Extension
.c
Size
6095 bytes
Lines
267
Domain
Support Tooling And Documentation
Bucket
scripts
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

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");
			free(*vals);
			*vals = NULL;
			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)

Annotation

Implementation Notes