aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
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
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')
-rw-r--r--tools/perf/builtin-annotate.c2
-rw-r--r--tools/perf/builtin-report.c2
-rw-r--r--tools/perf/builtin-top.c2
-rw-r--r--tools/perf/util/event.h12
-rw-r--r--tools/perf/util/map.c12
-rw-r--r--tools/perf/util/symbol.c59
-rw-r--r--tools/perf/util/symbol.h7
7 files changed, 56 insertions, 40 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 0846c8a155ed..c32e7609b77b 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -170,7 +170,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
170 map = thread__find_map(thread, ip); 170 map = thread__find_map(thread, ip);
171 if (map != NULL) { 171 if (map != NULL) {
172 ip = map->map_ip(map, ip); 172 ip = map->map_ip(map, ip);
173 sym = map__find_function(map, ip, symbol_filter); 173 sym = map__find_symbol(map, ip, symbol_filter);
174 } else { 174 } else {
175 /* 175 /*
176 * If this is outside of all known maps, 176 * If this is outside of all known maps,
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index e4b1004e76ea..400bef981c6c 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -455,7 +455,7 @@ got_map:
455 dump_printf(" ...... map: %Lx -> %Lx\n", *ipp, ip); 455 dump_printf(" ...... map: %Lx -> %Lx\n", *ipp, ip);
456 *ipp = ip; 456 *ipp = ip;
457 457
458 return map ? map__find_function(map, ip, NULL) : NULL; 458 return map ? map__find_symbol(map, ip, NULL) : NULL;
459} 459}
460 460
461static int call__match(struct symbol *sym) 461static int call__match(struct symbol *sym)
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index a0168f260d06..abe78bbd154a 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -948,7 +948,7 @@ static void event__process_sample(const event_t *self, int counter)
948 map = thread__find_map(thread, ip); 948 map = thread__find_map(thread, ip);
949 if (map != NULL) { 949 if (map != NULL) {
950 ip = map->map_ip(map, ip); 950 ip = map->map_ip(map, ip);
951 sym = map__find_function(map, ip, symbol_filter); 951 sym = map__find_symbol(map, ip, symbol_filter);
952 if (sym == NULL) 952 if (sym == NULL)
953 return; 953 return;
954 userspace_samples++; 954 userspace_samples++;
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 29543bd88007..3ae3c964c901 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -81,7 +81,9 @@ typedef union event_union {
81} event_t; 81} event_t;
82 82
83enum map_type { 83enum map_type {
84 MAP__FUNCTION, 84 MAP__FUNCTION = 0,
85
86 MAP__NR_TYPES,
85}; 87};
86 88
87struct map { 89struct map {
@@ -125,10 +127,10 @@ void map__delete(struct map *self);
125struct map *map__clone(struct map *self); 127struct map *map__clone(struct map *self);
126int map__overlap(struct map *l, struct map *r); 128int map__overlap(struct map *l, struct map *r);
127size_t map__fprintf(struct map *self, FILE *fp); 129size_t map__fprintf(struct map *self, FILE *fp);
128struct symbol *map__find_function(struct map *self, u64 ip, 130struct symbol *map__find_symbol(struct map *self, u64 addr,
129 symbol_filter_t filter); 131 symbol_filter_t filter);
130void map__fixup_start(struct map *self, struct rb_root *symbols); 132void map__fixup_start(struct map *self);
131void map__fixup_end(struct map *self, struct rb_root *symbols); 133void map__fixup_end(struct map *self);
132 134
133int event__synthesize_thread(pid_t pid, int (*process)(event_t *event)); 135int event__synthesize_thread(pid_t pid, int (*process)(event_t *event));
134void event__synthesize_threads(int (*process)(event_t *event)); 136void event__synthesize_threads(int (*process)(event_t *event));
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 52bb4c6cf74d..69f94fe9db20 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -82,8 +82,9 @@ void map__delete(struct map *self)
82 free(self); 82 free(self);
83} 83}
84 84
85void map__fixup_start(struct map *self, struct rb_root *symbols) 85void map__fixup_start(struct map *self)
86{ 86{
87 struct rb_root *symbols = &self->dso->symbols[self->type];
87 struct rb_node *nd = rb_first(symbols); 88 struct rb_node *nd = rb_first(symbols);
88 if (nd != NULL) { 89 if (nd != NULL) {
89 struct symbol *sym = rb_entry(nd, struct symbol, rb_node); 90 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
@@ -91,8 +92,9 @@ void map__fixup_start(struct map *self, struct rb_root *symbols)
91 } 92 }
92} 93}
93 94
94void map__fixup_end(struct map *self, struct rb_root *symbols) 95void map__fixup_end(struct map *self)
95{ 96{
97 struct rb_root *symbols = &self->dso->symbols[self->type];
96 struct rb_node *nd = rb_last(symbols); 98 struct rb_node *nd = rb_last(symbols);
97 if (nd != NULL) { 99 if (nd != NULL) {
98 struct symbol *sym = rb_entry(nd, struct symbol, rb_node); 100 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
@@ -102,8 +104,8 @@ void map__fixup_end(struct map *self, struct rb_root *symbols)
102 104
103#define DSO__DELETED "(deleted)" 105#define DSO__DELETED "(deleted)"
104 106
105struct symbol *map__find_function(struct map *self, u64 ip, 107struct symbol *map__find_symbol(struct map *self, u64 addr,
106 symbol_filter_t filter) 108 symbol_filter_t filter)
107{ 109{
108 if (!dso__loaded(self->dso, self->type)) { 110 if (!dso__loaded(self->dso, self->type)) {
109 int nr = dso__load(self->dso, self, filter); 111 int nr = dso__load(self->dso, self, filter);
@@ -138,7 +140,7 @@ struct symbol *map__find_function(struct map *self, u64 ip,
138 } 140 }
139 } 141 }
140 142
141 return self->dso->find_function(self->dso, ip); 143 return self->dso->find_symbol(self->dso, self->type, addr);
142} 144}
143 145
144struct map *map__clone(struct map *self) 146struct map *map__clone(struct map *self)
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;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 11d41952ce04..8934814d5a64 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -65,8 +65,9 @@ static inline void *symbol__priv(struct symbol *self)
65 65
66struct dso { 66struct dso {
67 struct list_head node; 67 struct list_head node;
68 struct rb_root functions; 68 struct rb_root symbols[MAP__NR_TYPES];
69 struct symbol *(*find_function)(struct dso *, u64 ip); 69 struct symbol *(*find_symbol)(struct dso *self,
70 enum map_type type, u64 addr);
70 u8 adjust_symbols:1; 71 u8 adjust_symbols:1;
71 u8 slen_calculated:1; 72 u8 slen_calculated:1;
72 u8 has_build_id:1; 73 u8 has_build_id:1;
@@ -83,8 +84,6 @@ struct dso {
83struct dso *dso__new(const char *name); 84struct dso *dso__new(const char *name);
84void dso__delete(struct dso *self); 85void dso__delete(struct dso *self);
85 86
86struct symbol *dso__find_function(struct dso *self, u64 ip);
87
88bool dso__loaded(const struct dso *self, enum map_type type); 87bool dso__loaded(const struct dso *self, enum map_type type);
89 88
90struct dso *dsos__findnew(const char *name); 89struct dso *dsos__findnew(const char *name);