From nobody Sat Feb 7 12:40:57 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 DB8772D8365 for ; Fri, 23 Jan 2026 22:22:29 +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=1769206951; cv=none; b=mC2swwgNJyqI0WLwSqlly7+P7z6CHfFItJA2GuDPnH2iCpkWsn9xflg5PcInmKjlvDL/9lLqErtwtn4J1KXvbKlKKzgWhIBdtr8bjSCxGeBaHJxGQbRbbVrojky3FEiN+Blaw8j3ObEoSeIismCJc5PodiivaJsLtXE2RZ/N6eU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769206951; c=relaxed/simple; bh=wWcDCBThkRzjxvkI58nrHd4ls94KVV87sGI/wAQ5CMQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Content-Type; b=V37w0iM4sJfpO4JlrDadbMB86dbFpxNJKOXabp3EJiVucrnoPxxHaYuKjaf6M000/Il8NOC8harfzGAnxoEWTMUTiW9IjWVEUh04x9xrbh4uEqtZrdg0aLQCxB275GtQSAGgu/iUCleW+mK+/5FTVrd68WCjO0QGeCgP8NzbxII= 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=iakSTq1q; 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="iakSTq1q" Received: by mail-dy1-f201.google.com with SMTP id 5a478bee46e88-2b71d3ac508so2669603eec.0 for ; Fri, 23 Jan 2026 14:22:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1769206949; x=1769811749; 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=cf7Y7FADq4PznKGJpGCjRHvBcF+nvW6t+j6b4wRmujU=; b=iakSTq1q0lVt8qbWV/1MbSXbUqZg2/4mfcEY44knmuhNyVYttgpMbbkuBXxV0B1GZH jIaKOqmz/5ZKM7RqLPprE1SoVzWN5oDmhPMMsTFw/rw7jp5NgqnHbUXCBsZblndg/5ju rVFHUAuzEwD9zVF8KncPAEv7jtqReXvAZcwtyvf+B3PoYo0hxYQlyLav7tl1dhupD30/ m7Jk5PdLKcg+BqYuv3oqFj9o1yJPJd7bHwEKpoBu4haF8B1ZJtL1Og+hUI98JS1SrsIo JMpRLscgTcn+00j3Mf0O66DrrVC5H5Q45ZmoswibkkhKDRB8I0nyfki16Eu18HkJ+RaO LZwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769206949; x=1769811749; 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=cf7Y7FADq4PznKGJpGCjRHvBcF+nvW6t+j6b4wRmujU=; b=U0vGfja7JGIeDyUmkclGChQnU9LoPLObslKfHOPXO2wRfS94o5qiWQak/vI17nIqgq Os4Me9k2nNy3Uu1HmdQG9iRYRW8+ETtwkgUCrQZLEM5D7IlK4EW2jHIUWNYeQwrOC+LA bynRJNSWfwB/Utl61evSuhErpEdsdksr4JwCqwqwlyZpRfbsYfuanbHMyED4XggIdCzc ZWohOvoMYAKATVRvs8GbZK5RJjRXBogCr+YsgtNwcge7vf5VH2obEipMmGUK3xviqwMU Hn/d3ywKMi746gp353pYsDDfmOwws0JNOxDIpZro2OfeMcCDO4FChBoqXJiYsY5MhNco p/Fw== X-Forwarded-Encrypted: i=1; AJvYcCX8c94+De84jKRezKa1/zMvd8clPsrVi6Cw9CPXEp1QKKD2eRmN/DjicAXD2XTV5Vc+7hGch+C4vjzjNO4=@vger.kernel.org X-Gm-Message-State: AOJu0YzilDijLFr7+dVpwPUsGdEfTNrMwjMDa5P9iPhPsVT2uRpc7Her lqFcRgM4PNmvnDU4uJLLYU6/NjHCcb3n5lBJJ/7cR+bF2JdKnM9vxX+tVU6JpVWhw6JXrtPz6BA zQJSKo5Ax7w== X-Received: from dlbto2.prod.google.com ([2002:a05:7022:3b02:b0:121:a019:8a44]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:438a:b0:11b:9386:8271 with SMTP id a92af1059eb24-1247dc14cbbmr2482480c88.46.1769206948958; Fri, 23 Jan 2026 14:22:28 -0800 (PST) Date: Fri, 23 Jan 2026 14:22:07 -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-3-irogers@google.com> Subject: [PATCH v1 2/4] perf thread: Add optional e_flags output argument to thread__e_machine 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" The e_flags are needed to accurately compute complete perf register information for CSKY. Add the ability to read and have this value associated with a thread. This change doesn't wire up the use of the e_flags except in disasm where use already exists but just wasn't set up yet. Signed-off-by: Ian Rogers --- tools/perf/builtin-script.c | 14 +++-- tools/perf/builtin-trace.c | 12 ++-- tools/perf/util/annotate.c | 5 +- tools/perf/util/disasm.c | 5 +- tools/perf/util/disasm.h | 2 +- tools/perf/util/dso.c | 43 +++++++++++--- tools/perf/util/dso.h | 4 +- .../scripting-engines/trace-event-python.c | 2 +- tools/perf/util/session.c | 4 +- tools/perf/util/thread.c | 59 +++++++++++++------ tools/perf/util/thread.h | 16 ++++- tools/perf/util/unwind-libdw.c | 4 +- 12 files changed, 122 insertions(+), 48 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 372bede30230..8c0de27a9713 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -2504,11 +2504,17 @@ static void process_event(struct perf_script *scrip= t, symbol_conf.bt_stop_list, fp); } =20 - if (PRINT_FIELD(IREGS)) - perf_sample__fprintf_iregs(sample, attr, thread__e_machine(thread, machi= ne), fp); + if (PRINT_FIELD(IREGS)) { + perf_sample__fprintf_iregs(sample, attr, + thread__e_machine(thread, machine, /*e_flags=3D*/NULL), + fp); + } =20 - if (PRINT_FIELD(UREGS)) - perf_sample__fprintf_uregs(sample, attr, thread__e_machine(thread, machi= ne), fp); + if (PRINT_FIELD(UREGS)) { + perf_sample__fprintf_uregs(sample, attr, + thread__e_machine(thread, machine, /*e_flags=3D*/NULL), + fp); + } =20 if (PRINT_FIELD(BRSTACK)) perf_sample__fprintf_brstack(sample, thread, evsel, fp); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 8df5ca44e4f9..311d9da9896a 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2789,7 +2789,7 @@ static int trace__sys_enter(struct trace *trace, stru= ct evsel *evsel, struct thread_trace *ttrace; =20 thread =3D machine__findnew_thread(trace->host, sample->pid, sample->tid); - e_machine =3D thread__e_machine(thread, trace->host); + e_machine =3D thread__e_machine(thread, trace->host, /*e_flags=3D*/NULL); sc =3D trace__syscall_info(trace, evsel, e_machine, id); if (sc =3D=3D NULL) goto out_put; @@ -2868,7 +2868,7 @@ static int trace__fprintf_sys_enter(struct trace *tra= ce, struct evsel *evsel, =20 =20 thread =3D machine__findnew_thread(trace->host, sample->pid, sample->tid); - e_machine =3D thread__e_machine(thread, trace->host); + e_machine =3D thread__e_machine(thread, trace->host, /*e_flags=3D*/NULL); sc =3D trace__syscall_info(trace, evsel, e_machine, id); if (sc =3D=3D NULL) goto out_put; @@ -2934,7 +2934,7 @@ static int trace__sys_exit(struct trace *trace, struc= t evsel *evsel, struct thread_trace *ttrace; =20 thread =3D machine__findnew_thread(trace->host, sample->pid, sample->tid); - e_machine =3D thread__e_machine(thread, trace->host); + e_machine =3D thread__e_machine(thread, trace->host, /*e_flags=3D*/NULL); sc =3D trace__syscall_info(trace, evsel, e_machine, id); if (sc =3D=3D NULL) goto out_put; @@ -3285,7 +3285,9 @@ static int trace__event_handler(struct trace *trace, = struct evsel *evsel, =20 if (evsel =3D=3D trace->syscalls.events.bpf_output) { int id =3D perf_evsel__sc_tp_uint(evsel, id, sample); - int e_machine =3D thread ? thread__e_machine(thread, trace->host) : EM_H= OST; + int e_machine =3D thread + ? thread__e_machine(thread, trace->host, /*e_flags=3D*/NULL) + : EM_HOST; struct syscall *sc =3D trace__syscall_info(trace, evsel, e_machine, id); =20 if (sc) { @@ -4916,7 +4918,7 @@ static size_t trace__fprintf_thread(FILE *fp, struct = thread *thread, struct trac { size_t printed =3D 0; struct thread_trace *ttrace =3D thread__priv(thread); - int e_machine =3D thread__e_machine(thread, trace->host); + int e_machine =3D thread__e_machine(thread, trace->host, /*e_flags=3D*/NU= LL); double ratio; =20 if (ttrace =3D=3D NULL) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index c16c6dfaa959..880b1bd300c2 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -984,6 +984,7 @@ int thread__get_arch(struct thread *thread, const struc= t arch **parch) { const struct arch *arch; struct machine *machine; + uint32_t e_flags; uint16_t e_machine; =20 if (!thread) { @@ -992,8 +993,8 @@ int thread__get_arch(struct thread *thread, const struc= t arch **parch) } =20 machine =3D maps__machine(thread__maps(thread)); - e_machine =3D thread__e_machine(thread, machine); - arch =3D arch__find(e_machine, machine->env ? machine->env->cpuid : NULL); + e_machine =3D thread__e_machine(thread, machine, &e_flags); + arch =3D arch__find(e_machine, e_flags, machine->env ? machine->env->cpui= d : NULL); if (arch =3D=3D NULL) { pr_err("%s: unsupported arch %d\n", __func__, e_machine); return errno; diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index 9b0ba1fc5aec..6b36287f30fe 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -134,7 +134,7 @@ static int arch__cmp(const void *a, const void *b) return e_machine_and_eflags__cmp(&(*aa)->id, &(*ab)->id); } =20 -const struct arch *arch__find(uint16_t e_machine, const char *cpuid) +const struct arch *arch__find(uint16_t e_machine, uint32_t e_flags, const = char *cpuid) { static const struct arch *(*const arch_new_fn[])(const struct e_machine_a= nd_e_flags *id, const char *cpuid) =3D { @@ -157,8 +157,7 @@ const struct arch *arch__find(uint16_t e_machine, const= char *cpuid) static size_t num_archs; struct e_machine_and_e_flags key =3D { .e_machine =3D e_machine, - // TODO: e_flags should really come from the same source as e_machine. - .e_flags =3D EF_HOST, + .e_flags =3D e_flags, }; const struct arch *result =3D NULL, **tmp; =20 diff --git a/tools/perf/util/disasm.h b/tools/perf/util/disasm.h index 6a1905f9d4fc..a6e478caf61a 100644 --- a/tools/perf/util/disasm.h +++ b/tools/perf/util/disasm.h @@ -108,7 +108,7 @@ struct annotate_args { char *fileloc; }; =20 -const struct arch *arch__find(uint16_t e_machine, const char *cpuid); +const struct arch *arch__find(uint16_t e_machine, uint32_t e_flags, const = char *cpuid); bool arch__is_x86(const struct arch *arch); bool arch__is_powerpc(const struct arch *arch); =20 diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 91c9f7cb9d8c..b791e1b6b2cf 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -1220,14 +1220,20 @@ static enum dso_swap_type dso_swap_type__from_elf_d= ata(unsigned char eidata) } =20 /* Reads e_machine from fd, optionally caching data in dso. */ -uint16_t dso__read_e_machine(struct dso *optional_dso, int fd) +uint16_t dso__read_e_machine(struct dso *optional_dso, int fd, uint32_t *e= _flags) { uint16_t e_machine =3D EM_NONE; unsigned char e_ident[EI_NIDENT]; enum dso_swap_type swap_type; + bool need_e_flags; =20 - _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 (e_flags) + *e_flags =3D 0; + + { + _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 sizeof(e_ident)) return EM_NONE; // Read failed. =20 @@ -1254,18 +1260,35 @@ uint16_t dso__read_e_machine(struct dso *optional_d= so, int fd) { _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. } + if (pread(fd, &e_machine, sizeof(e_machine), 18) !=3D sizeof(e_machine)) + return EM_NONE; // e_machine read failed. =20 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. =20 +#ifdef NDEBUG + /* In production code the e_flags are only needed on CSKY. */ + need_e_flags =3D e_flags && e_machine =3D=3D EM_CSKY; +#else + /* Debug code will always read the e_flags. */ + need_e_flags =3D e_flags !=3D NULL; +#endif + if (need_e_flags) { + off_t offset =3D e_ident[EI_CLASS] =3D=3D ELFCLASS32 + ? offsetof(Elf32_Ehdr, e_flags) + : offsetof(Elf64_Ehdr, e_flags); + + if (pread(fd, e_flags, sizeof(*e_flags), offset) !=3D sizeof(*e_flags)) { + *e_flags =3D 0; + return EM_NONE; // e_flags read failed. + } + } return e_machine; } =20 -uint16_t dso__e_machine(struct dso *dso, struct machine *machine) +uint16_t dso__e_machine(struct dso *dso, struct machine *machine, uint32_t= *e_flags) { uint16_t e_machine =3D EM_NONE; int fd; @@ -1285,6 +1308,8 @@ uint16_t dso__e_machine(struct dso *dso, struct machi= ne *machine) case DSO_BINARY_TYPE__BPF_IMAGE: case DSO_BINARY_TYPE__OOL: case DSO_BINARY_TYPE__JAVA_JIT: + if (e_flags) + *e_flags =3D EF_HOST; return EM_HOST; case DSO_BINARY_TYPE__DEBUGLINK: case DSO_BINARY_TYPE__BUILD_ID_CACHE: @@ -1299,6 +1324,8 @@ uint16_t dso__e_machine(struct dso *dso, struct machi= ne *machine) break; case DSO_BINARY_TYPE__NOT_FOUND: default: + if (e_flags) + *e_flags =3D 0; return EM_NONE; } =20 @@ -1311,7 +1338,9 @@ uint16_t dso__e_machine(struct dso *dso, struct machi= ne *machine) try_to_open_dso(dso, machine); fd =3D dso__data(dso)->fd; if (fd >=3D 0) - e_machine =3D dso__read_e_machine(dso, fd); + e_machine =3D dso__read_e_machine(dso, fd, e_flags); + else if (e_flags) + *e_flags =3D 0; =20 mutex_unlock(dso__data_open_lock()); return e_machine; diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index a95fee7d634b..ede691e9a249 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -866,8 +866,8 @@ 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); +uint16_t dso__read_e_machine(struct dso *optional_dso, int fd, uint32_t *e= _flags); +uint16_t dso__e_machine(struct dso *dso, struct machine *machine, uint32_t= *e_flags); ssize_t dso__data_read_addr(struct dso *dso, struct map *map, struct machine *machine, u64 addr, u8 *data, ssize_t size); diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools= /perf/util/scripting-engines/trace-event-python.c index b90edc147796..50f0d16520cc 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -925,7 +925,7 @@ static PyObject *get_perf_sample_dict(struct perf_sampl= e *sample, =20 if (al->thread) { machine =3D maps__machine(thread__maps(al->thread)); - e_machine =3D thread__e_machine(al->thread, machine); + e_machine =3D thread__e_machine(al->thread, machine, /*e_flags=3D*/NULL); } if (set_regs_in_dict(dict, sample, evsel, e_machine)) Py_FatalError("Failed to setting regs in dict"); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index c0231bc000e7..0e8a128d7c04 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1124,7 +1124,7 @@ static void dump_sample(struct machine *machine, stru= ct evsel *evsel, union perf if (sample_type & (PERF_SAMPLE_REGS_USER | PERF_SAMPLE_REGS_INTR)) { struct thread *thread =3D machine__find_thread(machine, sample->pid, sam= ple->pid); =20 - e_machine =3D thread__e_machine(thread, machine); + e_machine =3D thread__e_machine(thread, machine, /*e_flags=3D*/NULL); } =20 printf("(IP, 0x%x): %d/%d: %#" PRIx64 " period: %" PRIu64 " addr: %#" PRI= x64 "\n", @@ -2965,7 +2965,7 @@ static int perf_session__e_machine_cb(struct thread *= thread, uint16_t *result =3D arg; struct machine *machine =3D maps__machine(thread__maps(thread)); =20 - *result =3D thread__e_machine(thread, machine); + *result =3D thread__e_machine(thread, machine, /*e_flags=3D*/NULL); return *result !=3D EM_NONE ? 1 : 0; } =20 diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 3642858e6cbc..618f29afb160 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -449,7 +449,7 @@ void thread__find_cpumode_addr_location(struct thread *= thread, u64 addr, } } =20 -static uint16_t read_proc_e_machine_for_pid(pid_t pid) +static uint16_t read_proc_e_machine_for_pid(pid_t pid, uint32_t *e_flags) { char path[6 /* "/proc/" */ + 11 /* max length of pid */ + 5 /* "/exe\0" *= /]; int fd; @@ -458,30 +458,46 @@ 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) { - e_machine =3D dso__read_e_machine(/*optional_dso=3D*/NULL, fd); + e_machine =3D dso__read_e_machine(/*optional_dso=3D*/NULL, fd, e_flags); close(fd); } return e_machine; } =20 -static int thread__e_machine_callback(struct map *map, void *machine) +struct thread__e_machine_callback_args { + struct machine *machine; + uint32_t e_flags; + uint16_t e_machine; +}; + +static int thread__e_machine_callback(struct map *map, void *_args) { + struct thread__e_machine_callback_args *args =3D _args; struct dso *dso =3D map__dso(map); =20 - _Static_assert(0 =3D=3D EM_NONE, "Unexpected EM_NONE"); if (!dso) - return EM_NONE; + return 0; // No dso, continue search. =20 - return dso__e_machine(dso, machine); + args->e_machine =3D dso__e_machine(dso, args->machine, &args->e_flags); + return args->e_machine !=3D EM_NONE ? 1 /* stop search */ : 0 /* continue= search */; } =20 -uint16_t thread__e_machine(struct thread *thread, struct machine *machine) +uint16_t thread__e_machine(struct thread *thread, struct machine *machine,= uint32_t *e_flags) { pid_t tid, pid; uint16_t e_machine =3D RC_CHK_ACCESS(thread)->e_machine; + uint32_t local_e_flags =3D 0; + struct thread__e_machine_callback_args args =3D { + .machine =3D machine, + .e_flags =3D 0, + .e_machine =3D EM_NONE, + }; =20 - if (e_machine !=3D EM_NONE) + if (e_machine !=3D EM_NONE) { + if (e_flags) + *e_flags =3D thread__e_flags(thread); return e_machine; + } =20 tid =3D thread__tid(thread); pid =3D thread__pid(thread); @@ -489,18 +505,19 @@ uint16_t thread__e_machine(struct thread *thread, str= uct machine *machine) struct thread *parent =3D machine__findnew_thread(machine, pid, pid); =20 if (parent) { - e_machine =3D thread__e_machine(parent, machine); + e_machine =3D thread__e_machine(parent, machine, &local_e_flags); thread__put(parent); - thread__set_e_machine(thread, e_machine); - return e_machine; + goto out; } /* Something went wrong, fallback. */ } /* Reading on the PID thread. First try to find from the maps. */ - e_machine =3D maps__for_each_map(thread__maps(thread), - thread__e_machine_callback, - machine); - if (e_machine =3D=3D EM_NONE) { + maps__for_each_map(thread__maps(thread), thread__e_machine_callback, &arg= s); + + if (args.e_machine !=3D EM_NONE) { + e_machine =3D args.e_machine; + local_e_flags =3D args.e_flags; + } else { /* Maps failed, perhaps we're live with map events disabled. */ bool is_live =3D machine->machines =3D=3D NULL; =20 @@ -514,12 +531,18 @@ uint16_t thread__e_machine(struct thread *thread, str= uct machine *machine) } /* Read from /proc/pid/exe if live. */ if (is_live) - e_machine =3D read_proc_e_machine_for_pid(pid); + e_machine =3D read_proc_e_machine_for_pid(pid, &local_e_flags); } - if (e_machine !=3D EM_NONE) +out: + if (e_machine !=3D EM_NONE) { thread__set_e_machine(thread, e_machine); - else + thread__set_e_flags(thread, local_e_flags); + } else { e_machine =3D EM_HOST; + local_e_flags =3D EF_HOST; + } + if (e_flags) + *e_flags =3D local_e_flags; return e_machine; } =20 diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 310eaea344bb..f5792d3e8a16 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -60,6 +60,10 @@ DECLARE_RC_STRUCT(thread) { struct srccode_state srccode_state; bool filter; int filter_entry_depth; + /** + * @e_flags: The ELF EF_* associated with the thread. Valid if e_machine = !=3D EM_NONE. + */ + uint16_t e_flags; /** * @e_machine: The ELF EM_* associated with the thread. EM_NONE if not * computed. @@ -307,13 +311,23 @@ static inline void thread__set_filter_entry_depth(str= uct thread *thread, int dep RC_CHK_ACCESS(thread)->filter_entry_depth =3D depth; } =20 -uint16_t thread__e_machine(struct thread *thread, struct machine *machine); +uint16_t thread__e_machine(struct thread *thread, struct machine *machine,= uint32_t *e_flags); =20 static inline void thread__set_e_machine(struct thread *thread, uint16_t e= _machine) { RC_CHK_ACCESS(thread)->e_machine =3D e_machine; } =20 +static inline uint32_t thread__e_flags(const struct thread *thread) +{ + return RC_CHK_ACCESS(thread)->e_flags; +} + +static inline void thread__set_e_flags(struct thread *thread, uint32_t e_f= lags) +{ + RC_CHK_ACCESS(thread)->e_flags =3D e_flags; +} + =20 static inline bool thread__lbr_stitch_enable(const struct thread *thread) { diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index 9cb0960ef905..3fdcfa06bf22 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c @@ -213,7 +213,7 @@ static bool memory_read(Dwfl *dwfl __maybe_unused, Dwar= f_Addr addr, Dwarf_Word * { struct dwfl_ui_thread_info *dwfl_ui_ti =3D arg; struct unwind_info *ui =3D dwfl_ui_ti->ui; - uint16_t e_machine =3D thread__e_machine(ui->thread, ui->machine); + uint16_t e_machine =3D thread__e_machine(ui->thread, ui->machine, /*e_fla= gs=3D*/NULL); struct stack_dump *stack =3D &ui->sample->user_stack; u64 start, end; int offset; @@ -348,7 +348,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, { struct maps *maps =3D thread__maps(thread); struct machine *machine =3D maps__machine(maps); - uint16_t e_machine =3D thread__e_machine(thread, machine); + uint16_t e_machine =3D thread__e_machine(thread, machine, /*e_flags=3D*/N= ULL); struct dwfl_ui_thread_info *dwfl_ui_ti; static struct unwind_info *ui; Dwfl *dwfl; --=20 2.52.0.457.g6b5491de43-goog