summaryrefslogtreecommitdiffstats
path: root/libdw/dwarf_getalt.c
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2018-05-17 19:23:46 +0200
committerMark Wielaard <[email protected]>2018-05-20 23:35:15 +0200
commit46d5523c94b5e9c830aeba9de863e1b65b08b1df (patch)
tree98344940b8f62388620aec92054ea59bd5e4841a /libdw/dwarf_getalt.c
parent3d4998a9edd9f88b46662b3584de89ecd8f2f4c8 (diff)
libdw: Cache ELF directory early. Explicitly set it in dwfl.
The logic that finds alt files and dwo files relies on having an open file descriptor. But after all needed ELF data has been read the underlying Elf file descriptor can be closed. libdwfl in particular closes file descriptor fairly aggressively. So capture the directory early on. And make dwfl set it if it has recorded it. Which it will do now before closing a file descriptor for the main Dwfl_Module file. Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'libdw/dwarf_getalt.c')
-rw-r--r--libdw/dwarf_getalt.c44
1 files changed, 16 insertions, 28 deletions
diff --git a/libdw/dwarf_getalt.c b/libdw/dwarf_getalt.c
index 3e5af151..3339b3e1 100644
--- a/libdw/dwarf_getalt.c
+++ b/libdw/dwarf_getalt.c
@@ -47,7 +47,7 @@
char *
internal_function
-__libdw_filepath (int fd, const char *dir, const char *file)
+__libdw_filepath (const char *debugdir, const char *dir, const char *file)
{
if (file == NULL)
return NULL;
@@ -71,37 +71,25 @@ __libdw_filepath (int fd, const char *dir, const char *file)
return path;
}
- if (fd >= 0)
+ if (debugdir != NULL)
{
- /* 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 *path = NULL;
- char *fddir;
- if (fdpath != NULL && fdpath[0] == '/'
- && (fddir = strrchr (fdpath, '/')) != NULL)
+ size_t debugdirlen = strlen (debugdir);
+ size_t dirlen = dir != NULL ? strlen (dir) : 0;
+ size_t filelen = strlen (file);
+ size_t len = debugdirlen + 1 + dirlen + 1 + filelen + 1;
+ char *path = malloc (len);
+ if (path != NULL)
{
- *++fddir = '\0';
- size_t fdpathlen = strlen (fdpath);
- size_t dirlen = dir != NULL ? strlen (dir) : 0;
- size_t filelen = strlen (file);
- size_t len = fdpathlen + 1 + dirlen + 1 + filelen + 1;
- path = malloc (len);
- if (path != NULL)
+ char *c = mempcpy (path, debugdir, debugdirlen);
+ if (dirlen > 0)
{
- char *c = mempcpy (path, fdpath, fdpathlen);
- if (dirlen > 0)
- {
- c = mempcpy (c, dir, dirlen);
- if (dir[dirlen - 1] != '/')
- *c++ = '/';
- }
- mempcpy (c, file, filelen + 1);
+ c = mempcpy (c, dir, dirlen);
+ if (dir[dirlen - 1] != '/')
+ *c++ = '/';
}
+ mempcpy (c, file, filelen + 1);
+ return path;
}
- free (fdpath);
- return path;
}
return NULL;
@@ -151,7 +139,7 @@ find_debug_altlink (Dwarf *dbg)
/* Fall back on (possible relative) alt file path. */
if (fd < 0)
{
- char *altpath = __libdw_filepath (dbg->elf->fildes, NULL, altname);
+ char *altpath = __libdw_filepath (dbg->debugdir, NULL, altname);
if (altpath != NULL)
{
fd = TEMP_FAILURE_RETRY (open (altpath, O_RDONLY));