summaryrefslogtreecommitdiffstats
path: root/libdw/dwarf_ranges.c
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2018-05-19 00:46:02 +0200
committerMark Wielaard <[email protected]>2018-05-23 00:31:22 +0200
commit144b73c49acf3ed894e4635aedb9b0d1208ade2e (patch)
tree53ce2f235c75324b4010c419b5d5fe1a524c09ba /libdw/dwarf_ranges.c
parenta4c74cc67de22cb3208fc768989c509d6837cd77 (diff)
libdw: Handle GNU DebugFission split ranges.
GNU DebugFission split dwarf handles DW_FORM_sec_offset specially for attributes that point to ranges. The .debug_ranges section is not in the .dwo file, but in the main/skeleton object file. The sec_offset is not relocated (in the ELF file), but is an offset against the skeleton DIE DW_AT_GNU_ranges_base attribute. dwarf_formudata is changed so it still looks like a normal offset ptr into the .debug_ranges section. dwarf_ranges is adapted to look for the .debug_ranges in the main object file. dwarf_highpc and dwarf_lowpc now handle the highpc and lowpc attributes being inherited for the split unit DIE from the skeleton. A new testcase is added to iterate over all ranges in a split GNU DebugFission file. Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'libdw/dwarf_ranges.c')
-rw-r--r--libdw/dwarf_ranges.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/libdw/dwarf_ranges.c b/libdw/dwarf_ranges.c
index dbcfa2d4..b0450cf3 100644
--- a/libdw/dwarf_ranges.c
+++ b/libdw/dwarf_ranges.c
@@ -122,7 +122,17 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
/* We have to look for a noncontiguous range. */
size_t secidx = IDX_debug_ranges;
- const Elf_Data *d = die->cu->dbg->sectiondata[secidx];
+ Dwarf_CU *cu = die->cu;
+ const Elf_Data *d = cu->dbg->sectiondata[secidx];
+ if (d == NULL && cu->unit_type == DW_UT_split_compile)
+ {
+ Dwarf_CU *skel = __libdw_find_split_unit (cu);
+ if (skel != NULL)
+ {
+ cu = skel;
+ d = cu->dbg->sectiondata[secidx];
+ }
+ }
const unsigned char *readp;
const unsigned char *readendp;
@@ -131,6 +141,10 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
Dwarf_Attribute attr_mem;
Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, DW_AT_ranges,
&attr_mem);
+ if (attr == NULL
+ && is_cudie (die)
+ && die->cu->unit_type == DW_UT_split_compile)
+ attr = INTUSE(dwarf_attr_integrate) (die, DW_AT_ranges, &attr_mem);
if (attr == NULL)
/* No PC attributes in this DIE at all, so an empty range list. */
return 0;
@@ -144,7 +158,7 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
}
else
{
- if (__libdw_offset_in_section (die->cu->dbg,
+ if (__libdw_offset_in_section (cu->dbg,
secidx, offset, 1))
return -1;
}
@@ -156,9 +170,9 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
Dwarf_Addr end;
next:
- switch (__libdw_read_begin_end_pair_inc (die->cu->dbg, secidx,
+ switch (__libdw_read_begin_end_pair_inc (cu->dbg, secidx,
&readp, readendp,
- die->cu->address_size,
+ cu->address_size,
&begin, &end, basep))
{
case 0: