public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] libdw: Handle split dwarf debuglines.
@ 2018-05-18 10:58 Mark Wielaard
  2018-05-22 13:51 ` Mark Wielaard
  0 siblings, 1 reply; 2+ messages in thread
From: Mark Wielaard @ 2018-05-18 10:58 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Mark Wielaard

Split DWARF .dwo files do contain a .debug_line section, but only with
the file table, there is no actual line program. Also split DWARF CU DIEs
don't have a DW_AT_stmt_list attribute. To get at the file (and dir) table
for a split unit DIE take just the files from the .debug_line section
(at offset zero). To get the full line table use the skeleton DIE (which
does have a DW_AT_stmt_list).

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 libdw/ChangeLog           |  9 +++++++
 libdw/dwarf_getsrcfiles.c | 50 ++++++++++++++++++++++++++++-------
 libdw/dwarf_getsrclines.c | 25 ++++++++++++++++++
 libdw/libdw_findcu.c      |  1 +
 tests/ChangeLog           |  6 +++++
 tests/run-get-files.sh    | 66 +++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 148 insertions(+), 9 deletions(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 0a0728b..e067827 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,12 @@
+2018-05-18  Mark Wielaard  <mark@klomp.org>
+
+	* libdw_findcu.c (__libdw_intern_next_unit): Init files to NULL.
+	* dwarf_getsrclines.c (dwarf_getsrclines): Handle split units by
+	taking the line table from the skeleton.
+	* dwarf_getsrcfiles.c (dwarf_getsrcfiles): Handle split units by
+	only taking the files from .debug_line offset zero (if it exists),
+	otherwise fall back to the skeleton.
+
 2018-05-17  Mark Wielaard  <mark@klomp.org>
 
 	* dwarf_begin_elf.c (__libdw_debugdir): New function.
diff --git a/libdw/dwarf_getsrcfiles.c b/libdw/dwarf_getsrcfiles.c
index 5af6f68..12fdabf 100644
--- a/libdw/dwarf_getsrcfiles.c
+++ b/libdw/dwarf_getsrcfiles.c
@@ -1,7 +1,6 @@
 /* Return source file information of CU.
-   Copyright (C) 2004, 2005, 2013, 2015 Red Hat, Inc.
+   Copyright (C) 2004, 2005, 2013, 2015, 2018 Red Hat, Inc.
    This file is part of elfutils.
-   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
 
    This file is free software; you can redistribute it and/or modify
    it under the terms of either
@@ -51,14 +50,47 @@ dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles)
 
   /* Get the information if it is not already known.  */
   struct Dwarf_CU *const cu = cudie->cu;
-  if (cu->lines == NULL)
+  if (cu->files == NULL)
     {
-      Dwarf_Lines *lines;
-      size_t nlines;
-
-      /* Let the more generic function do the work.  It'll create more
-	 data but that will be needed in an real program anyway.  */
-      res = INTUSE(dwarf_getsrclines) (cudie, &lines, &nlines);
+      /* For split units there might be a simple file table (without lines).
+	 If not, use the one from the skeleton.  */
+      if (cu->unit_type == DW_UT_split_compile
+	  || cu->unit_type == DW_UT_split_type)
+	{
+	  /* We tried, assume we fail...  */
+	  cu->files = (void *) -1;
+
+	  /* See if there is a .debug_line section, for split CUs
+	     the table is at offset zero.  */
+	  if (cu->dbg->sectiondata[IDX_debug_line] != NULL)
+	    {
+	      /* We are only interested in the files, the lines will
+		 always come from the skeleton.  */
+	      res = __libdw_getsrclines (cu->dbg, 0,
+					 __libdw_getcompdir (cudie),
+					 cu->address_size, NULL,
+					 &cu->files);
+	    }
+	  else
+	    {
+	      Dwarf_CU *skel = __libdw_find_split_unit (cu);
+	      if (skel != NULL)
+		{
+		  Dwarf_Die skeldie = CUDIE (skel);
+		  res = INTUSE(dwarf_getsrcfiles) (&skeldie, files, nfiles);
+		  cu->files = skel->files;
+		}
+	    }
+	}
+      else
+	{
+	  Dwarf_Lines *lines;
+	  size_t nlines;
+
+	  /* Let the more generic function do the work.  It'll create more
+	     data but that will be needed in an real program anyway.  */
+	  res = INTUSE(dwarf_getsrclines) (cudie, &lines, &nlines);
+	}
     }
   else if (cu->files != (void *) -1l)
     /* We already have the information.  */
diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c
index 2f966ab..2bf3098 100644
--- a/libdw/dwarf_getsrclines.c
+++ b/libdw/dwarf_getsrclines.c
@@ -1147,6 +1147,31 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
   struct Dwarf_CU *const cu = cudie->cu;
   if (cu->lines == NULL)
     {
+      /* For split units always pick the lines from the skeleton.  */
+      if (cu->unit_type == DW_UT_split_compile
+	  || cu->unit_type == DW_UT_split_type)
+	{
+	  /* We tries, assume we fail...  */
+	  cu->lines = (void *) -1l;
+
+	  Dwarf_CU *skel = __libdw_find_split_unit (cu);
+	  if (skel != NULL)
+	    {
+	      Dwarf_Die skeldie = CUDIE (skel);
+	      int res = INTUSE(dwarf_getsrclines) (&skeldie, lines, nlines);
+	      if (res == 0)
+		{
+		  cu->lines = skel->lines;
+		  *lines = cu->lines;
+		  *nlines = cu->lines->nlines;
+		}
+	      return res;
+	    }
+
+	  __libdw_seterrno (DWARF_E_NO_DEBUG_LINE);
+	  return -1;
+	}
+
       /* Failsafe mode: no data found.  */
       cu->lines = (void *) -1l;
       cu->files = (void *) -1l;
diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c
index d6975f3..d22ddae 100644
--- a/libdw/libdw_findcu.c
+++ b/libdw/libdw_findcu.c
@@ -114,6 +114,7 @@ __libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
   newp->subdie_offset = subdie_offset;
   Dwarf_Abbrev_Hash_init (&newp->abbrev_hash, 41);
   newp->orig_abbrev_offset = newp->last_abbrev_offset = abbrev_offset;
+  newp->files = NULL;
   newp->lines = NULL;
   newp->locs = NULL;
   newp->split = (Dwarf_CU *) -1;
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 05e8f26..0370fbc 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,9 @@
+2018-05-18  Mark Wielaard  <mark@klomp.org>
+
+	* run-get-files.sh: Add testcases for testfile-splitdwarf-4,
+	testfile-hello4.dwo, testfile-world4.dwo and testfile-splitdwarf-5,
+	testfile-hello5.dwo, testfile-world5.dwo.
+
 2018-05-17  Mark Wielaard  <mark@klomp.org>
 
 	* Makefile.am (check_PROGRAMS): Add attr-integrate-skel.
diff --git a/tests/run-get-files.sh b/tests/run-get-files.sh
index a2f2373..6f90be7 100755
--- a/tests/run-get-files.sh
+++ b/tests/run-get-files.sh
@@ -64,4 +64,70 @@ cuhl = 11, o = 267, asz = 4, osz = 4, ncu = 2680
  file[1] = "/shoggoth/drepper/m.c"
 EOF
 
+# see tests/testfile-dwarf-45.source
+testfiles testfile-splitdwarf-4 testfile-hello4.dwo testfile-world4.dwo
+testfiles testfile-splitdwarf-5 testfile-hello5.dwo testfile-world5.dwo
+
+testrun_compare ${abs_builddir}/get-files testfile-splitdwarf-4 testfile-hello4.dwo testfile-world4.dwo <<\EOF
+cuhl = 11, o = 0, asz = 8, osz = 4, ncu = 52
+ dirs[0] = "/home/mark/src/elfutils/tests"
+ dirs[1] = "/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include"
+ file[0] = "???"
+ file[1] = "/home/mark/src/elfutils/tests/hello.c"
+ file[2] = "/home/mark/src/elfutils/tests/hello.h"
+ file[3] = "/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include/stddef.h"
+cuhl = 11, o = 26, asz = 8, osz = 4, ncu = 104
+ dirs[0] = "/home/mark/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "???"
+ file[1] = "/home/mark/src/elfutils/tests/world.c"
+ file[2] = "/home/mark/src/elfutils/tests/hello.h"
+ file[3] = "/usr/include/stdlib.h"
+cuhl = 11, o = 0, asz = 8, osz = 4, ncu = 414
+ dirs[0] = "/home/mark/src/elfutils/tests"
+ dirs[1] = "/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include"
+ file[0] = "???"
+ file[1] = "/home/mark/src/elfutils/tests/hello.c"
+ file[2] = "/home/mark/src/elfutils/tests/hello.h"
+ file[3] = "/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include/stddef.h"
+cuhl = 11, o = 0, asz = 8, osz = 4, ncu = 331
+ dirs[0] = "/home/mark/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "???"
+ file[1] = "/home/mark/src/elfutils/tests/world.c"
+ file[2] = "/home/mark/src/elfutils/tests/hello.h"
+ file[3] = "/usr/include/stdlib.h"
+EOF
+
+testrun_compare ${abs_builddir}/get-files testfile-splitdwarf-5 testfile-hello5.dwo testfile-world5.dwo <<\EOF
+cuhl = 20, o = 0, asz = 8, osz = 4, ncu = 53
+ dirs[0] = "/home/mark/src/elfutils/tests"
+ dirs[1] = "/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include"
+ file[0] = "/home/mark/src/elfutils/tests/hello.c"
+ file[1] = "/home/mark/src/elfutils/tests/hello.c"
+ file[2] = "/home/mark/src/elfutils/tests/hello.h"
+ file[3] = "/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include/stddef.h"
+cuhl = 20, o = 21, asz = 8, osz = 4, ncu = 106
+ dirs[0] = "/home/mark/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "/home/mark/src/elfutils/tests/world.c"
+ file[1] = "/home/mark/src/elfutils/tests/world.c"
+ file[2] = "/home/mark/src/elfutils/tests/hello.h"
+ file[3] = "/usr/include/stdlib.h"
+cuhl = 20, o = 0, asz = 8, osz = 4, ncu = 386
+ dirs[0] = "/home/mark/src/elfutils/tests"
+ dirs[1] = "/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include"
+ file[0] = "/home/mark/src/elfutils/tests/hello.c"
+ file[1] = "/home/mark/src/elfutils/tests/hello.c"
+ file[2] = "/home/mark/src/elfutils/tests/hello.h"
+ file[3] = "/opt/local/install/gcc/lib/gcc/x86_64-pc-linux-gnu/9.0.0/include/stddef.h"
+cuhl = 20, o = 0, asz = 8, osz = 4, ncu = 296
+ dirs[0] = "/home/mark/src/elfutils/tests"
+ dirs[1] = "/usr/include"
+ file[0] = "/home/mark/src/elfutils/tests/world.c"
+ file[1] = "/home/mark/src/elfutils/tests/world.c"
+ file[2] = "/home/mark/src/elfutils/tests/hello.h"
+ file[3] = "/usr/include/stdlib.h"
+EOF
+
 exit 0
-- 
1.8.3.1

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

* Re: [PATCH] libdw: Handle split dwarf debuglines.
  2018-05-18 10:58 [PATCH] libdw: Handle split dwarf debuglines Mark Wielaard
@ 2018-05-22 13:51 ` Mark Wielaard
  0 siblings, 0 replies; 2+ messages in thread
From: Mark Wielaard @ 2018-05-22 13:51 UTC (permalink / raw)
  To: elfutils-devel

On Fri, 2018-05-18 at 12:58 +0200, Mark Wielaard wrote:
> Split DWARF .dwo files do contain a .debug_line section, but only with
> the file table, there is no actual line program. Also split DWARF CU DIEs
> don't have a DW_AT_stmt_list attribute. To get at the file (and dir) table
> for a split unit DIE take just the files from the .debug_line section
> (at offset zero). To get the full line table use the skeleton DIE (which
> does have a DW_AT_stmt_list).

Pushed to master.

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

end of thread, other threads:[~2018-05-22 13:51 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-18 10:58 [PATCH] libdw: Handle split dwarf debuglines Mark Wielaard
2018-05-22 13:51 ` 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).