diff options
-rw-r--r-- | tools/perf/builtin-annotate.c | 4 | ||||
-rw-r--r-- | tools/perf/builtin-report.c | 4 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 5 | ||||
-rw-r--r-- | tools/perf/util/event.h | 3 | ||||
-rw-r--r-- | tools/perf/util/map.c | 38 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 16 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 4 |
7 files changed, 41 insertions, 33 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 6d63c2eea2c7..8688bfee42ab 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
@@ -165,7 +165,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) | |||
165 | if (map != NULL) { | 165 | if (map != NULL) { |
166 | got_map: | 166 | got_map: |
167 | ip = map->map_ip(map, ip); | 167 | ip = map->map_ip(map, ip); |
168 | sym = map->dso->find_symbol(map->dso, ip); | 168 | sym = map__find_symbol(map, ip, symbol_filter); |
169 | } else { | 169 | } else { |
170 | /* | 170 | /* |
171 | * If this is outside of all known maps, | 171 | * If this is outside of all known maps, |
@@ -203,7 +203,7 @@ static int | |||
203 | process_mmap_event(event_t *event, unsigned long offset, unsigned long head) | 203 | process_mmap_event(event_t *event, unsigned long offset, unsigned long head) |
204 | { | 204 | { |
205 | struct map *map = map__new(&event->mmap, NULL, 0, | 205 | struct map *map = map__new(&event->mmap, NULL, 0, |
206 | sizeof(struct sym_priv), symbol_filter); | 206 | sizeof(struct sym_priv)); |
207 | struct thread *thread = threads__findnew(event->mmap.pid); | 207 | struct thread *thread = threads__findnew(event->mmap.pid); |
208 | 208 | ||
209 | dump_printf("%p [%p]: PERF_RECORD_MMAP %d: [%p(%p) @ %p]: %s\n", | 209 | dump_printf("%p [%p]: PERF_RECORD_MMAP %d: [%p(%p) @ %p]: %s\n", |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index b3d814b54555..f1bcd35bd220 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->dso->find_symbol(map->dso, ip) : 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) |
@@ -751,7 +751,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) | |||
751 | static int | 751 | static int |
752 | process_mmap_event(event_t *event, unsigned long offset, unsigned long head) | 752 | process_mmap_event(event_t *event, unsigned long offset, unsigned long head) |
753 | { | 753 | { |
754 | struct map *map = map__new(&event->mmap, cwd, cwdlen, 0, NULL); | 754 | struct map *map = map__new(&event->mmap, cwd, cwdlen, 0); |
755 | struct thread *thread = threads__findnew(event->mmap.pid); | 755 | struct thread *thread = threads__findnew(event->mmap.pid); |
756 | 756 | ||
757 | dump_printf("%p [%p]: PERF_RECORD_MMAP %d/%d: [%p(%p) @ %p]: %s\n", | 757 | dump_printf("%p [%p]: PERF_RECORD_MMAP %d/%d: [%p(%p) @ %p]: %s\n", |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index a02fc4146017..ee87640b3359 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -834,7 +834,7 @@ static void event__process_sample(const event_t *self, int counter) | |||
834 | map = thread__find_map(thread, ip); | 834 | map = thread__find_map(thread, ip); |
835 | if (map != NULL) { | 835 | if (map != NULL) { |
836 | ip = map->map_ip(map, ip); | 836 | ip = map->map_ip(map, ip); |
837 | sym = map->dso->find_symbol(map->dso, ip); | 837 | sym = map__find_symbol(map, ip, symbol_filter); |
838 | if (sym == NULL) | 838 | if (sym == NULL) |
839 | return; | 839 | return; |
840 | userspace_samples++; | 840 | userspace_samples++; |
@@ -879,8 +879,7 @@ static void event__process_mmap(event_t *self) | |||
879 | 879 | ||
880 | if (thread != NULL) { | 880 | if (thread != NULL) { |
881 | struct map *map = map__new(&self->mmap, NULL, 0, | 881 | struct map *map = map__new(&self->mmap, NULL, 0, |
882 | sizeof(struct sym_entry), | 882 | sizeof(struct sym_entry)); |
883 | symbol_filter); | ||
884 | if (map != NULL) | 883 | if (map != NULL) |
885 | thread__insert_map(thread, map); | 884 | thread__insert_map(thread, map); |
886 | } | 885 | } |
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 2ae1177be40b..3064a05f0f52 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
@@ -106,10 +106,11 @@ struct symbol; | |||
106 | typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym); | 106 | typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym); |
107 | 107 | ||
108 | struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen, | 108 | struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen, |
109 | unsigned int sym_priv_size, symbol_filter_t filter); | 109 | unsigned int sym_priv_size); |
110 | struct map *map__clone(struct map *self); | 110 | struct map *map__clone(struct map *self); |
111 | int map__overlap(struct map *l, struct map *r); | 111 | int map__overlap(struct map *l, struct map *r); |
112 | size_t map__fprintf(struct map *self, FILE *fp); | 112 | size_t map__fprintf(struct map *self, FILE *fp); |
113 | struct symbol *map__find_symbol(struct map *self, u64 ip, symbol_filter_t filter); | ||
113 | 114 | ||
114 | int event__synthesize_thread(pid_t pid, int (*process)(event_t *event)); | 115 | int event__synthesize_thread(pid_t pid, int (*process)(event_t *event)); |
115 | void event__synthesize_threads(int (*process)(event_t *event)); | 116 | void event__synthesize_threads(int (*process)(event_t *event)); |
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index c1c556825343..d302e513e062 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
@@ -21,7 +21,7 @@ static int strcommon(const char *pathname, char *cwd, int cwdlen) | |||
21 | } | 21 | } |
22 | 22 | ||
23 | struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen, | 23 | struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen, |
24 | unsigned int sym_priv_size, symbol_filter_t filter) | 24 | unsigned int sym_priv_size) |
25 | { | 25 | { |
26 | struct map *self = malloc(sizeof(*self)); | 26 | struct map *self = malloc(sizeof(*self)); |
27 | 27 | ||
@@ -29,7 +29,6 @@ struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen, | |||
29 | const char *filename = event->filename; | 29 | const char *filename = event->filename; |
30 | char newfilename[PATH_MAX]; | 30 | char newfilename[PATH_MAX]; |
31 | int anon; | 31 | int anon; |
32 | bool new_dso; | ||
33 | 32 | ||
34 | if (cwd) { | 33 | if (cwd) { |
35 | int n = strcommon(filename, cwd, cwdlen); | 34 | int n = strcommon(filename, cwd, cwdlen); |
@@ -52,23 +51,10 @@ struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen, | |||
52 | self->end = event->start + event->len; | 51 | self->end = event->start + event->len; |
53 | self->pgoff = event->pgoff; | 52 | self->pgoff = event->pgoff; |
54 | 53 | ||
55 | self->dso = dsos__findnew(filename, sym_priv_size, &new_dso); | 54 | self->dso = dsos__findnew(filename, sym_priv_size); |
56 | if (self->dso == NULL) | 55 | if (self->dso == NULL) |
57 | goto out_delete; | 56 | goto out_delete; |
58 | 57 | ||
59 | if (new_dso) { | ||
60 | int nr = dso__load(self->dso, self, filter); | ||
61 | |||
62 | if (nr < 0) | ||
63 | pr_warning("Failed to open %s, continuing " | ||
64 | "without symbols\n", | ||
65 | self->dso->long_name); | ||
66 | else if (nr == 0) | ||
67 | pr_warning("No symbols found in %s, maybe " | ||
68 | "install a debug package?\n", | ||
69 | self->dso->long_name); | ||
70 | } | ||
71 | |||
72 | if (self->dso == vdso || anon) | 58 | if (self->dso == vdso || anon) |
73 | self->map_ip = self->unmap_ip = identity__map_ip; | 59 | self->map_ip = self->unmap_ip = identity__map_ip; |
74 | else { | 60 | else { |
@@ -82,6 +68,26 @@ out_delete: | |||
82 | return NULL; | 68 | return NULL; |
83 | } | 69 | } |
84 | 70 | ||
71 | struct symbol * | ||
72 | map__find_symbol(struct map *self, u64 ip, symbol_filter_t filter) | ||
73 | { | ||
74 | if (!self->dso->loaded) { | ||
75 | int nr = dso__load(self->dso, self, filter); | ||
76 | |||
77 | if (nr < 0) { | ||
78 | pr_warning("Failed to open %s, continuing without symbols\n", | ||
79 | self->dso->long_name); | ||
80 | return NULL; | ||
81 | } else if (nr == 0) { | ||
82 | pr_warning("No symbols found in %s, maybe install a debug package?\n", | ||
83 | self->dso->long_name); | ||
84 | return NULL; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | return self->dso->find_symbol(self->dso, ip); | ||
89 | } | ||
90 | |||
85 | struct map *map__clone(struct map *self) | 91 | struct map *map__clone(struct map *self) |
86 | { | 92 | { |
87 | struct map *map = malloc(sizeof(*self)); | 93 | struct map *map = malloc(sizeof(*self)); |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 8f0208ce237a..0273d83f728f 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -909,6 +909,8 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | |||
909 | int ret = -1; | 909 | int ret = -1; |
910 | int fd; | 910 | int fd; |
911 | 911 | ||
912 | self->loaded = true; | ||
913 | |||
912 | if (!name) | 914 | if (!name) |
913 | return -1; | 915 | return -1; |
914 | 916 | ||
@@ -1019,6 +1021,8 @@ static int dso__load_module_sym(struct dso *self, struct map *map, | |||
1019 | { | 1021 | { |
1020 | int err = 0, fd = open(self->long_name, O_RDONLY); | 1022 | int err = 0, fd = open(self->long_name, O_RDONLY); |
1021 | 1023 | ||
1024 | self->loaded = true; | ||
1025 | |||
1022 | if (fd < 0) { | 1026 | if (fd < 0) { |
1023 | pr_err("%s: cannot open %s\n", __func__, self->long_name); | 1027 | pr_err("%s: cannot open %s\n", __func__, self->long_name); |
1024 | return err; | 1028 | return err; |
@@ -1214,6 +1218,8 @@ static int dso__load_vmlinux(struct dso *self, struct map *map, | |||
1214 | { | 1218 | { |
1215 | int err, fd = open(vmlinux, O_RDONLY); | 1219 | int err, fd = open(vmlinux, O_RDONLY); |
1216 | 1220 | ||
1221 | self->loaded = true; | ||
1222 | |||
1217 | if (fd < 0) | 1223 | if (fd < 0) |
1218 | return -1; | 1224 | return -1; |
1219 | 1225 | ||
@@ -1312,19 +1318,15 @@ static struct dso *dsos__find(const char *name) | |||
1312 | return NULL; | 1318 | return NULL; |
1313 | } | 1319 | } |
1314 | 1320 | ||
1315 | struct dso *dsos__findnew(const char *name, unsigned int sym_priv_size, | 1321 | struct dso *dsos__findnew(const char *name, unsigned int sym_priv_size) |
1316 | bool *is_new) | ||
1317 | { | 1322 | { |
1318 | struct dso *dso = dsos__find(name); | 1323 | struct dso *dso = dsos__find(name); |
1319 | 1324 | ||
1320 | if (!dso) { | 1325 | if (!dso) { |
1321 | dso = dso__new(name, sym_priv_size); | 1326 | dso = dso__new(name, sym_priv_size); |
1322 | if (dso) { | 1327 | if (dso != NULL) |
1323 | dsos__add(dso); | 1328 | dsos__add(dso); |
1324 | *is_new = true; | 1329 | } |
1325 | } | ||
1326 | } else | ||
1327 | *is_new = false; | ||
1328 | 1330 | ||
1329 | return dso; | 1331 | return dso; |
1330 | } | 1332 | } |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 77b7b3e42417..432edbca7806 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -46,6 +46,7 @@ struct dso { | |||
46 | unsigned int sym_priv_size; | 46 | unsigned int sym_priv_size; |
47 | unsigned char adjust_symbols; | 47 | unsigned char adjust_symbols; |
48 | unsigned char slen_calculated; | 48 | unsigned char slen_calculated; |
49 | bool loaded; | ||
49 | unsigned char origin; | 50 | unsigned char origin; |
50 | const char *short_name; | 51 | const char *short_name; |
51 | char *long_name; | 52 | char *long_name; |
@@ -64,8 +65,7 @@ struct symbol *dso__find_symbol(struct dso *self, u64 ip); | |||
64 | 65 | ||
65 | int dsos__load_kernel(const char *vmlinux, unsigned int sym_priv_size, | 66 | int dsos__load_kernel(const char *vmlinux, unsigned int sym_priv_size, |
66 | symbol_filter_t filter, int modules); | 67 | symbol_filter_t filter, int modules); |
67 | struct dso *dsos__findnew(const char *name, unsigned int sym_priv_size, | 68 | struct dso *dsos__findnew(const char *name, unsigned int sym_priv_size); |
68 | bool *is_new); | ||
69 | int dso__load(struct dso *self, struct map *map, symbol_filter_t filter); | 69 | int dso__load(struct dso *self, struct map *map, symbol_filter_t filter); |
70 | void dsos__fprintf(FILE *fp); | 70 | void dsos__fprintf(FILE *fp); |
71 | 71 | ||