summaryrefslogtreecommitdiff
path: root/libdw/dwarf_begin_elf.c
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2018-05-20 23:30:01 +0200
committerMark Wielaard <mark@klomp.org>2018-05-25 15:07:58 +0200
commit6e3d2521a2b5a3b436901f52cfb9785887a7c961 (patch)
tree649d9c157ac680e9f99b61df772e429883602bf5 /libdw/dwarf_begin_elf.c
parent184fd30d1a453dc165ffc187b22dec6d196522ad (diff)
downloadelfutils-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.c27
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);