diff options
author | Mark Wielaard <mark@klomp.org> | 2018-05-20 23:30:01 +0200 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2018-05-25 15:07:58 +0200 |
commit | 6e3d2521a2b5a3b436901f52cfb9785887a7c961 (patch) | |
tree | 649d9c157ac680e9f99b61df772e429883602bf5 /libdw/dwarf_begin_elf.c | |
parent | 184fd30d1a453dc165ffc187b22dec6d196522ad (diff) | |
download | elfutils-6e3d2521a2b5a3b436901f52cfb9785887a7c961.tar.gz |
libdw: Support DW_OP_addrx/constx and split DWARF addrx/constx support.
DW_OP_addrx/constx and GNU DebugFission DW_OP_GNU_addr/const_index take
as argument an index into the .debug_addr section for the associated CU.
This index gets resolved through dwarf_getlocation_attr. A new fake addr
CU is created per Dwarf for use with this new attribute. For split DWARF
files, the IDX_debug_addr gets replaced with the skeleton section and the
addr base is resolved immediately when constructing the split DWARF CU.
Move __libdw_cu_addr_base to libdwP.h to share with eu-readelf. Also
make it possible to resolve addrx[1234]/GNU_addr_index also as constant
indexes to (also) show when displaying these attributes in eu-readelf.
A new varlocs tests is added to test the resolving for both the DWARF4
and DWARF5 DW_OP variants. And now that addrx forms are resolved in
split DWARF files add the new DIEs with "single ranges" (those DIEs that
have a lowpc/highpc attribute pair) to run-all-dwarf-ranges.sh.
Signed-off-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'libdw/dwarf_begin_elf.c')
-rw-r--r-- | libdw/dwarf_begin_elf.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c index 0e435c57..5d8e79e3 100644 --- a/libdw/dwarf_begin_elf.c +++ b/libdw/dwarf_begin_elf.c @@ -246,6 +246,33 @@ valid_p (Dwarf *result) } } + /* For DW_OP_constx/GNU_const_index and DW_OP_addrx/GNU_addr_index + the dwarf_location_attr () will need a "fake" address CU to + indicate where the attribute data comes from. This is a just + inside the .debug_addr section, if it exists. */ + if (result != NULL && result->sectiondata[IDX_debug_addr] != NULL) + { + result->fake_addr_cu = (Dwarf_CU *) calloc (1, sizeof (Dwarf_CU)); + if (unlikely (result->fake_addr_cu == NULL)) + { + Dwarf_Sig8_Hash_free (&result->sig8_hash); + __libdw_seterrno (DWARF_E_NOMEM); + free (result->fake_loc_cu); + free (result); + result = NULL; + } + else + { + result->fake_addr_cu->sec_idx = IDX_debug_addr; + result->fake_addr_cu->dbg = result; + result->fake_addr_cu->startp + = result->sectiondata[IDX_debug_addr]->d_buf; + result->fake_addr_cu->endp + = (result->sectiondata[IDX_debug_addr]->d_buf + + result->sectiondata[IDX_debug_addr]->d_size); + } + } + if (result != NULL) result->debugdir = __libdw_debugdir (result->elf->fildes); |