diff options
| -rw-r--r-- | tools/perf/builtin-annotate.c | 2 | ||||
| -rw-r--r-- | tools/perf/builtin-report.c | 2 | ||||
| -rw-r--r-- | tools/perf/builtin-top.c | 2 | ||||
| -rw-r--r-- | tools/perf/util/event.h | 12 | ||||
| -rw-r--r-- | tools/perf/util/map.c | 12 | ||||
| -rw-r--r-- | tools/perf/util/symbol.c | 59 | ||||
| -rw-r--r-- | tools/perf/util/symbol.h | 7 |
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 | ||
| 461 | static int call__match(struct symbol *sym) | 461 | static 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 | ||
| 83 | enum map_type { | 83 | enum map_type { |
| 84 | MAP__FUNCTION, | 84 | MAP__FUNCTION = 0, |
| 85 | |||
| 86 | MAP__NR_TYPES, | ||
| 85 | }; | 87 | }; |
| 86 | 88 | ||
| 87 | struct map { | 89 | struct map { |
| @@ -125,10 +127,10 @@ void map__delete(struct map *self); | |||
| 125 | struct map *map__clone(struct map *self); | 127 | struct map *map__clone(struct map *self); |
| 126 | int map__overlap(struct map *l, struct map *r); | 128 | int map__overlap(struct map *l, struct map *r); |
| 127 | size_t map__fprintf(struct map *self, FILE *fp); | 129 | size_t map__fprintf(struct map *self, FILE *fp); |
| 128 | struct symbol *map__find_function(struct map *self, u64 ip, | 130 | struct symbol *map__find_symbol(struct map *self, u64 addr, |
| 129 | symbol_filter_t filter); | 131 | symbol_filter_t filter); |
| 130 | void map__fixup_start(struct map *self, struct rb_root *symbols); | 132 | void map__fixup_start(struct map *self); |
| 131 | void map__fixup_end(struct map *self, struct rb_root *symbols); | 133 | void map__fixup_end(struct map *self); |
| 132 | 134 | ||
| 133 | int event__synthesize_thread(pid_t pid, int (*process)(event_t *event)); | 135 | int event__synthesize_thread(pid_t pid, int (*process)(event_t *event)); |
| 134 | void event__synthesize_threads(int (*process)(event_t *event)); | 136 | void 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 | ||
| 85 | void map__fixup_start(struct map *self, struct rb_root *symbols) | 85 | void 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 | ||
| 94 | void map__fixup_end(struct map *self, struct rb_root *symbols) | 95 | void 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 | ||
| 105 | struct symbol *map__find_function(struct map *self, u64 ip, | 107 | struct 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 | ||
| 144 | struct map *map__clone(struct map *self) | 146 | struct 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 { | |||
| 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; |
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 | ||
| 66 | struct dso { | 66 | struct 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 { | |||
| 83 | struct dso *dso__new(const char *name); | 84 | struct dso *dso__new(const char *name); |
| 84 | void dso__delete(struct dso *self); | 85 | void dso__delete(struct dso *self); |
| 85 | 86 | ||
| 86 | struct symbol *dso__find_function(struct dso *self, u64 ip); | ||
| 87 | |||
| 88 | bool dso__loaded(const struct dso *self, enum map_type type); | 87 | bool dso__loaded(const struct dso *self, enum map_type type); |
| 89 | 88 | ||
| 90 | struct dso *dsos__findnew(const char *name); | 89 | struct dso *dsos__findnew(const char *name); |
