From: Charlie Jenkins <charlie@rivosinc.com>
To: Ian Rogers <irogers@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Jiri Olsa <jolsa@kernel.org>,
Adrian Hunter <adrian.hunter@intel.com>,
Paul Walmsley <paul.walmsley@sifive.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
Nathan Chancellor <nathan@kernel.org>,
Nick Desaulniers <ndesaulniers@google.com>,
Bill Wendling <morbo@google.com>,
Justin Stitt <justinstitt@google.com>,
linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-riscv@lists.infradead.org
Subject: Re: [PATCH v2] tools: perf: tests: Fix code reading for riscv
Date: Tue, 17 Dec 2024 16:30:15 -0800 [thread overview]
Message-ID: <Z2IXl5cuKQJInJb0@ghost> (raw)
In-Reply-To: <CAP-5=fXK6HRzBKHzF=T_w9cn7ohWOdmZNRMXvJzN6QG11HE6tA@mail.gmail.com>
On Tue, Dec 17, 2024 at 04:18:32PM -0800, Ian Rogers wrote:
> On Tue, Dec 17, 2024 at 3:52 PM Charlie Jenkins <charlie@rivosinc.com> 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>
>
> Reviewed-by: Ian Rogers <irogers@google.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 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 | 84 ++++++++++++++++++++++++++++++++++++++++-
> > 1 file changed, 83 insertions(+), 1 deletion(-)
> >
> > diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
> > index 27c82cfb7e7de42284bf5af9cf7594a3a963052e..7e24d10a543ac18ac2be70b829d088874e0edfd5 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>
> > @@ -176,6 +177,66 @@ 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)
> > {
> > @@ -183,9 +244,30 @@ static int read_via_objdump(const char *filename, u64 addr, void *buf,
> > const char *fmt;
> > FILE *f;
> > int ret;
> > + u64 stop_address = addr + len;
> > +
> > + if (IS_ENABLED(__riscv)) {
>
> Not sure if there is a consistency issue here. Elsewhere we're just
> using ifdef, such as:
> https://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next.git/tree/tools/perf/util/include/dwarf-regs.h?h=perf-tools-next#n69
I don't have any strong feelings about that. I can change it to be an
ifdef. On other lists I have been told to use IS_ENABLED whenever
possible, but it's only a small difference.
- Charlie
>
> Thanks,
> Ian
>
> > + 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: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
> > change-id: 20241213-perf_fix_riscv_obj_reading-cabf02be3c85
> > --
> > - Charlie
> >
next prev parent reply other threads:[~2024-12-18 0:30 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-17 23:52 [PATCH v2] tools: perf: tests: Fix code reading for riscv Charlie Jenkins
2024-12-18 0:18 ` Ian Rogers
2024-12-18 0:30 ` Charlie Jenkins [this message]
2024-12-18 0:55 ` Ian Rogers
2024-12-18 18:41 ` Arnaldo Carvalho de Melo
2024-12-18 19:23 ` Ian Rogers
2024-12-18 21:02 ` Charlie Jenkins
2024-12-18 22:13 ` Ian Rogers
2024-12-18 22:32 ` Charlie Jenkins
2024-12-19 1:20 ` Ian Rogers
2024-12-19 1:52 ` Charlie Jenkins
2025-01-03 1:44 ` Charlie Jenkins
2025-01-03 16:51 ` Arnaldo Carvalho de Melo
2025-01-03 19:15 ` Charlie Jenkins
2024-12-18 20:57 ` Charlie Jenkins
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Z2IXl5cuKQJInJb0@ghost \
--to=charlie@rivosinc.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=aou@eecs.berkeley.edu \
--cc=irogers@google.com \
--cc=jolsa@kernel.org \
--cc=justinstitt@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=morbo@google.com \
--cc=namhyung@kernel.org \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=peterz@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox