[PATCH 2/3] ppc64le: Use LEP for probe location
Ravi Bangoria
ravi.bangoria@linux.vnet.ibm.com
Tue Jul 26 15:58:00 GMT 2016
Hi Frank, Mark,
I found test case at_var.exp. But it does not test uprobe with target
program
compiled without optimization. So I added this:
$ git diff
diff --git a/testsuite/systemtap.base/at_var.exp
b/testsuite/systemtap.base/at_var.exp
index fd681a7..42f83d9 100644
--- a/testsuite/systemtap.base/at_var.exp
+++ b/testsuite/systemtap.base/at_var.exp
@@ -45,5 +45,14 @@ if { $res != "" } {
stap_run3 $test $srcdir/$subdir/$test.stp -c ./${test}
+# Test for target program compiled without optimization
+set res [target_compile ${testpath}/${test}.c ${test} executable
"additional_flags=-g"]
+if { $res != "" } {
+ verbose "target_compile failed: $res" 2
+ fail "unable to compile ${test}.c"
+}
+
+stap_run3 $test $srcdir/$subdir/$test.stp -c ./${test}
+
# Cleanup
if { $verbose == 0 } { catch { exec rm -f $test } }
Here is the result before and after applying patch.
Before applying patch:
$ make verbose=1 installcheck RUNTESTFLAGS='at_var.exp -v --debug'
...
Running
/home/ravi/Workspace/systemtap/testsuite/systemtap.base/at_var.exp ...
PASS: at_var
FAIL: at_var
=== systemtap Summary ===
# of expected passes 1
# of unexpected failures 1
$ less testsuite/systemtap.log
...
executing: stap
/home/ravi/Workspace/systemtap/testsuite/systemtap.base/at_var.stp -c
./at_var
FAIL: at_var
line 1: expected "$argc: 1"
Got "ERROR: read fault [man error::fault] at 0x (null)
(addr) near identifier '$argv' at
/home/ravi/Workspace/systemtap/testsuite/systemtap.base/at_var.stp:6:53"
"WARNING: Number of errors: 1, skipped probes: 0"
"WARNING: /home/ravi/stap-git/bin/staprun exited with status: 1"
"Pass 5: run failed. [man error::pass5]"
After applying patch:
$ make verbose=1 installcheck RUNTESTFLAGS='at_var.exp -v --debug'
...
Running
/home/ravi/Workspace/systemtap/testsuite/systemtap.base/at_var.exp ...
PASS: at_var
PASS: at_var
=== systemtap Summary ===
# of expected passes 2
Please review patch. Please let me know if I need to resend v2 for this
patchset.
Regards,
Ravi
On Thursday 21 July 2016 06:47 PM, Ravi Bangoria wrote:
> 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. So it's guaranteed that LEP will hit wherever
> function is called but GEP may not.
>
> Before Applying patch:
>
> $ vim uprobe_test.c
> #include <stdio.h>
>
> void doit(int i)
> {
> printf("i : %d\n", i);
> }
>
> int main(int argc, char *argv[])
> {
> doit(42);
> return 0;
> }
>
> $ gcc uprobe_test.c -g -o uprobe_test
>
> $ sudo ./stap -e 'probe process("uprobe_test").function("doit") \
> {printf("hit %d\n", $i)}' -c ./uprobe_test
> i : 42
> hit 0
>
> After Applying patch:
>
> $ sudo ./stap -e 'probe process("uprobe_test").function("doit") \
> {printf("hit %d\n", $i)}' -c ./uprobe_test
> i : 42
> hit 42
>
> Fixes: Commit b4c6a4b1cd00 ("Prioritize symbol table lookup for ppc64le")
> Signed-off-by: Ravi Bangoria<ravi.bangoria@linux.vnet.ibm.com>
> ---
> tapsets.cxx | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 50 insertions(+)
>
> diff --git a/tapsets.cxx b/tapsets.cxx
> index e7be711..1b3a1ea 100644
> --- a/tapsets.cxx
> +++ b/tapsets.cxx
> @@ -1391,6 +1391,55 @@ 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
> +
> + if (addr == 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,
> @@ -1405,6 +1454,7 @@ dwarf_query::add_probe_point(interned_string 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
More information about the Systemtap
mailing list