aboutsummaryrefslogtreecommitdiff
path: root/libdw
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2018-04-09 00:03:43 +0200
committerMark Wielaard <mark@klomp.org>2018-05-28 17:19:41 +0200
commit7372ccf49a83d4eb38b39fe227345d53c8219254 (patch)
tree26b01e415fa1e067ad6167bcc32a51ca83affa00 /libdw
parent879f3a4f99dfc7f3678dc1c959e66784f21886bb (diff)
downloadelfutils-7372ccf49a83d4eb38b39fe227345d53c8219254.tar.gz
readelf: Find skeleton units when inspecting split .dwo (--dwarf-skeleton).
To get the right context (especially addresses) when looking at a .dwo file we really need the skeleton file. If we can find it (simply replace .dwo with .o) then use that to get to the split DWARF units so that libdw sets up all relevant information to resolve. Also adds a --dwarf-skeleton option so the user can explicitly give a skeleton file to use (for example when all .o files are linked and removed already). Unfortunately this might not work if libdw cannot get from the skeleton file to the .dwo file (because they have been moved around). In that case eu-readelf "cheats", it will link up the libdw datastructures so that the skeleton and split DWARF units are setup correctly anyway. This does introduce a problem when trying to cleanup the Dwarf handle ownership graph. So we will deliberately leak memory by not closing the underlying Dwfl in that case. Signed-off-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'libdw')
-rw-r--r--libdw/ChangeLog6
-rw-r--r--libdw/libdwP.h23
-rw-r--r--libdw/libdw_find_split_unit.c19
3 files changed, 31 insertions, 17 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index fef78eea..99916865 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,9 @@
+2018-05-25 Mark Wielaard <mark@klomp.org>
+
+ * libdw_find_split_unit.c (__libdw_find_split_unit): Extract linking
+ skeleton and split compile units code into...
+ * libdwP (__libdw_link_skel_split): ...this new function.
+
2018-04-06 Mark Wielaard <mark@klomp.org>
* dwarf_formaddr.c (__libdw_addrx): New function, extracted from...
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index c419e37a..18576d6b 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -1174,6 +1174,29 @@ __libdw_cu_ranges_base (Dwarf_CU *cu)
}
+/* Link skeleton and split compile units. */
+static inline void
+__libdw_link_skel_split (Dwarf_CU *skel, Dwarf_CU *split)
+{
+ skel->split = split;
+ split->split = skel;
+
+ /* Get .debug_addr and addr_base greedy.
+ We also need it for the fake addr cu.
+ There is only one per split debug. */
+ Dwarf *dbg = skel->dbg;
+ Dwarf *sdbg = split->dbg;
+ if (sdbg->sectiondata[IDX_debug_addr] == NULL
+ && dbg->sectiondata[IDX_debug_addr] != NULL)
+ {
+ sdbg->sectiondata[IDX_debug_addr]
+ = dbg->sectiondata[IDX_debug_addr];
+ split->addr_base = __libdw_cu_addr_base (skel);
+ sdbg->fake_addr_cu = dbg->fake_addr_cu;
+ }
+}
+
+
/* Given an address index for a CU return the address.
Returns -1 and sets libdw_errno if an error occurs. */
int __libdw_addrx (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr);
diff --git a/libdw/libdw_find_split_unit.c b/libdw/libdw_find_split_unit.c
index 78c9a2a5..fcfc46e4 100644
--- a/libdw/libdw_find_split_unit.c
+++ b/libdw/libdw_find_split_unit.c
@@ -84,23 +84,8 @@ __libdw_find_split_unit (Dwarf_CU *cu)
if (split->unit_type == DW_UT_split_compile
&& cu->unit_id8 == split->unit_id8)
{
- /* Link skeleton and split compule units. */
- cu->split = split;
- split->split = cu;
-
- /* Get .debug_addr and addr_base greedy.
- We also need it for the fake addr cu.
- There is only one per split debug. */
- Dwarf *dbg = cu->dbg;
- Dwarf *sdbg = split->dbg;
- if (sdbg->sectiondata[IDX_debug_addr] == NULL
- && dbg->sectiondata[IDX_debug_addr] != NULL)
- {
- sdbg->sectiondata[IDX_debug_addr]
- = dbg->sectiondata[IDX_debug_addr];
- split->addr_base = __libdw_cu_addr_base (cu);
- sdbg->fake_addr_cu = dbg->fake_addr_cu;
- }
+ /* 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