From c408fedfc4a1fa16e611ffd6f3280301b38614be Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 5 Aug 2010 12:59:47 -0300 Subject: perf symbols: Store the symbol binding So that tools that wan't to act only on a subset of (weak, global, local) symbols can do so, such as the upcoming uprobes support in 'perf probe'. Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Srikar Dronamraju Cc: Stephane Eranian LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'tools/perf/util/symbol.c') diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 6f0dd90c36ce..b6f5970f9106 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -131,7 +131,8 @@ static void map_groups__fixup_end(struct map_groups *self) __map_groups__fixup_end(self, i); } -static struct symbol *symbol__new(u64 start, u64 len, const char *name) +static struct symbol *symbol__new(u64 start, u64 len, u8 binding, + const char *name) { size_t namelen = strlen(name) + 1; struct symbol *self = calloc(1, (symbol_conf.priv_size + @@ -144,6 +145,7 @@ static struct symbol *symbol__new(u64 start, u64 len, const char *name) self->start = start; self->end = len ? start + len - 1 : start; + self->binding = binding; self->namelen = namelen - 1; pr_debug4("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end); @@ -160,8 +162,11 @@ void symbol__delete(struct symbol *self) static size_t symbol__fprintf(struct symbol *self, FILE *fp) { - return fprintf(fp, " %llx-%llx %s\n", - self->start, self->end, self->name); + return fprintf(fp, " %llx-%llx %c %s\n", + self->start, self->end, + self->binding == STB_GLOBAL ? 'g' : + self->binding == STB_LOCAL ? 'l' : 'w', + self->name); } void dso__set_long_name(struct dso *self, char *name) @@ -453,6 +458,14 @@ struct process_kallsyms_args { struct dso *dso; }; +static u8 kallsyms2elf_type(char type) +{ + if (type == 'W') + return STB_WEAK; + + return isupper(type) ? STB_GLOBAL : STB_LOCAL; +} + static int map__process_kallsym_symbol(void *arg, const char *name, char type, u64 start) { @@ -466,7 +479,7 @@ static int map__process_kallsym_symbol(void *arg, const char *name, /* * Will fix up the end later, when we have all symbols sorted. */ - sym = symbol__new(start, 0, name); + sym = symbol__new(start, 0, kallsyms2elf_type(type), name); if (sym == NULL) return -ENOMEM; @@ -661,7 +674,7 @@ static int dso__load_perf_map(struct dso *self, struct map *map, if (len + 2 >= line_len) continue; - sym = symbol__new(start, size, line + len); + sym = symbol__new(start, size, STB_GLOBAL, line + len); if (sym == NULL) goto out_delete_line; @@ -873,7 +886,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, struct map *map, "%s@plt", elf_sym__name(&sym, symstrs)); f = symbol__new(plt_offset, shdr_plt.sh_entsize, - sympltname); + STB_GLOBAL, sympltname); if (!f) goto out_elf_end; @@ -895,7 +908,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, struct map *map, "%s@plt", elf_sym__name(&sym, symstrs)); f = symbol__new(plt_offset, shdr_plt.sh_entsize, - sympltname); + STB_GLOBAL, sympltname); if (!f) goto out_elf_end; @@ -1146,7 +1159,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, if (demangled != NULL) elf_name = demangled; new_symbol: - f = symbol__new(sym.st_value, sym.st_size, elf_name); + f = symbol__new(sym.st_value, sym.st_size, + GELF_ST_BIND(sym.st_info), elf_name); free(demangled); if (!f) goto out_elf_end; -- cgit v1.2.3 From 696b97a5d2de9e2b22699300835e675dfffe8592 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Mon, 9 Aug 2010 12:21:18 +0100 Subject: perf symbols: Ignore mapping symbols on ARM ARM ELF files use symbols with special names $a, $t, $d to identify regions of ARM code, Thumb code and data within code sections. This can cause confusing output from the perf tools, especially for partially stripped binaries, or binaries containing user-added zero-sized symbols (which may occur in hand-written assembler which hasn't been fully annotated with .size directives). This patch filters out these symbols at load time. LKML-Reference: <1281352878-8735-2-git-send-email-dave.martin@linaro.org> Signed-off-by: Dave Martin Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tools/perf/util/symbol.c') diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index b6f5970f9106..1a367734e016 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1079,6 +1079,16 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, if (!is_label && !elf_sym__is_a(&sym, map->type)) continue; + /* Reject ARM ELF "mapping symbols": these aren't unique and + * don't identify functions, so will confuse the profile + * output: */ + if (ehdr.e_machine == EM_ARM) { + if (!strcmp(elf_name, "$a") || + !strcmp(elf_name, "$d") || + !strcmp(elf_name, "$t")) + continue; + } + if (opdsec && sym.st_shndx == opdidx) { u32 offset = sym.st_value - opdshdr.sh_addr; u64 *opd = opddata->d_buf + offset; -- cgit v1.2.3