perf probe ppc64le: Fix ppc64 ABIv2 symbol decoding

ppc64 ELF ABIv2 has a Global Entry Point (GEP) and a Local Entry Point
(LEP). For purposes of probing, we need the LEP - the offset to which is
encoded in st_other.

Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Reviewed-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: linuxppc-dev@lists.ozlabs.org
Link: http://lkml.kernel.org/r/ab9cc5e2b9de4cbaaf50f6ef2346a6a81100bad1.1430217967.git.naveen.n.rao@linux.vnet.ibm.com
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Ananth N Mavinakayanahalli 2015-04-28 17:35:38 +05:30 committed by Arnaldo Carvalho de Melo
parent 031b84c407
commit c50fc0a43e
3 changed files with 12 additions and 0 deletions

View File

@ -17,6 +17,13 @@ bool elf__needs_adjust_symbols(GElf_Ehdr ehdr)
ehdr.e_type == ET_REL || ehdr.e_type == ET_REL ||
ehdr.e_type == ET_DYN; ehdr.e_type == ET_DYN;
} }
#if defined(_CALL_ELF) && _CALL_ELF == 2
void arch__elf_sym_adjust(GElf_Sym *sym)
{
sym->st_value += PPC64_LOCAL_ENTRY_OFFSET(sym->st_other);
}
#endif
#endif #endif
#if !defined(_CALL_ELF) || _CALL_ELF != 2 #if !defined(_CALL_ELF) || _CALL_ELF != 2

View File

@ -775,6 +775,8 @@ static bool want_demangle(bool is_kernel_sym)
return is_kernel_sym ? symbol_conf.demangle_kernel : symbol_conf.demangle; return is_kernel_sym ? symbol_conf.demangle_kernel : symbol_conf.demangle;
} }
void __weak arch__elf_sym_adjust(GElf_Sym *sym __maybe_unused) { }
int dso__load_sym(struct dso *dso, struct map *map, int dso__load_sym(struct dso *dso, struct map *map,
struct symsrc *syms_ss, struct symsrc *runtime_ss, struct symsrc *syms_ss, struct symsrc *runtime_ss,
symbol_filter_t filter, int kmodule) symbol_filter_t filter, int kmodule)
@ -939,6 +941,8 @@ int dso__load_sym(struct dso *dso, struct map *map,
(sym.st_value & 1)) (sym.st_value & 1))
--sym.st_value; --sym.st_value;
arch__elf_sym_adjust(&sym);
if (dso->kernel || kmodule) { if (dso->kernel || kmodule) {
char dso_name[PATH_MAX]; char dso_name[PATH_MAX];

View File

@ -305,6 +305,7 @@ int setup_intlist(struct intlist **list, const char *list_str,
#ifdef HAVE_LIBELF_SUPPORT #ifdef HAVE_LIBELF_SUPPORT
bool elf__needs_adjust_symbols(GElf_Ehdr ehdr); bool elf__needs_adjust_symbols(GElf_Ehdr ehdr);
void arch__elf_sym_adjust(GElf_Sym *sym);
#endif #endif
#define SYMBOL_A 0 #define SYMBOL_A 0