diff options
author | Anton Blanchard <anton@samba.org> | 2011-08-24 16:40:15 +1000 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-09-23 14:36:12 -0300 |
commit | 3f5a42722b9e78a434d5a4ee5e607dc33c69ac80 (patch) | |
tree | 9e6afedc145ecb85a3cd80916cac5717547e9755 | |
parent | adb091846318f86e4f46c7d6a7b40d2f478abdbe (diff) | |
download | op-kernel-dev-3f5a42722b9e78a434d5a4ee5e607dc33c69ac80.zip op-kernel-dev-3f5a42722b9e78a434d5a4ee5e607dc33c69ac80.tar.gz |
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: Anton Blanchard <anton@samba.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/util/symbol.c | 33 |
1 files changed, 11 insertions, 22 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index bb5d32f..f119e85 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -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); - if (err) - break; - } - - memcpy(prev_symbol_name, symbol_name, len + 1); - prev_symbol_type = symbol_type; - prev_start = start; + /* + * 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; } - 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 |