diff options
| author | Mark Wielaard <[email protected]> | 2018-05-17 19:23:46 +0200 |
|---|---|---|
| committer | Mark Wielaard <[email protected]> | 2018-05-20 23:35:15 +0200 |
| commit | 46d5523c94b5e9c830aeba9de863e1b65b08b1df (patch) | |
| tree | 98344940b8f62388620aec92054ea59bd5e4841a /libdw/dwarf_getalt.c | |
| parent | 3d4998a9edd9f88b46662b3584de89ecd8f2f4c8 (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.c | 44 |
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)); |
