Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3f5a4272 authored by Anton Blanchard's avatar Anton Blanchard Committed by Arnaldo Carvalho de Melo
Browse files

perf symbols: /proc/kallsyms does not sort module symbols

kallsyms__parse assumes that /proc/kallsyms is sorted and sets the end
of the previous symbol to the start of the current one.

Unfortunately module symbols are not sorted, eg:

ffffffffa0081f30 t e1000_clean_rx_irq   [e1000e]
ffffffffa00817a0 t e1000_alloc_rx_buffers       [e1000e]

Some symbols end up with a negative length and others have a length
larger than they should. This results in confusing perf output.

We already have a function to fixup the end of zero length symbols so
use that instead.

Cc: Eric B Munson <emunson@mgebm.net>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/20110824065242.969681349@samba.org


Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent adb09184
Loading
Loading
Loading
Loading
+11 −22
Original line number Diff line number Diff line
@@ -438,18 +438,11 @@ int kallsyms__parse(const char *filename, void *arg,
	char *line = NULL;
	size_t n;
	int err = -1;
	u64 prev_start = 0;
	char prev_symbol_type = 0;
	char *prev_symbol_name;
	FILE *file = fopen(filename, "r");

	if (file == NULL)
		goto out_failure;

	prev_symbol_name = malloc(KSYM_NAME_LEN);
	if (prev_symbol_name == NULL)
		goto out_close;

	err = 0;

	while (!feof(file)) {
@@ -480,24 +473,18 @@ int kallsyms__parse(const char *filename, void *arg,
			break;
		}

		if (prev_symbol_type) {
			u64 end = start;
			if (end != prev_start)
				--end;
			err = process_symbol(arg, prev_symbol_name,
					     prev_symbol_type, prev_start, end);
		/*
		 * module symbols are not sorted so we add all
		 * symbols with zero length and rely on
		 * symbols__fixup_end() to fix it up.
		 */
		err = process_symbol(arg, symbol_name,
				     symbol_type, start, start);
		if (err)
			break;
	}

		memcpy(prev_symbol_name, symbol_name, len + 1);
		prev_symbol_type = symbol_type;
		prev_start = start;
	}

	free(prev_symbol_name);
	free(line);
out_close:
	fclose(file);
	return err;

@@ -703,6 +690,8 @@ int dso__load_kallsyms(struct dso *dso, const char *filename,
	if (dso__load_all_kallsyms(dso, filename, map) < 0)
		return -1;

	symbols__fixup_end(&dso->symbols[map->type]);

	if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
		dso->symtab_type = SYMTAB__GUEST_KALLSYMS;
	else