diff options
| -rw-r--r-- | tools/perf/util/event.h | 7 | ||||
| -rw-r--r-- | tools/perf/util/header.c | 41 | ||||
| -rw-r--r-- | tools/perf/util/symbol.c | 34 | ||||
| -rw-r--r-- | tools/perf/util/symbol.h | 1 |
4 files changed, 59 insertions, 24 deletions
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 34c6fcb82d92..1f771ce3a957 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
| @@ -69,6 +69,13 @@ struct build_id_event { | |||
| 69 | char filename[]; | 69 | char filename[]; |
| 70 | }; | 70 | }; |
| 71 | 71 | ||
| 72 | struct build_id_list { | ||
| 73 | struct build_id_event event; | ||
| 74 | struct list_head list; | ||
| 75 | const char *dso_name; | ||
| 76 | int len; | ||
| 77 | }; | ||
| 78 | |||
| 72 | typedef union event_union { | 79 | typedef union event_union { |
| 73 | struct perf_event_header header; | 80 | struct perf_event_header header; |
| 74 | struct ip_event ip; | 81 | struct ip_event ip; |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index a4d0bbef9a43..2f702c23f71a 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
| @@ -174,29 +174,18 @@ static void do_write(int fd, void *buf, size_t size) | |||
| 174 | } | 174 | } |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | static bool write_buildid_table(int fd) | 177 | static void write_buildid_table(int fd, struct list_head *id_head) |
| 178 | { | 178 | { |
| 179 | struct dso *pos; | 179 | struct build_id_list *iter, *next; |
| 180 | bool have_buildid = false; | 180 | |
| 181 | 181 | list_for_each_entry_safe(iter, next, id_head, list) { | |
| 182 | list_for_each_entry(pos, &dsos, node) { | 182 | struct build_id_event *b = &iter->event; |
| 183 | struct build_id_event b; | ||
| 184 | size_t len; | ||
| 185 | |||
| 186 | if (filename__read_build_id(pos->long_name, | ||
| 187 | &b.build_id, | ||
| 188 | sizeof(b.build_id)) < 0) | ||
| 189 | continue; | ||
| 190 | have_buildid = true; | ||
| 191 | memset(&b.header, 0, sizeof(b.header)); | ||
| 192 | len = strlen(pos->long_name) + 1; | ||
| 193 | len = ALIGN(len, 64); | ||
| 194 | b.header.size = sizeof(b) + len; | ||
| 195 | do_write(fd, &b, sizeof(b)); | ||
| 196 | do_write(fd, pos->long_name, len); | ||
| 197 | } | ||
| 198 | 183 | ||
| 199 | return have_buildid; | 184 | do_write(fd, b, sizeof(*b)); |
| 185 | do_write(fd, (void *)iter->dso_name, iter->len); | ||
| 186 | list_del(&iter->list); | ||
| 187 | free(iter); | ||
| 188 | } | ||
| 200 | } | 189 | } |
| 201 | 190 | ||
| 202 | static void | 191 | static void |
| @@ -226,10 +215,14 @@ perf_header__adds_write(struct perf_header *self, int fd, bool at_exit) | |||
| 226 | } | 215 | } |
| 227 | 216 | ||
| 228 | if (at_exit) { | 217 | if (at_exit) { |
| 229 | lseek(fd, self->data_offset + self->data_size, SEEK_SET); | 218 | LIST_HEAD(id_list); |
| 230 | if (write_buildid_table(fd)) | 219 | |
| 220 | if (fetch_build_id_table(&id_list)) { | ||
| 221 | lseek(fd, self->data_offset + self->data_size, SEEK_SET); | ||
| 231 | perf_header__set_feat(self, HEADER_BUILD_ID); | 222 | perf_header__set_feat(self, HEADER_BUILD_ID); |
| 232 | lseek(fd, cur_offset, SEEK_SET); | 223 | write_buildid_table(fd, &id_list); |
| 224 | lseek(fd, cur_offset, SEEK_SET); | ||
| 225 | } | ||
| 233 | } | 226 | } |
| 234 | }; | 227 | }; |
| 235 | 228 | ||
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index a2e95ce1f223..9c286db62003 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
| @@ -851,6 +851,40 @@ out_close: | |||
| 851 | return err; | 851 | return err; |
| 852 | } | 852 | } |
| 853 | 853 | ||
| 854 | bool fetch_build_id_table(struct list_head *head) | ||
| 855 | { | ||
| 856 | bool have_buildid = false; | ||
| 857 | struct dso *pos; | ||
| 858 | |||
| 859 | list_for_each_entry(pos, &dsos, node) { | ||
| 860 | struct build_id_list *new; | ||
| 861 | struct build_id_event b; | ||
| 862 | size_t len; | ||
| 863 | |||
| 864 | if (filename__read_build_id(pos->long_name, | ||
| 865 | &b.build_id, | ||
| 866 | sizeof(b.build_id)) < 0) | ||
| 867 | continue; | ||
| 868 | have_buildid = true; | ||
| 869 | memset(&b.header, 0, sizeof(b.header)); | ||
| 870 | len = strlen(pos->long_name) + 1; | ||
| 871 | len = ALIGN(len, 64); | ||
| 872 | b.header.size = sizeof(b) + len; | ||
| 873 | |||
| 874 | new = malloc(sizeof(*new)); | ||
| 875 | if (!new) | ||
| 876 | die("No memory\n"); | ||
| 877 | |||
| 878 | memcpy(&new->event, &b, sizeof(b)); | ||
| 879 | new->dso_name = pos->long_name; | ||
| 880 | new->len = len; | ||
| 881 | |||
| 882 | list_add_tail(&new->list, head); | ||
| 883 | } | ||
| 884 | |||
| 885 | return have_buildid; | ||
| 886 | } | ||
| 887 | |||
| 854 | int filename__read_build_id(const char *filename, void *bf, size_t size) | 888 | int filename__read_build_id(const char *filename, void *bf, size_t size) |
| 855 | { | 889 | { |
| 856 | int fd, err = -1; | 890 | int fd, err = -1; |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index f8c1899af483..0a34a5493f1b 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
| @@ -86,6 +86,7 @@ char dso__symtab_origin(const struct dso *self); | |||
| 86 | void dso__set_build_id(struct dso *self, void *build_id); | 86 | void dso__set_build_id(struct dso *self, void *build_id); |
| 87 | 87 | ||
| 88 | int filename__read_build_id(const char *filename, void *bf, size_t size); | 88 | int filename__read_build_id(const char *filename, void *bf, size_t size); |
| 89 | bool fetch_build_id_table(struct list_head *head); | ||
| 89 | int build_id__sprintf(u8 *self, int len, char *bf); | 90 | int build_id__sprintf(u8 *self, int len, char *bf); |
| 90 | 91 | ||
| 91 | int load_kernel(symbol_filter_t filter); | 92 | int load_kernel(symbol_filter_t filter); |
