From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10218 invoked by alias); 23 Jan 2015 14:00:57 -0000 Mailing-List: contact systemtap-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: systemtap-owner@sourceware.org Received: (qmail 10191 invoked by uid 89); 23 Jan 2015 14:00:54 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-3.5 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS,T_RP_MATCHES_RCVD autolearn=unavailable version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 23 Jan 2015 14:00:53 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t0NE0bNu028793 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 23 Jan 2015 09:00:37 -0500 Received: from bordewijk.wildebeest.org (ovpn-116-65.ams2.redhat.com [10.36.116.65]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t0NE0a2q030185 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 23 Jan 2015 09:00:37 -0500 Received: by bordewijk.wildebeest.org (Postfix, from userid 1000) id EE03580B2822; Fri, 23 Jan 2015 15:00:35 +0100 (CET) Message-ID: <1422021635.4858.12.camel@bordewijk.wildebeest.org> Subject: Re: [RFC PATCH] Fix PPC64 ELF ABI v2 symbol address retrieval From: Mark Wielaard To: Hemant Kumar Cc: systemtap@sourceware.org, uweigand@gcc.gnu.org, ulrich.weigand@de.ibm.com, fche@redhat.com, anton@samba.org, naveen.n.rao@linux.vnet.ibm.com Date: Fri, 23 Jan 2015 14:00:00 -0000 In-Reply-To: <20150116115342.1367.96228.stgit@hemant-fedora> References: <20150116115342.1367.96228.stgit@hemant-fedora> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 X-SW-Source: 2015-q1/txt/msg00060.txt.bz2 On Fri, 2015-01-16 at 17:24 +0530, Hemant Kumar wrote: > PPC64 ELF ABI v2 has a Global entry point and a local entry point for the > functions. We need the Local entry point in order to probe these function= s. > However, the DIE for these functions in debuginfo return the function.ent= rypc > which is same as the global entry point. The local entry point is not enc= oded > in the debuginfo of the ELFs. BTW. Would it make sense to let GCC encode this in the DWARF output? DWARF 4, 2.18 Entry Address says: Any debugging information entry describing an entity that has a range of code addresses, which includes compilation units, module initialization, subroutines, ordinary blocks, try/catch blocks, and the like, may have a DW_AT_entry_pc attribute to indicate the first executable instruction within that range of addresses. The value of the DW_AT_entry_pc attribute is a relocated address. If no DW_AT_entry_pc attribute is present, then the entry address is assumed to be the same as the value of the DW_AT_low_pc attribute, if present; otherwise, the entry address is unknown. Which seems to describe the situation exactly. And would make elfutils libdw dwarf_entrypc () do the right thing automagically (it will fall back to low_pc as described) without needing any extra lookups through symbol tables. > The offset to local entry point is however encoded in the st_other field = of > these symbols in the symbol table. We need to use this field to adjust the > sym.st_value to actually point to the local entry point instead of the gl= obal > entry point. >=20 > This patch is in relation to this bug : > https://sourceware.org/bugzilla/show_bug.cgi?id=3D17638 >=20 > So, while adding symbols to the sym_table, we add an offset of > PPC64_LOCAL_ENTRY_OFFSET(sym.st_other) to st_value. > And when the function address is queried in query_dwarf_func(), we give p= riority > to the cached sym_table, where we can retrieve the adjusted entry address= of the > function. If we don't get any address from the symbol table, then we proc= eed to > get from the debuginfo. The function_entrypc () part looks good (see some small nitpicks below). But I think the priority/fixup needs to be done the other way around (see also below). > Signed-off-by: Hemant Kumar > --- > tapsets.cxx | 34 +++++++++++++++++++++++++++++++++- > 1 file changed, 33 insertions(+), 1 deletion(-) >=20 > diff --git a/tapsets.cxx b/tapsets.cxx > index 85fd76b..d1382e4 100644 > --- a/tapsets.cxx > +++ b/tapsets.cxx > @@ -2099,7 +2099,19 @@ query_dwarf_func (Dwarf_Die * func, dwarf_query * = q) > q->dw.function_line (&func.decl_line); >=20=20 > Dwarf_Addr entrypc; > - if (q->dw.function_entrypc (&entrypc)) > + func.entrypc =3D 0; > + /* Giving priority to sym_table */ > + if (q->dw.mod_info->sym_table) > + { > + func_info * fi; > + fi =3D q->dw.mod_info->sym_table->lookup_symbol(func.name); > + if (fi) > + { > + func.entrypc =3D fi->addr; > + q->filtered_functions.push_back(func); > + } > + } > + if (!func.entrypc && q->dw.function_entrypc (&entrypc)) > { > func.entrypc =3D entrypc; > q->filtered_functions.push_back (func); I think this should be the other way around. q->dw.function_entrypc () will normally do the right thing (and take DW_AT_entrypc into account, which might be important for some cases, even if it isn't currently used for the PPC64 ELF ABI v2 case). Then when you do get the func.entrypc and func.name you look the name up in the symbol table and adjust it if the entrypc matches the symbol value. > @@ -8154,6 +8166,26 @@ symbol_table::get_from_elf() > reject =3D reject_section(section); > #endif >=20=20 > +/* > + * For ELF ABI v2 on PPC64 LE, we need to adjust sym.st_value correspond= ing > + * to the bits of sym.st_other. These bits will tell us what's the offset > + * of the local entry point from the global entry point. > + */ > +#if defined(_CALL_ELF) && _CALL_ELF =3D=3D 2 This won't work correctly when stap is ran remotely on a different architecture. That is not a very common situation, but I believe we do want to support that. So you will just have to always inspect the Elf ehdr. > + Dwarf_Addr bias; > + Elf* elf =3D (dwarf_getelf (dwfl_module_getdwarf (mod, &bias)) > + ?: dwfl_module_getelf (mod, &bias)); > + > + GElf_Ehdr ehdr_mem; > + GElf_Ehdr* em =3D gelf_getehdr (elf, &ehdr_mem); > + if (em =3D=3D 0) { DWFL_ASSERT ("dwfl_getehdr", dwfl_errno()); } > + assert(em); > + > + if ((em->e_machine =3D=3D EM_PPC64) && (GELF_ST_TYPE(sym.st_info) = =3D=3D STT_FUNC) > + && sym.st_other) > + addr =3D addr + PPC64_LOCAL_ENTRY_OFFSET(sym.st_other); Here you also want to have a check for EF_PPC64_ABI in e_flags then. Note that older elf.h files won't have those defines, so you should either check they are defined or explicitly define them here to make sure things will keep building on older systems. > +#endif > + > if (name && GELF_ST_TYPE(sym.st_info) =3D=3D STT_FUNC) > add_symbol(name, (GELF_ST_BIND(sym.st_info) =3D=3D STB_WEAK), > reject, addr, &high_addr); Thanks, Mark