diff options
author | Mark Wielaard <mark@klomp.org> | 2017-12-07 16:31:54 +0100 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2017-12-12 00:02:54 +0100 |
commit | 57b7f381e167356fa47d58c18bbc2e856f75ee16 (patch) | |
tree | 2d940044251ab49ea32192b28b5d8a1e07ba71fc /src | |
parent | b0654221fc2691b3ec633463285c9ef4a86267ae (diff) | |
download | elfutils-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/ChangeLog | 5 | ||||
-rw-r--r-- | src/readelf.c | 6 |
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; |