[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CAP-5=fW9wKgBN7vn6gK98iNjt6TpbGV1qhCv_qup_30iQP+o3g@mail.gmail.com>
Date: Tue, 17 Dec 2024 16:55:31 -0800
From: Ian Rogers <irogers@...gle.com>
To: Charlie Jenkins <charlie@...osinc.com>
Cc: Peter Zijlstra <peterz@...radead.org>, Ingo Molnar <mingo@...hat.com>,
Arnaldo Carvalho de Melo <acme@...nel.org>, Namhyung Kim <namhyung@...nel.org>,
Mark Rutland <mark.rutland@....com>,
Alexander Shishkin <alexander.shishkin@...ux.intel.com>, Jiri Olsa <jolsa@...nel.org>,
Adrian Hunter <adrian.hunter@...el.com>, Paul Walmsley <paul.walmsley@...ive.com>,
Palmer Dabbelt <palmer@...belt.com>, Albert Ou <aou@...s.berkeley.edu>,
Nathan Chancellor <nathan@...nel.org>, Nick Desaulniers <ndesaulniers@...gle.com>,
Bill Wendling <morbo@...gle.com>, Justin Stitt <justinstitt@...gle.com>,
linux-perf-users@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-riscv@...ts.infradead.org
Subject: Re: [PATCH v2] tools: perf: tests: Fix code reading for riscv
On Tue, Dec 17, 2024 at 4:30 PM Charlie Jenkins <charlie@...osinc.com> wrote:
>
> 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@...osinc.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@...osinc.com>
> >
> > Reviewed-by: Ian Rogers <irogers@...gle.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.
Agreed. Let's see what Arnaldo and Namhyung think.
Thanks,
Ian
Powered by blists - more mailing lists