From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>,
Jan Stancek <jstancek@redhat.com>,
linux-kernel@vger.kernel.org, xiakaixu@huawei.com,
cjashfor@linux.vnet.ibm.com, dsahern@gmail.com,
fweisbec@gmail.com, jolsa@kernel.org, namhyung@kernel.org,
paulus@samba.org, a.p.zijlstra@chello.nl
Subject: Re: [PATCH] perf tests: objdump output can contain multi byte chunks
Date: Tue, 2 Aug 2016 16:07:00 -0300 [thread overview]
Message-ID: <20160802190700.GA14639@kernel.org> (raw)
In-Reply-To: <5696092C.30100@intel.com>
Em Wed, Jan 13, 2016 at 10:22:04AM +0200, Adrian Hunter escreveu:
> On 12/01/16 17:30, Arnaldo Carvalho de Melo wrote:
> > Em Tue, Jan 12, 2016 at 11:07:44AM +0100, Jan Stancek escreveu:
> >> objdump's raw insn output can vary across architectures on number of
> >> bytes per chunk (bpc) displayed and their endian.
> >>
> >> code-reading test relied on reading objdump output as 1 bpc. Kaixu Xia
> >> reported test failure on ARM64, where objdump displays 4 bpc:
> >> 70c48: f90027bf str xzr, [x29,#72]
> >> 70c4c: 91224000 add x0, x0, #0x890
> >> 70c50: f90023a0 str x0, [x29,#64]
> >>
> >> This patch adds support to read raw insn output for any bpc length.
> >> In case of 2+ bpc it also guesses objdump's display endian.
> >
> > Adrian, from a quick read of the patch and problem/solution description,
> > I think this is ok and Kaixu reports it solves the problem on ARM64, can
> > I have your reviewed-by/Acked-by?
>
> Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Oops, this one got lost, finally applying...
- Arnaldo
> >
> > Thanks,
> >
> > - Arnaldo
> >
> >> Signed-off-by: Jan Stancek <jstancek@redhat.com>
> >> Reported-and-tested-by: Kaixu Xia <xiakaixu@huawei.com>
> >> Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
> >> Cc: Adrian Hunter <adrian.hunter@intel.com>
> >> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
> >> Cc: David Ahern <dsahern@gmail.com>
> >> Cc: Frederic Weisbecker <fweisbec@gmail.com>
> >> Cc: Jiri Olsa <jolsa@kernel.org>
> >> Cc: Namhyung Kim <namhyung@kernel.org>
> >> Cc: Paul Mackerras <paulus@samba.org>
> >> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> >> ---
> >> tools/perf/tests/code-reading.c | 100 ++++++++++++++++++++++++++++------------
> >> 1 file changed, 71 insertions(+), 29 deletions(-)
> >>
> >> diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
> >> index a767a6400c5c..0108cb22d1a2 100644
> >> --- a/tools/perf/tests/code-reading.c
> >> +++ b/tools/perf/tests/code-reading.c
> >> @@ -33,44 +33,86 @@ static unsigned int hex(char c)
> >> return c - 'A' + 10;
> >> }
> >>
> >> -static size_t read_objdump_line(const char *line, size_t line_len, void *buf,
> >> - size_t len)
> >> +static size_t read_objdump_chunk(const char **line, unsigned char **buf,
> >> + size_t *buf_len)
> >> +{
> >> + size_t bytes_read = 0;
> >> + unsigned char *chunk_start = *buf;
> >> +
> >> + /* Read bytes */
> >> + while (*buf_len > 0) {
> >> + char c1, c2;
> >> +
> >> + /* Get 2 hex digits */
> >> + c1 = *(*line)++;
> >> + if (!isxdigit(c1))
> >> + break;
> >> + c2 = *(*line)++;
> >> + if (!isxdigit(c2))
> >> + break;
> >> +
> >> + /* Store byte and advance buf */
> >> + **buf = (hex(c1) << 4) | hex(c2);
> >> + (*buf)++;
> >> + (*buf_len)--;
> >> + bytes_read++;
> >> +
> >> + /* End of chunk? */
> >> + if (isspace(**line))
> >> + break;
> >> + }
> >> +
> >> + /*
> >> + * objdump will display raw insn as LE if code endian
> >> + * is LE and bytes_per_chunk > 1. In that case reverse
> >> + * the chunk we just read.
> >> + *
> >> + * see disassemble_bytes() at binutils/objdump.c for details
> >> + * how objdump chooses display endian)
> >> + */
> >> + if (bytes_read > 1 && !bigendian()) {
> >> + unsigned char *chunk_end = chunk_start + bytes_read - 1;
> >> + unsigned char tmp;
> >> +
> >> + while (chunk_start < chunk_end) {
> >> + tmp = *chunk_start;
> >> + *chunk_start = *chunk_end;
> >> + *chunk_end = tmp;
> >> + chunk_start++;
> >> + chunk_end--;
> >> + }
> >> + }
> >> +
> >> + return bytes_read;
> >> +}
> >> +
> >> +static size_t read_objdump_line(const char *line, unsigned char *buf,
> >> + size_t buf_len)
> >> {
> >> const char *p;
> >> - size_t i, j = 0;
> >> + size_t ret, bytes_read = 0;
> >>
> >> /* Skip to a colon */
> >> p = strchr(line, ':');
> >> if (!p)
> >> return 0;
> >> - i = p + 1 - line;
> >> + p++;
> >>
> >> - /* Read bytes */
> >> - while (j < len) {
> >> - char c1, c2;
> >> -
> >> - /* Skip spaces */
> >> - for (; i < line_len; i++) {
> >> - if (!isspace(line[i]))
> >> - break;
> >> - }
> >> - /* Get 2 hex digits */
> >> - if (i >= line_len || !isxdigit(line[i]))
> >> - break;
> >> - c1 = line[i++];
> >> - if (i >= line_len || !isxdigit(line[i]))
> >> - break;
> >> - c2 = line[i++];
> >> - /* Followed by a space */
> >> - if (i < line_len && line[i] && !isspace(line[i]))
> >> + /* Skip initial spaces */
> >> + while (*p) {
> >> + if (!isspace(*p))
> >> break;
> >> - /* Store byte */
> >> - *(unsigned char *)buf = (hex(c1) << 4) | hex(c2);
> >> - buf += 1;
> >> - j++;
> >> + p++;
> >> }
> >> +
> >> + do {
> >> + ret = read_objdump_chunk(&p, &buf, &buf_len);
> >> + bytes_read += ret;
> >> + p++;
> >> + } while (ret > 0);
> >> +
> >> /* return number of successfully read bytes */
> >> - return j;
> >> + return bytes_read;
> >> }
> >>
> >> static int read_objdump_output(FILE *f, void *buf, size_t *len, u64 start_addr)
> >> @@ -95,7 +137,7 @@ static int read_objdump_output(FILE *f, void *buf, size_t *len, u64 start_addr)
> >> }
> >>
> >> /* read objdump data into temporary buffer */
> >> - read_bytes = read_objdump_line(line, ret, tmp, sizeof(tmp));
> >> + read_bytes = read_objdump_line(line, tmp, sizeof(tmp));
> >> if (!read_bytes)
> >> continue;
> >>
> >> @@ -152,7 +194,7 @@ static int read_via_objdump(const char *filename, u64 addr, void *buf,
> >>
> >> ret = read_objdump_output(f, buf, &len, addr);
> >> if (len) {
> >> - pr_debug("objdump read too few bytes\n");
> >> + pr_debug("objdump read too few bytes: %lu\n", len);
> >> if (!ret)
> >> ret = len;
> >> }
> >> --
> >> 1.8.3.1
> >
next prev parent reply other threads:[~2016-08-02 19:07 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-12 10:07 [PATCH] perf tests: objdump output can contain multi byte chunks Jan Stancek
2016-01-12 15:30 ` Arnaldo Carvalho de Melo
2016-01-13 8:22 ` Adrian Hunter
2016-08-02 19:07 ` Arnaldo Carvalho de Melo [this message]
2016-08-02 19:33 ` Arnaldo Carvalho de Melo
2016-08-02 19:47 ` Arnaldo Carvalho de Melo
2016-08-04 9:14 ` [tip:perf/urgent] " tip-bot for Jan Stancek
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=20160802190700.GA14639@kernel.org \
--to=acme@kernel.org \
--cc=a.p.zijlstra@chello.nl \
--cc=acme@redhat.com \
--cc=adrian.hunter@intel.com \
--cc=cjashfor@linux.vnet.ibm.com \
--cc=dsahern@gmail.com \
--cc=fweisbec@gmail.com \
--cc=jolsa@kernel.org \
--cc=jstancek@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=namhyung@kernel.org \
--cc=paulus@samba.org \
--cc=xiakaixu@huawei.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.