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 | ||
