public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] libdw: Recognize GNU DebugFission split units.
@ 2018-05-15 12:04 Mark Wielaard
  2018-05-19 11:26 ` Mark Wielaard
  0 siblings, 1 reply; 2+ messages in thread
From: Mark Wielaard @ 2018-05-15 12:04 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Mark Wielaard

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

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] libdw: Recognize GNU DebugFission split units.
  2018-05-15 12:04 [PATCH] libdw: Recognize GNU DebugFission split units Mark Wielaard
@ 2018-05-19 11:26 ` Mark Wielaard
  0 siblings, 0 replies; 2+ messages in thread
From: Mark Wielaard @ 2018-05-19 11:26 UTC (permalink / raw)
  To: elfutils-devel

On Tue, May 15, 2018 at 02:04:31PM +0200, Mark Wielaard wrote:
> 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.

Pushed to master.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-05-19 11:26 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-15 12:04 [PATCH] libdw: Recognize GNU DebugFission split units Mark Wielaard
2018-05-19 11:26 ` Mark Wielaard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).