From nobody Sun Feb 8 22:58:29 2026 Received: from mail-dy1-f201.google.com (mail-dy1-f201.google.com [74.125.82.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 D0B072D47E4 for ; Fri, 23 Jan 2026 22:22:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769206950; cv=none; b=E3MYq8q6l54zGMT+ZDnwm/B/ol+pP85bgD2Vwob5RdlmxUtdsFGhrTLOK/0ij+vxQYYZ1Cpj90kEDemKrjZ/1hOHIEt2ZLZxDuOvwjExaa8/I9ytM9RNArUjnqA3z7iwKMDoaG1S1g7x15GWy67irxZAR4f4nADgReNDC0gsnPM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769206950; c=relaxed/simple; bh=EkQnCI1q2pDYkyyeg8Nk3WtRPBP8LP0/xBc6aVriJtU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=oFN0H4PCwRSpz9gubaME4yd0KxHU9WaU/RkUs2oWV21L1aVRXK5zz8Ar0PuD0AY0NYW0l5VdDgxGQ64Ko8JBaULwsBikO7SS2WtbDJGqCI1qbpPUCHfH2DtAff9bKKY2RaNv6gFBea8nPHj1/yFnPCFxeqi+QHECcdXm/jyiTV0= 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=MOucuvzS; arc=none smtp.client-ip=74.125.82.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="MOucuvzS" Received: by mail-dy1-f201.google.com with SMTP id 5a478bee46e88-2b7174ab5faso3663408eec.1 for ; Fri, 23 Jan 2026 14:22:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1769206947; x=1769811747; 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=4oNTQ1SpPeomHkYYljia0MlXVcvHzoqRR2FSTzw2VhE=; b=MOucuvzSR+lz8hnVeqH3Vq9KyMGwVUGP6XD6pBkz60plKAkoPLb3sKhGIrqe/XQqAW 098H3EOAmt3A0DMxawZEVmeC/dHT33SYTenfs9hSfEnp3Kvmty+VKBlDtEsNYNIzt2NY ZHjDX20Ou+vH0o8AkZDouI388dbrr3q1Q43uLyPvv83WNBZufaf2l6nOHSBJuUNyC3tS dI+YQeqBIjv/lM1GMW+MIU1/2yY3sv8oScOWHngvSigFRJfX7mH3PtOQRYimvtvpMGGD +jO+rUgPyYq90P2ZwVVGF4aiofqdKvHObwUm+bdv/Qh3nd+9PFcKeUwOdD/zxyDbaiDf wJzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769206947; x=1769811747; 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=4oNTQ1SpPeomHkYYljia0MlXVcvHzoqRR2FSTzw2VhE=; b=xCI7an/VX0VqBxrr3H1Bt3cpBwTh3ts54TAe8RRR0aQ9Gx4c50KNnEJn+DRkRFf6Hl S6OOykLDq40WLj3oatBukiBM3uBV7/7dbIa0Ro5CiCL91vUUqZeNgjCDOGkpP3h/KPjY 5p+CKidhPEPzT7j79RlKfXjIZ1RLcuCzb9lKkRfgeAhW8j3r65uV1Wv8PSjYSWwgkaVR fhvHdj7/75Nbycwfo1d3XduV4aPq/qBhH3NQR/Gd0P5EkQElpnguyZR7J4IphguD8VAT oNPMUZMSGiZTblHTunSTi//dhJyLot9U9Qs7/o9x+pt5X58cSGgPqILfRhglssnonOLa rY3g== X-Forwarded-Encrypted: i=1; AJvYcCWP+XoQGhb3r51ibCg3bOtBK+ixfVAGhZo32ytMO87VCXz1ieaNsThE2N/HFFKYi/mGMn/ReZ8RDwEO3fU=@vger.kernel.org X-Gm-Message-State: AOJu0YzvFBMwv/mWjD6BoEgVE9m5/mCz5uHD0gMfqvRuvYDKS/ggHMel 892YHs90sHslaV/r3e3nw5F/bzCry83GVsm/EJg+HTY8SQjHQmreixxPxJ5bE9yS6B3liKVJQN4 uXeiokd2gLQ== X-Received: from dycqb8.prod.google.com ([2002:a05:7300:fe88:b0:2b7:4519:63a4]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7300:ef89:b0:2a4:3593:646a with SMTP id 5a478bee46e88-2b739b748d6mr2243173eec.26.1769206946998; Fri, 23 Jan 2026 14:22:26 -0800 (PST) Date: Fri, 23 Jan 2026 14:22:06 -0800 In-Reply-To: <20260123222209.1181249-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: <20260123222209.1181249-1-irogers@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260123222209.1181249-2-irogers@google.com> Subject: [PATCH v1 1/4] perf dso: Factor out e_machine reading for use in thread From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , Guo Ren , Tianyou Li , Athira Rajeev , Stephen Brennan , Aditya Bodkhe , Chun-Tse Shao , Swapnil Sapkal , Howard Chu , Sergei Trofimovich , Shimin Guo , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, linux-csky@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Factor out the resilient e_machine reading code in dso so that it may be used in thread. As there is no dso in that case, make the dso optional. This makes some minor other changes as the swap type from the dso cannot be ascertained. Signed-off-by: Ian Rogers --- tools/perf/util/dso.c | 110 ++++++++++++++++++++++++--------------- tools/perf/util/dso.h | 10 ++-- tools/perf/util/thread.c | 5 +- 3 files changed, 75 insertions(+), 50 deletions(-) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 3b272a6fae24..91c9f7cb9d8c 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -1203,6 +1203,68 @@ ssize_t dso__data_read_offset(struct dso *dso, struc= t machine *machine, return data_read_write_offset(dso, machine, offset, data, size, true); } =20 +static enum dso_swap_type dso_swap_type__from_elf_data(unsigned char eidat= a) +{ + static const unsigned int endian =3D 1; + + switch (eidata) { + case ELFDATA2LSB: + /* We are big endian, DSO is little endian. */ + return (*(unsigned char const *)&endian !=3D 1) ? DSO_SWAP__YES : DSO_SW= AP__NO; + case ELFDATA2MSB: + /* We are little endian, DSO is big endian. */ + return (*(unsigned char const *)&endian !=3D 0) ? DSO_SWAP__YES : DSO_SW= AP__NO; + default: + return DSO_SWAP__UNSET; + } +} + +/* Reads e_machine from fd, optionally caching data in dso. */ +uint16_t dso__read_e_machine(struct dso *optional_dso, int fd) +{ + uint16_t e_machine =3D EM_NONE; + unsigned char e_ident[EI_NIDENT]; + enum dso_swap_type swap_type; + + _Static_assert(offsetof(Elf32_Ehdr, e_ident) =3D=3D 0, "Unexpected offset= "); + _Static_assert(offsetof(Elf64_Ehdr, e_ident) =3D=3D 0, "Unexpected offset= "); + if (pread(fd, &e_ident, sizeof(e_ident), 0) !=3D sizeof(e_ident)) + return EM_NONE; // Read failed. + + if (memcmp(e_ident, ELFMAG, SELFMAG) !=3D 0) + return EM_NONE; // Not an ELF file. + + if (e_ident[EI_CLASS] =3D=3D ELFCLASSNONE || e_ident[EI_CLASS] >=3D ELFCL= ASSNUM) + return EM_NONE; // Bad ELF class (32 or 64-bit objects). + + if (e_ident[EI_VERSION] !=3D EV_CURRENT) + return EM_NONE; // Bad ELF version. + + swap_type =3D dso_swap_type__from_elf_data(e_ident[EI_DATA]); + if (swap_type =3D=3D DSO_SWAP__UNSET) + return EM_NONE; // Bad ELF data encoding. + + /* Cache the need for swapping. */ + if (optional_dso) { + assert(dso__needs_swap(optional_dso) =3D=3D DSO_SWAP__UNSET || + dso__needs_swap(optional_dso) =3D=3D swap_type); + dso__set_needs_swap(optional_dso, swap_type); + } + + { + _Static_assert(offsetof(Elf32_Ehdr, e_machine) =3D=3D 18, "Unexpected of= fset"); + _Static_assert(offsetof(Elf64_Ehdr, e_machine) =3D=3D 18, "Unexpected of= fset"); + if (pread(fd, &e_machine, sizeof(e_machine), 18) !=3D sizeof(e_machine)) + return EM_NONE; // e_machine read failed. + } + + e_machine =3D DSO_SWAP_TYPE__SWAP(swap_type, uint16_t, e_machine); + if (e_machine >=3D EM_NUM) + return EM_NONE; // Bad ELF machine number. + + return e_machine; +} + uint16_t dso__e_machine(struct dso *dso, struct machine *machine) { uint16_t e_machine =3D EM_NONE; @@ -1248,30 +1310,9 @@ uint16_t dso__e_machine(struct dso *dso, struct mach= ine *machine) */ try_to_open_dso(dso, machine); fd =3D dso__data(dso)->fd; - if (fd >=3D 0) { - unsigned char e_ident[EI_NIDENT]; - - _Static_assert(offsetof(Elf32_Ehdr, e_ident) =3D=3D 0, "Unexpected offse= t"); - _Static_assert(offsetof(Elf64_Ehdr, e_ident) =3D=3D 0, "Unexpected offse= t"); - if (pread(fd, &e_ident, sizeof(e_ident), 0) =3D=3D sizeof(e_ident) && - memcmp(e_ident, ELFMAG, SELFMAG) =3D=3D 0 && - e_ident[EI_CLASS] > ELFCLASSNONE && e_ident[EI_CLASS] < ELFCLASSNUM = && - e_ident[EI_DATA] > ELFDATANONE && e_ident[EI_DATA] < ELFDATANUM && - e_ident[EI_VERSION] =3D=3D EV_CURRENT) { - _Static_assert(offsetof(Elf32_Ehdr, e_machine) =3D=3D 18, "Unexpected o= ffset"); - _Static_assert(offsetof(Elf64_Ehdr, e_machine) =3D=3D 18, "Unexpected o= ffset"); - - if (dso__needs_swap(dso) =3D=3D DSO_SWAP__UNSET) - dso__swap_init(dso, e_ident[EI_DATA]); - - if (dso__needs_swap(dso) !=3D DSO_SWAP__UNSET && - pread(fd, &e_machine, sizeof(e_machine), 18) =3D=3D sizeof(e_machin= e) && - e_machine < EM_NUM) - e_machine =3D DSO__SWAP(dso, uint16_t, e_machine); - else - e_machine =3D EM_NONE; - } - } + if (fd >=3D 0) + e_machine =3D dso__read_e_machine(dso, fd); + mutex_unlock(dso__data_open_lock()); return e_machine; } @@ -1656,28 +1697,13 @@ void dso__put(struct dso *dso) =20 int dso__swap_init(struct dso *dso, unsigned char eidata) { - static unsigned int const endian =3D 1; - - dso__set_needs_swap(dso, DSO_SWAP__NO); + enum dso_swap_type type =3D dso_swap_type__from_elf_data(eidata); =20 - switch (eidata) { - case ELFDATA2LSB: - /* We are big endian, DSO is little endian. */ - if (*(unsigned char const *)&endian !=3D 1) - dso__set_needs_swap(dso, DSO_SWAP__YES); - break; - - case ELFDATA2MSB: - /* We are little endian, DSO is big endian. */ - if (*(unsigned char const *)&endian !=3D 0) - dso__set_needs_swap(dso, DSO_SWAP__YES); - break; - - default: + dso__set_needs_swap(dso, type); + if (type =3D=3D DSO_SWAP__UNSET) { pr_err("unrecognized DSO data encoding %d\n", eidata); return -EINVAL; } - return 0; } =20 diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index ac725bc8ea74..a95fee7d634b 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -160,12 +160,11 @@ enum dso_load_errno { __DSO_LOAD_ERRNO__END, }; =20 -#define DSO__SWAP(dso, type, val) \ +#define DSO_SWAP_TYPE__SWAP(swap_type, type, val) \ ({ \ type ____r =3D val; \ - enum dso_swap_type ___dst =3D dso__needs_swap(dso); \ - BUG_ON(___dst =3D=3D DSO_SWAP__UNSET); \ - if (___dst =3D=3D DSO_SWAP__YES) { \ + BUG_ON(swap_type =3D=3D DSO_SWAP__UNSET); \ + if (swap_type =3D=3D DSO_SWAP__YES) { \ switch (sizeof(____r)) { \ case 2: \ ____r =3D bswap_16(val); \ @@ -183,6 +182,8 @@ enum dso_load_errno { ____r; \ }) =20 +#define DSO__SWAP(dso, type, val) DSO_SWAP_TYPE__SWAP(dso__needs_swap(dso)= , type, val) + #define DSO__DATA_CACHE_SIZE 4096 #define DSO__DATA_CACHE_MASK ~(DSO__DATA_CACHE_SIZE - 1) =20 @@ -865,6 +866,7 @@ int dso__data_file_size(struct dso *dso, struct machine= *machine); off_t dso__data_size(struct dso *dso, struct machine *machine); ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, u64 offset, u8 *data, ssize_t size); +uint16_t dso__read_e_machine(struct dso *optional_dso, int fd); uint16_t dso__e_machine(struct dso *dso, struct machine *machine); ssize_t dso__data_read_addr(struct dso *dso, struct map *map, struct machine *machine, u64 addr, diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index aa9c58bbf9d3..3642858e6cbc 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -458,10 +458,7 @@ static uint16_t read_proc_e_machine_for_pid(pid_t pid) snprintf(path, sizeof(path), "/proc/%d/exe", pid); fd =3D open(path, O_RDONLY); if (fd >=3D 0) { - _Static_assert(offsetof(Elf32_Ehdr, e_machine) =3D=3D 18, "Unexpected of= fset"); - _Static_assert(offsetof(Elf64_Ehdr, e_machine) =3D=3D 18, "Unexpected of= fset"); - if (pread(fd, &e_machine, sizeof(e_machine), 18) !=3D sizeof(e_machine)) - e_machine =3D EM_NONE; + e_machine =3D dso__read_e_machine(/*optional_dso=3D*/NULL, fd); close(fd); } return e_machine; --=20 2.52.0.457.g6b5491de43-goog