[PATCH] libdw: Recognize GNU DebugFission split units.
Mark Wielaard
mark@klomp.org
Tue May 15 12:04:00 GMT 2018
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 <mark@klomp.org>
---
libdw/ChangeLog | 9 +++++++++
libdw/libdwP.h | 15 ++++++---------
libdw/libdw_findcu.c | 23 ++++++++++++++++++++---
src/ChangeLog | 5 +++++
src/readelf.c | 3 ++-
5 files changed, 42 insertions(+), 13 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index e41e5c8..385f52c 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,12 @@
+2018-05-15 Mark Wielaard <mark@klomp.org>
+
+ * 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 <mark@klomp.org>
* dwarf.h: Add GNU Debug Fission extensions. DW_AT_GNU_dwo_name,
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index da0383f..25a5ad3 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 3899c08..0a65c97 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 778d053..5a74e83 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2018-05-15 Mark Wielaard <mark@klomp.org>
+
+ * 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 <mark@klomp.org>
* readelf.c (print_ops): Handle DW_OP_GNU_addr_index and
diff --git a/src/readelf.c b/src/readelf.c
index 6d503c7..bb03d2c 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);
--
1.8.3.1
More information about the Elfutils-devel
mailing list