summaryrefslogtreecommitdiffstats
path: root/libdw
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2018-05-31 16:57:09 +0200
committerMark Wielaard <mark@klomp.org>2018-06-01 17:27:59 +0200
commite2872c91f65301b202b84497b2b955f9e9613d00 (patch)
tree9c714039ba9dad15e5142ef4fc845974f0793752 /libdw
parenta6a783a32ee0e6428c15c87e62476b74ecd77686 (diff)
libdw: Try both the relative and absolute paths when finding a .dwo file.
We would give up if one of them failed. With this fixed a self-test with make check succeeds when building elfutils itself with CFLAGS set to "-gdwarf-4 -gdwarf-split -O2". Signed-off-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'libdw')
-rw-r--r--libdw/ChangeLog7
-rw-r--r--libdw/libdw_find_split_unit.c114
2 files changed, 75 insertions, 46 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index d8433eb9..17acb909 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,10 @@
+2018-05-31 Mark Wielaard <mark@klomp.org>
+
+ * libdw_find_split_unit.c (try_split_file): New function extracted
+ from...
+ (__libdw_find_split_unit): ... here. Try both the relative and
+ absolute paths to find a .dwo file.
+
2018-05-30 Mark Wielaard <mark@klomp.org>
* libdw/dwarf_getsrclines.c (read_srclines): Change ndir and
diff --git a/libdw/libdw_find_split_unit.c b/libdw/libdw_find_split_unit.c
index dc62e0d0..da039e50 100644
--- a/libdw/libdw_find_split_unit.c
+++ b/libdw/libdw_find_split_unit.c
@@ -42,6 +42,49 @@
#include <fcntl.h>
#include <unistd.h>
+void
+try_split_file (Dwarf_CU *cu, const char *dwo_path)
+{
+ int split_fd = open (dwo_path, O_RDONLY);
+ if (split_fd != -1)
+ {
+ Dwarf *split_dwarf = dwarf_begin (split_fd, DWARF_C_READ);
+ if (split_dwarf != NULL)
+ {
+ Dwarf_CU *split = NULL;
+ while (dwarf_get_units (split_dwarf, split, &split,
+ NULL, NULL, NULL, NULL) == 0)
+ {
+ if (split->unit_type == DW_UT_split_compile
+ && cu->unit_id8 == split->unit_id8)
+ {
+ if (tsearch (split->dbg, &cu->dbg->split_tree,
+ __libdw_finddbg_cb) == NULL)
+ {
+ /* Something went wrong. Don't link. */
+ __libdw_seterrno (DWARF_E_NOMEM);
+ break;
+ }
+
+ /* Link skeleton and split compile units. */
+ __libdw_link_skel_split (cu, split);
+
+ /* We have everything we need from this ELF
+ file. And we are going to close the fd to
+ not run out of file descriptors. */
+ elf_cntl (split_dwarf->elf, ELF_C_FDDONE);
+ break;
+ }
+ }
+ if (cu->split == (Dwarf_CU *) -1)
+ dwarf_end (split_dwarf);
+ }
+ /* Always close, because we don't want to run out of file
+ descriptors. See also the elf_fcntl ELF_C_FDDONE call
+ above. */
+ close (split_fd);
+ }
+}
Dwarf_CU *
internal_function
@@ -57,63 +100,42 @@ __libdw_find_split_unit (Dwarf_CU *cu)
if (cu->unit_type == DW_UT_skeleton)
{
Dwarf_Die cudie = CUDIE (cu);
- Dwarf_Attribute compdir, dwo_name;
- /* It is fine if compdir doesn't exists, but then dwo_name needs
- to be an absolute path. Also try relative path first. */
- dwarf_attr (&cudie, DW_AT_comp_dir, &compdir);
- if (dwarf_attr (&cudie, DW_AT_dwo_name, &dwo_name) != NULL
- || dwarf_attr (&cudie, DW_AT_GNU_dwo_name, &dwo_name) != NULL)
+ Dwarf_Attribute dwo_name;
+ /* It is fine if dwo_dir doesn't exists, but then dwo_name needs
+ to be an absolute path. */
+ if (dwarf_attr (&cudie, DW_AT_dwo_name, &dwo_name) != NULL
+ || dwarf_attr (&cudie, DW_AT_GNU_dwo_name, &dwo_name) != NULL)
{
- const char *comp_dir = dwarf_formstring (&compdir);
+ /* First try the dwo file name in the same directory
+ as we found the skeleton file. */
const char *dwo_file = dwarf_formstring (&dwo_name);
const char *debugdir = cu->dbg->debugdir;
char *dwo_path = __libdw_filepath (debugdir, NULL, dwo_file);
- if (dwo_path == NULL && comp_dir != NULL)
- dwo_path = __libdw_filepath (debugdir, comp_dir, dwo_file);
if (dwo_path != NULL)
{
- int split_fd = open (dwo_path, O_RDONLY);
- if (split_fd != -1)
+ try_split_file (cu, dwo_path);
+ free (dwo_path);
+ }
+
+ if (cu->split == (Dwarf_CU *) -1)
+ {
+ /* Try compdir plus dwo_name. */
+ Dwarf_Attribute compdir;
+ dwarf_attr (&cudie, DW_AT_comp_dir, &compdir);
+ const char *dwo_dir = dwarf_formstring (&compdir);
+ if (dwo_dir != NULL)
{
- Dwarf *split_dwarf = dwarf_begin (split_fd, DWARF_C_READ);
- if (split_dwarf != NULL)
+ dwo_path = __libdw_filepath (debugdir, dwo_dir, dwo_file);
+ if (dwo_path != NULL)
{
- Dwarf_CU *split = NULL;
- while (dwarf_get_units (split_dwarf, split, &split,
- NULL, NULL, NULL, NULL) == 0)
- {
- if (split->unit_type == DW_UT_split_compile
- && cu->unit_id8 == split->unit_id8)
- {
- if (tsearch (split->dbg, &cu->dbg->split_tree,
- __libdw_finddbg_cb) == NULL)
- {
- /* Something went wrong. Don't link. */
- __libdw_seterrno (DWARF_E_NOMEM);
- break;
- }
-
- /* Link skeleton and split compile units. */
- __libdw_link_skel_split (cu, split);
-
- /* We have everything we need from this
- ELF file. And we are going to close
- the fd to not run out of file
- descriptors. */
- elf_cntl (split_dwarf->elf, ELF_C_FDDONE);
- break;
- }
- }
- if (cu->split == (Dwarf_CU *) -1)
- dwarf_end (split_dwarf);
+ try_split_file (cu, dwo_path);
+ free (dwo_path);
}
- /* Always close, because we don't want to run
- out of file descriptors. See also the
- elf_fcntl ELF_C_FDDONE call above. */
- close (split_fd);
}
- free (dwo_path);
}
+ /* XXX If still not found we could try stripping dirs from the
+ comp_dir and adding them from the comp_dir, assuming
+ someone moved a whole build tree around. */
}
}