diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-11-27 13:29:17 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-11-27 14:21:59 -0500 |
commit | 6a4694a433a218c729d336b348a01bfc720da095 (patch) | |
tree | 19c166d8cb244fa0ec504cd49f7de957552ce573 /tools/perf/util/symbol.c | |
parent | 3610583c29563e23dd038d2870f59c88438bf7a3 (diff) |
perf symbols: Better support for multiple symbol tables per dso
By using an array of rb_roots in struct dso we can, from a
struct map instance to get the right symbol rb_tree more easily.
This way we can have just one symbol lookup method for struct
map instances, map__find_symbol, instead of one per symtab type
(functions, variables).
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1259346563-12568-6-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r-- | tools/perf/util/symbol.c | 59 |
1 files changed, 36 insertions, 23 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 45a4a9a7618b..9a2dd819dee4 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -31,6 +31,7 @@ enum dso_origin { | |||
31 | static void dsos__add(struct list_head *head, struct dso *dso); | 31 | static void dsos__add(struct list_head *head, struct dso *dso); |
32 | static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); | 32 | static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); |
33 | static void kernel_maps__insert(struct map *map); | 33 | static void kernel_maps__insert(struct map *map); |
34 | struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr); | ||
34 | static int dso__load_kernel_sym(struct dso *self, struct map *map, | 35 | static int dso__load_kernel_sym(struct dso *self, struct map *map, |
35 | symbol_filter_t filter); | 36 | symbol_filter_t filter); |
36 | unsigned int symbol__priv_size; | 37 | unsigned int symbol__priv_size; |
@@ -151,11 +152,13 @@ struct dso *dso__new(const char *name) | |||
151 | struct dso *self = malloc(sizeof(*self) + strlen(name) + 1); | 152 | struct dso *self = malloc(sizeof(*self) + strlen(name) + 1); |
152 | 153 | ||
153 | if (self != NULL) { | 154 | if (self != NULL) { |
155 | int i; | ||
154 | strcpy(self->name, name); | 156 | strcpy(self->name, name); |
155 | dso__set_long_name(self, self->name); | 157 | dso__set_long_name(self, self->name); |
156 | self->short_name = self->name; | 158 | self->short_name = self->name; |
157 | self->functions = RB_ROOT; | 159 | for (i = 0; i < MAP__NR_TYPES; ++i) |
158 | self->find_function = dso__find_function; | 160 | self->symbols[i] = RB_ROOT; |
161 | self->find_symbol = dso__find_symbol; | ||
159 | self->slen_calculated = 0; | 162 | self->slen_calculated = 0; |
160 | self->origin = DSO__ORIG_NOT_FOUND; | 163 | self->origin = DSO__ORIG_NOT_FOUND; |
161 | self->loaded = 0; | 164 | self->loaded = 0; |
@@ -180,7 +183,9 @@ static void symbols__delete(struct rb_root *self) | |||
180 | 183 | ||
181 | void dso__delete(struct dso *self) | 184 | void dso__delete(struct dso *self) |
182 | { | 185 | { |
183 | symbols__delete(&self->functions); | 186 | int i; |
187 | for (i = 0; i < MAP__NR_TYPES; ++i) | ||
188 | symbols__delete(&self->symbols[i]); | ||
184 | if (self->long_name != self->name) | 189 | if (self->long_name != self->name) |
185 | free(self->long_name); | 190 | free(self->long_name); |
186 | free(self); | 191 | free(self); |
@@ -234,9 +239,9 @@ static struct symbol *symbols__find(struct rb_root *self, u64 ip) | |||
234 | return NULL; | 239 | return NULL; |
235 | } | 240 | } |
236 | 241 | ||
237 | struct symbol *dso__find_function(struct dso *self, u64 ip) | 242 | struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr) |
238 | { | 243 | { |
239 | return symbols__find(&self->functions, ip); | 244 | return symbols__find(&self->symbols[type], addr); |
240 | } | 245 | } |
241 | 246 | ||
242 | int build_id__sprintf(u8 *self, int len, char *bf) | 247 | int build_id__sprintf(u8 *self, int len, char *bf) |
@@ -262,17 +267,25 @@ size_t dso__fprintf_buildid(struct dso *self, FILE *fp) | |||
262 | return fprintf(fp, "%s", sbuild_id); | 267 | return fprintf(fp, "%s", sbuild_id); |
263 | } | 268 | } |
264 | 269 | ||
270 | static const char * map_type__name[MAP__NR_TYPES] = { | ||
271 | [MAP__FUNCTION] = "Functions", | ||
272 | }; | ||
273 | |||
265 | size_t dso__fprintf(struct dso *self, FILE *fp) | 274 | size_t dso__fprintf(struct dso *self, FILE *fp) |
266 | { | 275 | { |
276 | int i; | ||
267 | struct rb_node *nd; | 277 | struct rb_node *nd; |
268 | size_t ret = fprintf(fp, "dso: %s (", self->short_name); | 278 | size_t ret = fprintf(fp, "dso: %s (", self->short_name); |
269 | 279 | ||
270 | ret += dso__fprintf_buildid(self, fp); | 280 | ret += dso__fprintf_buildid(self, fp); |
271 | ret += fprintf(fp, ")\nFunctions:\n"); | 281 | ret += fprintf(fp, ")\n"); |
282 | for (i = 0; i < MAP__NR_TYPES; ++i) { | ||
283 | ret += fprintf(fp, "%s:\n", map_type__name[i]); | ||
272 | 284 | ||
273 | for (nd = rb_first(&self->functions); nd; nd = rb_next(nd)) { | 285 | for (nd = rb_first(&self->symbols[i]); nd; nd = rb_next(nd)) { |
274 | struct symbol *pos = rb_entry(nd, struct symbol, rb_node); | 286 | struct symbol *pos = rb_entry(nd, struct symbol, rb_node); |
275 | ret += symbol__fprintf(pos, fp); | 287 | ret += symbol__fprintf(pos, fp); |
288 | } | ||
276 | } | 289 | } |
277 | 290 | ||
278 | return ret; | 291 | return ret; |
@@ -335,7 +348,7 @@ static int kernel_maps__load_all_kallsyms(void) | |||
335 | * kernel_maps__split_kallsyms, when we have split the | 348 | * kernel_maps__split_kallsyms, when we have split the |
336 | * maps per module | 349 | * maps per module |
337 | */ | 350 | */ |
338 | symbols__insert(&kernel_map__functions->dso->functions, sym); | 351 | symbols__insert(&kernel_map__functions->dso->symbols[MAP__FUNCTION], sym); |
339 | } | 352 | } |
340 | 353 | ||
341 | free(line); | 354 | free(line); |
@@ -359,7 +372,7 @@ static int kernel_maps__split_kallsyms(symbol_filter_t filter) | |||
359 | struct map *map = kernel_map__functions; | 372 | struct map *map = kernel_map__functions; |
360 | struct symbol *pos; | 373 | struct symbol *pos; |
361 | int count = 0; | 374 | int count = 0; |
362 | struct rb_node *next = rb_first(&kernel_map__functions->dso->functions); | 375 | struct rb_node *next = rb_first(&kernel_map__functions->dso->symbols[map->type]); |
363 | int kernel_range = 0; | 376 | int kernel_range = 0; |
364 | 377 | ||
365 | while (next) { | 378 | while (next) { |
@@ -409,13 +422,13 @@ static int kernel_maps__split_kallsyms(symbol_filter_t filter) | |||
409 | } | 422 | } |
410 | 423 | ||
411 | if (filter && filter(map, pos)) { | 424 | if (filter && filter(map, pos)) { |
412 | rb_erase(&pos->rb_node, &kernel_map__functions->dso->functions); | 425 | rb_erase(&pos->rb_node, &kernel_map__functions->dso->symbols[map->type]); |
413 | symbol__delete(pos); | 426 | symbol__delete(pos); |
414 | } else { | 427 | } else { |
415 | if (map != kernel_map__functions) { | 428 | if (map != kernel_map__functions) { |
416 | rb_erase(&pos->rb_node, | 429 | rb_erase(&pos->rb_node, |
417 | &kernel_map__functions->dso->functions); | 430 | &kernel_map__functions->dso->symbols[map->type]); |
418 | symbols__insert(&map->dso->functions, pos); | 431 | symbols__insert(&map->dso->symbols[map->type], pos); |
419 | } | 432 | } |
420 | count++; | 433 | count++; |
421 | } | 434 | } |
@@ -430,7 +443,7 @@ static int kernel_maps__load_kallsyms(symbol_filter_t filter) | |||
430 | if (kernel_maps__load_all_kallsyms()) | 443 | if (kernel_maps__load_all_kallsyms()) |
431 | return -1; | 444 | return -1; |
432 | 445 | ||
433 | symbols__fixup_end(&kernel_map__functions->dso->functions); | 446 | symbols__fixup_end(&kernel_map__functions->dso->symbols[MAP__FUNCTION]); |
434 | kernel_map__functions->dso->origin = DSO__ORIG_KERNEL; | 447 | kernel_map__functions->dso->origin = DSO__ORIG_KERNEL; |
435 | 448 | ||
436 | return kernel_maps__split_kallsyms(filter); | 449 | return kernel_maps__split_kallsyms(filter); |
@@ -501,7 +514,7 @@ static int dso__load_perf_map(struct dso *self, struct map *map, | |||
501 | if (filter && filter(map, sym)) | 514 | if (filter && filter(map, sym)) |
502 | symbol__delete(sym); | 515 | symbol__delete(sym); |
503 | else { | 516 | else { |
504 | symbols__insert(&self->functions, sym); | 517 | symbols__insert(&self->symbols[map->type], sym); |
505 | nr_syms++; | 518 | nr_syms++; |
506 | } | 519 | } |
507 | } | 520 | } |
@@ -699,7 +712,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, struct map *map, | |||
699 | if (filter && filter(map, f)) | 712 | if (filter && filter(map, f)) |
700 | symbol__delete(f); | 713 | symbol__delete(f); |
701 | else { | 714 | else { |
702 | symbols__insert(&self->functions, f); | 715 | symbols__insert(&self->symbols[map->type], f); |
703 | ++nr; | 716 | ++nr; |
704 | } | 717 | } |
705 | } | 718 | } |
@@ -721,7 +734,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, struct map *map, | |||
721 | if (filter && filter(map, f)) | 734 | if (filter && filter(map, f)) |
722 | symbol__delete(f); | 735 | symbol__delete(f); |
723 | else { | 736 | else { |
724 | symbols__insert(&self->functions, f); | 737 | symbols__insert(&self->symbols[map->type], f); |
725 | ++nr; | 738 | ++nr; |
726 | } | 739 | } |
727 | } | 740 | } |
@@ -896,7 +909,7 @@ new_symbol: | |||
896 | if (filter && filter(curr_map, f)) | 909 | if (filter && filter(curr_map, f)) |
897 | symbol__delete(f); | 910 | symbol__delete(f); |
898 | else { | 911 | else { |
899 | symbols__insert(&curr_dso->functions, f); | 912 | symbols__insert(&curr_dso->symbols[curr_map->type], f); |
900 | nr++; | 913 | nr++; |
901 | } | 914 | } |
902 | } | 915 | } |
@@ -905,7 +918,7 @@ new_symbol: | |||
905 | * For misannotated, zeroed, ASM function sizes. | 918 | * For misannotated, zeroed, ASM function sizes. |
906 | */ | 919 | */ |
907 | if (nr > 0) | 920 | if (nr > 0) |
908 | symbols__fixup_end(&self->functions); | 921 | symbols__fixup_end(&self->symbols[map->type]); |
909 | err = nr; | 922 | err = nr; |
910 | out_elf_end: | 923 | out_elf_end: |
911 | elf_end(elf); | 924 | elf_end(elf); |
@@ -1191,7 +1204,7 @@ struct symbol *kernel_maps__find_function(u64 ip, struct map **mapp, | |||
1191 | 1204 | ||
1192 | if (map) { | 1205 | if (map) { |
1193 | ip = map->map_ip(map, ip); | 1206 | ip = map->map_ip(map, ip); |
1194 | return map__find_function(map, ip, filter); | 1207 | return map__find_symbol(map, ip, filter); |
1195 | } else | 1208 | } else |
1196 | WARN_ONCE(RB_EMPTY_ROOT(&kernel_maps__functions), | 1209 | WARN_ONCE(RB_EMPTY_ROOT(&kernel_maps__functions), |
1197 | "Empty kernel_maps, was symbol__init() called?\n"); | 1210 | "Empty kernel_maps, was symbol__init() called?\n"); |
@@ -1453,8 +1466,8 @@ do_kallsyms: | |||
1453 | 1466 | ||
1454 | if (err > 0) { | 1467 | if (err > 0) { |
1455 | out_fixup: | 1468 | out_fixup: |
1456 | map__fixup_start(map, &map->dso->functions); | 1469 | map__fixup_start(map); |
1457 | map__fixup_end(map, &map->dso->functions); | 1470 | map__fixup_end(map); |
1458 | } | 1471 | } |
1459 | 1472 | ||
1460 | return err; | 1473 | return err; |