aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/header.c11
-rw-r--r--tools/perf/util/symbol.c63
-rw-r--r--tools/perf/util/ui/util.c5
3 files changed, 67 insertions, 12 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index d7e67b167ea3..64a85bafde63 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -946,11 +946,16 @@ perf_header__find_attr(u64 id, struct perf_header *header)
946 946
947 /* 947 /*
948 * We set id to -1 if the data file doesn't contain sample 948 * We set id to -1 if the data file doesn't contain sample
949 * ids. Check for this and avoid walking through the entire 949 * ids. This can happen when the data file contains one type
950 * list of ids which may be large. 950 * of event and in that case, the header can still store the
951 * event attribute information. Check for this and avoid
952 * walking through the entire list of ids which may be large.
951 */ 953 */
952 if (id == -1ULL) 954 if (id == -1ULL) {
955 if (header->attrs > 0)
956 return &header->attr[0]->attr;
953 return NULL; 957 return NULL;
958 }
954 959
955 for (i = 0; i < header->attrs; i++) { 960 for (i = 0; i < header->attrs; i++) {
956 struct perf_header_attr *attr = header->attr[i]; 961 struct perf_header_attr *attr = header->attr[i];
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index b39f499e575a..d628c8d1cf5e 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,
@@ -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
diff --git a/tools/perf/util/ui/util.c b/tools/perf/util/ui/util.c
index 9706d9d40279..056c69521a38 100644
--- a/tools/perf/util/ui/util.c
+++ b/tools/perf/util/ui/util.c
@@ -104,9 +104,10 @@ out_destroy_form:
104 return rc; 104 return rc;
105} 105}
106 106
107static const char yes[] = "Yes", no[] = "No";
108
107bool ui__dialog_yesno(const char *msg) 109bool ui__dialog_yesno(const char *msg)
108{ 110{
109 /* newtWinChoice should really be accepting const char pointers... */ 111 /* newtWinChoice should really be accepting const char pointers... */
110 char yes[] = "Yes", no[] = "No"; 112 return newtWinChoice(NULL, (char *)yes, (char *)no, (char *)msg) == 1;
111 return newtWinChoice(NULL, yes, no, (char *)msg) == 1;
112} 113}