From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 72494 invoked by alias); 23 Aug 2016 11:24:56 -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 72368 invoked by uid 89); 23 Aug 2016 11:24:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.6 required=5.0 tests=AWL,BAYES_00,KAM_LAZY_DOMAIN_SECURITY,RCVD_IN_DNSWL_LOW autolearn=no version=3.3.2 spammy=H*Ad:U*hemant X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0b-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.158.5) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 23 Aug 2016 11:24:54 +0000 Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.11/8.16.0.11) with SMTP id u7NBODEJ014059 for ; Tue, 23 Aug 2016 07:24:52 -0400 Received: from e28smtp04.in.ibm.com (e28smtp04.in.ibm.com [125.16.236.4]) by mx0b-001b2d01.pphosted.com with ESMTP id 24ybqvx4rs-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 23 Aug 2016 07:24:52 -0400 Received: from localhost by e28smtp04.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 23 Aug 2016 16:54:48 +0530 Received: from d28dlp01.in.ibm.com (9.184.220.126) by e28smtp04.in.ibm.com (192.168.1.134) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 23 Aug 2016 16:54:46 +0530 X-IBM-Helo: d28dlp01.in.ibm.com X-IBM-MailFrom: ravi.bangoria@linux.vnet.ibm.com X-IBM-RcptTo: systemtap@sourceware.org Received: from d28relay02.in.ibm.com (d28relay02.in.ibm.com [9.184.220.59]) by d28dlp01.in.ibm.com (Postfix) with ESMTP id B3C29E006E for ; Tue, 23 Aug 2016 16:59:22 +0530 (IST) Received: from d28av02.in.ibm.com (d28av02.in.ibm.com [9.184.220.64]) by d28relay02.in.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u7NBOUnO53608540 for ; Tue, 23 Aug 2016 16:54:30 +0530 Received: from d28av02.in.ibm.com (localhost [127.0.0.1]) by d28av02.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u7NBOf53008091 for ; Tue, 23 Aug 2016 16:54:42 +0530 Received: from f24-tul163-qemu.localdomain (tul163p1.aus.stglabs.ibm.com [9.41.165.219]) by d28av02.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id u7NBOXjx007726; Tue, 23 Aug 2016 16:54:37 +0530 From: Ravi Bangoria To: systemtap@sourceware.org Cc: hemant@linux.vnet.ibm.com, atrajeev@linux.vnet.ibm.com, mjw@redhat.com, fche@redhat.com, dsmith@redhat.com, naveen.n.rao@linux.vnet.ibm.com, Ravi Bangoria Subject: [PATCH v3 2/2] ppc64le: Fix LEP usage for probing Date: Tue, 23 Aug 2016 11:24:00 -0000 In-Reply-To: <1471951468-2567-1-git-send-email-ravi.bangoria@linux.vnet.ibm.com> References: <1471951468-2567-1-git-send-email-ravi.bangoria@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16082311-0012-0000-0000-000002F37163 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16082311-0013-0000-0000-0000182D8682 Message-Id: <1471951468-2567-2-git-send-email-ravi.bangoria@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2016-08-23_06:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=4 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1604210000 definitions=main-1608230114 X-SW-Source: 2016-q3/txt/msg00197.txt.bz2 PPC64 ELF ABI v2 has a Global Entry Point and a Local Entry Point for the functions. Debuginfo of ELF contains GEP which is same as entrypc while symbol table contains GEP and offset, from which we can calculate LEP. LEP is used to call function within single CU, when TOC pointer update is not required. Placing a probe on LEP catches call from both the GEP and the LEP but, by default, systemtap probes on GEP. Commit b4c6a4b1cd00 ("Prioritize symbol table lookup for ppc64le") solve this issue by storing LEP in symbol table and prioritizing symbol table over debuginfo for ppc64le. But there are few regression effect of this patch. Couple of examples are given below. 1. If target program is compiled without optimization and user is interested in function parameter, systemtap should probe after function prologue. But above patch forces probe on LEP and which result in garbage value of function parameter will get recorded. $ make verbose=1 installcheck RUNTESTFLAGS='at_var.exp -v --debug' ... # of expected passes 1 # of unexpected failures 1 2. Probe on shared library function with parameter is failing at Pass 2. $ make verbose=1 installcheck RUNTESTFLAGS='exelib.exp -v --debug' ... # of expected passes 10 # of unexpected failures 64 3. When symbol_name with offset is used to register kprobe, kernel itself will find LEP and adds offset to it. Systemtap using LEP to find offset is resulting in offset being added two times. GEP + lep_offset (by systemtap) + lep_offset (by kernel) This can be solved by calculating LEP only at a time of adding a probe. That will make effect of LEP local to that area and won't have any regression effect. After applying patch: $ make verbose=1 installcheck RUNTESTFLAGS='at_var.exp -v --debug' ... # of expected passes 2 $ make verbose=1 installcheck RUNTESTFLAGS='exelib.exp -v --debug' ... # of expected passes 74 Fixes: Commit b4c6a4b1cd00 ("Prioritize symbol table lookup for ppc64le") Reported-by: Athira Rajeev [ Reported about issue with shared library ] Signed-off-by: Ravi Bangoria --- Changes in v3: - No changes tapsets.cxx | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/tapsets.cxx b/tapsets.cxx index 997cc88..bf1bcc0 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -1391,6 +1391,59 @@ string path_remove_sysroot(const systemtap_session& sess, const string& path) return retval; } +/* + * Convert 'Global Entry Point' to 'Local Entry Point'. + * + * if @gep contains next address after prologue, don't change it. + * + * For ELF ABI v2 on PPC64 LE, we need to adjust sym.st_value corresponding + * 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. + * + * st_other field is currently only used with ABIv2 on ppc64 + */ +static Dwarf_Addr +get_lep(dwarf_query *q, Dwarf_Addr gep) +{ + Dwarf_Addr bias; + Dwfl_Module *mod = q->dw.module; + Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (mod, &bias)) + ?: dwfl_module_getelf (mod, &bias)); + + GElf_Ehdr ehdr_mem; + GElf_Ehdr* em = gelf_getehdr (elf, &ehdr_mem); + if (em == NULL) + throw SEMANTIC_ERROR (_("Couldn't get elf header")); + + if (!(em->e_machine == EM_PPC64) || !((em->e_flags & EF_PPC64_ABI) == 2)) + return gep; + + int syments = dwfl_module_getsymtab(mod); + for (int i = 1; i < syments; ++i) + { + GElf_Sym sym; + GElf_Word section; + GElf_Addr addr; + +#if _ELFUTILS_PREREQ (0, 158) + dwfl_module_getsym_info (mod, i, &sym, &addr, §ion, NULL, NULL); +#else + dwfl_module_getsym (mod, i, &sym, §ion); + addr = sym.st_value; +#endif + + /* + * Symbol table contains module_bias + offset. Substract module_bias + * to compare offset with gep. + */ + if ((addr - bias) == gep && (GELF_ST_TYPE(sym.st_info) == STT_FUNC) + && sym.st_other) + return gep + PPC64_LOCAL_ENTRY_OFFSET(sym.st_other); + } + + return gep; +} + void dwarf_query::add_probe_point(interned_string dw_funcname, interned_string filename, @@ -1399,12 +1452,14 @@ dwarf_query::add_probe_point(interned_string dw_funcname, Dwarf_Addr addr) { interned_string reloc_section; // base section for relocation purposes + Dwarf_Addr orig_addr = addr; Dwarf_Addr reloc_addr; // relocated interned_string module = dw.module_name; // "kernel" or other interned_string funcname = dw_funcname; assert (! has_absolute); // already handled in dwarf_builder::build() + addr = get_lep(this, addr); reloc_addr = dw.relocate_address(addr, reloc_section); // If we originally used the linkage name, then let's call it that way @@ -1470,7 +1525,10 @@ dwarf_query::add_probe_point(interned_string dw_funcname, symbol_table *sym_table = mi->sym_table; func_info *symbol = sym_table->get_func_containing_address(addr); - Dwarf_Addr offset = addr - symbol->addr; + + // Do not use LEP to find offset here. When 'symbol_name' + // is used to register probe, kernel itself will find LEP. + Dwarf_Addr offset = orig_addr - symbol->addr; results.push_back (new dwarf_derived_probe(funcname, filename, line, module, reloc_section, addr, -- 1.8.3.1