From nobody Tue Dec 2 01:06:34 2025 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0674E280A51 for ; Mon, 1 Dec 2025 20:55:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764622552; cv=none; b=YifEYg6jQZ/GTAP/Iy/W8fcxwAqeq3G7lZPSYUTubht3apQPEu89y0XWALxlzIWVLmIbyIV60CcB+GqtnKZIX6eZanTWV5c16/I8EkzJtmdMhZzOBnjzfTB/ywxVa9bd9U1GDFK/QHt6TrOq7r5cwsocT1f03Htr1LlYDKWClzc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764622552; c=relaxed/simple; bh=2hLfLEdeG6Q9fp6ZEtSs1CidG+0p9Bs8uu4s6+QrX+A=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=dgrAH+3tDXDvE2exNQoDhMGU87vCVqnTWOjR65CLlvqAR/cVj8E8hjAPJ4KhDxPdlKe2tgoxWtxv0Av6gJdSu/HkXoknndciICmMaEo7swz8rdsfx9Z5xnGkfvtGYLhVaGObSPR59w9FiyaNC6/GuRKUCwl1JKF0ttp1hfTttdw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=lMqJfx/j; arc=none smtp.client-ip=209.85.215.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="lMqJfx/j" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-b98e6ff908aso10631592a12.2 for ; Mon, 01 Dec 2025 12:55:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764622548; x=1765227348; darn=vger.kernel.org; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=HKKNjh5F/DaKk8wuFOjnc86WkhY823H5ekf9jbrPtus=; b=lMqJfx/jvWsyx6G8U5XiToYWLJmjU+5j3mqN9w3TaQr1rxzi5o6IcQYXkpzTwIsweH 1NbQ3gLZS3s7Uv424BNmkwjdzow5IMxu6UrERUVE9z9DFOSGxwappWFbqX4wW5b8tJKF cCmWZ0puYQ+n/OJhjKdEZWFt5jmNUfpEMlNUigbMk4fYAGXKgAW5LGovDXo7w2vTI284 sFNfn+mCR3ADVQO2QXpOrC6xxC0mJvbhMRlcFmxG5unz0M1zgrBKTSsOR79VoIwPRI5E +5E+bdZKe7pKk3gAmFPIO50y011Q516VO1yTGeUPtzCB9xgkkN8FgnNOdRFfwAJNgw/s VS+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764622548; x=1765227348; h=to:from:subject:message-id:references:mime-version:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=HKKNjh5F/DaKk8wuFOjnc86WkhY823H5ekf9jbrPtus=; b=VvzmaCvCIz/oUMxPREEqvO2fIXAmB3Fknkqa0L9fdT4x+1qWrGCpddpPaphh6RS9/i Gs6GIfRDO2coM8IbgqKufe9kEmEtIarl/LkQxeSOmeJP1dvdfZQgerkUSkwXr6OaROug PrpJ+FaCC28bJZ15FmBoBJTCH2DqraRaq9Y4jtf06cyA+zYMH4tP3Gs8AhvACvgXFBiS MssS1Ulg/oCDb9na3uHGF7CO1mXsrPBaG2+aXFhE3zGzHWQq+jrDKGlkz3U/9xCz9ulr Bu47rQfwDYrcfkBhEJUxLkEZEFKgV5BVvTpsoyG6MD0eqy2LYxd9y81Rz+Lz5raStc0w ZCDw== X-Forwarded-Encrypted: i=1; AJvYcCXW9ZTURl4EYqG1qTpi11JAQ4kMjTjkBnZI3lY9bwwjdnNlzccy15SvX0bOZGseCICtpN1qyriyLBFy030=@vger.kernel.org X-Gm-Message-State: AOJu0YwT/p8gZPJ4IJFkdAI0nTyQhTXi2uLQf9LdcQ/9UsAY5vH3X4MG 8HhOUJGMqliuBHDcDl+KhbLC4Uwp/Bw64ig+oCPyH81H4oOVKel9Q/6R0paMjhHinqF3KN28RCh w12wF7b0bUQ== X-Google-Smtp-Source: AGHT+IFR17AdhrIQVLVcu0xi9Bguk4YjUWqci6Qpnra1PNK40h9hsWE1hc6G1x5ZPC695Q4w+8XCmSkGAurL X-Received: from dygu17.prod.google.com ([2002:a05:7300:5411:b0:2a4:85c9:5e08]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:693c:3943:b0:2a4:3592:cf77 with SMTP id 5a478bee46e88-2a941894852mr19882346eec.27.1764622548105; Mon, 01 Dec 2025 12:55:48 -0800 (PST) Date: Mon, 1 Dec 2025 12:55:07 -0800 In-Reply-To: <20251201205509.195451-1-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251201205509.195451-1-irogers@google.com> X-Mailer: git-send-email 2.52.0.158.g65b55ccf14-goog Message-ID: <20251201205509.195451-9-irogers@google.com> Subject: [PATCH v2 08/10] perf symbol: Make a common sysfs__read_build_id From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Suzuki K Poulose , Mike Leach , James Clark , John Garry , Will Deacon , Leo Yan , Athira Rajeev , tanze , Stephen Brennan , Andi Kleen , Chun-Tse Shao , Thomas Falcon , Dapeng Mi , "Dr. David Alan Gilbert" , Christophe Leroy , "=?UTF-8?q?Krzysztof=20=C5=81opatowski?=" , "Masami Hiramatsu (Google)" , Alexandre Ghiti , Haibo Xu , Sergei Trofimovich , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The libelf version of sysfs__read_build_id would read through the file, the symbol-minimal version would read the whole file and then use regular build-id parsing. Given we prefer the libelf code, make both implementations use the libelf implementation and not require reading the whole file. As the libelf implementation uses libelf structs, move the code to symbol-minimal and use the style/implementation that exists there already in the in memory read_build_id code. Note, this means we could avoid reading phdrs where read_build_id is used and switch to read_build_id_fd to potentially avoid some memory allocation. Clean up how bf was being used as it bound checked bf when a build ID note was found but not when the name wasn't "GNU". Switch to just lseek-ing forward the file to avoid any buffer overrun problems and unnecessary reading. Reduce scope of NOTE_ALIGN macro in perf-libelf.h. Signed-off-by: Ian Rogers --- tools/perf/util/perf-libelf.c | 5 ++ tools/perf/util/perf-libelf.h | 5 -- tools/perf/util/symbol-elf.c | 50 -------------------- tools/perf/util/symbol-minimal.c | 80 +++++++++++++++++++++++--------- tools/perf/util/symbol-minimal.h | 1 + tools/perf/util/symbol.c | 6 +++ 6 files changed, 69 insertions(+), 78 deletions(-) diff --git a/tools/perf/util/perf-libelf.c b/tools/perf/util/perf-libelf.c index a8a8c39056da..4198f4dfad9f 100644 --- a/tools/perf/util/perf-libelf.c +++ b/tools/perf/util/perf-libelf.c @@ -9,6 +9,11 @@ #include "build-id.h" #include "debug.h" =20 +/* + * Align offset to 4 bytes as needed for note name and descriptor data. + */ +#define NOTE_ALIGN(n) (((n) + 3) & -4U) + Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, GElf_Shdr *shp, const char *name, size_t *idx) { diff --git a/tools/perf/util/perf-libelf.h b/tools/perf/util/perf-libelf.h index 167679f9fc9b..2118325c04e5 100644 --- a/tools/perf/util/perf-libelf.h +++ b/tools/perf/util/perf-libelf.h @@ -21,11 +21,6 @@ struct build_id; # define PERF_ELF_C_READ_MMAP ELF_C_READ #endif =20 -/* - * Align offset to 4 bytes as needed for note name and descriptor data. - */ -#define NOTE_ALIGN(n) (((n) + 3) & -4U) - Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, GElf_Shdr *shp, cons= t char *name, size_t *idx); =20 diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 9ceb746b6c59..cb890de31044 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -751,56 +751,6 @@ int dso__synthesize_plt_symbols(struct dso *dso, struc= t symsrc *ss) return 0; } =20 -int sysfs__read_build_id(const char *filename, struct build_id *bid) -{ - size_t size =3D sizeof(bid->data); - int fd, err =3D -1; - - fd =3D open(filename, O_RDONLY); - if (fd < 0) - goto out; - - while (1) { - char bf[BUFSIZ]; - GElf_Nhdr nhdr; - size_t namesz, descsz; - - if (read(fd, &nhdr, sizeof(nhdr)) !=3D sizeof(nhdr)) - break; - - namesz =3D NOTE_ALIGN(nhdr.n_namesz); - descsz =3D NOTE_ALIGN(nhdr.n_descsz); - if (nhdr.n_type =3D=3D NT_GNU_BUILD_ID && - nhdr.n_namesz =3D=3D sizeof("GNU")) { - if (read(fd, bf, namesz) !=3D (ssize_t)namesz) - break; - if (memcmp(bf, "GNU", sizeof("GNU")) =3D=3D 0) { - size_t sz =3D min(descsz, size); - if (read(fd, bid->data, sz) =3D=3D (ssize_t)sz) { - memset(bid->data + sz, 0, size - sz); - bid->size =3D sz; - err =3D 0; - break; - } - } else if (read(fd, bf, descsz) !=3D (ssize_t)descsz) - break; - } else { - int n =3D namesz + descsz; - - if (n > (int)sizeof(bf)) { - n =3D sizeof(bf); - pr_debug("%s: truncating reading of build id in sysfs file %s: n_names= z=3D%u, n_descsz=3D%u.\n", - __func__, filename, nhdr.n_namesz, nhdr.n_descsz); - } - if (read(fd, bf, n) !=3D n) - break; - } - } - close(fd); -out: - return err; -} - bool symsrc__possibly_runtime(struct symsrc *ss) { return ss->dynsym || ss->opdsec; diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-mini= mal.c index 445307f230af..0e3a27dae9d6 100644 --- a/tools/perf/util/symbol-minimal.c +++ b/tools/perf/util/symbol-minimal.c @@ -77,6 +77,58 @@ static int read_build_id(void *note_data, size_t note_le= n, struct build_id *bid, return -1; } =20 +static int read_build_id_fd(int fd, struct build_id *bid, bool need_swap) +{ + size_t size =3D sizeof(bid->data); + struct { + u32 n_namesz; + u32 n_descsz; + u32 n_type; + } nhdr; + + while (true) { + size_t namesz, descsz, n; + ssize_t err; + + err =3D read(fd, &nhdr, sizeof(nhdr)); + if (err !=3D sizeof(nhdr)) + return err =3D=3D -1 ? -errno : -EIO; + + if (need_swap) { + nhdr.n_namesz =3D bswap_32(nhdr.n_namesz); + nhdr.n_descsz =3D bswap_32(nhdr.n_descsz); + nhdr.n_type =3D bswap_32(nhdr.n_type); + } + namesz =3D NOTE_ALIGN(nhdr.n_namesz); + descsz =3D NOTE_ALIGN(nhdr.n_descsz); + n =3D namesz + descsz; /* Remaining bytes of this note. */ + + if (nhdr.n_type =3D=3D NT_GNU_BUILD_ID && nhdr.n_namesz =3D=3D sizeof("G= NU")) { + char name[NOTE_ALIGN(sizeof("GNU"))]; + + err =3D read(fd, name, sizeof(name)); + if (err !=3D sizeof(name)) + return err =3D=3D -1 ? -errno : -EIO; + + n =3D descsz; + if (memcmp(name, "GNU", sizeof("GNU")) =3D=3D 0) { + /* Successfully found build ID. */ + ssize_t sz =3D min(descsz, size); + + err =3D read(fd, bid->data, sz); + if (err !=3D sz) + return err =3D=3D -1 ? -errno : -EIO; + + memset(bid->data + sz, 0, size - sz); + bid->size =3D sz; + return 0; + } + } + if (lseek(fd, n, SEEK_CUR) =3D=3D -1) + return -errno; + } +} + /* * Just try PT_NOTE header otherwise fails */ @@ -194,38 +246,20 @@ int sym_min__read_build_id(int _fd, const char *filen= ame, struct build_id *bid) return ret; } =20 -#ifndef HAVE_LIBELF_SUPPORT -int sysfs__read_build_id(const char *filename, struct build_id *bid) +int sym_min_sysfs__read_build_id(const char *filename, struct build_id *bi= d) { - int fd; - int ret =3D -1; - struct stat stbuf; - size_t buf_size; - void *buf; + int fd, ret; =20 fd =3D open(filename, O_RDONLY); if (fd < 0) - return -1; - - if (fstat(fd, &stbuf) < 0) - goto out; - - buf_size =3D stbuf.st_size; - buf =3D malloc(buf_size); - if (buf =3D=3D NULL) - goto out; - - if (read(fd, buf, buf_size) !=3D (ssize_t) buf_size) - goto out_free; + return -errno; =20 - ret =3D read_build_id(buf, buf_size, bid, false); -out_free: - free(buf); -out: + ret =3D read_build_id_fd(fd, bid, /*need_swap=3D*/false); close(fd); return ret; } =20 +#ifndef HAVE_LIBELF_SUPPORT int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name, enum dso_binary_type type) { diff --git a/tools/perf/util/symbol-minimal.h b/tools/perf/util/symbol-mini= mal.h index 185d98968212..5cce1f1f0f16 100644 --- a/tools/perf/util/symbol-minimal.h +++ b/tools/perf/util/symbol-minimal.h @@ -5,5 +5,6 @@ struct build_id; =20 int sym_min__read_build_id(int _fd, const char *filename, struct build_id = *bid); +int sym_min_sysfs__read_build_id(const char *filename, struct build_id *bi= d); =20 #endif /* __PERF_SYMBOL_MINIMAL_H */ diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index da75a1c159f2..76dc5b70350a 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -2050,6 +2050,12 @@ int filename__read_build_id(const char *filename, st= ruct build_id *bid) return err; } =20 +int sysfs__read_build_id(const char *filename, struct build_id *bid) +{ + /* Doesn't mmap file into memory. */ + return sym_min_sysfs__read_build_id(filename, bid); +} + int filename__read_debuglink(const char *filename, char *debuglink, size_t= size) { int err =3D libbfd_filename__read_debuglink(filename, debuglink, size); --=20 2.52.0.158.g65b55ccf14-goog