aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/util/header.c5
-rw-r--r--tools/perf/util/symbol.c53
-rw-r--r--tools/perf/util/symbol.h2
3 files changed, 59 insertions, 1 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 31731f1606b2..d3d656f9a621 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -241,6 +241,11 @@ perf_header__adds_write(struct perf_header *self, int fd)
241 241
242 buildid_sec = &feat_sec[idx++]; 242 buildid_sec = &feat_sec[idx++];
243 243
244 /*
245 * Read the list of loaded modules with its build_ids
246 */
247 dsos__load_modules();
248
244 /* Write build-ids */ 249 /* Write build-ids */
245 buildid_sec->offset = lseek(fd, 0, SEEK_CUR); 250 buildid_sec->offset = lseek(fd, 0, SEEK_CUR);
246 if (dsos__write_buildid_table(fd) < 0) 251 if (dsos__write_buildid_table(fd) < 0)
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 946ec319568b..7b4cedeb3020 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -9,6 +9,7 @@
9#include <libelf.h> 9#include <libelf.h>
10#include <gelf.h> 10#include <gelf.h>
11#include <elf.h> 11#include <elf.h>
12#include <limits.h>
12#include <sys/utsname.h> 13#include <sys/utsname.h>
13 14
14enum dso_origin { 15enum dso_origin {
@@ -943,6 +944,50 @@ out:
943 return err; 944 return err;
944} 945}
945 946
947int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
948{
949 int fd, err = -1;
950
951 if (size < BUILD_ID_SIZE)
952 goto out;
953
954 fd = open(filename, O_RDONLY);
955 if (fd < 0)
956 goto out;
957
958 while (1) {
959 char bf[BUFSIZ];
960 GElf_Nhdr nhdr;
961 int namesz, descsz;
962
963 if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
964 break;
965
966 namesz = (nhdr.n_namesz + 3) & -4U;
967 descsz = (nhdr.n_descsz + 3) & -4U;
968 if (nhdr.n_type == NT_GNU_BUILD_ID &&
969 nhdr.n_namesz == sizeof("GNU")) {
970 if (read(fd, bf, namesz) != namesz)
971 break;
972 if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
973 if (read(fd, build_id,
974 BUILD_ID_SIZE) == BUILD_ID_SIZE) {
975 err = 0;
976 break;
977 }
978 } else if (read(fd, bf, descsz) != descsz)
979 break;
980 } else {
981 int n = namesz + descsz;
982 if (read(fd, bf, n) != n)
983 break;
984 }
985 }
986 close(fd);
987out:
988 return err;
989}
990
946char dso__symtab_origin(const struct dso *self) 991char dso__symtab_origin(const struct dso *self)
947{ 992{
948 static const char origin[] = { 993 static const char origin[] = {
@@ -1218,7 +1263,7 @@ static struct map *map__new2(u64 start, struct dso *dso)
1218 return self; 1263 return self;
1219} 1264}
1220 1265
1221static int dsos__load_modules(void) 1266int dsos__load_modules(void)
1222{ 1267{
1223 char *line = NULL; 1268 char *line = NULL;
1224 size_t n; 1269 size_t n;
@@ -1268,6 +1313,12 @@ static int dsos__load_modules(void)
1268 goto out_delete_line; 1313 goto out_delete_line;
1269 } 1314 }
1270 1315
1316 snprintf(name, sizeof(name),
1317 "/sys/module/%s/notes/.note.gnu.build-id", line);
1318 if (sysfs__read_build_id(name, dso->build_id,
1319 sizeof(dso->build_id)) == 0)
1320 dso->has_build_id = true;
1321
1271 dso->origin = DSO__ORIG_KMODULE; 1322 dso->origin = DSO__ORIG_KMODULE;
1272 kernel_maps__insert(map); 1323 kernel_maps__insert(map);
1273 dsos__add(dso); 1324 dsos__add(dso);
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 546eb766d81e..da7ec1af255a 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -78,6 +78,7 @@ void dso__delete(struct dso *self);
78struct symbol *dso__find_symbol(struct dso *self, u64 ip); 78struct symbol *dso__find_symbol(struct dso *self, u64 ip);
79 79
80int dsos__load_kernel(const char *vmlinux, symbol_filter_t filter, int modules); 80int dsos__load_kernel(const char *vmlinux, symbol_filter_t filter, int modules);
81int dsos__load_modules(void);
81struct dso *dsos__findnew(const char *name); 82struct dso *dsos__findnew(const char *name);
82int dso__load(struct dso *self, struct map *map, symbol_filter_t filter); 83int dso__load(struct dso *self, struct map *map, symbol_filter_t filter);
83void dsos__fprintf(FILE *fp); 84void dsos__fprintf(FILE *fp);
@@ -89,6 +90,7 @@ char dso__symtab_origin(const struct dso *self);
89void dso__set_build_id(struct dso *self, void *build_id); 90void dso__set_build_id(struct dso *self, void *build_id);
90 91
91int filename__read_build_id(const char *filename, void *bf, size_t size); 92int filename__read_build_id(const char *filename, void *bf, size_t size);
93int sysfs__read_build_id(const char *filename, void *bf, size_t size);
92bool dsos__read_build_ids(void); 94bool dsos__read_build_ids(void);
93int build_id__sprintf(u8 *self, int len, char *bf); 95int build_id__sprintf(u8 *self, int len, char *bf);
94 96