]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blobdiff - tools/perf/arch/powerpc/util/sym-handling.c
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[mirror_ubuntu-hirsute-kernel.git] / tools / perf / arch / powerpc / util / sym-handling.c
index bbc1a50768dd5de5183f1890a806f710545bf28e..c6d0f91731a14732333af62d0a40a3ea43fb4c99 100644 (file)
@@ -19,12 +19,6 @@ bool elf__needs_adjust_symbols(GElf_Ehdr ehdr)
               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
 
 #if !defined(_CALL_ELF) || _CALL_ELF != 2
@@ -65,18 +59,45 @@ bool arch__prefers_symtab(void)
        return true;
 }
 
+#ifdef HAVE_LIBELF_SUPPORT
+void arch__sym_update(struct symbol *s, GElf_Sym *sym)
+{
+       s->arch_sym = sym->st_other;
+}
+#endif
+
 #define PPC64LE_LEP_OFFSET     8
 
 void arch__fix_tev_from_maps(struct perf_probe_event *pev,
-                            struct probe_trace_event *tev, struct map *map)
+                            struct probe_trace_event *tev, struct map *map,
+                            struct symbol *sym)
 {
+       int lep_offset;
+
        /*
-        * ppc64 ABIv2 local entry point is currently always 2 instructions
-        * (8 bytes) after the global entry point.
+        * When probing at a function entry point, we normally always want the
+        * LEP since that catches calls to the function through both the GEP and
+        * the LEP. Hence, we would like to probe at an offset of 8 bytes if
+        * the user only specified the function entry.
+        *
+        * However, if the user specifies an offset, we fall back to using the
+        * GEP since all userspace applications (objdump/readelf) show function
+        * disassembly with offsets from the GEP.
+        *
+        * In addition, we shouldn't specify an offset for kretprobes.
         */
-       if (!pev->uprobes && map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS) {
-               tev->point.address += PPC64LE_LEP_OFFSET;
+       if (pev->point.offset || pev->point.retprobe || !map || !sym)
+               return;
+
+       lep_offset = PPC64_LOCAL_ENTRY_OFFSET(sym->arch_sym);
+
+       if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS)
                tev->point.offset += PPC64LE_LEP_OFFSET;
+       else if (lep_offset) {
+               if (pev->uprobes)
+                       tev->point.address += lep_offset;
+               else
+                       tev->point.offset += lep_offset;
        }
 }
 #endif