public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] libdw: Try both the relative and absolute paths when finding a .dwo file.
@ 2018-06-01 11:23 Mark Wielaard
  2018-06-01 15:36 ` Mark Wielaard
  0 siblings, 1 reply; 2+ messages in thread
From: Mark Wielaard @ 2018-06-01 11:23 UTC (permalink / raw)
  To: elfutils-devel; +Cc: Mark Wielaard

We would give up if one of them failed. With this fixed a self-test with
make check succeeds when building elfutils itself with CFLAGS set to
"-gdwarf-4 -gdwarf-split -O2".

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 libdw/ChangeLog               |   7 +++
 libdw/libdw_find_split_unit.c | 114 +++++++++++++++++++++++++-----------------
 src/ChangeLog                 |   5 ++
 src/readelf.c                 |  13 ++++-
 4 files changed, 92 insertions(+), 47 deletions(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index d8433eb..17acb90 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,10 @@
+2018-05-31  Mark Wielaard  <mark@klomp.org>
+
+	* libdw_find_split_unit.c (try_split_file): New function extracted
+	from...
+	(__libdw_find_split_unit): ... here. Try both the relative and
+	absolute paths to find a .dwo file.
+
 2018-05-30  Mark Wielaard  <mark@klomp.org>
 
 	* libdw/dwarf_getsrclines.c (read_srclines): Change ndir and
diff --git a/libdw/libdw_find_split_unit.c b/libdw/libdw_find_split_unit.c
index dc62e0d..da039e5 100644
--- a/libdw/libdw_find_split_unit.c
+++ b/libdw/libdw_find_split_unit.c
@@ -42,6 +42,49 @@
 #include <fcntl.h>
 #include <unistd.h>
 
+void
+try_split_file (Dwarf_CU *cu, const char *dwo_path)
+{
+  int split_fd = open (dwo_path, O_RDONLY);
+  if (split_fd != -1)
+    {
+      Dwarf *split_dwarf = dwarf_begin (split_fd, DWARF_C_READ);
+      if (split_dwarf != NULL)
+	{
+	  Dwarf_CU *split = NULL;
+	  while (dwarf_get_units (split_dwarf, split, &split,
+				  NULL, NULL, NULL, NULL) == 0)
+	    {
+	      if (split->unit_type == DW_UT_split_compile
+		  && cu->unit_id8 == split->unit_id8)
+		{
+		  if (tsearch (split->dbg, &cu->dbg->split_tree,
+			       __libdw_finddbg_cb) == NULL)
+		    {
+		      /* Something went wrong.  Don't link.  */
+		      __libdw_seterrno (DWARF_E_NOMEM);
+		      break;
+		    }
+
+		  /* Link skeleton and split compile units.  */
+		  __libdw_link_skel_split (cu, split);
+
+		  /* We have everything we need from this ELF
+		     file.  And we are going to close the fd to
+		     not run out of file descriptors.  */
+		  elf_cntl (split_dwarf->elf, ELF_C_FDDONE);
+		  break;
+		}
+	    }
+	  if (cu->split == (Dwarf_CU *) -1)
+	    dwarf_end (split_dwarf);
+	}
+      /* Always close, because we don't want to run out of file
+	 descriptors.  See also the elf_fcntl ELF_C_FDDONE call
+	 above.  */
+      close (split_fd);
+    }
+}
 
 Dwarf_CU *
 internal_function
@@ -57,63 +100,42 @@ __libdw_find_split_unit (Dwarf_CU *cu)
   if (cu->unit_type == DW_UT_skeleton)
     {
       Dwarf_Die cudie = CUDIE (cu);
-      Dwarf_Attribute compdir, dwo_name;
-      /* It is fine if compdir doesn't exists, but then dwo_name needs
-	 to be an absolute path.  Also try relative path first.  */
-      dwarf_attr (&cudie, DW_AT_comp_dir, &compdir);
-	if (dwarf_attr (&cudie, DW_AT_dwo_name, &dwo_name) != NULL
-	    || dwarf_attr (&cudie, DW_AT_GNU_dwo_name, &dwo_name) != NULL)
+      Dwarf_Attribute dwo_name;
+      /* It is fine if dwo_dir doesn't exists, but then dwo_name needs
+	 to be an absolute path.  */
+      if (dwarf_attr (&cudie, DW_AT_dwo_name, &dwo_name) != NULL
+	  || dwarf_attr (&cudie, DW_AT_GNU_dwo_name, &dwo_name) != NULL)
 	{
-	  const char *comp_dir = dwarf_formstring (&compdir);
+	  /* First try the dwo file name in the same directory
+	     as we found the skeleton file.  */
 	  const char *dwo_file = dwarf_formstring (&dwo_name);
 	  const char *debugdir = cu->dbg->debugdir;
 	  char *dwo_path = __libdw_filepath (debugdir, NULL, dwo_file);
-	  if (dwo_path == NULL && comp_dir != NULL)
-	    dwo_path = __libdw_filepath (debugdir, comp_dir, dwo_file);
 	  if (dwo_path != NULL)
 	    {
-	      int split_fd = open (dwo_path, O_RDONLY);
-	      if (split_fd != -1)
+	      try_split_file (cu, dwo_path);
+	      free (dwo_path);
+	    }
+
+	  if (cu->split == (Dwarf_CU *) -1)
+	    {
+	      /* Try compdir plus dwo_name.  */
+	      Dwarf_Attribute compdir;
+	      dwarf_attr (&cudie, DW_AT_comp_dir, &compdir);
+	      const char *dwo_dir = dwarf_formstring (&compdir);
+	      if (dwo_dir != NULL)
 		{
-		  Dwarf *split_dwarf = dwarf_begin (split_fd, DWARF_C_READ);
-		  if (split_dwarf != NULL)
+		  dwo_path = __libdw_filepath (debugdir, dwo_dir, dwo_file);
+		  if (dwo_path != NULL)
 		    {
-		      Dwarf_CU *split = NULL;
-		      while (dwarf_get_units (split_dwarf, split, &split,
-					      NULL, NULL, NULL, NULL) == 0)
-			{
-			  if (split->unit_type == DW_UT_split_compile
-			      && cu->unit_id8 == split->unit_id8)
-			    {
-			      if (tsearch (split->dbg, &cu->dbg->split_tree,
-					   __libdw_finddbg_cb) == NULL)
-				{
-				  /* Something went wrong.  Don't link.  */
-				  __libdw_seterrno (DWARF_E_NOMEM);
-				  break;
-				}
-
-			      /* Link skeleton and split compile units.  */
-			      __libdw_link_skel_split (cu, split);
-
-			      /* We have everything we need from this
-				 ELF file.  And we are going to close
-				 the fd to not run out of file
-				 descriptors.  */
-			      elf_cntl (split_dwarf->elf, ELF_C_FDDONE);
-			      break;
-			    }
-			}
-		      if (cu->split == (Dwarf_CU *) -1)
-			dwarf_end (split_dwarf);
+		      try_split_file (cu, dwo_path);
+		      free (dwo_path);
 		    }
-		  /* Always close, because we don't want to run
-		     out of file descriptors.  See also the
-		     elf_fcntl ELF_C_FDDONE call above.  */
-		  close (split_fd);
 		}
-	      free (dwo_path);
 	    }
+	  /* XXX If still not found we could try stripping dirs from the
+	     comp_dir and adding them from the comp_dir, assuming
+	     someone moved a whole build tree around.  */
 	}
     }
 
diff --git a/src/ChangeLog b/src/ChangeLog
index 0e6f1f2..95f8a72 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2018-05-31  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (print_debug_units): Print the dwo name and id when
+	unable to find a .dwo file.
+
 2018-05-30  Mark Wielaard  <mark@klomp.org>
 
 	* readelf.c (print_debug_loc_section): Use correct listptr for
diff --git a/src/readelf.c b/src/readelf.c
index db7723d..8d85dc8 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -7668,7 +7668,18 @@ print_debug_units (Dwfl_Module *dwflmod,
 	  || dwarf_tag (&subdie) == DW_TAG_invalid)
 	{
 	  if (!silent)
-	    fprintf (stderr, gettext ("Could not find split compile unit"));
+	    {
+	      Dwarf_Attribute dwo_at;
+	      const char *dwo_name =
+		(dwarf_formstring (dwarf_attr (&cudie, DW_AT_dwo_name,
+					       &dwo_at))
+		 ?: (dwarf_formstring (dwarf_attr (&cudie, DW_AT_GNU_dwo_name,
+						   &dwo_at))
+		     ?: "<unknow"));
+	      fprintf (stderr,
+		       "Could not find split unit '%s', id: %" PRIx64 "\n",
+		       dwo_name, unit_id);
+	    }
 	}
       else
 	{
-- 
1.8.3.1

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

* Re: [PATCH] libdw: Try both the relative and absolute paths when finding a .dwo file.
  2018-06-01 11:23 [PATCH] libdw: Try both the relative and absolute paths when finding a .dwo file Mark Wielaard
@ 2018-06-01 15:36 ` Mark Wielaard
  0 siblings, 0 replies; 2+ messages in thread
From: Mark Wielaard @ 2018-06-01 15:36 UTC (permalink / raw)
  To: elfutils-devel

On Fri, 2018-06-01 at 13:23 +0200, Mark Wielaard wrote:
> We would give up if one of them failed. With this fixed a self-test with
> make check succeeds when building elfutils itself with CFLAGS set to
> "-gdwarf-4 -gdwarf-split -O2".

Pushed to master.

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

end of thread, other threads:[~2018-06-01 15:36 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-01 11:23 [PATCH] libdw: Try both the relative and absolute paths when finding a .dwo file Mark Wielaard
2018-06-01 15:36 ` 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).