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.c67
1 files changed, 58 insertions, 9 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index b39f499e575a..439ab947daf4 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -295,7 +295,9 @@ static void symbols__insert_by_name(struct rb_root *self, struct symbol *sym)
295{ 295{
296 struct rb_node **p = &self->rb_node; 296 struct rb_node **p = &self->rb_node;
297 struct rb_node *parent = NULL; 297 struct rb_node *parent = NULL;
298 struct symbol_name_rb_node *symn = ((void *)sym) - sizeof(*parent), *s; 298 struct symbol_name_rb_node *symn, *s;
299
300 symn = container_of(sym, struct symbol_name_rb_node, sym);
299 301
300 while (*p != NULL) { 302 while (*p != NULL) {
301 parent = *p; 303 parent = *p;
@@ -530,7 +532,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
530 struct machine *machine = kmaps->machine; 532 struct machine *machine = kmaps->machine;
531 struct map *curr_map = map; 533 struct map *curr_map = map;
532 struct symbol *pos; 534 struct symbol *pos;
533 int count = 0; 535 int count = 0, moved = 0;
534 struct rb_root *root = &self->symbols[map->type]; 536 struct rb_root *root = &self->symbols[map->type];
535 struct rb_node *next = rb_first(root); 537 struct rb_node *next = rb_first(root);
536 int kernel_range = 0; 538 int kernel_range = 0;
@@ -588,6 +590,11 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
588 char dso_name[PATH_MAX]; 590 char dso_name[PATH_MAX];
589 struct dso *dso; 591 struct dso *dso;
590 592
593 if (count == 0) {
594 curr_map = map;
595 goto filter_symbol;
596 }
597
591 if (self->kernel == DSO_TYPE_GUEST_KERNEL) 598 if (self->kernel == DSO_TYPE_GUEST_KERNEL)
592 snprintf(dso_name, sizeof(dso_name), 599 snprintf(dso_name, sizeof(dso_name),
593 "[guest.kernel].%d", 600 "[guest.kernel].%d",
@@ -613,7 +620,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
613 map_groups__insert(kmaps, curr_map); 620 map_groups__insert(kmaps, curr_map);
614 ++kernel_range; 621 ++kernel_range;
615 } 622 }
616 623filter_symbol:
617 if (filter && filter(curr_map, pos)) { 624 if (filter && filter(curr_map, pos)) {
618discard_symbol: rb_erase(&pos->rb_node, root); 625discard_symbol: rb_erase(&pos->rb_node, root);
619 symbol__delete(pos); 626 symbol__delete(pos);
@@ -621,8 +628,9 @@ discard_symbol: rb_erase(&pos->rb_node, root);
621 if (curr_map != map) { 628 if (curr_map != map) {
622 rb_erase(&pos->rb_node, root); 629 rb_erase(&pos->rb_node, root);
623 symbols__insert(&curr_map->dso->symbols[curr_map->type], pos); 630 symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
624 } 631 ++moved;
625 count++; 632 } else
633 ++count;
626 } 634 }
627 } 635 }
628 636
@@ -632,7 +640,7 @@ discard_symbol: rb_erase(&pos->rb_node, root);
632 dso__set_loaded(curr_map->dso, curr_map->type); 640 dso__set_loaded(curr_map->dso, curr_map->type);
633 } 641 }
634 642
635 return count; 643 return count + moved;
636} 644}
637 645
638int dso__load_kallsyms(struct dso *self, const char *filename, 646int dso__load_kallsyms(struct dso *self, const char *filename,
@@ -1772,8 +1780,8 @@ out_failure:
1772 return -1; 1780 return -1;
1773} 1781}
1774 1782
1775static int dso__load_vmlinux(struct dso *self, struct map *map, 1783int dso__load_vmlinux(struct dso *self, struct map *map,
1776 const char *vmlinux, symbol_filter_t filter) 1784 const char *vmlinux, symbol_filter_t filter)
1777{ 1785{
1778 int err = -1, fd; 1786 int err = -1, fd;
1779 1787
@@ -2123,14 +2131,55 @@ static struct dso *machine__create_kernel(struct machine *self)
2123 return kernel; 2131 return kernel;
2124} 2132}
2125 2133
2134struct process_args {
2135 u64 start;
2136};
2137
2138static int symbol__in_kernel(void *arg, const char *name,
2139 char type __used, u64 start)
2140{
2141 struct process_args *args = arg;
2142
2143 if (strchr(name, '['))
2144 return 0;
2145
2146 args->start = start;
2147 return 1;
2148}
2149
2150/* Figure out the start address of kernel map from /proc/kallsyms */
2151static u64 machine__get_kernel_start_addr(struct machine *machine)
2152{
2153 const char *filename;
2154 char path[PATH_MAX];
2155 struct process_args args;
2156
2157 if (machine__is_host(machine)) {
2158 filename = "/proc/kallsyms";
2159 } else {
2160 if (machine__is_default_guest(machine))
2161 filename = (char *)symbol_conf.default_guest_kallsyms;
2162 else {
2163 sprintf(path, "%s/proc/kallsyms", machine->root_dir);
2164 filename = path;
2165 }
2166 }
2167
2168 if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0)
2169 return 0;
2170
2171 return args.start;
2172}
2173
2126int __machine__create_kernel_maps(struct machine *self, struct dso *kernel) 2174int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
2127{ 2175{
2128 enum map_type type; 2176 enum map_type type;
2177 u64 start = machine__get_kernel_start_addr(self);
2129 2178
2130 for (type = 0; type < MAP__NR_TYPES; ++type) { 2179 for (type = 0; type < MAP__NR_TYPES; ++type) {
2131 struct kmap *kmap; 2180 struct kmap *kmap;
2132 2181
2133 self->vmlinux_maps[type] = map__new2(0, kernel, type); 2182 self->vmlinux_maps[type] = map__new2(start, kernel, type);
2134 if (self->vmlinux_maps[type] == NULL) 2183 if (self->vmlinux_maps[type] == NULL)
2135 return -1; 2184 return -1;
2136 2185