From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30142 invoked by alias); 22 May 2018 11:10:40 -0000 Mailing-List: contact elfutils-devel-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Post: List-Help: List-Subscribe: Sender: elfutils-devel-owner@sourceware.org Received: (qmail 30108 invoked by uid 89); 22 May 2018 11:10:36 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.99.4 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.0 required=5.0 tests=BAYES_50,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LOTSOFHASH,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=odm, ODM, th, ti X-Spam-Status: No, score=-24.0 required=5.0 tests=BAYES_50,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LOTSOFHASH,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on sourceware.org X-Spam-Level: X-HELO: gnu.wildebeest.org Received: from wildebeest.demon.nl (HELO gnu.wildebeest.org) (212.238.236.112) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 22 May 2018 11:10:31 +0000 Received: from tarox.wildebeest.org (tarox.wildebeest.org [172.31.17.39]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 21256300090E; Tue, 22 May 2018 13:10:25 +0200 (CEST) Received: by tarox.wildebeest.org (Postfix, from userid 1000) id CE03840011A2; Tue, 22 May 2018 13:10:25 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: Mark Wielaard Subject: [PATCH] libdw: Support DW_OP_addrx/constx and split DWARF addrx/constx support. Date: Tue, 22 May 2018 11:10:00 -0000 Message-Id: <1526987421-32644-1-git-send-email-mark@klomp.org> X-Mailer: git-send-email 1.8.3.1 X-Spam-Flag: NO X-IsSubscribed: yes X-SW-Source: 2018-q2/txt/msg00069.txt.bz2 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 --- 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 + + * 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 * 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 + + * 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 * 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 + + * 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 * 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}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#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<+wjM0L!;+#>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 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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 zcma)#WmwaT0*C+9fH`E;94RG&j2?9q+!&4;N~hF_vk^xc1P(F@iP2rsB||#I00v4b zBLpO5G!h~l0TtAH?&tgEzMp>2`#itr)v+UJDxqzq%x%x$>i}@U|`xO#y6*kDJ?n7{H!uQsfZy{>GBgHv)IT}nfOqL4^Ht*qtW z2B&HH{~JLGfKW`vAaWD{iJC%ZqJ{tf7#eWKaFqfC0S*p803fCj0DvIWaJ@sL$vX9z zP0JCYbw9aCDpxF~S>&*!q{dIq1hV+_scE>vo~@qTWM^=W=Zte%|5>q4kujI@X2 z{b)1~uk(5)DW4zAy>5G3Fl2l8rm4X-9Lh?Ooi3uiaN#n!Gaxx~Fh5dm#^dq0d;R1b zA+~~9S%B7OYusO8fL$gF$A#(aD$J_Ksg4_@jZ9%|n-=bm9RCb)DIl)i`7?i_ChUDt z#~i??7Wdu$>rmdOwX+Uleh2NQ|K62 z$YxTeB_3UPtJ4rN9TvLNQa&GMbCjv}X)$|Dn&4GSKwoBhRpdNRWO7zxytq**;X4V< zB(j6B47w*65>hJDr&_Gz5W=gt)YeT(YU^flR)$#&v2aMnJ14gqo(RoyD9F$HDUw7i zD|34UphkQ)jDo1B^`;HQoK(qveOvXD&9>yJ7@w(v#CP=b*-m#vf0i&qTDdi{B~MJ{(mRBMXZB4wqU{v|zO!-qeFl zY)0xQfv--V5L7|EryU*HvO4m`0?n2(uI{+!jcY6M)B>46!b+*m@c^$Ns3k%^ML1qk{_6~757hTCwZ7`}bsP=Y+ z_Y*F29fS;_pf#>e?GC}$s_H;$BTFv2+Zep6w^dcS6{p%FMvdHLB^DD2U(;SrrFCuJ zTYgaB*sP+x>Mr-s)^5F7+B+FV{sTP~%ex^t$-KtW82nVN?)L?>f@&^uvzIP;eJywO zM3Tp=gmF)fbq24JhsU>Ww&g5U<}#Efx@33q2Z%&SMq92#%p#5o4_uT^1b4db?f>vz zlzn!8ya6=&R%;?-h?gE<;Tqm4I9C|0+f_eC7lU;<5^o?X$BH0b-!mWq+71XE>GIjf zqAuT5KOr9JIP*G%I~|tVrF(f0h7wB%T$U3N{?Z#NUK&ipw2E8T_0hX64=q1)hRott zLm6VeLUnNl8?DEQS-0#5>mnu;dQx_Hr{|oX^gsM0Ol^>m7}~l9vu}GF)PPfAkI@tw z8`D-k>;6r&esTT9j8igx5WXZdMk(xK;avT8LsJ!_yp5iFrk_@*UwUoBbaBLUvx5DLzP{;{+5|<9t)Eww|H@P!E^JH=7I2}KoWa&w zIUzbhak$)Z%kOEbufws3&cMP*+Lg=M0-kK{R$d^rZzm)fE`7!aS$e@|P49J>--&B| z23cWcWnI?t-H>9Xft>7lOHNKSp=55!v zw3B3D07m_ZY)e8-9t9UT|0Be9|2+e}F-Uhg)P7)Z7Ls;w$I)d=-hJ_`1R0G?TAhAY z9sm~3ntk!EtRQISkXTjnL#biYj7g)8ew)I-Lq^BHe|>^)vG{bKq(dEPe<=oypK;wg zbTanjgjANC4!&Vyp^jAF4l$h8|ky%^0~ER zZ4)yHmLmt$^Z9ono2Nl_TZ}(YhM`R)AG<7YFDm8^pM>N!I5zUoWBy2%oSj3PCWzd_|?j3mYX9N0f4;o8U|gL(Vq!kyIO{ z6hs>|G;zsVPS$oi$T8Z$TPs23MpJ^zPscu, 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