diff --git a/tools/perf/arch/arm/util/Build b/tools/perf/arch/arm/util/Build index fd695e1fdaee..3291f893b943 100644 --- a/tools/perf/arch/arm/util/Build +++ b/tools/perf/arch/arm/util/Build @@ -1,6 +1,5 @@ perf-util-y += perf_regs.o perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o perf-util-y += pmu.o auxtrace.o cs-etm.o diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build index d63881081d2e..0177af19cc00 100644 --- a/tools/perf/arch/arm64/util/Build +++ b/tools/perf/arch/arm64/util/Build @@ -1,4 +1,3 @@ -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o perf-util-y += ../../arm/util/auxtrace.o diff --git a/tools/perf/arch/csky/util/Build b/tools/perf/arch/csky/util/Build index 5e6ea82c4202..6b2d0e021b11 100644 --- a/tools/perf/arch/csky/util/Build +++ b/tools/perf/arch/csky/util/Build @@ -1,3 +1 @@ perf-util-y += perf_regs.o - -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o diff --git a/tools/perf/arch/powerpc/util/Build b/tools/perf/arch/powerpc/util/Build index 3d0d5427aef7..5fd28ec713a4 100644 --- a/tools/perf/arch/powerpc/util/Build +++ b/tools/perf/arch/powerpc/util/Build @@ -9,5 +9,4 @@ perf-util-y += evsel.o perf-util-$(CONFIG_LIBDW) += skip-callchain-idx.o perf-util-$(CONFIG_LIBUNWIND) += unwind-libunwind.o -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o perf-util-y += auxtrace.o diff --git a/tools/perf/arch/riscv/util/Build b/tools/perf/arch/riscv/util/Build index 58a672246024..628b9ebd418b 100644 --- a/tools/perf/arch/riscv/util/Build +++ b/tools/perf/arch/riscv/util/Build @@ -2,4 +2,3 @@ perf-util-y += perf_regs.o perf-util-y += header.o perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o diff --git a/tools/perf/arch/s390/util/Build b/tools/perf/arch/s390/util/Build index c64eb18dbdae..5391d26fedd4 100644 --- a/tools/perf/arch/s390/util/Build +++ b/tools/perf/arch/s390/util/Build @@ -2,8 +2,6 @@ perf-util-y += header.o perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o perf-util-y += perf_regs.o -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o - perf-util-y += machine.o perf-util-y += pmu.o diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build index c0dc5965f362..fad256252bb9 100644 --- a/tools/perf/arch/x86/util/Build +++ b/tools/perf/arch/x86/util/Build @@ -12,7 +12,6 @@ perf-util-y += evsel.o perf-util-y += iostat.o perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o perf-util-y += auxtrace.o perf-util-y += archinsn.o diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 4915f237ba9e..5efec73be474 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -227,6 +227,7 @@ perf-util-$(CONFIG_LIBDW) += annotate-data.o perf-util-$(CONFIG_LIBDW) += libdw.o perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o +perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw-arch/ perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind-local.o perf-util-$(CONFIG_LIBUNWIND) += unwind-libunwind.o perf-util-$(CONFIG_LIBUNWIND_X86) += libunwind/x86_32.o diff --git a/tools/perf/util/unwind-libdw-arch/Build b/tools/perf/util/unwind-libdw-arch/Build new file mode 100644 index 000000000000..ef17a83a7813 --- /dev/null +++ b/tools/perf/util/unwind-libdw-arch/Build @@ -0,0 +1,8 @@ +perf-util-y += unwind-libdw-x86.o +perf-util-y += unwind-libdw-arm.o +perf-util-y += unwind-libdw-arm64.o +perf-util-y += unwind-libdw-csky.o +perf-util-y += unwind-libdw-loongarch.o +perf-util-y += unwind-libdw-powerpc.o +perf-util-y += unwind-libdw-riscv.o +perf-util-y += unwind-libdw-s390.o diff --git a/tools/perf/arch/arm/util/unwind-libdw.c b/tools/perf/util/unwind-libdw-arch/unwind-libdw-arm.c similarity index 80% rename from tools/perf/arch/arm/util/unwind-libdw.c rename to tools/perf/util/unwind-libdw-arch/unwind-libdw-arm.c index fbb643f224ec..56e9b5975bcc 100644 --- a/tools/perf/arch/arm/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw-arch/unwind-libdw-arm.c @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-2.0 #include -#include "perf_regs.h" -#include "../../../util/unwind-libdw.h" -#include "../../../util/perf_regs.h" -#include "../../../util/sample.h" +#include "../arch/arm/include/uapi/asm/perf_regs.h" +#include "util/unwind-libdw.h" +#include "util/perf_regs.h" +#include "util/sample.h" -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) +bool libdw_set_initial_registers_arm(Dwfl_Thread *thread, void *arg) { struct unwind_info *ui = arg; struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); diff --git a/tools/perf/arch/arm64/util/unwind-libdw.c b/tools/perf/util/unwind-libdw-arch/unwind-libdw-arm64.c similarity index 87% rename from tools/perf/arch/arm64/util/unwind-libdw.c rename to tools/perf/util/unwind-libdw-arch/unwind-libdw-arm64.c index b89b0a7e5ad9..29b6833e036c 100644 --- a/tools/perf/arch/arm64/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw-arch/unwind-libdw-arm64.c @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-2.0 #include -#include "perf_regs.h" -#include "../../../util/unwind-libdw.h" -#include "../../../util/perf_regs.h" -#include "../../../util/sample.h" +#include "../arch/arm64/include/uapi/asm/perf_regs.h" +#include "util/unwind-libdw.h" +#include "util/perf_regs.h" +#include "util/sample.h" -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) +bool libdw_set_initial_registers_arm64(Dwfl_Thread *thread, void *arg) { struct unwind_info *ui = arg; struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); diff --git a/tools/perf/arch/csky/util/unwind-libdw.c b/tools/perf/util/unwind-libdw-arch/unwind-libdw-csky.c similarity index 90% rename from tools/perf/arch/csky/util/unwind-libdw.c rename to tools/perf/util/unwind-libdw-arch/unwind-libdw-csky.c index b20b1569783d..2556d034c32a 100644 --- a/tools/perf/arch/csky/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw-arch/unwind-libdw-csky.c @@ -2,12 +2,12 @@ // Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. #include -#include "perf_regs.h" -#include "../../util/unwind-libdw.h" -#include "../../util/perf_regs.h" -#include "../../util/event.h" +#include "../arch/csky/include/uapi/asm/perf_regs.h" +#include "util/unwind-libdw.h" +#include "util/perf_regs.h" +#include "util/sample.h" -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) +bool libdw_set_initial_registers_csky(Dwfl_Thread *thread, void *arg) { struct unwind_info *ui = arg; struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); diff --git a/tools/perf/arch/loongarch/util/unwind-libdw.c b/tools/perf/util/unwind-libdw-arch/unwind-libdw-loongarch.c similarity index 86% rename from tools/perf/arch/loongarch/util/unwind-libdw.c rename to tools/perf/util/unwind-libdw-arch/unwind-libdw-loongarch.c index 60b1144bedd5..5fca673508be 100644 --- a/tools/perf/arch/loongarch/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw-arch/unwind-libdw-loongarch.c @@ -2,12 +2,12 @@ /* Copyright (C) 2020-2023 Loongson Technology Corporation Limited */ #include -#include "perf_regs.h" -#include "../../util/unwind-libdw.h" -#include "../../util/perf_regs.h" -#include "../../util/sample.h" +#include "../arch/loongarch/include/uapi/asm/perf_regs.h" +#include "util/unwind-libdw.h" +#include "util/perf_regs.h" +#include "util/sample.h" -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) +bool libdw_set_initial_registers_loongarch(Dwfl_Thread *thread, void *arg) { struct unwind_info *ui = arg; struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); diff --git a/tools/perf/arch/powerpc/util/unwind-libdw.c b/tools/perf/util/unwind-libdw-arch/unwind-libdw-powerpc.c similarity index 89% rename from tools/perf/arch/powerpc/util/unwind-libdw.c rename to tools/perf/util/unwind-libdw-arch/unwind-libdw-powerpc.c index 82d0c28ae345..1560db45e7b4 100644 --- a/tools/perf/arch/powerpc/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw-arch/unwind-libdw-powerpc.c @@ -1,10 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 #include #include -#include "perf_regs.h" -#include "../../../util/unwind-libdw.h" -#include "../../../util/perf_regs.h" -#include "../../../util/sample.h" +#include "../arch/powerpc/include/uapi/asm/perf_regs.h" +#include "util/unwind-libdw.h" +#include "util/perf_regs.h" +#include "util/sample.h" /* See backends/ppc_initreg.c and backends/ppc_regs.c in elfutils. */ static const int special_regs[3][2] = { @@ -13,7 +13,7 @@ static const int special_regs[3][2] = { { 109, PERF_REG_POWERPC_CTR }, }; -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) +bool libdw_set_initial_registers_powerpc(Dwfl_Thread *thread, void *arg) { struct unwind_info *ui = arg; struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); diff --git a/tools/perf/arch/riscv/util/unwind-libdw.c b/tools/perf/util/unwind-libdw-arch/unwind-libdw-riscv.c similarity index 87% rename from tools/perf/arch/riscv/util/unwind-libdw.c rename to tools/perf/util/unwind-libdw-arch/unwind-libdw-riscv.c index dc1476e16321..c2e2c4b6b2e0 100644 --- a/tools/perf/arch/riscv/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw-arch/unwind-libdw-riscv.c @@ -2,12 +2,12 @@ /* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */ #include -#include "perf_regs.h" -#include "../../util/unwind-libdw.h" -#include "../../util/perf_regs.h" -#include "../../util/sample.h" +#include "../arch/riscv/include/uapi/asm/perf_regs.h" +#include "util/unwind-libdw.h" +#include "util/perf_regs.h" +#include "util/sample.h" -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) +bool libdw_set_initial_registers_riscv(Dwfl_Thread *thread, void *arg) { struct unwind_info *ui = arg; struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); diff --git a/tools/perf/arch/s390/util/unwind-libdw.c b/tools/perf/util/unwind-libdw-arch/unwind-libdw-s390.c similarity index 84% rename from tools/perf/arch/s390/util/unwind-libdw.c rename to tools/perf/util/unwind-libdw-arch/unwind-libdw-s390.c index c27c7a0d1076..1e05e9d9d95f 100644 --- a/tools/perf/arch/s390/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw-arch/unwind-libdw-s390.c @@ -1,14 +1,14 @@ #include #include -#include "../../util/unwind-libdw.h" -#include "../../util/perf_regs.h" -#include "../../util/event.h" -#include "../../util/sample.h" -#include "dwarf-regs-table.h" -#include "perf_regs.h" +#include "util/unwind-libdw.h" +#include "util/perf_regs.h" +#include "util/event.h" +#include "util/sample.h" +#include "../arch/s390/include/dwarf-regs-table.h" +#include "../arch/s390/include/uapi/asm/perf_regs.h" -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) +bool libdw_set_initial_registers_s390(Dwfl_Thread *thread, void *arg) { struct unwind_info *ui = arg; struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); diff --git a/tools/perf/arch/x86/util/unwind-libdw.c b/tools/perf/util/unwind-libdw-arch/unwind-libdw-x86.c similarity index 87% rename from tools/perf/arch/x86/util/unwind-libdw.c rename to tools/perf/util/unwind-libdw-arch/unwind-libdw-x86.c index 798493e887d7..dd27545a4a68 100644 --- a/tools/perf/arch/x86/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw-arch/unwind-libdw-x86.c @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-2.0 #include -#include "perf_regs.h" -#include "../../../util/unwind-libdw.h" -#include "../../../util/perf_regs.h" +#include "../arch/x86/include/uapi/asm/perf_regs.h" +#include "util/unwind-libdw.h" +#include "util/perf_regs.h" #include "util/sample.h" -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) +bool libdw_set_initial_registers_x86(Dwfl_Thread *thread, void *arg) { struct unwind_info *ui = arg; struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index 3ff427a49e4c..b2e194a8be39 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c @@ -225,11 +225,45 @@ static bool memory_read(Dwfl *dwfl __maybe_unused, Dwarf_Addr addr, Dwarf_Word * return true; } -static const Dwfl_Thread_Callbacks callbacks = { - .next_thread = next_thread, - .memory_read = memory_read, - .set_initial_registers = libdw__arch_set_initial_registers, -}; +#define DEFINE_DWFL_THREAD_CALLBACKS(arch) \ +static const Dwfl_Thread_Callbacks callbacks_##arch = { \ + .next_thread = next_thread, \ + .memory_read = memory_read, \ + .set_initial_registers = libdw_set_initial_registers_##arch, \ +} + +DEFINE_DWFL_THREAD_CALLBACKS(x86); +DEFINE_DWFL_THREAD_CALLBACKS(arm); +DEFINE_DWFL_THREAD_CALLBACKS(arm64); +DEFINE_DWFL_THREAD_CALLBACKS(csky); +DEFINE_DWFL_THREAD_CALLBACKS(loongarch); +DEFINE_DWFL_THREAD_CALLBACKS(powerpc); +DEFINE_DWFL_THREAD_CALLBACKS(riscv); +DEFINE_DWFL_THREAD_CALLBACKS(s390); + +static const Dwfl_Thread_Callbacks *get_thread_callbacks(const char *arch) +{ + if (!strcmp(arch, "arm")) + return &callbacks_arm; + else if (!strcmp(arch, "arm64")) + return &callbacks_arm64; + else if (!strcmp(arch, "csky")) + return &callbacks_csky; + else if (!strcmp(arch, "loongarch")) + return &callbacks_loongarch; + else if (!strcmp(arch, "powerpc")) + return &callbacks_powerpc; + else if (!strcmp(arch, "riscv")) + return &callbacks_riscv; + else if (!strcmp(arch, "s390")) + return &callbacks_s390; + else if (!strcmp(arch, "x86")) + return &callbacks_x86; + + pr_err("Fail to get thread callbacks for arch %s, returns NULL\n", + arch); + return NULL; +} static int frame_callback(Dwfl_Frame *state, void *arg) @@ -278,6 +312,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, const char *arch = perf_env__arch(ui_buf.machine->env); Dwarf_Word ip; int err = -EINVAL, i; + const Dwfl_Thread_Callbacks *callbacks; if (!data->user_regs || !data->user_regs->regs) return -EINVAL; @@ -300,7 +335,11 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, if (err) goto out; - err = !dwfl_attach_state(ui->dwfl, EM_NONE, thread__tid(thread), &callbacks, ui); + callbacks = get_thread_callbacks(arch); + if (!callbacks) + goto out; + + err = !dwfl_attach_state(ui->dwfl, EM_NONE, thread__tid(thread), callbacks, ui); if (err) goto out; diff --git a/tools/perf/util/unwind-libdw.h b/tools/perf/util/unwind-libdw.h index 8c88bc4f2304..574b29848cce 100644 --- a/tools/perf/util/unwind-libdw.h +++ b/tools/perf/util/unwind-libdw.h @@ -9,7 +9,15 @@ struct machine; struct perf_sample; struct thread; -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg); +bool libdw_set_initial_registers_x86(Dwfl_Thread *thread, void *arg); +bool libdw_set_initial_registers_arm(Dwfl_Thread *thread, void *arg); +bool libdw_set_initial_registers_arm64(Dwfl_Thread *thread, void *arg); +bool libdw_set_initial_registers_csky(Dwfl_Thread *thread, void *arg); +bool libdw_set_initial_registers_loongarch(Dwfl_Thread *thread, void *arg); +bool libdw_set_initial_registers_mips(Dwfl_Thread *thread, void *arg); +bool libdw_set_initial_registers_powerpc(Dwfl_Thread *thread, void *arg); +bool libdw_set_initial_registers_riscv(Dwfl_Thread *thread, void *arg); +bool libdw_set_initial_registers_s390(Dwfl_Thread *thread, void *arg); struct unwind_info { Dwfl *dwfl;