dwarf_highpc can use any address FORM, not just DW_FORM_addr. Just try whether the address can be resolved as address. Always set error when attribute couldn't be found or resolved. When calculating the base address for a CU don't try to second guess the error code, just treat an error the same as the attribute not being there.
Signed-off-by: Mark Wielaard <m...@klomp.org> --- libdw/ChangeLog | 7 +++++++ libdw/dwarf_getlocation.c | 17 ++++------------- libdw/dwarf_highpc.c | 10 ++++++---- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index e7fd217..3045359 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,10 @@ +2018-05-22 Mark Wielaard <m...@klomp.org> + + * dwarf_getlocation.c (__libdw_cu_base_address): Treat errors of + getting lowpc or entrypc the same as missing base address (zero). + * dwarf_highpc (dwarf_highpc): Handle any address form. Always set + error when attribute could not be found. + 2018-05-21 Mark Wielaard <m...@klomp.org> * dwarf_begin_elf.c (valid_p): Add a fake_addr_cu to the result. diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c index 116fa71..ade3e6c 100644 --- a/libdw/dwarf_getlocation.c +++ b/libdw/dwarf_getlocation.c @@ -682,19 +682,10 @@ __libdw_cu_base_address (Dwarf_CU *cu) &attr_mem), &base) != 0) { - int err = INTUSE(dwarf_errno) (); - if (err != 0) - { - __libdw_seterrno (err); - base = (Dwarf_Addr) -1; - } - else - { - /* The compiler provided no base address when it should - have. Buggy GCC does this when it used absolute - addresses in the location list and no DW_AT_ranges. */ - base = 0; - } + /* The compiler provided no base address when it should + have. Buggy GCC does this when it used absolute + addresses in the location list and no DW_AT_ranges. */ + base = 0; } cu->base_address = base; } diff --git a/libdw/dwarf_highpc.c b/libdw/dwarf_highpc.c index 1baffa7..5b2f0fd 100644 --- a/libdw/dwarf_highpc.c +++ b/libdw/dwarf_highpc.c @@ -47,10 +47,10 @@ dwarf_highpc (Dwarf_Die *die, Dwarf_Addr *return_addr) attr_high = INTUSE(dwarf_attr) (die, DW_AT_high_pc, &attr_high_mem); if (attr_high == NULL) - return -1; + goto no_addr; - if (attr_high->form == DW_FORM_addr) - return INTUSE(dwarf_formaddr) (attr_high, return_addr); + if (INTUSE(dwarf_formaddr) (attr_high, return_addr) == 0) + return 0; /* DWARF 4 allows high_pc to be a constant offset from low_pc. */ if (INTUSE(dwarf_lowpc) (die, return_addr) == 0) @@ -61,8 +61,10 @@ dwarf_highpc (Dwarf_Die *die, Dwarf_Addr *return_addr) *return_addr += uval; return 0; } - __libdw_seterrno (DWARF_E_NO_ADDR); } + +no_addr: + __libdw_seterrno (DWARF_E_NO_ADDR); return -1; } INTDEF(dwarf_highpc) -- 1.8.3.1