Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 729a7ed1 authored by Jan Stancek's avatar Jan Stancek Committed by Arnaldo Carvalho de Melo
Browse files

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 <retint_swapgs+0x9>:
  ffffffff8164efb3:  c1 5d 00 eb        rcrl   $0xeb,0x0(%rbp)
  ffffffff8164efb7:  00 4c 8b 5c        add    %cl,0x5c(%rbx,%rcx,4)

  ffffffff8164efb8 <restore_c_regs_and_iret>:
  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: default avatarJan Stancek <jstancek@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>
Link: http://lkml.kernel.org/r/ad13289a55d6350f7717757c7e32c2d4286402bd.1441181335.git.jstancek@redhat.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 8f3e5684
Loading
Loading
Loading
Loading
+38 −13
Original line number Original line Diff line number Diff line
@@ -33,20 +33,20 @@ static unsigned int hex(char c)
	return c - 'A' + 10;
	return c - 'A' + 10;
}
}


static void read_objdump_line(const char *line, size_t line_len, void **buf,
static size_t read_objdump_line(const char *line, size_t line_len, void *buf,
			      size_t *len)
			      size_t len)
{
{
	const char *p;
	const char *p;
	size_t i;
	size_t i, j = 0;


	/* Skip to a colon */
	/* Skip to a colon */
	p = strchr(line, ':');
	p = strchr(line, ':');
	if (!p)
	if (!p)
		return;
		return 0;
	i = p + 1 - line;
	i = p + 1 - line;


	/* Read bytes */
	/* Read bytes */
	while (*len) {
	while (j < len) {
		char c1, c2;
		char c1, c2;


		/* Skip spaces */
		/* 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]))
		if (i < line_len && line[i] && !isspace(line[i]))
			break;
			break;
		/* Store byte */
		/* Store byte */
		*(unsigned char *)*buf = (hex(c1) << 4) | hex(c2);
		*(unsigned char *)buf = (hex(c1) << 4) | hex(c2);
		*buf += 1;
		buf += 1;
		*len -= 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;
	char *line = NULL;
	size_t line_len;
	size_t line_len, off_last = 0;
	ssize_t ret;
	ssize_t ret;
	int err = 0;
	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);
		ret = getline(&line, &line_len, f);
		if (feof(f))
		if (feof(f))
			break;
			break;
@@ -87,9 +93,28 @@ static int read_objdump_output(FILE *f, void **buf, size_t *len)
			err = -1;
			err = -1;
			break;
			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);
	free(line);


	return err;
	return err;
@@ -120,7 +145,7 @@ static int read_via_objdump(const char *filename, u64 addr, void *buf,
		return -1;
		return -1;
	}
	}


	ret = read_objdump_output(f, &buf, &len);
	ret = read_objdump_output(f, buf, &len, addr);
	if (len) {
	if (len) {
		pr_debug("objdump read too few bytes\n");
		pr_debug("objdump read too few bytes\n");
		if (!ret)
		if (!ret)