]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdwfl_stacktrace + libebl: dwflst_sample_getframes non-perf api
authorSerhei Makarov <serhei@serhei.io>
Fri, 12 Sep 2025 20:00:16 +0000 (16:00 -0400)
committerSerhei Makarov <serhei@serhei.io>
Thu, 5 Mar 2026 14:43:41 +0000 (09:43 -0500)
This patch adds a generic dwflst_sample_getframes() API that does not
depend on perf_events concepts, in particular the
linux-kernel-specific enum defining the perf_regs_mask register order.
This involves reworking the register-handling backend to use
regs_mapping arrays rather than perf_regs_mask, and provide a way to
translate perf_regs_mask to regs_mapping.

A regs_mapping array, for each item in a provided regs[] array,
specifies its position in the full register file expected by the DWARF
functionality.

Changes for v3:
- Added dwflst_sample_getframes to libdw.map.

Changes for v2:
- Addressed Aaron Merey's review comments.
- Removed dwflst_sample_frame.c dependency on perf_events abi constants.

* libdwfl_stacktrace/Makefile.am: Rename dwflst_sample_frame.c from
  dwflst_perf_frame.c.
* libdwfl_stacktrace/libdwfl_stacktrace.h (dwflst_sample_getframes):
  New function providing unwinding functionality with a regs_mapping
  array rather than a linux-kernel-dependent perf_regs_mask.
* libdw/libdw.map (ELFUTILS_0.193_EXPERIMENTAL): Add dwflst_sample_getframes.
* libdwfl_stacktrace/dwflst_sample_frame.c: Renamed from
  dwflst_perf_frame.c. Remove linux/perf_event.h dependency.
  (struct sample_info): Rename from perf_sample_info, include
  regs_mapping field, replace abi with elfclass field.
  (sample_next_thread): Renamed struct sample_info.
  (sample_getthread): Renamed struct sample_info.
  (copy_word): Use elfclass instead of perf abi field.
  (elf_memory_read): Renamed struct sample_info, use elfclass.
  (sample_memory_read): Renamed struct sample_info, use elfclass.
  (sample_set_initial_registers): Renamed struct sample_info,
  pass regs_mapping to ebl_set_initial_registers_sample.
  (dwflst_sample_getframes): New function.
  (dwflst_perf_sample_getframes): Reimplement in terms of
  dwflst_sample_getframes and ebl_sample_perf_regs_mapping.
* libebl/ebl-hooks.h (set_initial_registers_sample): Now
  takes regs_mapping instead of regs_mask.
  (sample_base_addr): Removed.
  (sample_pc): Removed.
  (sample_sp_pc): New function combining the removed functions for
  efficiency.
  (sample_perf_regs_mapping): New function translating
  perf_regs_mask to regs_mapping array.
* libebl/eblinitreg_sample.c (ebl_sample_base_addr): Removed.
  (ebl_sample_pc): Removed.
  (ebl_sample_sp_pc): New function.
  (ebl_set_initial_registers_sample): Take regs_mapping, provide
  a default implementation for contiguous dwarf_regs array.
  (ebl_sample_perf_regs_mapping): New function.
* libebl/eblclosebackend.c (ebl_closebackend):
  Free cached_regs_mapping.
* libebl/libebl.h (ebl_set_initial_registers_sample): Now takes
  regs_mapping instead of regs_mask.
  (ebl_sample_base_addr): Removed.
  (ebl_sample_pc): Removed.
  (ebl_sample_sp_pc): New function.
  (ebl_sample_perf_regs_mapping): New function.
* libebl/libeblP.h (struct ebl): Add caching fields to remove the
  need to repeat a sample_perf_regs_mapping() computation for
  every frame when the perf_regs_mask is consistent.
* backends/Makefile.am: Remove no-longer-needed linux-perf-regs.c.
* backends/i386_init.c (i386_init): Renamed sample_* functions,
  added cached_regs_mapping and related fields/functions.
* backends/i386_initreg_sample.c (i386_sample_base_addr): Removed.
  (i386_sample_pc): Removed.
  (i386_sample_sp_pc): New function combining the removed functions.
  (i386_set_initial_registers_sample): Removed.
  (i386_sample_perf_regs_mapping): New function translating
  perf_regs_mask to regs_mapping array.
* backends/linux-perf-regs.c: Removed as perf_sample_find_reg is no
  longer needed.
* backends/x86_64_init.c (x86_64_init): Renamed sample_* functions,
  added cached_regs_mapping and related fields/functions.
* backends/x86_64_initreg_sample.c (x86_64_sample_base_addr): Removed.
  (x86_64_sample_pc): Removed.
  (x86_64_sample_sp_pc): New function combining the removed functions.
  (x86_64_set_initial_registers_sample): Removed.
  (x86_64_sample_perf_regs_mapping): New function translating
  perf_regs_mask to regs_mapping array.
* backends/x86_initreg_sample.c (x86_set_initial_registers_sample):
  Removed.
  (x86_sample_sp_pc): New function.
  (x86_sample_perf_regs_mapping): New function translating
  perf_regs_mask to regs_mapping array.

libdw/libdw.map

index b45647e6fa4c499762c0180da8f9337ceeaf764f..f8b2cfaaec6f80390d8193bd24d47b9524420e6f 100644 (file)
@@ -405,6 +405,7 @@ ELFUTILS_0.193_EXPERIMENTAL {
     dwflst_tracker_linux_proc_find_elf;
     dwflst_tracker_find_pid;
     dwflst_perf_sample_getframes;
+    dwflst_sample_getframes;
 };
 
 ELFUTILS_0.194_EXPERIMENTAL {