diff options
| author | Mark Wielaard <[email protected]> | 2018-05-19 00:46:02 +0200 |
|---|---|---|
| committer | Mark Wielaard <[email protected]> | 2018-05-23 00:31:22 +0200 |
| commit | 144b73c49acf3ed894e4635aedb9b0d1208ade2e (patch) | |
| tree | 53ce2f235c75324b4010c419b5d5fe1a524c09ba /libdw/dwarf_ranges.c | |
| parent | a4c74cc67de22cb3208fc768989c509d6837cd77 (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.c | 22 |
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: |
