This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 2/3] ppc64le: Use LEP for probe location


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]