From 729a7ed103ae1b04a5c87a5855885e0973161da4 Mon Sep 17 00:00:00 2001 From: Jan Stancek Date: Wed, 2 Sep 2015 10:19:14 +0200 Subject: perf tests: Take into account address of each objdump line objdump output can contain repeated bytes. At the moment test reads all output sequentially, assuming each address is represented in output only once: ffffffff8164efb3 : ffffffff8164efb3: c1 5d 00 eb rcrl $0xeb,0x0(%rbp) ffffffff8164efb7: 00 4c 8b 5c add %cl,0x5c(%rbx,%rcx,4) ffffffff8164efb8 : ffffffff8164efb8: 4c 8b 5c 24 30 mov 0x30(%rsp),%r11 ffffffff8164efbd: 4c 8b 54 24 38 mov 0x38(%rsp),%r10 Store objdump output to buffer according to offset calculated from address on each line. Signed-off-by: Jan Stancek Cc: Adrian Hunter Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/ad13289a55d6350f7717757c7e32c2d4286402bd.1441181335.git.jstancek@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/code-reading.c | 51 ++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 13 deletions(-) (limited to 'tools/perf/tests/code-reading.c') diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 39c784a100a9..38ee90bc2228 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -33,20 +33,20 @@ static unsigned int hex(char c) return c - 'A' + 10; } -static void read_objdump_line(const char *line, size_t line_len, void **buf, - size_t *len) +static size_t read_objdump_line(const char *line, size_t line_len, void *buf, + size_t len) { const char *p; - size_t i; + size_t i, j = 0; /* Skip to a colon */ p = strchr(line, ':'); if (!p) - return; + return 0; i = p + 1 - line; /* Read bytes */ - while (*len) { + while (j < len) { char c1, c2; /* Skip spaces */ @@ -65,20 +65,26 @@ static void read_objdump_line(const char *line, size_t line_len, void **buf, if (i < line_len && line[i] && !isspace(line[i])) break; /* Store byte */ - *(unsigned char *)*buf = (hex(c1) << 4) | hex(c2); - *buf += 1; - *len -= 1; + *(unsigned char *)buf = (hex(c1) << 4) | hex(c2); + buf += 1; + j++; } + /* return number of successfully read bytes */ + return j; } -static int read_objdump_output(FILE *f, void **buf, size_t *len) +static int read_objdump_output(FILE *f, void *buf, size_t *len, u64 start_addr) { char *line = NULL; - size_t line_len; + size_t line_len, off_last = 0; ssize_t ret; int err = 0; + u64 addr; + + while (off_last < *len) { + size_t off, read_bytes, written_bytes; + unsigned char tmp[BUFSZ]; - while (1) { ret = getline(&line, &line_len, f); if (feof(f)) break; @@ -87,9 +93,28 @@ static int read_objdump_output(FILE *f, void **buf, size_t *len) err = -1; break; } - read_objdump_line(line, ret, buf, len); + + /* read objdump data into temporary buffer */ + read_bytes = read_objdump_line(line, ret, tmp, sizeof(tmp)); + if (!read_bytes) + continue; + + if (sscanf(line, "%"PRIx64, &addr) != 1) + continue; + + /* copy it from temporary buffer to 'buf' according + * to address on current objdump line */ + off = addr - start_addr; + if (off >= *len) + break; + written_bytes = MIN(read_bytes, *len - off); + memcpy(buf + off, tmp, written_bytes); + off_last = off + written_bytes; } + /* len returns number of bytes that could not be read */ + *len -= off_last; + free(line); return err; @@ -120,7 +145,7 @@ static int read_via_objdump(const char *filename, u64 addr, void *buf, return -1; } - ret = read_objdump_output(f, &buf, &len); + ret = read_objdump_output(f, buf, &len, addr); if (len) { pr_debug("objdump read too few bytes\n"); if (!ret) -- cgit v1.2.3 From 06f679c18fcf414cc8462938466f8361315f18cb Mon Sep 17 00:00:00 2001 From: Jan Stancek Date: Thu, 3 Sep 2015 13:23:32 +0200 Subject: perf tests: Make objdump disassemble zero blocks Add -z parameter to avoid skipping zero blocks: ffffffff816704fe : ffffffff816704fe: 7b 34 jnp ffffffff81670534 ... ffffffff81670501 : ffffffff81670501: 0f ba e2 03 bt $0x3,%edx ffffffff81670505: 73 11 jae ffffffff81670518 Signed-off-by: Jan Stancek Acked-by: Adrian Hunter Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/130c6267fbdb9af506633a9efa06f3269ff5bd2c.1441275982.git.jstancek@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/code-reading.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf/tests/code-reading.c') diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 38ee90bc2228..c409409d7765 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -128,7 +128,7 @@ static int read_via_objdump(const char *filename, u64 addr, void *buf, FILE *f; int ret; - fmt = "%s -d --start-address=0x%"PRIx64" --stop-address=0x%"PRIx64" %s"; + fmt = "%s -z -d --start-address=0x%"PRIx64" --stop-address=0x%"PRIx64" %s"; ret = snprintf(cmd, sizeof(cmd), fmt, "objdump", addr, addr + len, filename); if (ret <= 0 || (size_t)ret >= sizeof(cmd)) -- cgit v1.2.3 From edfdb7eab0fe5f98f2951598dc679b71bdb3e16b Mon Sep 17 00:00:00 2001 From: Jan Stancek Date: Wed, 2 Sep 2015 10:19:16 +0200 Subject: perf tests: Stop reading if objdump output crossed sections objdump output can span across multiple sections: Disassembly of section .text: 0000000000000008 : 8: 48 89 e5 mov %rsp,%rbp b: 53 push %rbx c: 8b 01 mov (%rcx),%eax 6b: 90 nop Disassembly of section .init.text: 0000000000000008 : 8: 00 00 add %al,(%rax) a: 00 00 add %al,(%rax) c: 48 89 e5 Stop further reading if an address starts going backwards, assuming we crossed sections. Signed-off-by: Jan Stancek Acked-by: Adrian Hunter Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/9d1ea95e5f9884fdff1be6f761a2feabef37412c.1441181335.git.jstancek@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/code-reading.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'tools/perf/tests/code-reading.c') diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index c409409d7765..8145c67fb43a 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -79,7 +79,7 @@ static int read_objdump_output(FILE *f, void *buf, size_t *len, u64 start_addr) size_t line_len, off_last = 0; ssize_t ret; int err = 0; - u64 addr; + u64 addr, last_addr = start_addr; while (off_last < *len) { size_t off, read_bytes, written_bytes; @@ -101,6 +101,11 @@ static int read_objdump_output(FILE *f, void *buf, size_t *len, u64 start_addr) if (sscanf(line, "%"PRIx64, &addr) != 1) continue; + if (addr < last_addr) { + pr_debug("addr going backwards, read beyond section?\n"); + break; + } + last_addr = addr; /* copy it from temporary buffer to 'buf' according * to address on current objdump line */ -- cgit v1.2.3 From fd405cf6cfddd300377bd5fd9b93d2ff66fbc32d Mon Sep 17 00:00:00 2001 From: Jan Stancek Date: Wed, 2 Sep 2015 10:19:17 +0200 Subject: perf tests: Print objdump/dso buffers if they don't match Signed-off-by: Jan Stancek Acked-by: Adrian Hunter Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/d0f42f786bc0e965918e0f422df25617a12a4021.1441181335.git.jstancek@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/code-reading.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'tools/perf/tests/code-reading.c') diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 8145c67fb43a..2d21183bd661 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -162,6 +162,18 @@ static int read_via_objdump(const char *filename, u64 addr, void *buf, return ret; } +static void dump_buf(unsigned char *buf, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) { + pr_debug("0x%02x ", buf[i]); + if (i % 16 == 15) + pr_debug("\n"); + } + pr_debug("\n"); +} + static int read_object_code(u64 addr, size_t len, u8 cpumode, struct thread *thread, struct state *state) { @@ -264,6 +276,10 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, /* The results should be identical */ if (memcmp(buf1, buf2, len)) { pr_debug("Bytes read differ from those read by objdump\n"); + pr_debug("buf1 (dso):\n"); + dump_buf(buf1, len); + pr_debug("buf2 (objdump):\n"); + dump_buf(buf2, len); return -1; } pr_debug("Bytes read match those read by objdump\n"); -- cgit v1.2.3 From 77e65977495cd6f6fcfacd8c16bdd9c8c18a1d72 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 30 Sep 2015 11:08:58 -0300 Subject: perf machine: Use machine__kernel_map() thoroughly In places where we were using its open coded equivalent. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-khkdugcdoqy3tkszm3jdxgbe@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/code-reading.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf/tests/code-reading.c') diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 2d21183bd661..47017a8aa685 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -473,7 +473,7 @@ static int do_test_code_reading(bool try_kcore) symbol_conf.kallsyms_name = "/proc/kallsyms"; /* Load kernel map */ - map = machine->vmlinux_maps[MAP__FUNCTION]; + map = machine__kernel_map(machine, MAP__FUNCTION); ret = map__load(map, NULL); if (ret < 0) { pr_debug("map__load failed\n"); -- cgit v1.2.3 From a5e813c68649366aaa3f785772b00ea6ccad7b8d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 30 Sep 2015 11:54:04 -0300 Subject: perf machine: Add method for common kernel_map(FUNCTION) operation And it is also a step in the direction of killing the separation of data and text maps in map_groups. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-rrds86kb3wx5wk8v38v56gw8@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/code-reading.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf/tests/code-reading.c') diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 47017a8aa685..49b1959dda41 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -473,7 +473,7 @@ static int do_test_code_reading(bool try_kcore) symbol_conf.kallsyms_name = "/proc/kallsyms"; /* Load kernel map */ - map = machine__kernel_map(machine, MAP__FUNCTION); + map = machine__kernel_map(machine); ret = map__load(map, NULL); if (ret < 0) { pr_debug("map__load failed\n"); -- cgit v1.2.3