summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2008-01-12 03:06:47 +0000
committerUlrich Drepper <drepper@redhat.com>2008-01-12 03:06:47 +0000
commitfd47989094090138b0c857d067ac7ff05e7b6d91 (patch)
tree8c2aff1c3a3b3586cbdf608ff1bef9ba4ac6f0fa
parent5eee122f63233ad4df924fedceab5e2649922aeb (diff)
Add comment with absolute address to %rip based address modes.
-rw-r--r--libcpu/ChangeLog7
-rw-r--r--libcpu/i386_data.h3
-rw-r--r--libcpu/i386_disasm.c65
-rw-r--r--src/objdump.c5
-rw-r--r--tests/ChangeLog5
-rw-r--r--tests/testfile45.expect.bz2bin74315 -> 75010 bytes
6 files changed, 79 insertions, 6 deletions
diff --git a/libcpu/ChangeLog b/libcpu/ChangeLog
index cb0f4edf..f4478795 100644
--- a/libcpu/ChangeLog
+++ b/libcpu/ChangeLog
@@ -1,5 +1,12 @@
2008-01-11 Ulrich Drepper <drepper@redhat.com>
+ * i386_disasm.c (struct output)buffer): Add labelbuf, labelbufsize,
+ symaddr_use, and symaddr fields.
+ (i386_disasm): Remove labelbuf and labelbufsize variables.
+ Add back %e format. Implement %a and %l formats.
+ * i386_data.h (general_mod$r_m): Set symaddr_use and symaddr for %rip
+ base addressing.
+
* i386_disasm.c (i386_disasm): Resize output buffer if necessary.
Optimize output_data initialization. Free buffers before return.
(struct output_data): Remove op1str field. Adjust code.
diff --git a/libcpu/i386_data.h b/libcpu/i386_data.h
index 89fa3089..43eb13f9 100644
--- a/libcpu/i386_data.h
+++ b/libcpu/i386_data.h
@@ -264,6 +264,9 @@ general_mod$r_m (struct output_data *d)
#ifdef X86_64
n = snprintf (tmpbuf, sizeof (tmpbuf), "%s0x%" PRIx32 "(%%rip)",
disp < 0 ? "-" : "", disp < 0 ? -disp : disp);
+
+ d->symaddr_use = addr_rel_always;
+ d->symaddr = disp;
#else
n = snprintf (tmpbuf, sizeof (tmpbuf), "0x%" PRIx32, disp);
#endif
diff --git a/libcpu/i386_disasm.c b/libcpu/i386_disasm.c
index 2a843923..57a870f1 100644
--- a/libcpu/i386_disasm.c
+++ b/libcpu/i386_disasm.c
@@ -199,6 +199,17 @@ struct output_data
const uint8_t *end;
DisasmGetSymCB_t symcb;
void *symcbarg;
+ char *labelbuf;
+ size_t labelbufsize;
+ enum
+ {
+ addr_none = 0,
+ addr_abs_symbolic,
+ addr_abs_always,
+ addr_rel_symbolic,
+ addr_rel_always
+ } symaddr_use;
+ GElf_Addr symaddr;
};
@@ -233,8 +244,6 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr,
void *outcbarg, void *symcbarg)
{
const char *save_fmt = fmt;
- char *labelbuf = NULL;
- //size_t labelbufsize = 0;
#define BUFSIZE 512
char initbuf[BUFSIZE];
@@ -800,6 +809,56 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr,
string_end_idx = bufcnt;
}
+ else
+ bufcnt = string_end_idx;
+ break;
+
+ case 'e':
+ string_end_idx = bufcnt;
+ break;
+
+ case 'a':
+ /* Pad to requested column. */
+ while (bufcnt < (size_t) width)
+ ADD_CHAR (' ');
+ width = 0;
+ break;
+
+ case 'l':
+ if (output_data.labelbuf != NULL
+ && output_data.labelbuf[0] != '\0')
+ {
+ ADD_STRING (output_data.labelbuf);
+ output_data.labelbuf[0] = '\0';
+ string_end_idx = bufcnt;
+ }
+ else if (output_data.symaddr_use != addr_none)
+ {
+ GElf_Addr symaddr = output_data.symaddr;
+ if (output_data.symaddr_use >= addr_rel_symbolic)
+ symaddr += addr + param_start - begin;
+
+ // XXX Lookup symbol based on symaddr
+ const char *symstr = NULL;
+
+ size_t bufavail = bufsize - bufcnt;
+ int r = 0;
+ if (symstr != NULL)
+ r = snprintf (&buf[bufcnt], bufavail, "# %s", symstr);
+ else if (output_data.symaddr_use == addr_abs_always
+ || output_data.symaddr_use == addr_rel_always)
+ r = snprintf (&buf[bufcnt], bufavail, "# %#" PRIx64,
+ (uint64_t) symaddr);
+
+ if (r < 0)
+ goto not;
+ if ((size_t) r >= bufavail)
+ goto enomem;
+ bufcnt += r;
+ string_end_idx = bufcnt;
+
+ output_data.symaddr_use = addr_none;
+ }
break;
}
@@ -841,7 +900,7 @@ i386_disasm (const uint8_t **startp, const uint8_t *end, GElf_Addr addr,
}
do_ret:
- free (labelbuf);
+ free (output_data.labelbuf);
if (buf != initbuf)
free (buf);
diff --git a/src/objdump.c b/src/objdump.c
index 7b95ddd6..91fa8750 100644
--- a/src/objdump.c
+++ b/src/objdump.c
@@ -756,8 +756,7 @@ show_disasm (Ebl *ebl, const char *fname, uint32_t shstrndx)
info.last_end = info.cur = data->d_buf;
disasm_cb (ctx, &info.cur, info.cur + data->d_size, info.addr,
- //"%7m%e %.1o%e,%.2o%e,%.3o%e", disasm_output, &info,
- "%7m %.1o,%.2o,%.3o", disasm_output, &info,
+ "%7m %.1o,%.2o,%.3o%34a %l", disasm_output, &info,
NULL /* XXX */);
}
}
@@ -776,7 +775,7 @@ handle_elf (Elf *elf, const char *prefix, const char *fname,
/* Get the backend for this object file type. */
Ebl *ebl = ebl_openbackend (elf);
- printf (gettext ("%s: elf%d-%s\n\n"),
+ printf ("%s: elf%d-%s\n\n",
fname, gelf_getclass (elf) == ELFCLASS32 ? 32 : 64,
ebl_backend_name (ebl));
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 458acd15..95ed7833 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,8 @@
+2008-01-11 Ulrich Drepper <drepper@redhat.com>
+
+ * testfile45.expect.bz2: Adjust for adding of address for %rip based
+ address mode.
+
2008-01-10 Ulrich Drepper <drepper@redhat.com>
* testfile45.S.bz2: Add more tests.
diff --git a/tests/testfile45.expect.bz2 b/tests/testfile45.expect.bz2
index 9236cf7f..adce5e0e 100644
--- a/tests/testfile45.expect.bz2
+++ b/tests/testfile45.expect.bz2
Binary files differ