diff options
author | Mark Wielaard <mark@klomp.org> | 2017-12-06 12:30:12 +0100 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2018-05-15 11:25:43 +0200 |
commit | cdf865b890c2480c14245e2dbcae33dea0a03cf7 (patch) | |
tree | 73cd9e8e7340948b5d188df7e6ed4189e5d75d3d /libdw | |
parent | 6ed8b94952ddf155960c799ef76f3048f033e873 (diff) | |
download | elfutils-cdf865b890c2480c14245e2dbcae33dea0a03cf7.tar.gz |
readelf, libdw: Handle DWARF5 .debug_macro.
Almost identical to GNU .debug_macro extension. Just accept and use
DW_AT_macros where we accept or use DW_AT_GNU_macros. And be a little
stricter in which FORMs we accept (this could have caused problems
with the GNU variant too). Deals with DW_FORM_strx[1234], but not yet
with imported macros through DW_MACRO_import_sup.
Signed-off-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'libdw')
-rw-r--r-- | libdw/ChangeLog | 8 | ||||
-rw-r--r-- | libdw/dwarf_formudata.c | 1 | ||||
-rw-r--r-- | libdw/dwarf_getmacros.c | 42 |
3 files changed, 40 insertions, 11 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog index efdd927f..e66a1ec4 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,11 @@ +2018-05-11 Mark Wielaard <mark@klomp.org> + + * dwarf_formudata.c (dwarf_formudata): Handle DW_AT_macros as macptr. + * dwarf_getmacros.c (get_table_for_offset): Add DW_MACRO_define_sup, + DW_MACRO_undef_sup, DW_MACRO_import_sup, DW_MACRO_define_strx and + DW_MACRO_undef_strx. Add str_offsets_base_off to fake CU. Deal with + DW_AT_macros. Use libdw_valid_user_form. + 2018-05-09 Mark Wielaard <mark@klomp.org> * dwarf_formstring.c (__libdw_cu_str_off_base): Moved to... diff --git a/libdw/dwarf_formudata.c b/libdw/dwarf_formudata.c index 02c16945..62352eed 100644 --- a/libdw/dwarf_formudata.c +++ b/libdw/dwarf_formudata.c @@ -158,6 +158,7 @@ dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval) break; case DW_AT_GNU_macros: + case DW_AT_macros: /* macptr into .debug_macro */ if (__libdw_formptr (attr, IDX_debug_macro, DWARF_E_NO_ENTRY, NULL, diff --git a/libdw/dwarf_getmacros.c b/libdw/dwarf_getmacros.c index c456051c..fd929669 100644 --- a/libdw/dwarf_getmacros.c +++ b/libdw/dwarf_getmacros.c @@ -1,7 +1,6 @@ /* Get macro information. - Copyright (C) 2002-2009, 2014 Red Hat, Inc. + Copyright (C) 2002-2009, 2014, 2017, 2018 Red Hat, Inc. This file is part of elfutils. - Written by Ulrich Drepper <drepper@redhat.com>, 2002. This file is free software; you can redistribute it and/or modify it under the terms of either @@ -192,6 +191,8 @@ get_table_for_offset (Dwarf *dbg, Dwarf_Word macoff, MACRO_PROTO (p_udata_str, DW_FORM_udata, DW_FORM_string); MACRO_PROTO (p_udata_strp, DW_FORM_udata, DW_FORM_strp); + MACRO_PROTO (p_udata_strsup, DW_FORM_udata, DW_FORM_strp_sup); + MACRO_PROTO (p_udata_strx, DW_FORM_udata, DW_FORM_strx); MACRO_PROTO (p_udata_udata, DW_FORM_udata, DW_FORM_udata); MACRO_PROTO (p_secoffset, DW_FORM_sec_offset); MACRO_PROTO (p_none); @@ -205,10 +206,11 @@ get_table_for_offset (Dwarf *dbg, Dwarf_Word macoff, [DW_MACRO_start_file - 1] = p_udata_udata, [DW_MACRO_end_file - 1] = p_none, [DW_MACRO_import - 1] = p_secoffset, - /* When adding support for DWARF5 supplementary object files and - indirect string tables also add support for DW_MACRO_define_sup, - DW_MACRO_undef_sup, DW_MACRO_import_sup, DW_MACRO_define_strx - and DW_MACRO_undef_strx. */ + [DW_MACRO_define_sup - 1] = p_udata_strsup, + [DW_MACRO_undef_sup - 1] = p_udata_strsup, + [DW_MACRO_import_sup - 1] = p_secoffset, /* XXX - but in sup!. */ + [DW_MACRO_define_strx - 1] = p_udata_strx, + [DW_MACRO_undef_strx - 1] = p_udata_strx, }; if ((flags & 0x4) != 0) @@ -357,12 +359,18 @@ read_macros (Dwarf *dbg, int sec_index, /* A fake CU with bare minimum data to fool dwarf_formX into doing the right thing with the attributes that we put out. We pretend it is the same version as the actual table. - Version 4 for the old GNU extension, version 5 for DWARF5. */ + Version 4 for the old GNU extension, version 5 for DWARF5. + To handle DW_FORM_strx[1234] we set the .str_offsets_base + from the given CU. + XXX We will need to deal with DW_MACRO_import_sup and change + out the dbg somehow for the DW_FORM_sec_offset to make sense. */ Dwarf_CU fake_cu = { .dbg = dbg, .sec_idx = sec_index, .version = table->version, .offset_size = table->is_64bit ? 8 : 4, + .str_off_base = str_offsets_base_off (dbg, (cudie != NULL + ? cudie->cu: NULL)), .startp = (void *) startp + offset, .endp = (void *) endp, }; @@ -385,14 +393,25 @@ read_macros (Dwarf *dbg, int sec_index, for (Dwarf_Word i = 0; i < proto->nforms; ++i) { - /* We pretend this is a DW_AT_GNU_macros attribute so that + /* We pretend this is a DW_AT[_GNU]_macros attribute so that DW_FORM_sec_offset forms get correctly interpreted as - offset into .debug_macro. */ - attributes[i].code = DW_AT_GNU_macros; + offset into .debug_macro. XXX Deal with DW_MACRO_import_sup + (swap .dbg) for DW_FORM_sec_offset? */ + attributes[i].code = (fake_cu.version == 4 ? DW_AT_GNU_macros + : DW_AT_macros); attributes[i].form = proto->forms[i]; attributes[i].valp = (void *) readp; attributes[i].cu = &fake_cu; + /* We don't want forms that aren't allowed because they could + read from the "abbrev" like DW_FORM_implicit_const. */ + if (! libdw_valid_user_form (attributes[i].form)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + free (attributesp); + return -1; + } + size_t len = __libdw_form_val_len (&fake_cu, proto->forms[i], readp); if (unlikely (len == (size_t) -1)) { @@ -562,7 +581,8 @@ dwarf_getmacros (Dwarf_Die *cudie, int (*callback) (Dwarf_Macro *, void *), { /* DW_AT_GNU_macros, DW_AT_macros */ Dwarf_Word macoff; - if (get_offset_from (cudie, DW_AT_GNU_macros, &macoff) != 0) + if (get_offset_from (cudie, DW_AT_GNU_macros, &macoff) != 0 + && get_offset_from (cudie, DW_AT_macros, &macoff) != 0) return -1; offset = gnu_macros_getmacros_off (cudie->cu->dbg, macoff, callback, arg, offset, accept_0xff, |