aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/symbol.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r--tools/perf/util/symbol.c104
1 files changed, 96 insertions, 8 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index e63ddb469de7..8134c49deae6 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -29,7 +29,6 @@ enum dso_origin {
29}; 29};
30 30
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_groups__find_by_name(struct map_groups *self, char *name);
33static 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);
34struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr); 33struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr);
35static int dso__load_kernel_sym(struct dso *self, struct map *map, 34static int dso__load_kernel_sym(struct dso *self, struct map *map,
@@ -51,11 +50,21 @@ bool dso__loaded(const struct dso *self, enum map_type type)
51 return self->loaded & (1 << type); 50 return self->loaded & (1 << type);
52} 51}
53 52
53bool dso__sorted_by_name(const struct dso *self, enum map_type type)
54{
55 return self->sorted_by_name & (1 << type);
56}
57
54static void dso__set_loaded(struct dso *self, enum map_type type) 58static void dso__set_loaded(struct dso *self, enum map_type type)
55{ 59{
56 self->loaded |= (1 << type); 60 self->loaded |= (1 << type);
57} 61}
58 62
63static void dso__set_sorted_by_name(struct dso *self, enum map_type type)
64{
65 self->sorted_by_name |= (1 << type);
66}
67
59static bool symbol_type__is_a(char symbol_type, enum map_type map_type) 68static bool symbol_type__is_a(char symbol_type, enum map_type map_type)
60{ 69{
61 switch (map_type) { 70 switch (map_type) {
@@ -176,11 +185,12 @@ struct dso *dso__new(const char *name)
176 dso__set_long_name(self, self->name); 185 dso__set_long_name(self, self->name);
177 self->short_name = self->name; 186 self->short_name = self->name;
178 for (i = 0; i < MAP__NR_TYPES; ++i) 187 for (i = 0; i < MAP__NR_TYPES; ++i)
179 self->symbols[i] = RB_ROOT; 188 self->symbols[i] = self->symbol_names[i] = RB_ROOT;
180 self->find_symbol = dso__find_symbol; 189 self->find_symbol = dso__find_symbol;
181 self->slen_calculated = 0; 190 self->slen_calculated = 0;
182 self->origin = DSO__ORIG_NOT_FOUND; 191 self->origin = DSO__ORIG_NOT_FOUND;
183 self->loaded = 0; 192 self->loaded = 0;
193 self->sorted_by_name = 0;
184 self->has_build_id = 0; 194 self->has_build_id = 0;
185 } 195 }
186 196
@@ -258,11 +268,85 @@ static struct symbol *symbols__find(struct rb_root *self, u64 ip)
258 return NULL; 268 return NULL;
259} 269}
260 270
261struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr) 271struct symbol_name_rb_node {
272 struct rb_node rb_node;
273 struct symbol sym;
274};
275
276static void symbols__insert_by_name(struct rb_root *self, struct symbol *sym)
277{
278 struct rb_node **p = &self->rb_node;
279 struct rb_node *parent = NULL;
280 struct symbol_name_rb_node *symn = ((void *)sym) - sizeof(*parent), *s;
281
282 while (*p != NULL) {
283 parent = *p;
284 s = rb_entry(parent, struct symbol_name_rb_node, rb_node);
285 if (strcmp(sym->name, s->sym.name) < 0)
286 p = &(*p)->rb_left;
287 else
288 p = &(*p)->rb_right;
289 }
290 rb_link_node(&symn->rb_node, parent, p);
291 rb_insert_color(&symn->rb_node, self);
292}
293
294static void symbols__sort_by_name(struct rb_root *self, struct rb_root *source)
295{
296 struct rb_node *nd;
297
298 for (nd = rb_first(source); nd; nd = rb_next(nd)) {
299 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
300 symbols__insert_by_name(self, pos);
301 }
302}
303
304static struct symbol *symbols__find_by_name(struct rb_root *self, const char *name)
305{
306 struct rb_node *n;
307
308 if (self == NULL)
309 return NULL;
310
311 n = self->rb_node;
312
313 while (n) {
314 struct symbol_name_rb_node *s;
315 int cmp;
316
317 s = rb_entry(n, struct symbol_name_rb_node, rb_node);
318 cmp = strcmp(name, s->sym.name);
319
320 if (cmp < 0)
321 n = n->rb_left;
322 else if (cmp > 0)
323 n = n->rb_right;
324 else
325 return &s->sym;
326 }
327
328 return NULL;
329}
330
331struct symbol *dso__find_symbol(struct dso *self,
332 enum map_type type, u64 addr)
262{ 333{
263 return symbols__find(&self->symbols[type], addr); 334 return symbols__find(&self->symbols[type], addr);
264} 335}
265 336
337struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type,
338 const char *name)
339{
340 return symbols__find_by_name(&self->symbol_names[type], name);
341}
342
343void dso__sort_by_name(struct dso *self, enum map_type type)
344{
345 dso__set_sorted_by_name(self, type);
346 return symbols__sort_by_name(&self->symbol_names[type],
347 &self->symbols[type]);
348}
349
266int build_id__sprintf(u8 *self, int len, char *bf) 350int build_id__sprintf(u8 *self, int len, char *bf)
267{ 351{
268 char *bid = bf; 352 char *bid = bf;
@@ -397,7 +481,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
397 *module++ = '\0'; 481 *module++ = '\0';
398 482
399 if (strcmp(self->name, module)) { 483 if (strcmp(self->name, module)) {
400 curr_map = map_groups__find_by_name(mg, module); 484 curr_map = map_groups__find_by_name(mg, map->type, module);
401 if (curr_map == NULL) { 485 if (curr_map == NULL) {
402 pr_debug("/proc/{kallsyms,modules} " 486 pr_debug("/proc/{kallsyms,modules} "
403 "inconsistency!\n"); 487 "inconsistency!\n");
@@ -895,7 +979,7 @@ static int dso__load_sym(struct dso *self, struct map *map,
895 snprintf(dso_name, sizeof(dso_name), 979 snprintf(dso_name, sizeof(dso_name),
896 "%s%s", self->short_name, section_name); 980 "%s%s", self->short_name, section_name);
897 981
898 curr_map = map_groups__find_by_name(mg, dso_name); 982 curr_map = map_groups__find_by_name(mg, map->type, dso_name);
899 if (curr_map == NULL) { 983 if (curr_map == NULL) {
900 u64 start = sym.st_value; 984 u64 start = sym.st_value;
901 985
@@ -1226,11 +1310,12 @@ out:
1226 return ret; 1310 return ret;
1227} 1311}
1228 1312
1229static struct map *map_groups__find_by_name(struct map_groups *self, char *name) 1313struct map *map_groups__find_by_name(struct map_groups *self,
1314 enum map_type type, const char *name)
1230{ 1315{
1231 struct rb_node *nd; 1316 struct rb_node *nd;
1232 1317
1233 for (nd = rb_first(&self->maps[MAP__FUNCTION]); nd; nd = rb_next(nd)) { 1318 for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
1234 struct map *map = rb_entry(nd, struct map, rb_node); 1319 struct map *map = rb_entry(nd, struct map, rb_node);
1235 1320
1236 if (map->dso && strcmp(map->dso->name, name) == 0) 1321 if (map->dso && strcmp(map->dso->name, name) == 0)
@@ -1274,7 +1359,7 @@ static int dsos__set_modules_path_dir(char *dirname)
1274 (int)(dot - dent->d_name), dent->d_name); 1359 (int)(dot - dent->d_name), dent->d_name);
1275 1360
1276 strxfrchar(dso_name, '-', '_'); 1361 strxfrchar(dso_name, '-', '_');
1277 map = map_groups__find_by_name(kmaps, dso_name); 1362 map = map_groups__find_by_name(kmaps, MAP__FUNCTION, dso_name);
1278 if (map == NULL) 1363 if (map == NULL)
1279 continue; 1364 continue;
1280 1365
@@ -1671,6 +1756,9 @@ int symbol__init(struct symbol_conf *conf)
1671 1756
1672 elf_version(EV_CURRENT); 1757 elf_version(EV_CURRENT);
1673 symbol__priv_size = pconf->priv_size; 1758 symbol__priv_size = pconf->priv_size;
1759 if (pconf->sort_by_name)
1760 symbol__priv_size += (sizeof(struct symbol_name_rb_node) -
1761 sizeof(struct symbol));
1674 map_groups__init(kmaps); 1762 map_groups__init(kmaps);
1675 1763
1676 if (pconf->try_vmlinux_path && vmlinux_path__init() < 0) 1764 if (pconf->try_vmlinux_path && vmlinux_path__init() < 0)