[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251125080748.461014-1-namhyung@kernel.org>
Date: Tue, 25 Nov 2025 00:07:46 -0800
From: Namhyung Kim <namhyung@...nel.org>
To: Arnaldo Carvalho de Melo <acme@...nel.org>,
Ian Rogers <irogers@...gle.com>,
James Clark <james.clark@...aro.org>
Cc: Jiri Olsa <jolsa@...nel.org>,
Adrian Hunter <adrian.hunter@...el.com>,
Peter Zijlstra <peterz@...radead.org>,
Ingo Molnar <mingo@...nel.org>,
LKML <linux-kernel@...r.kernel.org>,
linux-perf-users@...r.kernel.org,
Eric Biggers <ebiggers@...nel.org>,
Pablo Galindo <pablogsal@...il.com>,
Fangrui Song <maskray@...rceware.org>
Subject: [PATCH v2 1/2] perf jitdump: Add sym/str-tables to build-ID generation
It was reported that python backtrace with JIT dump was broken after the
change to built-in SHA-1 implementation. It seems python generates the
same JIT code for each function. They will become separate DSOs but the
contents are the same. Only difference is in the symbol name.
But this caused a problem that every JIT'ed DSOs will have the same
build-ID which makes perf confused. And it resulted in no python
symbols (from JIT) in the output.
Looking back at the original code before the conversion, it used the
load_addr as well as the code section to distinguish each DSO. But it'd
be better to use contents of symtab and strtab instead as it aligns with
some linker behaviors.
This patch adds a buffer to save all the contents in a single place for
SHA-1 calculation. Probably we need to add sha1_update() or similar to
update the existing hash value with different contents and use it here.
But it's out of scope for this change and I'd like something that can be
backported to the stable trees easily.
Fixes: e3f612c1d8f3945b ("perf genelf: Remove libcrypto dependency and use built-in sha1()")
Cc: Eric Biggers <ebiggers@...nel.org>
Cc: Pablo Galindo <pablogsal@...il.com>
Cc: Fangrui Song <maskray@...rceware.org>
Link: https://github.com/python/cpython/issues/139544
Signed-off-by: Namhyung Kim <namhyung@...nel.org>
---
v2) use symtab/strtab instead of load_addr
tools/perf/util/genelf.c | 32 ++++++++++++++++++++++++++++++--
1 file changed, 30 insertions(+), 2 deletions(-)
diff --git a/tools/perf/util/genelf.c b/tools/perf/util/genelf.c
index 591548b10e34ef6a..a1cd5196f4ec8f88 100644
--- a/tools/perf/util/genelf.c
+++ b/tools/perf/util/genelf.c
@@ -173,6 +173,8 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym,
Elf_Shdr *shdr;
uint64_t eh_frame_base_offset;
char *strsym = NULL;
+ void *build_id_data = NULL, *tmp;
+ int build_id_data_len;
int symlen;
int retval = -1;
@@ -251,6 +253,14 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym,
shdr->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
shdr->sh_entsize = 0;
+ build_id_data = malloc(csize);
+ if (build_id_data == NULL) {
+ warnx("cannot allocate build-id data");
+ goto error;
+ }
+ memcpy(build_id_data, code, csize);
+ build_id_data_len = csize;
+
/*
* Setup .eh_frame_hdr and .eh_frame
*/
@@ -334,6 +344,15 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym,
shdr->sh_entsize = sizeof(Elf_Sym);
shdr->sh_link = unwinding ? 6 : 4; /* index of .strtab section */
+ tmp = realloc(build_id_data, build_id_data_len + sizeof(symtab));
+ if (tmp == NULL) {
+ warnx("cannot allocate build-id data");
+ goto error;
+ }
+ memcpy(tmp + build_id_data_len, symtab, sizeof(symtab));
+ build_id_data = tmp;
+ build_id_data_len += sizeof(symtab);
+
/*
* setup symbols string table
* 2 = 1 for 0 in 1st entry, 1 for the 0 at end of symbol for 2nd entry
@@ -376,6 +395,15 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym,
shdr->sh_flags = 0;
shdr->sh_entsize = 0;
+ tmp = realloc(build_id_data, build_id_data_len + symlen);
+ if (tmp == NULL) {
+ warnx("cannot allocate build-id data");
+ goto error;
+ }
+ memcpy(tmp + build_id_data_len, strsym, symlen);
+ build_id_data = tmp;
+ build_id_data_len += symlen;
+
/*
* setup build-id section
*/
@@ -394,7 +422,7 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym,
/*
* build-id generation
*/
- sha1(code, csize, bnote.build_id);
+ sha1(build_id_data, build_id_data_len, bnote.build_id);
bnote.desc.namesz = sizeof(bnote.name); /* must include 0 termination */
bnote.desc.descsz = sizeof(bnote.build_id);
bnote.desc.type = NT_GNU_BUILD_ID;
@@ -439,7 +467,7 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym,
(void)elf_end(e);
free(strsym);
-
+ free(build_id_data);
return retval;
}
--
2.52.0.460.gd25c4c69ec-goog
Powered by blists - more mailing lists