On Thu, Dec 07, 2017 at 04:32:39PM +0100, Mark Wielaard wrote:
> That makes it easier to follow the call to the actual DIE.
That only made it more clear we weren't handling DW_OP_call2/4
correctly. We were not updating the data pointer. Now includes
a somewhat interesting Ada testcase.
>From bbbf5f9cb84828cac051267aa8359d2df2da5787 Mon Sep 17 00:00:00 2001
From: Mark Wielaard
Date: Thu, 7 Dec 2017 16:31:54 +0100
Subject: [PATCH] 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
---
src/ChangeLog | 5 +++
src/readelf.c | 6 ++-
tests/ChangeLog| 8
tests/Makefile.am | 2 +
tests/run-readelf-variant.sh | 89 +
tests/testfile-ada-variant.bz2 | Bin 0 -> 1305 bytes
6 files changed, 108 insertions(+), 2 deletions(-)
create mode 100755 tests/run-readelf-variant.sh
create mode 100644 tests/testfile-ada-variant.bz2
diff --git a/src/ChangeLog b/src/ChangeLog
index c56c323..3c53c5c 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2017-12-07 Mark Wielaard
+
+ * readelf.c (print_ops): Update data pointer and print arguments
+ to DW_OP_call2 and DW_OP_call4 as DIE offsets.
+
2017-11-21 Mark Wielaard
* readelf.c (attr_callback): Print attribute name and form in error
diff --git a/src/readelf.c b/src/readelf.c
index a9168d1..6a194ee 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -4323,19 +4323,21 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int
indent, int indentrest,
case DW_OP_call2:
NEED (2);
- printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n",
+ printf ("%*s[%4" 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[%4" PRIuMAX "] %s %" PRIu32 "\n",
+ printf ("%*s[%4" PRIuMAX "] %s [%6" PRIx32 "]\n",
indent, "", (uintmax_t) offset, op_name,
read_4ubyte_unaligned (dbg, data));
CONSUME (4);
+ data += 4;
offset += 5;
break;
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 0162034..9eb6839 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,11 @@
+2017-12-07 Mark Wielaard
+
+ * run-readelf-variant.sh: New test.
+ * testfile-ada-variant.bz2: New testfile.
+ * Makefile.am (TESTS): Add run-readelf-variant.sh.
+ (EXTRA_DISTS): Add run-readelf-variant.sh and
+ testfile-ada-variant.bz2.
+
2017-11-16 Mark Wielaard
* varlocs.c (main): Fix cfi_debug => cfi_debug_bias typo in assert.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d502054..fca0072 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -110,6 +110,7 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile
test-nlist \
run-low_high_pc.sh run-macro-test.sh run-elf_cntl_gelf_getshdr.sh \
run-test-archive64.sh run-readelf-vmcoreinfo.sh \
run-readelf-mixed-corenote.sh run-dwfllines.sh \
+ run-readelf-variant.sh \
run-dwfl-report-elf-align.sh run-addr2line-test.sh \
run-addr2line-i-test.sh run-addr2line-i-lex-test.sh \
run-addr2line-i-demangle-test.sh run-addr