* [PATCH] libdw: Support DW_OP_addrx/constx and split DWARF addrx/constx support.
@ 2018-05-22 11:10 Mark Wielaard
2018-05-25 13:10 ` Mark Wielaard
0 siblings, 1 reply; 2+ messages in thread
From: Mark Wielaard @ 2018-05-22 11:10 UTC (permalink / raw)
To: elfutils-devel; +Cc: Mark Wielaard
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>
---
libdw/ChangeLog | 19 ++++
libdw/dwarf_begin_elf.c | 27 +++++
libdw/dwarf_end.c | 12 ++-
libdw/dwarf_formaddr.c | 18 ----
libdw/dwarf_formudata.c | 33 ++++++
libdw/dwarf_getlocation_attr.c | 31 ++++++
libdw/libdwP.h | 24 ++++-
libdw/libdw_find_split_unit.c | 14 +++
src/ChangeLog | 9 ++
src/readelf.c | 64 ++++++++++--
tests/ChangeLog | 14 +++
tests/Makefile.am | 2 +
tests/addrx_constx-4.dwo.bz2 | Bin 0 -> 809 bytes
tests/addrx_constx-5.dwo.bz2 | Bin 0 -> 824 bytes
tests/run-all-dwarf-ranges.sh | 24 +++++
tests/run-varlocs.sh | 208 ++++++++++++++++++++++++++++++++++++++
tests/testfile-addrx_constx-4.bz2 | Bin 0 -> 2851 bytes
tests/testfile-addrx_constx-5.bz2 | Bin 0 -> 2847 bytes
tests/varlocs.c | 65 +++++++++---
19 files changed, 523 insertions(+), 41 deletions(-)
create mode 100644 tests/addrx_constx-4.dwo.bz2
create mode 100644 tests/addrx_constx-5.dwo.bz2
create mode 100755 tests/testfile-addrx_constx-4.bz2
create mode 100755 tests/testfile-addrx_constx-5.bz2
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index c575f64..e7fd217 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,22 @@
+2018-05-21 Mark Wielaard <mark@klomp.org>
+
+ * dwarf_begin_elf.c (valid_p): Add a fake_addr_cu to the result.
+ * dwarf_end.c (cu_free): Disconnect the fake_addr_cu from the split
+ dwarf if shared with skeleton.
+ (dwarf_end): release fake_addr_cu.
+ * dwarf_formaddr.c (__libdw_cu_addr_base): Move to...
+ * libdwP.h (__libdw_cu_addr_base): ... here.
+ (struct Dwarf): Add fake_addr_cu field.
+ * dwarf_formudata.c (dwarf_formudata): Handle
+ DW_FORM_GNU_addr_index and DW_FORM_addrx[1234].
+ * dwarf_getlocation_attr.c (addr_valp): New static function.
+ (dwarf_getlocation_attr): Create attribute for values of
+ DW_OP_GNU_const_index, DW_OP_constx and DW_OP_GNU_addr_index and
+ DW_OP_addrx.
+ * libdw_find_split_unit.c (__libdw_find_split_unit): Connect
+ IDX_debug_addr sectiondata and fake_addr_cu between split and
+ skeleton.
+
2018-05-20 Mark Wielaard <mark@klomp.org>
* dwarf_cu_info.c: New file.
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
index 0e435c5..5d8e79e 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);
diff --git a/libdw/dwarf_end.c b/libdw/dwarf_end.c
index 4702f1b..1954674 100644
--- a/libdw/dwarf_end.c
+++ b/libdw/dwarf_end.c
@@ -59,7 +59,12 @@ cu_free (void *arg)
/* Free split dwarf one way (from skeleton to split). */
if (p->unit_type == DW_UT_skeleton
&& p->split != NULL && p->split != (void *)-1)
- INTUSE(dwarf_end) (p->split->dbg);
+ {
+ /* The fake_addr_cu might be shared, only release one. */
+ if (p->dbg->fake_addr_cu == p->split->dbg->fake_addr_cu)
+ p->split->dbg->fake_addr_cu = NULL;
+ INTUSE(dwarf_end) (p->split->dbg);
+ }
}
@@ -108,6 +113,11 @@ dwarf_end (Dwarf *dwarf)
cu_free (dwarf->fake_loc_cu);
free (dwarf->fake_loc_cu);
}
+ if (dwarf->fake_addr_cu != NULL)
+ {
+ cu_free (dwarf->fake_addr_cu);
+ free (dwarf->fake_addr_cu);
+ }
/* Did we find and allocate the alt Dwarf ourselves? */
if (dwarf->alt_fd != -1)
diff --git a/libdw/dwarf_formaddr.c b/libdw/dwarf_formaddr.c
index c917dea..3c89a5d 100644
--- a/libdw/dwarf_formaddr.c
+++ b/libdw/dwarf_formaddr.c
@@ -136,21 +136,3 @@ dwarf_formaddr (Dwarf_Attribute *attr, Dwarf_Addr *return_addr)
return 0;
}
INTDEF(dwarf_formaddr)
-
-Dwarf_Off __libdw_cu_addr_base (Dwarf_CU *cu)
-{
- if (cu->addr_base == (Dwarf_Off) -1)
- {
- Dwarf_Die cu_die = CUDIE(cu);
- Dwarf_Attribute attr;
- if (dwarf_attr (&cu_die, DW_AT_GNU_addr_base, &attr) != NULL
- || dwarf_attr (&cu_die, DW_AT_addr_base, &attr) != NULL)
- {
- Dwarf_Word off;
- if (dwarf_formudata (&attr, &off) == 0)
- cu->addr_base = off;
- }
- }
-
- return cu->addr_base;
-}
diff --git a/libdw/dwarf_formudata.c b/libdw/dwarf_formudata.c
index 316ad86..d56e7dc 100644
--- a/libdw/dwarf_formudata.c
+++ b/libdw/dwarf_formudata.c
@@ -288,6 +288,39 @@ dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval)
get_sleb128_unchecked (*return_uval, datap);
break;
+ /* These are indexes into the .debug_addr section, normally resolved
+ with dwarf_formaddr. Here treat as constants. */
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_addrx:
+ if (datap >= endp)
+ goto invalid;
+ get_uleb128 (*return_uval, datap, endp);
+ break;
+
+ case DW_FORM_addrx1:
+ if (datap >= endp - 1)
+ goto invalid;
+ *return_uval = *datap;
+ break;
+
+ case DW_FORM_addrx2:
+ if (datap >= endp - 2)
+ goto invalid;
+ *return_uval = read_2ubyte_unaligned (attr->cu->dbg, datap);
+ break;
+
+ case DW_FORM_addrx3:
+ if (datap >= endp - 3)
+ goto invalid;
+ *return_uval = read_3ubyte_unaligned (attr->cu->dbg, datap);
+ break;
+
+ case DW_FORM_addrx4:
+ if (datap >= endp - 4)
+ goto invalid;
+ *return_uval = read_4ubyte_unaligned (attr->cu->dbg, datap);
+ break;
+
default:
__libdw_seterrno (DWARF_E_NO_CONSTANT);
return -1;
diff --git a/libdw/dwarf_getlocation_attr.c b/libdw/dwarf_getlocation_attr.c
index 162330f..62ef47a 100644
--- a/libdw/dwarf_getlocation_attr.c
+++ b/libdw/dwarf_getlocation_attr.c
@@ -52,6 +52,18 @@ attr_form_cu (Dwarf_Attribute *attr)
}
}
+static unsigned char *
+addr_valp (Dwarf_CU *cu, Dwarf_Word index)
+{
+ Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr];
+ Dwarf_Word offset = __libdw_cu_addr_base (cu) + (index * cu->address_size);
+ if (debug_addr == NULL)
+ /* This is really an error, will trigger with dwarf_formaddr. */
+ return (unsigned char *) offset;
+
+ return (unsigned char *) debug_addr->d_buf + offset;
+}
+
int
dwarf_getlocation_attr (Dwarf_Attribute *attr, const Dwarf_Op *op, Dwarf_Attribute *result)
{
@@ -83,6 +95,25 @@ dwarf_getlocation_attr (Dwarf_Attribute *attr, const Dwarf_Op *op, Dwarf_Attribu
result->cu = attr_form_cu (attr);
break;
+ case DW_OP_GNU_const_index:
+ case DW_OP_constx:
+ result->code = DW_AT_const_value;
+ if (attr->cu->address_size == 4)
+ result->form = DW_FORM_data4;
+ else
+ result->form = DW_FORM_data8;
+ result->valp = addr_valp (attr->cu, op->number);
+ result->cu = attr->cu->dbg->fake_addr_cu;
+ break;
+
+ case DW_OP_GNU_addr_index:
+ case DW_OP_addrx:
+ result->code = DW_AT_low_pc;
+ result->form = DW_FORM_addr;
+ result->valp = addr_valp (attr->cu, op->number);
+ result->cu = attr->cu->dbg->fake_addr_cu;
+ break;
+
case DW_OP_call2:
case DW_OP_call4:
case DW_OP_call_ref:
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 2b5b5ea..82ee5d0 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -204,6 +204,9 @@ struct Dwarf
came from a location list entry in dwarf_getlocation_attr. */
struct Dwarf_CU *fake_loc_cu;
+ /* Similar for addrx/constx, which will come from .debug_addr section. */
+ struct Dwarf_CU *fake_addr_cu;
+
/* Internal memory handling. This is basically a simplified
reimplementation of obstacks. Unfortunately the standard obstack
implementation is not usable in libraries. */
@@ -947,7 +950,26 @@ const char *__libdw_getcompdir (Dwarf_Die *cudie);
Dwarf_Addr __libdw_cu_base_address (Dwarf_CU *cu);
/* Get the address base for the CU, fetches it when not yet set. */
-Dwarf_Off __libdw_cu_addr_base (Dwarf_CU *cu);
+static inline Dwarf_Off
+__libdw_cu_addr_base (Dwarf_CU *cu)
+{
+ if (cu->addr_base == (Dwarf_Off) -1)
+ {
+ Dwarf_Die cu_die = CUDIE(cu);
+ Dwarf_Attribute attr;
+ Dwarf_Off offset = 0;
+ if (dwarf_attr (&cu_die, DW_AT_GNU_addr_base, &attr) != NULL
+ || dwarf_attr (&cu_die, DW_AT_addr_base, &attr) != NULL)
+ {
+ Dwarf_Word off;
+ if (dwarf_formudata (&attr, &off) == 0)
+ offset = off;
+ }
+ cu->addr_base = offset;
+ }
+
+ return cu->addr_base;
+}
/* Gets the .debug_str_offsets base offset to use. static inline to
be shared between libdw and eu-readelf. */
diff --git a/libdw/libdw_find_split_unit.c b/libdw/libdw_find_split_unit.c
index bd48b9e..78c9a2a 100644
--- a/libdw/libdw_find_split_unit.c
+++ b/libdw/libdw_find_split_unit.c
@@ -88,6 +88,20 @@ __libdw_find_split_unit (Dwarf_CU *cu)
cu->split = split;
split->split = cu;
+ /* Get .debug_addr and addr_base greedy.
+ We also need it for the fake addr cu.
+ There is only one per split debug. */
+ Dwarf *dbg = cu->dbg;
+ Dwarf *sdbg = split->dbg;
+ if (sdbg->sectiondata[IDX_debug_addr] == NULL
+ && dbg->sectiondata[IDX_debug_addr] != NULL)
+ {
+ sdbg->sectiondata[IDX_debug_addr]
+ = dbg->sectiondata[IDX_debug_addr];
+ split->addr_base = __libdw_cu_addr_base (cu);
+ sdbg->fake_addr_cu = dbg->fake_addr_cu;
+ }
+
/* We have everything we need from this
ELF file. And we are going to close
the fd to not run out of file
diff --git a/src/ChangeLog b/src/ChangeLog
index e187277..1a9f4a3 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,12 @@
+2018-01-21 Mark Wielaard <mark@klomp.org>
+
+ * readelf.c (get_indexed_addr): New function.
+ (print_ops): Handle DW_OP_addrx, DW_OP_GNU_addr_index,
+ DW_OP_constx, DW_OP_GNU_const_index separately and resolve
+ address.
+ (attr_callback): Print index and address for
+ DW_FORM_GNU_addr_index and DW_FORM_addrx[1234].
+
2018-01-19 Mark Wielaard <mark@klomp.org>
* readelf.c (options): Add info+.
diff --git a/src/readelf.c b/src/readelf.c
index 466d941..1858802 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -4180,6 +4180,29 @@ print_bytes (size_t n, const unsigned char *bytes)
}
}
+static int
+get_indexed_addr (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr)
+{
+ Elf_Data *debug_addr = cu->dbg->sectiondata[IDX_debug_addr];
+ if (debug_addr == NULL)
+ return -1;
+
+ Dwarf_Off base = __libdw_cu_addr_base (cu);
+ Dwarf_Word off = idx * cu->address_size;
+ if (base > debug_addr->d_size
+ || off > debug_addr->d_size - base
+ || cu->address_size > debug_addr->d_size - base - off)
+ return -1;
+
+ const unsigned char *addrp = debug_addr->d_buf + base + off;
+ if (cu->address_size == 4)
+ *addr = read_4ubyte_unaligned (cu->dbg, addrp);
+ else
+ *addr = read_8ubyte_unaligned (cu->dbg, addrp);
+
+ return 0;
+}
+
static void
print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
unsigned int vers, unsigned int addrsize, unsigned int offset_size,
@@ -4348,19 +4371,36 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
case DW_OP_piece:
case DW_OP_regx:
case DW_OP_plus_uconst:
- case DW_OP_constu:
+ case DW_OP_constu:;
+ const unsigned char *start = data;
+ uint64_t uleb;
+ NEED (1);
+ get_uleb128 (uleb, data, data + len);
+ printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
+ indent, "", (uintmax_t) offset, op_name, uleb);
+ CONSUME (data - start);
+ offset += 1 + (data - start);
+ break;
+
case DW_OP_addrx:
case DW_OP_GNU_addr_index:
case DW_OP_constx:
case DW_OP_GNU_const_index:;
- const unsigned char *start = data;
- uint64_t uleb;
+ start = data;
NEED (1);
get_uleb128 (uleb, data, data + len);
- printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
+ printf ("%*s[%2" PRIuMAX "] %s [%" PRIu64 "] ",
indent, "", (uintmax_t) offset, op_name, uleb);
CONSUME (data - start);
offset += 1 + (data - start);
+ if (get_indexed_addr (cu, uleb, &addr) != 0)
+ printf ("???\n");
+ else
+ {
+ a = format_dwarf_addr (dwflmod, 0, addr, addr);
+ printf ("%s\n", a);
+ free (a);
+ }
break;
case DW_OP_bit_piece:
@@ -6148,9 +6188,19 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
}
char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
addr, addr);
- printf (" %*s%-20s (%s) %s\n",
- (int) (level * 2), "", dwarf_attr_name (attr),
- dwarf_form_name (form), a);
+ if (form != DW_FORM_addr )
+ {
+ Dwarf_Word index;
+ if (dwarf_formudata (attrp, &index) != 0)
+ goto attrval_out;
+ printf (" %*s%-20s (%s) [%" PRIx64 "] %s\n",
+ (int) (level * 2), "", dwarf_attr_name (attr),
+ dwarf_form_name (form), index, a);
+ }
+ else
+ printf (" %*s%-20s (%s) %s\n",
+ (int) (level * 2), "", dwarf_attr_name (attr),
+ dwarf_form_name (form), a);
free (a);
}
break;
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 3dc1db7..e6f9959 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,17 @@
+2018-05-21 Mark Wielaard <mark@klomp.org>
+
+ * addrx_constx-4.dwo.bz2: New testfile.
+ * addrx_constx-5.dwo.bz2: Likewise.
+ * testfile-addrx_constx-4.bz2: Likewise.
+ * testfile-addrx_constx-5.bz2: Likewise
+ * Makefile.am (EXTRA_DIST): Add addrx_constx-5.dwo.bz2
+ testfile-addrx_constx-4\ .bz2 testfile-addrx_constx-5.bz2.
+ * run-varlocs.sh: Add addrx_constx tests for DWARF4 and DWARF5.
+ * varlocx.c (print_expr): Handle DW_OP_GNU_addr_index,
+ DW_OP_addrx, DW_OP_GNU_const_index and DW_OP_constx.
+ (main): Handle split DWARF.
+ * run-all-dwarf-ranges.sh: Add new ranges for addrx low/highpc.
+
2018-05-20 Mark Wielaard <mark@klomp.org>
* unit-info.c: New test.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 9beae14..4b13be2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -305,6 +305,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
testfile_entry_value.c testfile_entry_value.bz2 \
testfile_implicit_value.c testfile_implicit_value.bz2 \
testfile_aarch64_core.bz2 testfile_i686_core.bz2 \
+ addrx_constx-4.dwo.bz2 addrx_constx-5.dwo.bz2 \
+ testfile-addrx_constx-4.bz2 testfile-addrx_constx-5.bz2 \
run-funcretval.sh funcretval_test.c funcretval_test_aarch64.bz2 \
run-backtrace-data.sh run-backtrace-dwarf.sh cleanup-13.c \
run-backtrace-native.sh run-backtrace-native-biarch.sh \
diff --git a/tests/addrx_constx-4.dwo.bz2 b/tests/addrx_constx-4.dwo.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..f0bae1cd56a3448993c40664f22ab1d7ebfb9a9a
GIT binary patch
literal 809
zcmV+^1J?XPT4*^jL0KkKS+X85FaQCsfB*mQ`0m$l|NHx|?-&37|K|T>aNLsnHd6Fr
zVUC1Gd*eU?91Bg(;Zss#8a)xFgGPf*4^RU^pfn8tXlNP+o}r)vMuv?VG6PING}<PE
z)YH_{Oq)=OOqwRt(`htf14bYX28>KbgG~U@pglt%4F;Mt0MG!_Kn#XKlR(e`6+DTk
zY2`LZ%?%?XAZRiT4F-S!0B8nAfB*o{00000000=06pz%z^-m;dHmB;3C;-u+pfu0`
zdV|tv&<0OJ02&%J000dSNB{uP2v|9SKqd6NtdaeGp$kZ1<B`vP`qMFq;66;rZBi37
z$u|?UdhO0;Wpa>#6KAjjy$IB35@xHsKPAAzfv7|n5fQAS0Fc^x#|(ljh$#&aM6wA3
z5(aVrW{?0{*0w8liWWFWg1V&Wkb3qP0oAH!=hqV8mOVW3V6Z=U%`5NIzstOKi$NO`
zs6z6C8z~?#mWaim*d`=HS7&9=edG{CB}D)-F)?wXTBeC(GXpx}DNUz+gROuK{Hm+H
z;~^g+0YQsSha?H|n6MOs?Y75XVhhEH^R@|?&q5QgjF=sYM(zzJ?vOzi%pd}$EDzA`
zfw2Q_$swdeh9cdo!sE{v?qC*`V`b(>Xrb}cyX0g_CL}E+VNZn@=)xX<1zl)HHUKL{
z(Wx?N!qEr~-ByUE7R0(Z+tJLD?)ALG=A1wxgUuQl<@I(lMhTs@C+V@XD<+wjM<ScW
zC;|(hf$EVNOMqyAx&T~&3V5st#_L5nQUv>0L<CS1rMQY+7?cD_f#<k(a=d6ztAkAy
z`4M6Y-6?RzydX5`4-&F`Eeb(n%7Q(Xra3}Bl12w48Za8<KzT*ao*HZwaViJpA_D+K
z1PE0iLRJgS14vu~PXG(aQkVeJMh5~T4EHOr@PZBrO@Q-+P*Hm%oh=>!;+#>t2nAmS
zOT6B5ePZQxX+Nd8u!g#0>Uh#pU8?PPNq+ANepBuBL$b%iv!8HB;_|r6KH4Dc0-;5F
nQzMLr2}B4`TAY(dQd~9NOp7f;+vfF=-{S5_rwS4lL&gRG7{6Ga
literal 0
HcmV?d00001
diff --git a/tests/addrx_constx-5.dwo.bz2 b/tests/addrx_constx-5.dwo.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..a5f4b1a6766b726587ea13584ece648527c0fea9
GIT binary patch
literal 824
zcmV-81IPSAT4*^jL0KkKS=}ah;s628fB*mfz5VxV|NHyD?)Sg{|Nh%MV<thgM6j;@
z_f+-+TW~-EJA&PJcHpRnga)3YCX9g4Jw}0`0iXte&}aY#jWoyr4Kxf)K+s}n0Mih8
z2B6g@jG$?uqfI?WsiQy*4Kx~L(?9@d0B8n=fEoiJ&;S4cXaE2JA{5h8)XbyF2Gjrm
z00Te(0009(27m^DXaE7A27mwn9-x%eN<(PW_KBilHj(7@L7)v810&J^00Yz>pa1{>
z001-whJXM70fb^=0LB0@`LIOPl$Kz@LWSZC(wNg&8+e>TQh5}B$V3*dd6du5v#8Z7
zbTNIJ<_M^|!B{3{ZZ(x2ECW*}D-#Tm*ksdC0aTeF9h$6u4Fi_d134E00mw*ca~w2C
z3sk^Ns!WOUU@v=@5!2BH&avU?km^XWEYA{#2ou>ezZZA<d_}RArS(Ss|F@KlK}Jzq
zJ0VcuI4QESLBt7#d2@9W2Xz&5<-O^p4jjT<%S*R`U1cflL8v+!1B~JHFR}b6R}6>@
z>WBb$th&X+7&e!Z#U%>Fve?UzHw|fk*z|fmPRg~|noWCPrp-Ey4Uq-_-u}Yj2C+aW
z_@<&wh`cZZ90?+gG6?uUVR*#K;RV;4fodK~EG`vH(qkdZMP}Iii`zKI56pB05|rVo
zNI@G)C{H>D#PJz?e6@*;_%e!4nA9}U!r>knh6gL<<yA0mAIEGN2M!}=$?)AN$7h<B
zagZ=bw?y`{j83|Nc?3ap)T-dG!ZC7oE!)QohMkQmn()R^r%OyAV5kP1KyW80tQn)X
zQ6M#!KGGb>G7uqvG^i^YfcAp{&<L#LP8uJI3l|vQ$dEsWBTk3}NJHQ}r<kLm;lz^2
zCD?#zVEm|hAjmr3b#YT#h~getwA%6VB8n0h*s`g=6CkT41TZ<Ivqz2ytWau(5CjTV
z6ei{n!Ux>UcGAd0J^&Ocla@Lstv;xa9zcoDia|i^mJPmVn3qQJ`Dxd#-9IXpUGL-q
zBL^q1sEv=}NE!C}$g^<npPOaVn*wdhapWq{NUBT*ussDOS#TYx{}*yaI8cz?CV1jK
CENl}1
literal 0
HcmV?d00001
diff --git a/tests/run-all-dwarf-ranges.sh b/tests/run-all-dwarf-ranges.sh
index 0bd641b..b1b7fce 100755
--- a/tests/run-all-dwarf-ranges.sh
+++ b/tests/run-all-dwarf-ranges.sh
@@ -33,9 +33,30 @@ die: hello.c (11)
4004e0..4004ff
4003e0..4003f7
+die: no_say (2e)
+ 4004f0..4004ff
+
+die: main (2e)
+ 4003e0..4003f7
+
+die: subject (1d)
+ 4003e3..4003ef
+
+die: subject (2e)
+ 4004e0..4004f0
+
die: world.c (11)
400500..400567
+die: no_main (2e)
+ 400550..400567
+
+die: no_subject (1d)
+ 400553..40055f
+
+die: say (2e)
+ 400500..400540
+
die: happy (1d)
8009e0..8009ff
8008e0..8008f7
@@ -44,6 +65,9 @@ die: sad (1d)
400530..400534
400535..40053f
+die: no_subject (2e)
+ 400540..400550
+
EOF
exit 0
diff --git a/tests/run-varlocs.sh b/tests/run-varlocs.sh
index 9c4b313..2781fef 100755
--- a/tests/run-varlocs.sh
+++ b/tests/run-varlocs.sh
@@ -125,4 +125,212 @@ module 'testfile_implicit_pointer'
EOF
+# DW_OP_addrx and DW_OP_constx testcases.
+#
+# int i, j, k;
+# __thread int l, m, n;
+#
+# int main ()
+# {
+# int r1 = i + j + k;
+# int r2 = l + m + n;
+# int res = r1 + r2;
+#
+# return res;
+# }
+#
+# gcc -O2 -gdwarf-5 -gsplit-dwarf -o addrx_constx-5.o -c addrx_constx.c
+# gcc -O2 -gdwarf-5 -gsplit-dwarf -o testfile-addrx_constx-5 addrx_constx-5.o
+# gcc -O2 -gdwarf-4 -gsplit-dwarf -o addrx_constx-4.o -c addrx_constx.c
+# gcc -O2 -gdwarf-4 -gsplit-dwarf -o testfile-addrx_constx-4 addrx_constx-4.o
+
+testfiles testfile-addrx_constx-5 addrx_constx-5.dwo
+testrun_compare ${abs_top_builddir}/tests/varlocs --exprlocs -e testfile-addrx_constx-5 <<\EOF
+module 'testfile-addrx_constx-5'
+[14] CU 'addrx_constx.c'
+ producer (strx)
+ language (data1)
+ name (strx)
+ comp_dir (strx)
+ [19] variable "i"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {addr: 0x404038}
+ [25] base_type "int"
+ byte_size (data1)
+ encoding (data1)
+ name (string)
+ [2c] variable "j"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {addr: 0x404034}
+ [38] variable "k"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {addr: 0x40403c}
+ [44] variable "l"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {const: 0x403e10, form_tls_address}
+ [51] variable "m"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {const: 0x403e0c, form_tls_address}
+ [5e] variable "n"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {const: 0x403e08, form_tls_address}
+ [6b] subprogram "main"
+ external (flag_present)
+ name (strx)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ low_pc (addrx)
+ high_pc (data8)
+ frame_base (exprloc) {call_frame_cfa {bregx(7,8)}}
+ call_all_calls (flag_present)
+ [7f] variable "r1"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (implicit_const)
+ type (ref4)
+ location (exprloc) {addr: 0x404038, deref_size(4), addr: 0x404034, deref_size(4), plus, addr: 0x40403c, deref_size(4), plus, stack_value}
+ [98] variable "r2"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (implicit_const)
+ type (ref4)
+ location (exprloc) {form_tls_address, const: 0x403e10, deref_size(4), form_tls_address, const: 0x403e0c, deref_size(4), plus, form_tls_address, const: 0x403e08, deref_size(4), plus, stack_value}
+ [b4] variable "res"
+ name (string)
+ decl_file (implicit_const)
+ decl_line (data1)
+ decl_column (implicit_const)
+ type (ref4)
+ location (exprloc) {addr: 0x404038, deref_size(4), form_tls_address, const: 0x403e08, deref_size(4), plus, form_tls_address, const: 0x403e0c, deref_size(4), plus, form_tls_address, const: 0x403e10, deref_size(4), plus, addr: 0x404034, deref_size(4), plus, addr: 0x40403c, deref_size(4), plus, stack_value}
+EOF
+
+testfiles testfile-addrx_constx-4 addrx_constx-4.dwo
+testrun_compare ${abs_top_builddir}/tests/varlocs --exprlocs -e testfile-addrx_constx-4 <<\EOF
+module 'testfile-addrx_constx-4'
+[b] CU 'addrx_constx.c'
+ producer (GNU_str_index)
+ language (data1)
+ name (GNU_str_index)
+ comp_dir (GNU_str_index)
+ GNU_dwo_id (data8)
+ [18] variable "i"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {addr: 0x404038}
+ [25] base_type "int"
+ byte_size (data1)
+ encoding (data1)
+ name (string)
+ [2c] variable "j"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {addr: 0x404034}
+ [39] variable "k"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {addr: 0x40403c}
+ [46] variable "l"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {const: 0x403e10, GNU_push_tls_address}
+ [54] variable "m"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {const: 0x403e0c, GNU_push_tls_address}
+ [62] variable "n"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ external (flag_present)
+ location (exprloc) {const: 0x403e08, GNU_push_tls_address}
+ [70] subprogram "main"
+ external (flag_present)
+ name (GNU_str_index)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ low_pc (GNU_addr_index)
+ high_pc (data8)
+ frame_base (exprloc) {call_frame_cfa {bregx(7,8)}}
+ GNU_all_call_sites (flag_present)
+ [84] variable "r1"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ location (exprloc) {addr: 0x404038, deref_size(4), addr: 0x404034, deref_size(4), plus, addr: 0x40403c, deref_size(4), plus, stack_value}
+ [9f] variable "r2"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ location (exprloc) {GNU_push_tls_address, const: 0x403e10, deref_size(4), GNU_push_tls_address, const: 0x403e0c, deref_size(4), plus, GNU_push_tls_address, const: 0x403e08, deref_size(4), plus, stack_value}
+ [bd] variable "res"
+ name (string)
+ decl_file (data1)
+ decl_line (data1)
+ decl_column (data1)
+ type (ref4)
+ location (exprloc) {addr: 0x404038, deref_size(4), GNU_push_tls_address, const: 0x403e08, deref_size(4), plus, GNU_push_tls_address, const: 0x403e0c, deref_size(4), plus, GNU_push_tls_address, const: 0x403e10, deref_size(4), plus, addr: 0x404034, deref_size(4), plus, addr: 0x40403c, deref_size(4), plus, stack_value}
+EOF
+
exit 0
diff --git a/tests/testfile-addrx_constx-4.bz2 b/tests/testfile-addrx_constx-4.bz2
new file mode 100755
index 0000000000000000000000000000000000000000..cf10fbb1082a5a188c5ac11af0c8404de461b9e0
GIT binary patch
literal 2851
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
B1&aUx
literal 0
HcmV?d00001
diff --git a/tests/testfile-addrx_constx-5.bz2 b/tests/testfile-addrx_constx-5.bz2
new file mode 100755
index 0000000000000000000000000000000000000000..eb2a1f17817ab13a32ea7256cf2a60c69cf9b53b
GIT binary patch
literal 2847
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
literal 0
HcmV?d00001
diff --git a/tests/varlocs.c b/tests/varlocs.c
index b2ceda2..859068d 100644
--- a/tests/varlocs.c
+++ b/tests/varlocs.c
@@ -652,6 +652,42 @@ print_expr (Dwarf_Attribute *attr, Dwarf_Op *expr, Dwarf_Addr addr)
}
break;
+ case DW_OP_GNU_addr_index:
+ case DW_OP_addrx:
+ /* Address from the .debug_addr section (indexed based on CU). */
+ {
+ Dwarf_Attribute addr_attr;
+ if (dwarf_getlocation_attr (attr, expr, &addr_attr) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_getlocation_attr for addr: %s",
+ dwarf_errmsg (-1));
+
+ Dwarf_Addr address;
+ if (dwarf_formaddr (&addr_attr, &address) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_formaddr address failed: %s",
+ dwarf_errmsg (-1));
+
+ printf ("addr: 0x%" PRIx64, address);
+ }
+ break;
+
+ case DW_OP_GNU_const_index:
+ case DW_OP_constx:
+ /* Constant from the .debug_addr section (indexed based on CU). */
+ {
+ Dwarf_Attribute addr_attr;
+ if (dwarf_getlocation_attr (attr, expr, &addr_attr) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_getlocation_attr for addr: %s",
+ dwarf_errmsg (-1));
+
+ Dwarf_Word constant;
+ if (dwarf_formudata (&addr_attr, &constant) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_formudata constant failed: %s",
+ dwarf_errmsg (-1));
+
+ printf ("const: 0x%" PRIx64, constant);
+ }
+ break;
+
default:
error (EXIT_FAILURE, 0, "unhandled opcode: DW_OP_%s (0x%x)",
opname, atom);
@@ -1019,9 +1055,18 @@ main (int argc, char *argv[])
/* Only walk actual compile units (not partial units) that
contain code if we are only interested in the function variable
locations. */
+ Dwarf_Die cudie;
+ Dwarf_Die subdie;
+ uint8_t unit_type;
+ if (dwarf_cu_info (cu->cu, NULL, &unit_type, &cudie, &subdie,
+ NULL, NULL, NULL) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_cu_info: %s", dwarf_errmsg (-1));
+ if (unit_type == DW_UT_skeleton)
+ cudie = subdie;
+
Dwarf_Addr cubase;
- if (dwarf_tag (cu) == DW_TAG_compile_unit
- && (exprlocs || dwarf_lowpc (cu, &cubase) == 0))
+ if (dwarf_tag (&cudie) == DW_TAG_compile_unit
+ && (exprlocs || dwarf_lowpc (&cudie, &cubase) == 0))
{
found_cu = true;
@@ -1043,7 +1088,7 @@ main (int argc, char *argv[])
? modname
: basename (mainfile));
printf ("module '%s'\n", name);
- print_die (cu, "CU", 0);
+ print_die (&cudie, "CU", 0);
Dwarf_Addr elfbias;
Elf *elf = dwfl_module_getelf (mod, &elfbias);
@@ -1060,18 +1105,10 @@ main (int argc, char *argv[])
GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
is_ET_REL = ehdr->e_type == ET_REL;
- // Get the actual CU DIE and walk all all DIEs (or just the
- // functions) inside it.
- Dwarf_Die cudie;
- uint8_t offsize;
- uint8_t addrsize;
- if (dwarf_diecu (cu, &cudie, &addrsize, &offsize) == NULL)
- error (EXIT_FAILURE, 0, "dwarf_diecu %s", dwarf_errmsg (-1));
-
if (exprlocs)
{
Dwarf_Addr entrypc;
- if (dwarf_entrypc (cu, &entrypc) != 0)
+ if (dwarf_entrypc (&cudie, &entrypc) != 0)
entrypc = 0;
/* XXX - Passing true for has_frame_base is not really true.
@@ -1079,9 +1116,9 @@ main (int argc, char *argv[])
attributes. Technically we should check that the DIE
(types) are referenced from variables that are defined in
a context (function) that has a frame base. */
- handle_die (cu, 0, true /* Should be false */, entrypc);
+ handle_die (&cudie, 0, true /* Should be false */, entrypc);
}
- else if (dwarf_getfuncs (cu, handle_function, NULL, 0) != 0)
+ else if (dwarf_getfuncs (&cudie, handle_function, NULL, 0) != 0)
error (EXIT_FAILURE, 0, "dwarf_getfuncs %s",
dwarf_errmsg (-1));
}
--
1.8.3.1
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] libdw: Support DW_OP_addrx/constx and split DWARF addrx/constx support.
2018-05-22 11:10 [PATCH] libdw: Support DW_OP_addrx/constx and split DWARF addrx/constx support Mark Wielaard
@ 2018-05-25 13:10 ` Mark Wielaard
0 siblings, 0 replies; 2+ messages in thread
From: Mark Wielaard @ 2018-05-25 13:10 UTC (permalink / raw)
To: elfutils-devel
On Tue, 2018-05-22 at 13:10 +0200, Mark Wielaard wrote:
> 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.
Pushed to master.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-05-25 13:10 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-22 11:10 [PATCH] libdw: Support DW_OP_addrx/constx and split DWARF addrx/constx support Mark Wielaard
2018-05-25 13:10 ` Mark Wielaard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).