From: Mark Wielaard Date: Mon, 14 May 2018 15:29:05 +0000 (+0200) Subject: libdw: Recognize GNU DebugFission split units. X-Git-Tag: elfutils-0.171~33 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=77cbbbd40432ca79f052c3d5bb620afbced0c1a1;p=thirdparty%2Felfutils.git libdw: Recognize GNU DebugFission split units. The split dwarf dwo unit id and type are not in the CU header itself, but can be found in the CU DIE DW_AT_GNU_dwo attributes. Use this to set the correct unit_type and id for GNU DebugFission split units. Also show this information in eu-readelf when printing units. Signed-off-by: Mark Wielaard --- diff --git a/libdw/ChangeLog b/libdw/ChangeLog index e41e5c85f..385f52c20 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,12 @@ +2018-05-15 Mark Wielaard + + * libdwP.h (__libdw_first_die_from_cu_start): Adjust commented out + asserts. + * libdw_findcu.c (__libdw_intern_next_unit): For version 4 DWARF if + the cudie has a DW_AT_GNU_dwi_id set the unit_id8 and unit_type to + DW_UT_skeleton or DW_UT_split_compile based on whether the cudie has + child DIEs and a DW_AT_GNU_dwo_name attribute. + 2018-05-14 Mark Wielaard * dwarf.h: Add GNU Debug Fission extensions. DW_AT_GNU_dwo_name, diff --git a/libdw/libdwP.h b/libdw/libdwP.h index da0383f47..25a5ad316 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -360,15 +360,12 @@ __libdw_first_die_from_cu_start (Dwarf_Off cu_start, /* assert (offset_size == 4 || offset_size == 8); assert (version >= 2 && version <= 5); - assert (version >= 5 || (unit_type == DW_UT_compile - || unit_type == DW_UT_partial - || unit_type == DW_UT_type)); - assert (version != 5 || (unit_type == DW_UT_compile - || unit_type == DW_UT_partial - || unit_type == DW_UT_skeleton - || unit_type == DW_UT_split_compile - || unit_type == DW_UT_type - || unit_type == DW_UT_split_type)); + assert (unit_type == DW_UT_compile + || unit_type == DW_UT_partial + || unit_type == DW_UT_skeleton + || unit_type == DW_UT_split_compile + || unit_type == DW_UT_type + || unit_type == DW_UT_split_type); */ Dwarf_Off off = cu_start; diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c index 3899c0875..0a65c973b 100644 --- a/libdw/libdw_findcu.c +++ b/libdw/libdw_findcu.c @@ -123,7 +123,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types) newp->startp = data->d_buf + newp->start; newp->endp = data->d_buf + newp->end; - /* v4 debug type units have version == 4 and unit_type == 1. */ + /* v4 debug type units have version == 4 and unit_type == DW_UT_type. */ if (debug_types) newp->unit_type = DW_UT_type; else if (version < 5) @@ -133,9 +133,26 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types) /* But set it correctly from the actual CUDIE tag. */ Dwarf_Die cudie = CUDIE (newp); - int tag = dwarf_tag (&cudie); + int tag = INTUSE(dwarf_tag) (&cudie); if (tag == DW_TAG_compile_unit) - newp->unit_type = DW_UT_compile; + { + Dwarf_Attribute dwo_id; + if (INTUSE(dwarf_attr) (&cudie, DW_AT_GNU_dwo_id, &dwo_id) != NULL) + { + Dwarf_Word id8; + if (INTUSE(dwarf_formudata) (&dwo_id, &id8) == 0) + { + if (INTUSE(dwarf_haschildren) (&cudie) == 0 + && INTUSE(dwarf_hasattr) (&cudie, + DW_AT_GNU_dwo_name) == 1) + newp->unit_type = DW_UT_skeleton; + else + newp->unit_type = DW_UT_split_compile; + + newp->unit_id8 = id8; + } + } + } else if (tag == DW_TAG_partial_unit) newp->unit_type = DW_UT_partial; else if (tag == DW_TAG_type_unit) diff --git a/src/ChangeLog b/src/ChangeLog index 4f08312ef..9a6adab17 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2018-05-15 Mark Wielaard + + * readelf.c (print_debug_units): Print unit type and id for any + unit type that has it even when version < 5. + 2018-05-14 Mark Wielaard * readelf.c (print_ops): Handle DW_OP_GNU_addr_index and diff --git a/src/readelf.c b/src/readelf.c index 6d503c716..bb03d2c27 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -6577,7 +6577,8 @@ print_debug_units (Dwfl_Module *dwflmod, ", Offset size: %" PRIu8 "\n"), (uint64_t) offset, version, abbroffset, addrsize, offsize); - if (version >= 5) + if (version >= 5 || (unit_type != DW_UT_compile + && unit_type != DW_UT_partial)) { printf (gettext (" Unit type: %s (%" PRIu8 ")"), dwarf_unit_name (unit_type), unit_type);