]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdw, libdwfl: Save original path of ELF file
authorOmar Sandoval <osandov@fb.com>
Wed, 27 Sep 2023 18:20:58 +0000 (11:20 -0700)
committerMark Wielaard <mark@klomp.org>
Thu, 2 Nov 2023 17:03:40 +0000 (18:03 +0100)
libdw and libdwfl currently save the path of the directory containing
the ELF file to use when searching for alt and dwo files.  To search for
dwp files, we need the file name too.  Add an elfpath field to Dwarf,
and set the debugdir field from it.  Also update libdwfl to set elfpath
and debugdir.

Signed-off-by: Omar Sandoval <osandov@fb.com>
libdw/ChangeLog
libdw/dwarf_begin_elf.c
libdw/dwarf_end.c
libdw/libdwP.h
libdwfl/ChangeLog
libdwfl/dwfl_module.c
libdwfl/dwfl_module_getdwarf.c
libdwfl/libdwflP.h
libdwfl/offline.c

index 52327688451604c3279000debeffebbc86259fcd..b19fc80df6807ac49992d691f663c72c83f81083 100644 (file)
@@ -1,3 +1,16 @@
+2023-09-27  Omar Sandoval  <osandov@fb.com>
+
+       * libdwP.h ((Dwarf): Add elfpath.
+       * dwarf_begin_elf.c (__libdw_debugdir): Replace declaration with...
+       (__libdw_elfpath): New declaration.
+       (__libdw_set_debugdir): New declaration.
+       (__libdw_debugdir): Replace with..
+       (__libdw_elfpath): New function.
+       (__libdw_set_debugdir): New function.
+       (valid_p): Call __libdw_elfpath and __libdw_set_debugdir instead of
+       __libdw_debugdir.
+       * dwarf_end.c (dwarf_end): Free dwarf->elfpath.
+
 2023-09-27  Omar Sandoval  <osandov@fb.com>
 
        * libdw_find_split_unit.c (try_split_file): Make static.
index 7936d343219fe226dd55f169d5822307c63b3a6a..323a91d07943a762fa6e995330a25dabd98f1f17 100644 (file)
@@ -272,24 +272,27 @@ check_section (Dwarf *result, size_t shstrndx, Elf_Scn *scn, bool inscngrp)
   return result;
 }
 
-
-/* Helper function to set debugdir field.  We want to cache the dir
-   where we found this Dwarf ELF file to locate alt and dwo files.  */
 char *
-__libdw_debugdir (int fd)
+__libdw_elfpath (int fd)
 {
   /* strlen ("/proc/self/fd/") = 14 + strlen (<MAXINT>) = 10 + 1 = 25.  */
   char devfdpath[25];
   sprintf (devfdpath, "/proc/self/fd/%u", fd);
-  char *fdpath = realpath (devfdpath, NULL);
-  char *fddir;
-  if (fdpath != NULL && fdpath[0] == '/'
-      && (fddir = strrchr (fdpath, '/')) != NULL)
-    {
-      *++fddir = '\0';
-      return fdpath;
-    }
-  return NULL;
+  return realpath (devfdpath, NULL);
+}
+
+
+void
+__libdw_set_debugdir (Dwarf *dbg)
+{
+  if (dbg->elfpath == NULL || dbg->elfpath[0] != '/')
+    return;
+  size_t dirlen = strrchr (dbg->elfpath, '/') - dbg->elfpath + 1;
+  dbg->debugdir = malloc (dirlen + 1);
+  if (dbg->debugdir == NULL)
+    return;
+  memcpy (dbg->debugdir, dbg->elfpath, dirlen);
+  dbg->debugdir[dirlen] = '\0';
 }
 
 
@@ -421,7 +424,10 @@ valid_p (Dwarf *result)
     }
 
   if (result != NULL)
-    result->debugdir = __libdw_debugdir (result->elf->fildes);
+    {
+      result->elfpath = __libdw_elfpath (result->elf->fildes);
+      __libdw_set_debugdir(result);
+    }
 
   return result;
 }
index 8dd075cf6b29fc0e50be32f5785acfefcc48cf62..e51d5dd78856b78caf6b839aaf5a7853c0255226 100644 (file)
@@ -144,7 +144,8 @@ dwarf_end (Dwarf *dwarf)
          close (dwarf->alt_fd);
        }
 
-      /* The cached dir we found the Dwarf ELF file in.  */
+      /* The cached path and dir we found the Dwarf ELF file in.  */
+      free (dwarf->elfpath);
       free (dwarf->debugdir);
 
       /* Free the context descriptor.  */
index 0c44d40c910a1865811c69fcb7bec3c880dd9032..aef42267e7f9526ca7c369a0f135ceeb0703d89d 100644 (file)
@@ -168,6 +168,10 @@ struct Dwarf
   /* The underlying ELF file.  */
   Elf *elf;
 
+  /* The (absolute) path to the ELF file, if known.  To help locating
+     dwp files.  */
+  char *elfpath;
+
   /* The (absolute) path to the ELF dir, if known.  To help locating
      alt and dwo files.  */
   char *debugdir;
@@ -1350,9 +1354,13 @@ __libdw_link_skel_split (Dwarf_CU *skel, Dwarf_CU *split)
 int __libdw_addrx (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr);
 
 
-/* Helper function to set debugdir field in Dwarf, used from dwarf_begin_elf
+/* Helper function to set elfpath field in Dwarf, used from dwarf_begin_elf
    and libdwfl process_file.  */
-char * __libdw_debugdir (int fd);
+char * __libdw_elfpath (int fd);
+
+/* Helper function to set debugdir field in Dwarf after elfpath field has been
+   set.  */
+void __libdw_set_debugdir (Dwarf *dbg);
 
 
 /* Given the directory of a debug file, an absolute or relative dir
index 54d859214ce849fa9215128a07fc8177a2b16d62..abbf0dfe203e2293c59964fb6305a9b087dee0c2 100644 (file)
@@ -1,3 +1,12 @@
+2023-09-27  Omar Sandoval  <osandov@fb.com>
+       * dwfl_module.c (__libdwfl_module_free): Free mod->elfpath instead of
+       mod->elfdir.
+       * dwfl_module_getdwarf.c (load_dw): Set mod->dw->elfpath and call
+       __libdw_set_debugdir instead of setting mod->dw->debugdir.
+       * libdwflP.h (Dwfl_Module): Replace elfdir with elfpath.
+       * offline.c (process_elf): Call __libdw_elfpath and set mod->elfpath
+       instead of mod->elfdir.
+
 2023-04-24  John Gallagher  <john@gllghr.com>
 
        * gzip.c: Fix memory leak in unzip()
index 221d726da6e57bb8ad65a70e7b7f6ab59d51914e..c4d872d497f0c4ae09085eac6fa825a42dc50bb2 100644 (file)
@@ -119,7 +119,7 @@ __libdwfl_module_free (Dwfl_Module *mod)
     free (mod->reloc_info);
 
   free (mod->name);
-  free (mod->elfdir);
+  free (mod->elfpath);
   free (mod);
 }
 
index 9ba499bbfed34bae5fe12309a6563e753c759bce..6f98c02b4f3fe675ec1ef4b3f677a542751a7b2a 100644 (file)
@@ -1362,11 +1362,14 @@ load_dw (Dwfl_Module *mod, struct dwfl_file *debugfile)
     }
 
   /* We might have already closed the fd when we asked dwarf_begin_elf to
-     create an Dwarf.  Help out a little in case we need to find an alt or
-     dwo file later.  */
-  if (mod->dw->debugdir == NULL && mod->elfdir != NULL
+     create an Dwarf.  Help out a little in case we need to find an alt,
+     dwo, or dwp file later.  */
+  if (mod->dw->elfpath == NULL && mod->elfpath != NULL
       && debugfile == &mod->main)
-    mod->dw->debugdir = strdup (mod->elfdir);
+    {
+      mod->dw->elfpath = strdup (mod->elfpath);
+      __libdw_set_debugdir (mod->dw);
+    }
 
   /* Until we have iterated through all CU's, we might do lazy lookups.  */
   mod->lazycu = 1;
index cdc528d08ed8ab7beff51118226b1f879c4a7b12..b3dfea1d1b9aa4114c5ad58b01be261572221013 100644 (file)
@@ -186,7 +186,7 @@ struct Dwfl_Module
   Elf_Data *symxndxdata;       /* Data in the extended section index table. */
   Elf_Data *aux_symxndxdata;   /* Data in the extended auxiliary table. */
 
-  char *elfdir;                        /* The dir where we found the main Elf.  */
+  char *elfpath;               /* The path where we found the main Elf.  */
 
   Dwarf *dw;                   /* libdw handle for its debugging info.  */
   Dwarf *alt;                  /* Dwarf used for dwarf_setalt, or NULL.  */
index 52539fe371f6aac542beb719502f967a17668d79..e9ab0cc1d5c4f29d07bdbf32490ee927ccb9a093 100644 (file)
@@ -152,9 +152,9 @@ process_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd,
       /* Don't keep the file descriptor around.  */
       if (mod->main.fd != -1 && elf_cntl (mod->main.elf, ELF_C_FDREAD) == 0)
        {
-         /* Grab the dir path in case we want to report this file as
+         /* Grab the path in case we want to report this file as
             Dwarf later.  */
-         mod->elfdir = __libdw_debugdir (mod->main.fd);
+         mod->elfpath = __libdw_elfpath (mod->main.fd);
          close (mod->main.fd);
          mod->main.fd = -1;
        }