summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOmar Sandoval <osandov@fb.com>2023-09-27 11:20:58 -0700
committerMark Wielaard <mark@klomp.org>2023-11-02 18:03:40 +0100
commit14c5658acfc24367bc1cf63b0e04b70220bedad2 (patch)
treeff291bc186a44d1a4ce16296334cf832f342ff16
parent0999fca6431594d49d5eceb5cd9eba685cdf1305 (diff)
libdw, libdwfl: Save original path of ELF file
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>
-rw-r--r--libdw/ChangeLog13
-rw-r--r--libdw/dwarf_begin_elf.c34
-rw-r--r--libdw/dwarf_end.c3
-rw-r--r--libdw/libdwP.h12
-rw-r--r--libdwfl/ChangeLog9
-rw-r--r--libdwfl/dwfl_module.c2
-rw-r--r--libdwfl/dwfl_module_getdwarf.c11
-rw-r--r--libdwfl/libdwflP.h2
-rw-r--r--libdwfl/offline.c4
9 files changed, 65 insertions, 25 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 52327688..b19fc80d 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,5 +1,18 @@
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.
* dwarf_entrypc.c (dwarf_entrypc): Call dwarf_lowpc.
* dwarf_ranges.c (dwarf_ranges): Use skeleton ranges section for
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
index 7936d343..323a91d0 100644
--- a/libdw/dwarf_begin_elf.c
+++ b/libdw/dwarf_begin_elf.c
@@ -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;
}
diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c
index 8dd075cf..e51d5dd7 100644
--- a/libdw/dwarf_end.c
+++ b/libdw/dwarf_end.c
@@ -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. */
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 0c44d40c..aef42267 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -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
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 54d85921..abbf0dfe 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -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()
diff --git a/libdwfl/dwfl_module.c b/libdwfl/dwfl_module.c
index 221d726d..c4d872d4 100644
--- a/libdwfl/dwfl_module.c
+++ b/libdwfl/dwfl_module.c
@@ -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);
}
diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
index 9ba499bb..6f98c02b 100644
--- a/libdwfl/dwfl_module_getdwarf.c
+++ b/libdwfl/dwfl_module_getdwarf.c
@@ -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;
diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
index cdc528d0..b3dfea1d 100644
--- a/libdwfl/libdwflP.h
+++ b/libdwfl/libdwflP.h
@@ -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. */
diff --git a/libdwfl/offline.c b/libdwfl/offline.c
index 52539fe3..e9ab0cc1 100644
--- a/libdwfl/offline.c
+++ b/libdwfl/offline.c
@@ -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;
}