aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2017-12-07 16:31:54 +0100
committerMark Wielaard <mark@klomp.org>2017-12-12 00:02:54 +0100
commit57b7f381e167356fa47d58c18bbc2e856f75ee16 (patch)
tree2d940044251ab49ea32192b28b5d8a1e07ba71fc /src
parentb0654221fc2691b3ec633463285c9ef4a86267ae (diff)
downloadelfutils-57b7f381e167356fa47d58c18bbc2e856f75ee16.tar.gz
readelf: Handle DW_OP_call2 and DW_OP_call4 correctly.
DW_OP_call2 and DW_OP_call4 didn't correctly advance the data pointer. This caused print_ops to produce garbage operands. Also format the arguments as DIE offsets. That makes it easier to follow the call to the actual dwarf_procedure DIE. Testcase from https://sourceware.org/bugzilla/show_bug.cgi?id=22532 The testcase only checks the eu-readelf output is correct for the byte_size attribute. But it might be interesting to write a full expression parser to check the actual sizes. [ 3e] structure_type name (strp) "pck__rec" byte_size (exprloc) [ 0] push_object_address [ 1] deref_size 1 [ 3] call4 [ 95] [ 8] plus_uconst 7 [ 10] const1s -4 [ 12] and [ 95] dwarf_procedure location (exprloc) [ 0] dup [ 1] lit1 [ 2] ne [ 3] bra 10 [ 6] lit4 [ 7] skip 31 [ 10] dup [ 11] lit4 [ 12] ne [ 13] bra 20 [ 16] lit0 [ 17] skip 31 [ 20] dup [ 21] lit3 [ 22] eq [ 23] bra 30 [ 26] lit0 [ 27] skip 31 [ 30] lit4 [ 31] swap [ 32] drop The "answer" depends on the Discr value (first byte at object address), and is rounded up to 4 or 8 bytes. Signed-off-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog5
-rw-r--r--src/readelf.c6
2 files changed, 9 insertions, 2 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index eed8569d..8935022b 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2017-12-07 Mark Wielaard <mark@klomp.org>
+
+ * readelf.c (print_ops): Update data pointer and print arguments
+ to DW_OP_call2 and DW_OP_call4 as DIE offsets.
+
2017-11-29 Mark Wielaard <mark@klomp.org>
* readelf.c (argp_options): Add "section-groups", 'g'.
diff --git a/src/readelf.c b/src/readelf.c
index 357c73e3..ed21ef7a 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -4324,19 +4324,21 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
case DW_OP_call2:
NEED (2);
- printf ("%*s[%2" PRIuMAX "] %s %" PRIu16 "\n",
+ printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx16 "]\n",
indent, "", (uintmax_t) offset, op_name,
read_2ubyte_unaligned (dbg, data));
CONSUME (2);
+ data += 2;
offset += 3;
break;
case DW_OP_call4:
NEED (4);
- printf ("%*s[%2" PRIuMAX "] %s %" PRIu32 "\n",
+ printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx32 "]\n",
indent, "", (uintmax_t) offset, op_name,
read_4ubyte_unaligned (dbg, data));
CONSUME (4);
+ data += 4;
offset += 5;
break;