diff options
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r-- | tools/perf/util/symbol.c | 68 |
1 files changed, 37 insertions, 31 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 8db85b4f553f..4ed379b915fe 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -45,9 +45,9 @@ static struct symbol_conf symbol_conf__defaults = { | |||
45 | 45 | ||
46 | static struct rb_root kernel_maps; | 46 | static struct rb_root kernel_maps; |
47 | 47 | ||
48 | static void dso__fixup_sym_end(struct dso *self) | 48 | static void symbols__fixup_end(struct rb_root *self) |
49 | { | 49 | { |
50 | struct rb_node *nd, *prevnd = rb_first(&self->syms); | 50 | struct rb_node *nd, *prevnd = rb_first(self); |
51 | struct symbol *curr, *prev; | 51 | struct symbol *curr, *prev; |
52 | 52 | ||
53 | if (prevnd == NULL) | 53 | if (prevnd == NULL) |
@@ -144,8 +144,8 @@ struct dso *dso__new(const char *name) | |||
144 | strcpy(self->name, name); | 144 | strcpy(self->name, name); |
145 | dso__set_long_name(self, self->name); | 145 | dso__set_long_name(self, self->name); |
146 | self->short_name = self->name; | 146 | self->short_name = self->name; |
147 | self->syms = RB_ROOT; | 147 | self->functions = RB_ROOT; |
148 | self->find_symbol = dso__find_symbol; | 148 | self->find_function = dso__find_function; |
149 | self->slen_calculated = 0; | 149 | self->slen_calculated = 0; |
150 | self->origin = DSO__ORIG_NOT_FOUND; | 150 | self->origin = DSO__ORIG_NOT_FOUND; |
151 | self->loaded = 0; | 151 | self->loaded = 0; |
@@ -155,22 +155,22 @@ struct dso *dso__new(const char *name) | |||
155 | return self; | 155 | return self; |
156 | } | 156 | } |
157 | 157 | ||
158 | static void dso__delete_symbols(struct dso *self) | 158 | static void symbols__delete(struct rb_root *self) |
159 | { | 159 | { |
160 | struct symbol *pos; | 160 | struct symbol *pos; |
161 | struct rb_node *next = rb_first(&self->syms); | 161 | struct rb_node *next = rb_first(self); |
162 | 162 | ||
163 | while (next) { | 163 | while (next) { |
164 | pos = rb_entry(next, struct symbol, rb_node); | 164 | pos = rb_entry(next, struct symbol, rb_node); |
165 | next = rb_next(&pos->rb_node); | 165 | next = rb_next(&pos->rb_node); |
166 | rb_erase(&pos->rb_node, &self->syms); | 166 | rb_erase(&pos->rb_node, self); |
167 | symbol__delete(pos); | 167 | symbol__delete(pos); |
168 | } | 168 | } |
169 | } | 169 | } |
170 | 170 | ||
171 | void dso__delete(struct dso *self) | 171 | void dso__delete(struct dso *self) |
172 | { | 172 | { |
173 | dso__delete_symbols(self); | 173 | symbols__delete(&self->functions); |
174 | if (self->long_name != self->name) | 174 | if (self->long_name != self->name) |
175 | free(self->long_name); | 175 | free(self->long_name); |
176 | free(self); | 176 | free(self); |
@@ -182,9 +182,9 @@ void dso__set_build_id(struct dso *self, void *build_id) | |||
182 | self->has_build_id = 1; | 182 | self->has_build_id = 1; |
183 | } | 183 | } |
184 | 184 | ||
185 | static void dso__insert_symbol(struct dso *self, struct symbol *sym) | 185 | static void symbols__insert(struct rb_root *self, struct symbol *sym) |
186 | { | 186 | { |
187 | struct rb_node **p = &self->syms.rb_node; | 187 | struct rb_node **p = &self->rb_node; |
188 | struct rb_node *parent = NULL; | 188 | struct rb_node *parent = NULL; |
189 | const u64 ip = sym->start; | 189 | const u64 ip = sym->start; |
190 | struct symbol *s; | 190 | struct symbol *s; |
@@ -198,17 +198,17 @@ static void dso__insert_symbol(struct dso *self, struct symbol *sym) | |||
198 | p = &(*p)->rb_right; | 198 | p = &(*p)->rb_right; |
199 | } | 199 | } |
200 | rb_link_node(&sym->rb_node, parent, p); | 200 | rb_link_node(&sym->rb_node, parent, p); |
201 | rb_insert_color(&sym->rb_node, &self->syms); | 201 | rb_insert_color(&sym->rb_node, self); |
202 | } | 202 | } |
203 | 203 | ||
204 | struct symbol *dso__find_symbol(struct dso *self, u64 ip) | 204 | static struct symbol *symbols__find(struct rb_root *self, u64 ip) |
205 | { | 205 | { |
206 | struct rb_node *n; | 206 | struct rb_node *n; |
207 | 207 | ||
208 | if (self == NULL) | 208 | if (self == NULL) |
209 | return NULL; | 209 | return NULL; |
210 | 210 | ||
211 | n = self->syms.rb_node; | 211 | n = self->rb_node; |
212 | 212 | ||
213 | while (n) { | 213 | while (n) { |
214 | struct symbol *s = rb_entry(n, struct symbol, rb_node); | 214 | struct symbol *s = rb_entry(n, struct symbol, rb_node); |
@@ -224,6 +224,11 @@ struct symbol *dso__find_symbol(struct dso *self, u64 ip) | |||
224 | return NULL; | 224 | return NULL; |
225 | } | 225 | } |
226 | 226 | ||
227 | struct symbol *dso__find_function(struct dso *self, u64 ip) | ||
228 | { | ||
229 | return symbols__find(&self->functions, ip); | ||
230 | } | ||
231 | |||
227 | int build_id__sprintf(u8 *self, int len, char *bf) | 232 | int build_id__sprintf(u8 *self, int len, char *bf) |
228 | { | 233 | { |
229 | char *bid = bf; | 234 | char *bid = bf; |
@@ -253,9 +258,9 @@ size_t dso__fprintf(struct dso *self, FILE *fp) | |||
253 | size_t ret = fprintf(fp, "dso: %s (", self->short_name); | 258 | size_t ret = fprintf(fp, "dso: %s (", self->short_name); |
254 | 259 | ||
255 | ret += dso__fprintf_buildid(self, fp); | 260 | ret += dso__fprintf_buildid(self, fp); |
256 | ret += fprintf(fp, ")\n"); | 261 | ret += fprintf(fp, ")\nFunctions:\n"); |
257 | 262 | ||
258 | for (nd = rb_first(&self->syms); nd; nd = rb_next(nd)) { | 263 | for (nd = rb_first(&self->functions); nd; nd = rb_next(nd)) { |
259 | struct symbol *pos = rb_entry(nd, struct symbol, rb_node); | 264 | struct symbol *pos = rb_entry(nd, struct symbol, rb_node); |
260 | ret += symbol__fprintf(pos, fp); | 265 | ret += symbol__fprintf(pos, fp); |
261 | } | 266 | } |
@@ -320,7 +325,7 @@ static int kernel_maps__load_all_kallsyms(void) | |||
320 | * kernel_maps__split_kallsyms, when we have split the | 325 | * kernel_maps__split_kallsyms, when we have split the |
321 | * maps per module | 326 | * maps per module |
322 | */ | 327 | */ |
323 | dso__insert_symbol(kernel_map->dso, sym); | 328 | symbols__insert(&kernel_map->dso->functions, sym); |
324 | } | 329 | } |
325 | 330 | ||
326 | free(line); | 331 | free(line); |
@@ -344,7 +349,7 @@ static int kernel_maps__split_kallsyms(symbol_filter_t filter) | |||
344 | struct map *map = kernel_map; | 349 | struct map *map = kernel_map; |
345 | struct symbol *pos; | 350 | struct symbol *pos; |
346 | int count = 0; | 351 | int count = 0; |
347 | struct rb_node *next = rb_first(&kernel_map->dso->syms); | 352 | struct rb_node *next = rb_first(&kernel_map->dso->functions); |
348 | int kernel_range = 0; | 353 | int kernel_range = 0; |
349 | 354 | ||
350 | while (next) { | 355 | while (next) { |
@@ -394,12 +399,13 @@ static int kernel_maps__split_kallsyms(symbol_filter_t filter) | |||
394 | } | 399 | } |
395 | 400 | ||
396 | if (filter && filter(map, pos)) { | 401 | if (filter && filter(map, pos)) { |
397 | rb_erase(&pos->rb_node, &kernel_map->dso->syms); | 402 | rb_erase(&pos->rb_node, &kernel_map->dso->functions); |
398 | symbol__delete(pos); | 403 | symbol__delete(pos); |
399 | } else { | 404 | } else { |
400 | if (map != kernel_map) { | 405 | if (map != kernel_map) { |
401 | rb_erase(&pos->rb_node, &kernel_map->dso->syms); | 406 | rb_erase(&pos->rb_node, |
402 | dso__insert_symbol(map->dso, pos); | 407 | &kernel_map->dso->functions); |
408 | symbols__insert(&map->dso->functions, pos); | ||
403 | } | 409 | } |
404 | count++; | 410 | count++; |
405 | } | 411 | } |
@@ -414,7 +420,7 @@ static int kernel_maps__load_kallsyms(symbol_filter_t filter) | |||
414 | if (kernel_maps__load_all_kallsyms()) | 420 | if (kernel_maps__load_all_kallsyms()) |
415 | return -1; | 421 | return -1; |
416 | 422 | ||
417 | dso__fixup_sym_end(kernel_map->dso); | 423 | symbols__fixup_end(&kernel_map->dso->functions); |
418 | kernel_map->dso->origin = DSO__ORIG_KERNEL; | 424 | kernel_map->dso->origin = DSO__ORIG_KERNEL; |
419 | 425 | ||
420 | return kernel_maps__split_kallsyms(filter); | 426 | return kernel_maps__split_kallsyms(filter); |
@@ -485,7 +491,7 @@ static int dso__load_perf_map(struct dso *self, struct map *map, | |||
485 | if (filter && filter(map, sym)) | 491 | if (filter && filter(map, sym)) |
486 | symbol__delete(sym); | 492 | symbol__delete(sym); |
487 | else { | 493 | else { |
488 | dso__insert_symbol(self, sym); | 494 | symbols__insert(&self->functions, sym); |
489 | nr_syms++; | 495 | nr_syms++; |
490 | } | 496 | } |
491 | } | 497 | } |
@@ -683,7 +689,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, struct map *map, | |||
683 | if (filter && filter(map, f)) | 689 | if (filter && filter(map, f)) |
684 | symbol__delete(f); | 690 | symbol__delete(f); |
685 | else { | 691 | else { |
686 | dso__insert_symbol(self, f); | 692 | symbols__insert(&self->functions, f); |
687 | ++nr; | 693 | ++nr; |
688 | } | 694 | } |
689 | } | 695 | } |
@@ -705,7 +711,7 @@ static int dso__synthesize_plt_symbols(struct dso *self, struct map *map, | |||
705 | if (filter && filter(map, f)) | 711 | if (filter && filter(map, f)) |
706 | symbol__delete(f); | 712 | symbol__delete(f); |
707 | else { | 713 | else { |
708 | dso__insert_symbol(self, f); | 714 | symbols__insert(&self->functions, f); |
709 | ++nr; | 715 | ++nr; |
710 | } | 716 | } |
711 | } | 717 | } |
@@ -879,7 +885,7 @@ new_symbol: | |||
879 | if (filter && filter(curr_map, f)) | 885 | if (filter && filter(curr_map, f)) |
880 | symbol__delete(f); | 886 | symbol__delete(f); |
881 | else { | 887 | else { |
882 | dso__insert_symbol(curr_dso, f); | 888 | symbols__insert(&curr_dso->functions, f); |
883 | nr++; | 889 | nr++; |
884 | } | 890 | } |
885 | } | 891 | } |
@@ -888,7 +894,7 @@ new_symbol: | |||
888 | * For misannotated, zeroed, ASM function sizes. | 894 | * For misannotated, zeroed, ASM function sizes. |
889 | */ | 895 | */ |
890 | if (nr > 0) | 896 | if (nr > 0) |
891 | dso__fixup_sym_end(self); | 897 | symbols__fixup_end(&self->functions); |
892 | err = nr; | 898 | err = nr; |
893 | out_elf_end: | 899 | out_elf_end: |
894 | elf_end(elf); | 900 | elf_end(elf); |
@@ -1160,8 +1166,8 @@ static void kernel_maps__insert(struct map *map) | |||
1160 | maps__insert(&kernel_maps, map); | 1166 | maps__insert(&kernel_maps, map); |
1161 | } | 1167 | } |
1162 | 1168 | ||
1163 | struct symbol *kernel_maps__find_symbol(u64 ip, struct map **mapp, | 1169 | struct symbol *kernel_maps__find_function(u64 ip, struct map **mapp, |
1164 | symbol_filter_t filter) | 1170 | symbol_filter_t filter) |
1165 | { | 1171 | { |
1166 | struct map *map = maps__find(&kernel_maps, ip); | 1172 | struct map *map = maps__find(&kernel_maps, ip); |
1167 | 1173 | ||
@@ -1170,7 +1176,7 @@ struct symbol *kernel_maps__find_symbol(u64 ip, struct map **mapp, | |||
1170 | 1176 | ||
1171 | if (map) { | 1177 | if (map) { |
1172 | ip = map->map_ip(map, ip); | 1178 | ip = map->map_ip(map, ip); |
1173 | return map__find_symbol(map, ip, filter); | 1179 | return map__find_function(map, ip, filter); |
1174 | } else | 1180 | } else |
1175 | WARN_ONCE(RB_EMPTY_ROOT(&kernel_maps), | 1181 | WARN_ONCE(RB_EMPTY_ROOT(&kernel_maps), |
1176 | "Empty kernel_maps, was symbol__init() called?\n"); | 1182 | "Empty kernel_maps, was symbol__init() called?\n"); |
@@ -1432,8 +1438,8 @@ do_kallsyms: | |||
1432 | 1438 | ||
1433 | if (err > 0) { | 1439 | if (err > 0) { |
1434 | out_fixup: | 1440 | out_fixup: |
1435 | map__fixup_start(map); | 1441 | map__fixup_start(map, &map->dso->functions); |
1436 | map__fixup_end(map); | 1442 | map__fixup_end(map, &map->dso->functions); |
1437 | } | 1443 | } |
1438 | 1444 | ||
1439 | return err; | 1445 | return err; |