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]

[RFC PATCH] Fix PPC64 ELF ABI v2 symbol address retrieval


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 functions.
However, the DIE for these functions in debuginfo return the function.entrypc
which is same as the global entry point. The local entry point is not encoded
in the debuginfo of the ELFs.
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 global
entry point.

This patch is in relation to this bug :
https://sourceware.org/bugzilla/show_bug.cgi?id=17638

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 priority
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 proceed to
get from the debuginfo.

Signed-off-by: Hemant Kumar <hemant@linux.vnet.ibm.com>
---
 tapsets.cxx |   34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

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);
 
           Dwarf_Addr entrypc;
-          if (q->dw.function_entrypc (&entrypc))
+          func.entrypc = 0;
+          /* Giving priority to sym_table */
+          if (q->dw.mod_info->sym_table)
+            {
+              func_info * fi;
+              fi = q->dw.mod_info->sym_table->lookup_symbol(func.name);
+              if (fi)
+                {
+                  func.entrypc = fi->addr;
+                  q->filtered_functions.push_back(func);
+                }
+            }
+          if (!func.entrypc && q->dw.function_entrypc (&entrypc))
             {
               func.entrypc = entrypc;
               q->filtered_functions.push_back (func);
@@ -8154,6 +8166,26 @@ symbol_table::get_from_elf()
       reject = reject_section(section);
 #endif
 
+/*
+ * 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.
+ */
+#if defined(_CALL_ELF) && _CALL_ELF == 2
+      Dwarf_Addr bias;
+      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 == 0) { DWFL_ASSERT ("dwfl_getehdr", dwfl_errno()); }
+      assert(em);
+
+      if ((em->e_machine == EM_PPC64) && (GELF_ST_TYPE(sym.st_info) == STT_FUNC)
+        && sym.st_other)
+        addr = addr + PPC64_LOCAL_ENTRY_OFFSET(sym.st_other);
+#endif
+
       if (name && GELF_ST_TYPE(sym.st_info) == STT_FUNC)
         add_symbol(name, (GELF_ST_BIND(sym.st_info) == STB_WEAK),
                    reject, addr, &high_addr);


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