This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[RFC PATCH] Fix PPC64 ELF ABI v2 symbol address retrieval
- From: Hemant Kumar <hemant at linux dot vnet dot ibm dot com>
- To: systemtap at sourceware dot org
- Cc: uweigand at gcc dot gnu dot org, mjw at redhat dot com, ulrich dot weigand at de dot ibm dot com, fche at redhat dot com, anton at samba dot org, naveen dot n dot rao at linux dot vnet dot ibm dot com
- Date: Fri, 16 Jan 2015 17:24:23 +0530
- Subject: [RFC PATCH] Fix PPC64 ELF ABI v2 symbol address retrieval
- Authentication-results: sourceware.org; auth=none
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);