aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/symbol.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2009-11-27 13:29:17 -0500
committerIngo Molnar <mingo@elte.hu>2009-11-27 14:21:59 -0500
commit6a4694a433a218c729d336b348a01bfc720da095 (patch)
tree19c166d8cb244fa0ec504cd49f7de957552ce573 /tools/perf/util/symbol.c
parent3610583c29563e23dd038d2870f59c88438bf7a3 (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.c59
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 {
31static void dsos__add(struct list_head *head, struct dso *dso); 31static void dsos__add(struct list_head *head, struct dso *dso);
32static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); 32static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
33static void kernel_maps__insert(struct map *map); 33static void kernel_maps__insert(struct map *map);
34struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr);
34static int dso__load_kernel_sym(struct dso *self, struct map *map, 35static int dso__load_kernel_sym(struct dso *self, struct map *map,
35 symbol_filter_t filter); 36 symbol_filter_t filter);
36unsigned int symbol__priv_size; 37unsigned 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
181void dso__delete(struct dso *self) 184void 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
237struct symbol *dso__find_function(struct dso *self, u64 ip) 242struct 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
242int build_id__sprintf(u8 *self, int len, char *bf) 247int 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
270static const char * map_type__name[MAP__NR_TYPES] = {
271 [MAP__FUNCTION] = "Functions",
272};
273
265size_t dso__fprintf(struct dso *self, FILE *fp) 274size_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;
910out_elf_end: 923out_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) {
1455out_fixup: 1468out_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;