* [PATCH v3] tools: perf: tests: Fix code reading for riscv
@ 2024-12-19 21:44 Charlie Jenkins
2025-02-03 19:15 ` patchwork-bot+linux-riscv
0 siblings, 1 reply; 2+ messages in thread
From: Charlie Jenkins @ 2024-12-19 21:44 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Nathan Chancellor, Nick Desaulniers, Bill Wendling,
Justin Stitt
Cc: linux-perf-users, linux-kernel, linux-riscv, Charlie Jenkins
After binutils commit e43d876 which was first included in binutils 2.41,
riscv no longer supports dumping in the middle of instructions. Increase
the objdump window by 2-bytes to ensure that any instruction that sits
on the boundary of the specified stop-address is not cut in half.
Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
---
A binutils patch has been sent as well to fix this in objdump [1].
Link:
https://sourceware.org/pipermail/binutils/2024-December/138139.html [1]
---
Changes in v3:
- Dynamically detect riscv for objdump change (Arnaldo)
- Link to v2: https://lore.kernel.org/r/20241217-perf_fix_riscv_obj_reading-v2-1-58f81b7b4c7d@rivosinc.com
Changes in v2:
- Do objdump version detection at runtime (Ian)
- Link to v1: https://lore.kernel.org/r/20241216-perf_fix_riscv_obj_reading-v1-0-b75962660a9b@rivosinc.com
---
tools/perf/tests/code-reading.c | 92 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 91 insertions(+), 1 deletion(-)
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 27c82cfb7e7de42284bf5af9cf7594a3a963052e..b1abb34d7818d8a9ac963e2185ec3e7d9bf8d387 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
+#include <linux/kconfig.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <inttypes.h>
@@ -8,6 +9,7 @@
#include <stdio.h>
#include <string.h>
#include <sys/param.h>
+#include <sys/utsname.h>
#include <perf/cpumap.h>
#include <perf/evlist.h>
#include <perf/mmap.h>
@@ -176,16 +178,104 @@ static int read_objdump_output(FILE *f, void *buf, size_t *len, u64 start_addr)
return err;
}
+/*
+ * Only gets GNU objdump version. Returns 0 for llvm-objdump.
+ */
+static int objdump_version(void)
+{
+ size_t line_len;
+ char cmd[PATH_MAX * 2];
+ char *line = NULL;
+ const char *fmt;
+ FILE *f;
+ int ret;
+
+ int version_tmp, version_num = 0;
+ char *version = 0, *token;
+
+ fmt = "%s --version";
+ ret = snprintf(cmd, sizeof(cmd), fmt, test_objdump_path);
+ if (ret <= 0 || (size_t)ret >= sizeof(cmd))
+ return -1;
+ /* Ignore objdump errors */
+ strcat(cmd, " 2>/dev/null");
+ f = popen(cmd, "r");
+ if (!f) {
+ pr_debug("popen failed\n");
+ return -1;
+ }
+ /* Get first line of objdump --version output */
+ ret = getline(&line, &line_len, f);
+ pclose(f);
+ if (ret < 0) {
+ pr_debug("getline failed\n");
+ return -1;
+ }
+
+ token = strsep(&line, " ");
+ if (token != NULL && !strcmp(token, "GNU")) {
+ // version is last part of first line of objdump --version output.
+ while ((token = strsep(&line, " ")))
+ version = token;
+
+ // Convert version into a format we can compare with
+ token = strsep(&version, ".");
+ version_num = atoi(token);
+ if (version_num)
+ version_num *= 10000;
+
+ token = strsep(&version, ".");
+ version_tmp = atoi(token);
+ if (token)
+ version_num += version_tmp * 100;
+
+ token = strsep(&version, ".");
+ version_tmp = atoi(token);
+ if (token)
+ version_num += version_tmp;
+ }
+
+ return version_num;
+}
+
static int read_via_objdump(const char *filename, u64 addr, void *buf,
size_t len)
{
+ u64 stop_address = addr + len;
+ struct utsname uname_buf;
char cmd[PATH_MAX * 2];
const char *fmt;
FILE *f;
int ret;
+ ret = uname(&uname_buf);
+ if (ret) {
+ pr_debug("uname failed\n");
+ return -1;
+ }
+
+ if (!strncmp(uname_buf.machine, "riscv", 5)) {
+ int version = objdump_version();
+
+ /* Default to this workaround if version parsing fails */
+ if (version < 0 || version > 24100) {
+ /*
+ * Starting at riscv objdump version 2.41, dumping in
+ * the middle of an instruction is not supported. riscv
+ * instructions are aligned along 2-byte intervals and
+ * can be either 2-bytes or 4-bytes. This makes it
+ * possible that the stop-address lands in the middle of
+ * a 4-byte instruction. Increase the stop_address by
+ * two to ensure an instruction is not cut in half, but
+ * leave the len as-is so only the expected number of
+ * bytes are collected.
+ */
+ stop_address += 2;
+ }
+ }
+
fmt = "%s -z -d --start-address=0x%"PRIx64" --stop-address=0x%"PRIx64" %s";
- ret = snprintf(cmd, sizeof(cmd), fmt, test_objdump_path, addr, addr + len,
+ ret = snprintf(cmd, sizeof(cmd), fmt, test_objdump_path, addr, stop_address,
filename);
if (ret <= 0 || (size_t)ret >= sizeof(cmd))
return -1;
---
base-commit: 233157785a34612e5899be6edcc6a53ea682d379
change-id: 20241213-perf_fix_riscv_obj_reading-cabf02be3c85
--
- Charlie
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH v3] tools: perf: tests: Fix code reading for riscv
2024-12-19 21:44 [PATCH v3] tools: perf: tests: Fix code reading for riscv Charlie Jenkins
@ 2025-02-03 19:15 ` patchwork-bot+linux-riscv
0 siblings, 0 replies; 2+ messages in thread
From: patchwork-bot+linux-riscv @ 2025-02-03 19:15 UTC (permalink / raw)
To: Charlie Jenkins
Cc: linux-riscv, peterz, mingo, acme, namhyung, mark.rutland,
alexander.shishkin, jolsa, irogers, adrian.hunter, paul.walmsley,
palmer, aou, nathan, ndesaulniers, morbo, justinstitt,
linux-perf-users, linux-kernel
Hello:
This patch was applied to riscv/linux.git (fixes)
by Arnaldo Carvalho de Melo <acme@redhat.com>:
On Thu, 19 Dec 2024 13:44:25 -0800 you wrote:
> After binutils commit e43d876 which was first included in binutils 2.41,
> riscv no longer supports dumping in the middle of instructions. Increase
> the objdump window by 2-bytes to ensure that any instruction that sits
> on the boundary of the specified stop-address is not cut in half.
>
> Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
>
> [...]
Here is the summary with links:
- [v3] tools: perf: tests: Fix code reading for riscv
https://git.kernel.org/riscv/c/0f9ad973b095
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-02-03 19:20 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-19 21:44 [PATCH v3] tools: perf: tests: Fix code reading for riscv Charlie Jenkins
2025-02-03 19:15 ` patchwork-bot+linux-riscv
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox