aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/symbol.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r--tools/perf/util/symbol.c53
1 files changed, 52 insertions, 1 deletions
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);