diff options
-rw-r--r-- | tools/perf/util/build-id.c | 22 | ||||
-rw-r--r-- | tools/perf/util/build-id.h | 2 | ||||
-rw-r--r-- | tools/perf/util/callchain.c | 1 | ||||
-rw-r--r-- | tools/perf/util/callchain.h | 1 | ||||
-rw-r--r-- | tools/perf/util/hist.c | 34 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 12 |
6 files changed, 54 insertions, 18 deletions
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 0f60a3906808..70c5cf87d020 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c | |||
@@ -6,6 +6,8 @@ | |||
6 | * Copyright (C) 2009, 2010 Red Hat Inc. | 6 | * Copyright (C) 2009, 2010 Red Hat Inc. |
7 | * Copyright (C) 2009, 2010 Arnaldo Carvalho de Melo <acme@redhat.com> | 7 | * Copyright (C) 2009, 2010 Arnaldo Carvalho de Melo <acme@redhat.com> |
8 | */ | 8 | */ |
9 | #include "util.h" | ||
10 | #include <stdio.h> | ||
9 | #include "build-id.h" | 11 | #include "build-id.h" |
10 | #include "event.h" | 12 | #include "event.h" |
11 | #include "symbol.h" | 13 | #include "symbol.h" |
@@ -37,3 +39,23 @@ struct perf_event_ops build_id__mark_dso_hit_ops = { | |||
37 | .mmap = event__process_mmap, | 39 | .mmap = event__process_mmap, |
38 | .fork = event__process_task, | 40 | .fork = event__process_task, |
39 | }; | 41 | }; |
42 | |||
43 | char *dso__build_id_filename(struct dso *self, char *bf, size_t size) | ||
44 | { | ||
45 | char build_id_hex[BUILD_ID_SIZE * 2 + 1]; | ||
46 | const char *home; | ||
47 | |||
48 | if (!self->has_build_id) | ||
49 | return NULL; | ||
50 | |||
51 | build_id__sprintf(self->build_id, sizeof(self->build_id), build_id_hex); | ||
52 | home = getenv("HOME"); | ||
53 | if (bf == NULL) { | ||
54 | if (asprintf(&bf, "%s/%s/.build-id/%.2s/%s", home, | ||
55 | DEBUG_CACHE_DIR, build_id_hex, build_id_hex + 2) < 0) | ||
56 | return NULL; | ||
57 | } else | ||
58 | snprintf(bf, size, "%s/%s/.build-id/%.2s/%s", home, | ||
59 | DEBUG_CACHE_DIR, build_id_hex, build_id_hex + 2); | ||
60 | return bf; | ||
61 | } | ||
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h index 1d981d63cf9a..5dafb00eaa06 100644 --- a/tools/perf/util/build-id.h +++ b/tools/perf/util/build-id.h | |||
@@ -5,4 +5,6 @@ | |||
5 | 5 | ||
6 | extern struct perf_event_ops build_id__mark_dso_hit_ops; | 6 | extern struct perf_event_ops build_id__mark_dso_hit_ops; |
7 | 7 | ||
8 | char *dso__build_id_filename(struct dso *self, char *bf, size_t size); | ||
9 | |||
8 | #endif | 10 | #endif |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 21a52e0a4435..62b69ad4aa73 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <errno.h> | 15 | #include <errno.h> |
16 | #include <math.h> | 16 | #include <math.h> |
17 | 17 | ||
18 | #include "util.h" | ||
18 | #include "callchain.h" | 19 | #include "callchain.h" |
19 | 20 | ||
20 | bool ip_callchain__valid(struct ip_callchain *chain, event_t *event) | 21 | bool ip_callchain__valid(struct ip_callchain *chain, event_t *event) |
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 1cba1f5504e7..1ca73e4a2723 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
@@ -5,7 +5,6 @@ | |||
5 | #include <linux/list.h> | 5 | #include <linux/list.h> |
6 | #include <linux/rbtree.h> | 6 | #include <linux/rbtree.h> |
7 | #include "event.h" | 7 | #include "event.h" |
8 | #include "util.h" | ||
9 | #include "symbol.h" | 8 | #include "symbol.h" |
10 | 9 | ||
11 | enum chain_mode { | 10 | enum chain_mode { |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 9a71c94f057a..739c39fd0ade 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #include "build-id.h" | ||
1 | #include "util.h" | 2 | #include "util.h" |
2 | #include "hist.h" | 3 | #include "hist.h" |
3 | #include "session.h" | 4 | #include "session.h" |
@@ -988,22 +989,35 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head) | |||
988 | struct symbol *sym = self->ms.sym; | 989 | struct symbol *sym = self->ms.sym; |
989 | struct map *map = self->ms.map; | 990 | struct map *map = self->ms.map; |
990 | struct dso *dso = map->dso; | 991 | struct dso *dso = map->dso; |
991 | const char *filename = dso->long_name; | 992 | char *filename = dso__build_id_filename(dso, NULL, 0); |
992 | char command[PATH_MAX * 2]; | 993 | char command[PATH_MAX * 2]; |
993 | FILE *file; | 994 | FILE *file; |
995 | int err = -1; | ||
994 | u64 len; | 996 | u64 len; |
995 | 997 | ||
996 | if (!filename) | 998 | if (filename == NULL) { |
997 | return -1; | 999 | if (dso->has_build_id) { |
1000 | pr_err("Can't annotate %s: not enough memory\n", | ||
1001 | sym->name); | ||
1002 | return -1; | ||
1003 | } | ||
1004 | /* | ||
1005 | * If we don't have build-ids, well, lets hope that this | ||
1006 | * DSO is the same as when 'perf record' ran. | ||
1007 | */ | ||
1008 | filename = dso->long_name; | ||
1009 | } | ||
998 | 1010 | ||
999 | if (dso->origin == DSO__ORIG_KERNEL) { | 1011 | if (dso->origin == DSO__ORIG_KERNEL) { |
1000 | if (dso->annotate_warned) | 1012 | if (dso->annotate_warned) { |
1001 | return 0; | 1013 | err = 0; |
1014 | goto out_free_filename; | ||
1015 | } | ||
1002 | dso->annotate_warned = 1; | 1016 | dso->annotate_warned = 1; |
1003 | pr_err("Can't annotate %s: No vmlinux file was found in the " | 1017 | pr_err("Can't annotate %s: No vmlinux file was found in the " |
1004 | "path:\n", sym->name); | 1018 | "path:\n", sym->name); |
1005 | vmlinux_path__fprintf(stderr); | 1019 | vmlinux_path__fprintf(stderr); |
1006 | return -1; | 1020 | goto out_free_filename; |
1007 | } | 1021 | } |
1008 | 1022 | ||
1009 | pr_debug("%s: filename=%s, sym=%s, start=%#Lx, end=%#Lx\n", __func__, | 1023 | pr_debug("%s: filename=%s, sym=%s, start=%#Lx, end=%#Lx\n", __func__, |
@@ -1025,14 +1039,18 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head) | |||
1025 | 1039 | ||
1026 | file = popen(command, "r"); | 1040 | file = popen(command, "r"); |
1027 | if (!file) | 1041 | if (!file) |
1028 | return -1; | 1042 | goto out_free_filename; |
1029 | 1043 | ||
1030 | while (!feof(file)) | 1044 | while (!feof(file)) |
1031 | if (hist_entry__parse_objdump_line(self, file, head) < 0) | 1045 | if (hist_entry__parse_objdump_line(self, file, head) < 0) |
1032 | break; | 1046 | break; |
1033 | 1047 | ||
1034 | pclose(file); | 1048 | pclose(file); |
1035 | return 0; | 1049 | err = 0; |
1050 | out_free_filename: | ||
1051 | if (dso->has_build_id) | ||
1052 | free(filename); | ||
1053 | return err; | ||
1036 | } | 1054 | } |
1037 | 1055 | ||
1038 | void hists__inc_nr_events(struct hists *self, u32 type) | 1056 | void hists__inc_nr_events(struct hists *self, u32 type) |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 96bff0e54863..aaa51ba147df 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <sys/param.h> | 11 | #include <sys/param.h> |
12 | #include <fcntl.h> | 12 | #include <fcntl.h> |
13 | #include <unistd.h> | 13 | #include <unistd.h> |
14 | #include "build-id.h" | ||
14 | #include "symbol.h" | 15 | #include "symbol.h" |
15 | #include "strlist.h" | 16 | #include "strlist.h" |
16 | 17 | ||
@@ -1293,7 +1294,6 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | |||
1293 | int size = PATH_MAX; | 1294 | int size = PATH_MAX; |
1294 | char *name; | 1295 | char *name; |
1295 | u8 build_id[BUILD_ID_SIZE]; | 1296 | u8 build_id[BUILD_ID_SIZE]; |
1296 | char build_id_hex[BUILD_ID_SIZE * 2 + 1]; | ||
1297 | int ret = -1; | 1297 | int ret = -1; |
1298 | int fd; | 1298 | int fd; |
1299 | struct machine *machine; | 1299 | struct machine *machine; |
@@ -1325,15 +1325,8 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) | |||
1325 | } | 1325 | } |
1326 | 1326 | ||
1327 | self->origin = DSO__ORIG_BUILD_ID_CACHE; | 1327 | self->origin = DSO__ORIG_BUILD_ID_CACHE; |
1328 | 1328 | if (dso__build_id_filename(self, name, size) != NULL) | |
1329 | if (self->has_build_id) { | ||
1330 | build_id__sprintf(self->build_id, sizeof(self->build_id), | ||
1331 | build_id_hex); | ||
1332 | snprintf(name, size, "%s/%s/.build-id/%.2s/%s", | ||
1333 | getenv("HOME"), DEBUG_CACHE_DIR, | ||
1334 | build_id_hex, build_id_hex + 2); | ||
1335 | goto open_file; | 1329 | goto open_file; |
1336 | } | ||
1337 | more: | 1330 | more: |
1338 | do { | 1331 | do { |
1339 | self->origin++; | 1332 | self->origin++; |
@@ -1349,6 +1342,7 @@ more: | |||
1349 | case DSO__ORIG_BUILDID: | 1342 | case DSO__ORIG_BUILDID: |
1350 | if (filename__read_build_id(self->long_name, build_id, | 1343 | if (filename__read_build_id(self->long_name, build_id, |
1351 | sizeof(build_id))) { | 1344 | sizeof(build_id))) { |
1345 | char build_id_hex[BUILD_ID_SIZE * 2 + 1]; | ||
1352 | build_id__sprintf(build_id, sizeof(build_id), | 1346 | build_id__sprintf(build_id, sizeof(build_id), |
1353 | build_id_hex); | 1347 | build_id_hex); |
1354 | snprintf(name, size, | 1348 | snprintf(name, size, |