From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21607 invoked by alias); 1 Jun 2018 11:23:33 -0000 Mailing-List: contact elfutils-devel-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Post: List-Help: List-Subscribe: Sender: elfutils-devel-owner@sourceware.org Received: (qmail 20351 invoked by uid 89); 1 Jun 2018 11:23:31 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.99.4 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy= X-Spam-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on sourceware.org X-Spam-Level: X-HELO: gnu.wildebeest.org Received: from wildebeest.demon.nl (HELO gnu.wildebeest.org) (212.238.236.112) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 01 Jun 2018 11:23:30 +0000 Received: from tarox.wildebeest.org (tarox.wildebeest.org [172.31.17.39]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id C9D8A3000702; Fri, 1 Jun 2018 13:23:27 +0200 (CEST) Received: by tarox.wildebeest.org (Postfix, from userid 1000) id B878A4001058; Fri, 1 Jun 2018 13:23:27 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: Mark Wielaard Subject: [PATCH] libdw: Try both the relative and absolute paths when finding a .dwo file. Date: Fri, 01 Jun 2018 11:23:00 -0000 Message-Id: <1527852200-1415-1-git-send-email-mark@klomp.org> X-Mailer: git-send-email 1.8.3.1 X-Spam-Flag: NO X-IsSubscribed: yes X-SW-Source: 2018-q2/txt/msg00137.txt.bz2 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 --- libdw/ChangeLog | 7 +++ libdw/libdw_find_split_unit.c | 114 +++++++++++++++++++++++++----------------- src/ChangeLog | 5 ++ src/readelf.c | 13 ++++- 4 files changed, 92 insertions(+), 47 deletions(-) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index d8433eb..17acb90 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,10 @@ +2018-05-31 Mark Wielaard + + * 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 * 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 dc62e0d..da039e5 100644 --- a/libdw/libdw_find_split_unit.c +++ b/libdw/libdw_find_split_unit.c @@ -42,6 +42,49 @@ #include #include +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. */ } } diff --git a/src/ChangeLog b/src/ChangeLog index 0e6f1f2..95f8a72 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2018-05-31 Mark Wielaard + + * readelf.c (print_debug_units): Print the dwo name and id when + unable to find a .dwo file. + 2018-05-30 Mark Wielaard * readelf.c (print_debug_loc_section): Use correct listptr for diff --git a/src/readelf.c b/src/readelf.c index db7723d..8d85dc8 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -7668,7 +7668,18 @@ print_debug_units (Dwfl_Module *dwflmod, || dwarf_tag (&subdie) == DW_TAG_invalid) { if (!silent) - fprintf (stderr, gettext ("Could not find split compile unit")); + { + Dwarf_Attribute dwo_at; + const char *dwo_name = + (dwarf_formstring (dwarf_attr (&cudie, DW_AT_dwo_name, + &dwo_at)) + ?: (dwarf_formstring (dwarf_attr (&cudie, DW_AT_GNU_dwo_name, + &dwo_at)) + ?: "