aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/arch/powerpc/util/sym-handling.c28
-rw-r--r--tools/perf/util/probe-event.c5
-rw-r--r--tools/perf/util/probe-event.h3
-rw-r--r--tools/perf/util/symbol-elf.c7
-rw-r--r--tools/perf/util/symbol.h3
5 files changed, 31 insertions, 15 deletions
diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c
index 6974ba0fa065..c6d0f91731a1 100644
--- a/tools/perf/arch/powerpc/util/sym-handling.c
+++ b/tools/perf/arch/powerpc/util/sym-handling.c
@@ -19,12 +19,6 @@ bool elf__needs_adjust_symbols(GElf_Ehdr ehdr)
19 ehdr.e_type == ET_DYN; 19 ehdr.e_type == ET_DYN;
20} 20}
21 21
22#if defined(_CALL_ELF) && _CALL_ELF == 2
23void arch__elf_sym_adjust(GElf_Sym *sym)
24{
25 sym->st_value += PPC64_LOCAL_ENTRY_OFFSET(sym->st_other);
26}
27#endif
28#endif 22#endif
29 23
30#if !defined(_CALL_ELF) || _CALL_ELF != 2 24#if !defined(_CALL_ELF) || _CALL_ELF != 2
@@ -65,11 +59,21 @@ bool arch__prefers_symtab(void)
65 return true; 59 return true;
66} 60}
67 61
62#ifdef HAVE_LIBELF_SUPPORT
63void arch__sym_update(struct symbol *s, GElf_Sym *sym)
64{
65 s->arch_sym = sym->st_other;
66}
67#endif
68
68#define PPC64LE_LEP_OFFSET 8 69#define PPC64LE_LEP_OFFSET 8
69 70
70void arch__fix_tev_from_maps(struct perf_probe_event *pev, 71void arch__fix_tev_from_maps(struct perf_probe_event *pev,
71 struct probe_trace_event *tev, struct map *map) 72 struct probe_trace_event *tev, struct map *map,
73 struct symbol *sym)
72{ 74{
75 int lep_offset;
76
73 /* 77 /*
74 * When probing at a function entry point, we normally always want the 78 * When probing at a function entry point, we normally always want the
75 * LEP since that catches calls to the function through both the GEP and 79 * LEP since that catches calls to the function through both the GEP and
@@ -82,10 +86,18 @@ void arch__fix_tev_from_maps(struct perf_probe_event *pev,
82 * 86 *
83 * In addition, we shouldn't specify an offset for kretprobes. 87 * In addition, we shouldn't specify an offset for kretprobes.
84 */ 88 */
85 if (pev->point.offset || pev->point.retprobe || !map) 89 if (pev->point.offset || pev->point.retprobe || !map || !sym)
86 return; 90 return;
87 91
92 lep_offset = PPC64_LOCAL_ENTRY_OFFSET(sym->arch_sym);
93
88 if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS) 94 if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS)
89 tev->point.offset += PPC64LE_LEP_OFFSET; 95 tev->point.offset += PPC64LE_LEP_OFFSET;
96 else if (lep_offset) {
97 if (pev->uprobes)
98 tev->point.address += lep_offset;
99 else
100 tev->point.offset += lep_offset;
101 }
90} 102}
91#endif 103#endif
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 85d82f4dc5e9..c82c625395ab 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2477,7 +2477,8 @@ static int find_probe_functions(struct map *map, char *name,
2477 2477
2478void __weak arch__fix_tev_from_maps(struct perf_probe_event *pev __maybe_unused, 2478void __weak arch__fix_tev_from_maps(struct perf_probe_event *pev __maybe_unused,
2479 struct probe_trace_event *tev __maybe_unused, 2479 struct probe_trace_event *tev __maybe_unused,
2480 struct map *map __maybe_unused) { } 2480 struct map *map __maybe_unused,
2481 struct symbol *sym __maybe_unused) { }
2481 2482
2482/* 2483/*
2483 * Find probe function addresses from map. 2484 * Find probe function addresses from map.
@@ -2614,7 +2615,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
2614 strdup_or_goto(pev->args[i].type, 2615 strdup_or_goto(pev->args[i].type,
2615 nomem_out); 2616 nomem_out);
2616 } 2617 }
2617 arch__fix_tev_from_maps(pev, tev, map); 2618 arch__fix_tev_from_maps(pev, tev, map, sym);
2618 } 2619 }
2619 if (ret == skipped) { 2620 if (ret == skipped) {
2620 ret = -ENOENT; 2621 ret = -ENOENT;
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index e2209623f981..5a27eb4fad05 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -154,7 +154,8 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
154int show_available_funcs(const char *module, struct strfilter *filter, bool user); 154int show_available_funcs(const char *module, struct strfilter *filter, bool user);
155bool arch__prefers_symtab(void); 155bool arch__prefers_symtab(void);
156void arch__fix_tev_from_maps(struct perf_probe_event *pev, 156void arch__fix_tev_from_maps(struct perf_probe_event *pev,
157 struct probe_trace_event *tev, struct map *map); 157 struct probe_trace_event *tev, struct map *map,
158 struct symbol *sym);
158 159
159/* If there is no space to write, returns -E2BIG. */ 160/* If there is no space to write, returns -E2BIG. */
160int e_snprintf(char *str, size_t size, const char *format, ...) 161int e_snprintf(char *str, size_t size, const char *format, ...)
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 3f9d6798bd18..87a297dd8901 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -770,7 +770,8 @@ static bool want_demangle(bool is_kernel_sym)
770 return is_kernel_sym ? symbol_conf.demangle_kernel : symbol_conf.demangle; 770 return is_kernel_sym ? symbol_conf.demangle_kernel : symbol_conf.demangle;
771} 771}
772 772
773void __weak arch__elf_sym_adjust(GElf_Sym *sym __maybe_unused) { } 773void __weak arch__sym_update(struct symbol *s __maybe_unused,
774 GElf_Sym *sym __maybe_unused) { }
774 775
775int dso__load_sym(struct dso *dso, struct map *map, 776int dso__load_sym(struct dso *dso, struct map *map,
776 struct symsrc *syms_ss, struct symsrc *runtime_ss, 777 struct symsrc *syms_ss, struct symsrc *runtime_ss,
@@ -947,8 +948,6 @@ int dso__load_sym(struct dso *dso, struct map *map,
947 (sym.st_value & 1)) 948 (sym.st_value & 1))
948 --sym.st_value; 949 --sym.st_value;
949 950
950 arch__elf_sym_adjust(&sym);
951
952 if (dso->kernel || kmodule) { 951 if (dso->kernel || kmodule) {
953 char dso_name[PATH_MAX]; 952 char dso_name[PATH_MAX];
954 953
@@ -1082,6 +1081,8 @@ new_symbol:
1082 if (!f) 1081 if (!f)
1083 goto out_elf_end; 1082 goto out_elf_end;
1084 1083
1084 arch__sym_update(f, &sym);
1085
1085 if (filter && filter(curr_map, f)) 1086 if (filter && filter(curr_map, f))
1086 symbol__delete(f); 1087 symbol__delete(f);
1087 else { 1088 else {
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index c8e43979ed5c..07211c2f8456 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -55,6 +55,7 @@ struct symbol {
55 u16 namelen; 55 u16 namelen;
56 u8 binding; 56 u8 binding;
57 bool ignore; 57 bool ignore;
58 u8 arch_sym;
58 char name[0]; 59 char name[0];
59}; 60};
60 61
@@ -323,7 +324,7 @@ int setup_intlist(struct intlist **list, const char *list_str,
323 324
324#ifdef HAVE_LIBELF_SUPPORT 325#ifdef HAVE_LIBELF_SUPPORT
325bool elf__needs_adjust_symbols(GElf_Ehdr ehdr); 326bool elf__needs_adjust_symbols(GElf_Ehdr ehdr);
326void arch__elf_sym_adjust(GElf_Sym *sym); 327void arch__sym_update(struct symbol *s, GElf_Sym *sym);
327#endif 328#endif
328 329
329#define SYMBOL_A 0 330#define SYMBOL_A 0