Skip to content

Commit

Permalink
libdw: Handle .debug_rnglists in dwarf_ranges.
Browse files Browse the repository at this point in the history
Handle all new DW_RLE opcodes in .debug_rnglists in dwarf_ranges. Extract
code for reading .debug_addr indexes from dwarf_formaddr as __libdw_addrx
to reuse in __libdw_read_begin_end_pair_inc. And add new testcase for
"plain" DWARF5 and add a new test all-dwarf-ranges to test split DWARF5.

Signed-off-by: Mark Wielaard <[email protected]>
  • Loading branch information
Mark Wielaard committed May 28, 2018
1 parent bc1f86b commit 879f3a4
Show file tree
Hide file tree
Showing 15 changed files with 453 additions and 79 deletions.
15 changes: 15 additions & 0 deletions libdw/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
2018-04-06 Mark Wielaard <[email protected]>

* dwarf_formaddr.c (__libdw_addrx): New function, extracted from...
(dwarf_formaddr): here. Use __libdw_addrx.
* dwarf_getlocation.c (getlocations_addr): Pass cu to
__libdw_read_begin_end_pair_inc.
* dwarf_ranges.c (__libdw_read_begin_end_pair_inc): Take cu as
argument. Handle .debug_rnglists.
(initial_offset): Handle .debug_rnglists and DW_FORM_rnglistx.
(dwarf_ranges): Likewise. Check cu isn't NULL before use. Pass cu to
__libdw_read_begin_end_pair_inc.
* libdwP.h (__libdw_read_begin_end_pair_inc): Take cu as argument.
(__libdw_cu_ranges_base): Handle DW_AT_rnglists_base.
(__libdw_addrx): New function definition.

2018-04-11 Mark Wielaard <[email protected]>

* dwarf.h: Add DWARF5 range list entry DW_RLE encodings.
Expand Down
76 changes: 43 additions & 33 deletions libdw/dwarf_formaddr.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,48 @@
#include "libdwP.h"


int
__libdw_addrx (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr)
{
Dwarf_Off addr_off = __libdw_cu_addr_base (cu);
if (addr_off == (Dwarf_Off) -1)
return -1;

Dwarf *dbg = cu->dbg;
if (dbg->sectiondata[IDX_debug_addr] == NULL)
{
__libdw_seterrno (DWARF_E_NO_DEBUG_ADDR);
return -1;
}

/* The section should at least contain room for one address. */
int address_size = cu->address_size;
if (cu->address_size > dbg->sectiondata[IDX_debug_addr]->d_size)
{
invalid_offset:
__libdw_seterrno (DWARF_E_INVALID_OFFSET);
return -1;
}

if (addr_off > (dbg->sectiondata[IDX_debug_addr]->d_size
- address_size))
goto invalid_offset;

idx *= address_size;
if (idx > (dbg->sectiondata[IDX_debug_addr]->d_size
- address_size - addr_off))
goto invalid_offset;

const unsigned char *datap;
datap = dbg->sectiondata[IDX_debug_addr]->d_buf + addr_off + idx;
if (address_size == 4)
*addr = read_4ubyte_unaligned (dbg, datap);
else
*addr = read_8ubyte_unaligned (dbg, datap);

return 0;
}

int
dwarf_formaddr (Dwarf_Attribute *attr, Dwarf_Addr *return_addr)
{
Expand Down Expand Up @@ -98,41 +140,9 @@ dwarf_formaddr (Dwarf_Attribute *attr, Dwarf_Addr *return_addr)

/* So we got an index. Lets see if it is valid and we can get the actual
address. */

Dwarf_Off addr_off = __libdw_cu_addr_base (cu);
if (addr_off == (Dwarf_Off) -1)
if (__libdw_addrx (cu, idx, return_addr) != 0)
return -1;

if (dbg->sectiondata[IDX_debug_addr] == NULL)
{
__libdw_seterrno (DWARF_E_NO_DEBUG_ADDR);
return -1;
}

/* The section should at least contain room for one address. */
int address_size = cu->address_size;
if (cu->address_size > dbg->sectiondata[IDX_debug_addr]->d_size)
{
invalid_offset:
__libdw_seterrno (DWARF_E_INVALID_OFFSET);
return -1;
}

if (addr_off > (dbg->sectiondata[IDX_debug_addr]->d_size
- address_size))
goto invalid_offset;

idx *= address_size;
if (idx > (dbg->sectiondata[IDX_debug_addr]->d_size
- address_size - addr_off))
goto invalid_offset;

datap = dbg->sectiondata[IDX_debug_addr]->d_buf + addr_off + idx;
if (address_size == 4)
*return_addr = read_4ubyte_unaligned (dbg, datap);
else
*return_addr = read_8ubyte_unaligned (dbg, datap);

return 0;
}
INTDEF(dwarf_formaddr)
2 changes: 1 addition & 1 deletion libdw/dwarf_getlocation.c
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ getlocations_addr (Dwarf_Attribute *attr, ptrdiff_t offset,
Dwarf_Addr end;

next:
switch (__libdw_read_begin_end_pair_inc (dbg, secidx,
switch (__libdw_read_begin_end_pair_inc (cu, secidx,
&readp, readendp,
cu->address_size,
&begin, &end, basep))
Expand Down
Loading

0 comments on commit 879f3a4

Please sign in to comment.