hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/tools/perf/util/build-id.c
....@@ -7,14 +7,18 @@
77 * Copyright (C) 2009, 2010 Red Hat Inc.
88 * Copyright (C) 2009, 2010 Arnaldo Carvalho de Melo <acme@redhat.com>
99 */
10
-#include "util.h"
10
+#include "util.h" // lsdir(), mkdir_p(), rm_rf()
1111 #include <dirent.h>
1212 #include <errno.h>
1313 #include <stdio.h>
1414 #include <sys/stat.h>
1515 #include <sys/types.h>
16
+#include "util/copyfile.h"
17
+#include "dso.h"
1618 #include "build-id.h"
1719 #include "event.h"
20
+#include "namespaces.h"
21
+#include "map.h"
1822 #include "symbol.h"
1923 #include "thread.h"
2024 #include <linux/kernel.h>
....@@ -27,14 +31,20 @@
2731 #include "probe-file.h"
2832 #include "strlist.h"
2933
30
-#include "sane_ctype.h"
34
+#ifdef HAVE_DEBUGINFOD_SUPPORT
35
+#include <elfutils/debuginfod.h>
36
+#endif
37
+
38
+#include <linux/ctype.h>
39
+#include <linux/zalloc.h>
40
+#include <asm/bug.h>
3141
3242 static bool no_buildid_cache;
3343
3444 int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused,
3545 union perf_event *event,
3646 struct perf_sample *sample,
37
- struct perf_evsel *evsel __maybe_unused,
47
+ struct evsel *evsel __maybe_unused,
3848 struct machine *machine)
3949 {
4050 struct addr_location al;
....@@ -86,13 +96,15 @@
8696 .ordered_events = true,
8797 };
8898
89
-int build_id__sprintf(const u8 *build_id, int len, char *bf)
99
+int build_id__sprintf(const struct build_id *build_id, char *bf)
90100 {
91101 char *bid = bf;
92
- const u8 *raw = build_id;
93
- int i;
102
+ const u8 *raw = build_id->data;
103
+ size_t i;
94104
95
- for (i = 0; i < len; ++i) {
105
+ bf[0] = 0x0;
106
+
107
+ for (i = 0; i < build_id->size; ++i) {
96108 sprintf(bid, "%02x", *raw);
97109 ++raw;
98110 bid += 2;
....@@ -104,7 +116,7 @@
104116 int sysfs__sprintf_build_id(const char *root_dir, char *sbuild_id)
105117 {
106118 char notes[PATH_MAX];
107
- u8 build_id[BUILD_ID_SIZE];
119
+ struct build_id bid;
108120 int ret;
109121
110122 if (!root_dir)
....@@ -112,25 +124,23 @@
112124
113125 scnprintf(notes, sizeof(notes), "%s/sys/kernel/notes", root_dir);
114126
115
- ret = sysfs__read_build_id(notes, build_id, sizeof(build_id));
127
+ ret = sysfs__read_build_id(notes, &bid);
116128 if (ret < 0)
117129 return ret;
118130
119
- return build_id__sprintf(build_id, sizeof(build_id), sbuild_id);
131
+ return build_id__sprintf(&bid, sbuild_id);
120132 }
121133
122134 int filename__sprintf_build_id(const char *pathname, char *sbuild_id)
123135 {
124
- u8 build_id[BUILD_ID_SIZE];
136
+ struct build_id bid;
125137 int ret;
126138
127
- ret = filename__read_build_id(pathname, build_id, sizeof(build_id));
139
+ ret = filename__read_build_id(pathname, &bid);
128140 if (ret < 0)
129141 return ret;
130
- else if (ret != sizeof(build_id))
131
- return -EINVAL;
132142
133
- return build_id__sprintf(build_id, sizeof(build_id), sbuild_id);
143
+ return build_id__sprintf(&bid, sbuild_id);
134144 }
135145
136146 /* asnprintf consolidates asprintf and snprintf */
....@@ -263,7 +273,7 @@
263273 if (!dso->has_build_id)
264274 return NULL;
265275
266
- build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
276
+ build_id__sprintf(&dso->bid, sbuild_id);
267277 linkname = build_id_cache__linkname(sbuild_id, NULL, 0);
268278 if (!linkname)
269279 return NULL;
....@@ -288,18 +298,20 @@
288298 continue; \
289299 else
290300
291
-static int write_buildid(const char *name, size_t name_len, u8 *build_id,
301
+static int write_buildid(const char *name, size_t name_len, struct build_id *bid,
292302 pid_t pid, u16 misc, struct feat_fd *fd)
293303 {
294304 int err;
295
- struct build_id_event b;
305
+ struct perf_record_header_build_id b;
296306 size_t len;
297307
298308 len = name_len + 1;
299309 len = PERF_ALIGN(len, NAME_ALIGN);
300310
301311 memset(&b, 0, sizeof(b));
302
- memcpy(&b.build_id, build_id, BUILD_ID_SIZE);
312
+ memcpy(&b.data, bid->data, bid->size);
313
+ b.size = (u8) bid->size;
314
+ misc |= PERF_RECORD_MISC_BUILD_ID_SIZE;
303315 b.pid = pid;
304316 b.header.misc = misc;
305317 b.header.size = sizeof(b) + len;
....@@ -346,7 +358,7 @@
346358 in_kernel = pos->kernel ||
347359 is_kernel_module(name,
348360 PERF_RECORD_MISC_CPUMODE_UNKNOWN);
349
- err = write_buildid(name, name_len, pos->build_id, machine->pid,
361
+ err = write_buildid(name, name_len, &pos->bid, machine->pid,
350362 in_kernel ? kmisc : umisc, fd);
351363 if (err)
352364 break;
....@@ -364,7 +376,8 @@
364376 if (err)
365377 return err;
366378
367
- for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) {
379
+ for (nd = rb_first_cached(&session->machines.guests); nd;
380
+ nd = rb_next(nd)) {
368381 struct machine *pos = rb_entry(nd, struct machine, rb_node);
369382 err = machine__write_buildid_table(pos, fd);
370383 if (err)
....@@ -397,7 +410,8 @@
397410 if (err)
398411 return err;
399412
400
- for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) {
413
+ for (nd = rb_first_cached(&session->machines.guests); nd;
414
+ nd = rb_next(nd)) {
401415 struct machine *pos = rb_entry(nd, struct machine, rb_node);
402416
403417 err = machine__hit_all_dsos(pos);
....@@ -629,6 +643,21 @@
629643 if (realname && access(realname, R_OK))
630644 zfree(&realname);
631645 nsinfo__mountns_exit(&nsc);
646
+
647
+#ifdef HAVE_DEBUGINFOD_SUPPORT
648
+ if (realname == NULL) {
649
+ debuginfod_client* c = debuginfod_begin();
650
+ if (c != NULL) {
651
+ int fd = debuginfod_find_debuginfo(c,
652
+ (const unsigned char*)sbuild_id, 0,
653
+ &realname);
654
+ if (fd >= 0)
655
+ close(fd); /* retaining reference by realname */
656
+ debuginfod_end(c);
657
+ }
658
+ }
659
+#endif
660
+
632661 out:
633662 free(debugfile);
634663 return realname;
....@@ -743,13 +772,13 @@
743772 return err;
744773 }
745774
746
-static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size,
775
+static int build_id_cache__add_b(const struct build_id *bid,
747776 const char *name, struct nsinfo *nsi,
748777 bool is_kallsyms, bool is_vdso)
749778 {
750779 char sbuild_id[SBUILD_ID_SIZE];
751780
752
- build_id__sprintf(build_id, build_id_size, sbuild_id);
781
+ build_id__sprintf(bid, sbuild_id);
753782
754783 return build_id_cache__add_s(sbuild_id, name, nsi, is_kallsyms,
755784 is_vdso);
....@@ -815,8 +844,8 @@
815844 is_kallsyms = true;
816845 name = machine->mmap_name;
817846 }
818
- return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id), name,
819
- dso->nsinfo, is_kallsyms, is_vdso);
847
+ return build_id_cache__add_b(&dso->bid, name, dso->nsinfo,
848
+ is_kallsyms, is_vdso);
820849 }
821850
822851 static int __dsos__cache_build_ids(struct list_head *head,
....@@ -850,7 +879,8 @@
850879
851880 ret = machine__cache_build_ids(&session->machines.host);
852881
853
- for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) {
882
+ for (nd = rb_first_cached(&session->machines.guests); nd;
883
+ nd = rb_next(nd)) {
854884 struct machine *pos = rb_entry(nd, struct machine, rb_node);
855885 ret |= machine__cache_build_ids(pos);
856886 }
....@@ -867,10 +897,18 @@
867897 struct rb_node *nd;
868898 bool ret = machine__read_build_ids(&session->machines.host, with_hits);
869899
870
- for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) {
900
+ for (nd = rb_first_cached(&session->machines.guests); nd;
901
+ nd = rb_next(nd)) {
871902 struct machine *pos = rb_entry(nd, struct machine, rb_node);
872903 ret |= machine__read_build_ids(pos, with_hits);
873904 }
874905
875906 return ret;
876907 }
908
+
909
+void build_id__init(struct build_id *bid, const u8 *data, size_t size)
910
+{
911
+ WARN_ON(size > BUILD_ID_SIZE);
912
+ memcpy(bid->data, data, size);
913
+ bid->size = size;
914
+}