diff options
-rw-r--r-- | tools/perf/arch/powerpc/util/sym-handling.c | 28 | ||||
-rw-r--r-- | tools/perf/util/probe-event.c | 5 | ||||
-rw-r--r-- | tools/perf/util/probe-event.h | 3 | ||||
-rw-r--r-- | tools/perf/util/symbol-elf.c | 7 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 3 |
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 | ||
23 | void 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 | ||
63 | void 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 | ||
70 | void arch__fix_tev_from_maps(struct perf_probe_event *pev, | 71 | void 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 | ||
2478 | void __weak arch__fix_tev_from_maps(struct perf_probe_event *pev __maybe_unused, | 2478 | void __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, | |||
154 | int show_available_funcs(const char *module, struct strfilter *filter, bool user); | 154 | int show_available_funcs(const char *module, struct strfilter *filter, bool user); |
155 | bool arch__prefers_symtab(void); | 155 | bool arch__prefers_symtab(void); |
156 | void arch__fix_tev_from_maps(struct perf_probe_event *pev, | 156 | void 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. */ |
160 | int e_snprintf(char *str, size_t size, const char *format, ...) | 161 | int 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 | ||
773 | void __weak arch__elf_sym_adjust(GElf_Sym *sym __maybe_unused) { } | 773 | void __weak arch__sym_update(struct symbol *s __maybe_unused, |
774 | GElf_Sym *sym __maybe_unused) { } | ||
774 | 775 | ||
775 | int dso__load_sym(struct dso *dso, struct map *map, | 776 | int 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 |
325 | bool elf__needs_adjust_symbols(GElf_Ehdr ehdr); | 326 | bool elf__needs_adjust_symbols(GElf_Ehdr ehdr); |
326 | void arch__elf_sym_adjust(GElf_Sym *sym); | 327 | void 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 |