aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2018-06-15 16:25:15 +0200
committerMark Wielaard <mark@klomp.org>2018-06-17 20:32:06 +0200
commit62aed3f99ce6229a7bf6b1a6e66c49d9e676680f (patch)
tree1e3e44993805bf35d44cf79234d0c62b87a4b359 /src
parent58ed0e647f1012f8b75eda47967d849aeb619ec2 (diff)
downloadplatform_external_elfutils-62aed3f99ce6229a7bf6b1a6e66c49d9e676680f.tar.gz
platform_external_elfutils-62aed3f99ce6229a7bf6b1a6e66c49d9e676680f.tar.bz2
platform_external_elfutils-62aed3f99ce6229a7bf6b1a6e66c49d9e676680f.zip
libdw, readelf: Don't handle DW_FORM_data16 as expression block/location.
Also found by afl-fuzz on the varlocs testcase. DW_FORM_data16 is constant form according to the DWARF5 spec. But since it is 128bits it isn't really representable as Dwarf_Word. So we treat it as block form. But we cannot treat it as an expression block. Make sure readelf prints it as a regular block and that dwarf_getlocation[s|_addr] doesn't treat it as location expression. Signed-off-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog5
-rw-r--r--src/readelf.c15
2 files changed, 15 insertions, 5 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 805a1bf0..54bb9254 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2018-06-15 Mark Wielaard <mark@klomp.org>
+
+ * readelf.c (attr_callback): Only print block as expressions if it
+ isn't DW_FORM_data16.
+
2018-06-12 Mark Wielaard <mark@klomp.org>
* readelf.c (print_form_data): Check we have 4, not 2, bytes
diff --git a/src/readelf.c b/src/readelf.c
index 2e7378e2..41720469 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -7483,11 +7483,16 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
case DW_AT_GNU_call_site_data_value:
case DW_AT_GNU_call_site_target:
case DW_AT_GNU_call_site_target_clobbered:
- putchar ('\n');
- print_ops (cbargs->dwflmod, cbargs->dbg,
- 12 + level * 2, 12 + level * 2,
- cbargs->version, cbargs->addrsize, cbargs->offset_size,
- attrp->cu, block.length, block.data);
+ if (form != DW_FORM_data16)
+ {
+ putchar ('\n');
+ print_ops (cbargs->dwflmod, cbargs->dbg,
+ 12 + level * 2, 12 + level * 2,
+ cbargs->version, cbargs->addrsize, cbargs->offset_size,
+ attrp->cu, block.length, block.data);
+ }
+ else
+ print_block (block.length, block.data);
break;
}
break;