#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
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. */
}
}