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 /libdwfl | |
| 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 'libdwfl')
| -rw-r--r-- | libdwfl/ChangeLog | 10 | ||||
| -rw-r--r-- | libdwfl/dwfl_module.c | 1 | ||||
| -rw-r--r-- | libdwfl/dwfl_module_getdwarf.c | 23 | ||||
| -rw-r--r-- | libdwfl/libdwflP.h | 2 | ||||
| -rw-r--r-- | libdwfl/offline.c | 3 |
5 files changed, 33 insertions, 6 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index b6262c20..d69fe0cd 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,13 @@ +2018-05-17 Mark Wielaard <[email protected]> + + * dwfl_module (__libdwfl_module_free): Free elfdir. + * dwfl_module_getdwarf.c (load_dw): Close file descriptors after + dwarf_begin_elf call. Set Dwarf debugdir if it is NULL, this is the + main module file and we recorded the elfdir. + * libdwflP.h (struct Dwfl_Module): Add elfdir field. + * offline.c (process_elf): Record the elfdir before we close the + main ELF file descriptor. + 2018-04-10 Mark Wielaard <[email protected]> * frame_unwind.c (unwind): If __libdwfl_frame_reg_get fails for diff --git a/libdwfl/dwfl_module.c b/libdwfl/dwfl_module.c index 510bd691..e7dfdace 100644 --- a/libdwfl/dwfl_module.c +++ b/libdwfl/dwfl_module.c @@ -120,6 +120,7 @@ __libdwfl_module_free (Dwfl_Module *mod) free (mod->reloc_info); free (mod->name); + free (mod->elfdir); free (mod); } diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c index 9775aced..af6838a6 100644 --- a/libdwfl/dwfl_module_getdwarf.c +++ b/libdwfl/dwfl_module_getdwarf.c @@ -1335,7 +1335,18 @@ load_dw (Dwfl_Module *mod, struct dwfl_file *debugfile) result = __libdwfl_relocate (mod, debugfile->elf, true); if (result != DWFL_E_NOERROR) return result; + } + + mod->dw = INTUSE(dwarf_begin_elf) (debugfile->elf, DWARF_C_READ, NULL); + if (mod->dw == NULL) + { + int err = INTUSE(dwarf_errno) (); + return err == DWARF_E_NO_DWARF ? DWFL_E_NO_DWARF : DWFL_E (LIBDW, err); + } + /* Do this after dwarf_begin_elf has a chance to process the fd. */ + if (mod->e_type == ET_REL && !debugfile->relocated) + { /* Don't keep the file descriptors around. */ if (mod->main.fd != -1 && elf_cntl (mod->main.elf, ELF_C_FDREAD) == 0) { @@ -1349,12 +1360,12 @@ load_dw (Dwfl_Module *mod, struct dwfl_file *debugfile) } } - mod->dw = INTUSE(dwarf_begin_elf) (debugfile->elf, DWARF_C_READ, NULL); - if (mod->dw == NULL) - { - int err = INTUSE(dwarf_errno) (); - return err == DWARF_E_NO_DWARF ? DWFL_E_NO_DWARF : DWFL_E (LIBDW, err); - } + /* 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 + && debugfile == &mod->main) + mod->dw->debugdir = strdup (mod->elfdir); /* 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 15ca0a11..36298711 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -190,6 +190,8 @@ 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. */ + Dwarf *dw; /* libdw handle for its debugging info. */ Dwarf *alt; /* Dwarf used for dwarf_setalt, or NULL. */ int alt_fd; /* descriptor, only valid when alt != NULL. */ diff --git a/libdwfl/offline.c b/libdwfl/offline.c index 80c80a16..d8697cf2 100644 --- a/libdwfl/offline.c +++ b/libdwfl/offline.c @@ -150,6 +150,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 + Dwarf later. */ + mod->elfdir = __libdw_debugdir (mod->main.fd); close (mod->main.fd); mod->main.fd = -1; } |
