Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf probe ppc: Fix symbol fixup issues due to ELF type

If using the symbol table, symbol addresses are not being fixed up
properly, resulting in probes being placed at wrong addresses:

# perf probe do_fork
Added new event:
probe:do_fork (on do_fork)

You can now use it in all perf tools, such as:

perf record -e probe:do_fork -aR sleep 1

# cat /sys/kernel/debug/tracing/kprobe_events
p:probe/do_fork _text+635952
# printf "%x" 635952
9b430
# grep do_fork /boot/System.map
c0000000000ab430 T .do_fork

Fix by checking for ELF type ET_DYN used by ppc64 kernels.

Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Reviewed-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.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/41392bb856ef62d929995e0b61967689b7915207.1430217967.git.naveen.n.rao@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Naveen N. Rao and committed by
Arnaldo Carvalho de Melo
d2332098 b64aa553

+30 -2
+1
tools/perf/arch/powerpc/util/Build
··· 1 1 libperf-y += header.o 2 + libperf-y += sym-handling.o 2 3 3 4 libperf-$(CONFIG_DWARF) += dwarf-regs.o 4 5 libperf-$(CONFIG_DWARF) += skip-callchain-idx.o
+19
tools/perf/arch/powerpc/util/sym-handling.c
··· 1 + /* 2 + * This program is free software; you can redistribute it and/or modify 3 + * it under the terms of the GNU General Public License, version 2, as 4 + * published by the Free Software Foundation. 5 + * 6 + * Copyright (C) 2015 Naveen N. Rao, IBM Corporation 7 + */ 8 + 9 + #include "debug.h" 10 + #include "symbol.h" 11 + 12 + #ifdef HAVE_LIBELF_SUPPORT 13 + bool elf__needs_adjust_symbols(GElf_Ehdr ehdr) 14 + { 15 + return ehdr.e_type == ET_EXEC || 16 + ehdr.e_type == ET_REL || 17 + ehdr.e_type == ET_DYN; 18 + } 19 + #endif
+6 -2
tools/perf/util/symbol-elf.c
··· 630 630 close(ss->fd); 631 631 } 632 632 633 + bool __weak elf__needs_adjust_symbols(GElf_Ehdr ehdr) 634 + { 635 + return ehdr.e_type == ET_EXEC || ehdr.e_type == ET_REL; 636 + } 637 + 633 638 int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name, 634 639 enum dso_binary_type type) 635 640 { ··· 716 711 ".gnu.prelink_undo", 717 712 NULL) != NULL); 718 713 } else { 719 - ss->adjust_symbols = ehdr.e_type == ET_EXEC || 720 - ehdr.e_type == ET_REL; 714 + ss->adjust_symbols = elf__needs_adjust_symbols(ehdr); 721 715 } 722 716 723 717 ss->name = strdup(name);
+4
tools/perf/util/symbol.h
··· 303 303 int setup_intlist(struct intlist **list, const char *list_str, 304 304 const char *list_name); 305 305 306 + #ifdef HAVE_LIBELF_SUPPORT 307 + bool elf__needs_adjust_symbols(GElf_Ehdr ehdr); 308 + #endif 309 + 306 310 #endif /* __PERF_SYMBOL */