[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, &section, NULL, NULL);
> +#else
> +      dwfl_module_getsym (mod, i, &sym, &section);
> +      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