Renaming to dwfl_set_initial_registers_thread. This callback was private to one file, but now that other tools (eu-stacktrace, sysprof via the dwfl_perf_sample_getframes) are invoking the ebl set_initial_registers_sample api, we need to expose it. Otherwise, clients would need to reimplement this code identically, including the undocumented/unexplained use of -2 for aarch64 insn_mask.
TODO(REVIEW): Should this be in libdwflP.h since libebl is private? On the other hand, dwfl_thread_state_register_pc et al. are also public in spite of being used primarily by the previously-internal code in dwfl_set_initial_registers_thread. * libdw/libdw.map: Add dwfl_set_initial_registers_thread. * libdwfl/libdwfl.h (dwfl_set_initial_registers_thread): New function. * libdwfl/linux-pid-attach.c (dwfl_set_initial_registers_thread): Renamed from pid_thread_state_registers_cb. (pid_set_initial_registers): Pass the newly renamed callback. --- libdw/libdw.map | 5 +++++ libdwfl/libdwfl.h | 10 +++++++++- libdwfl/linux-pid-attach.c | 10 +++++----- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/libdw/libdw.map b/libdw/libdw.map index bc53385f..afbc467f 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -385,3 +385,8 @@ ELFUTILS_0.192 { dwfl_frame_unwound_source; dwfl_unwound_source_str; } ELFUTILS_0.191; + +ELFUTILS_0.193 { + global: + dwfl_set_initial_registers_thread; +} ELFUTILS_0.192; diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h index 90523283..b3b32d51 100644 --- a/libdwfl/libdwfl.h +++ b/libdwfl/libdwfl.h @@ -1,5 +1,5 @@ /* Interfaces for libdwfl. - Copyright (C) 2005-2010, 2013, 2024 Red Hat, Inc. + Copyright (C) 2005-2010, 2013, 2024-2025 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -783,6 +783,14 @@ bool dwfl_thread_state_registers (Dwfl_Thread *thread, int firstreg, void dwfl_thread_state_register_pc (Dwfl_Thread *thread, Dwarf_Word pc) __nonnull_attribute__ (1); +/* Basic implementation of Dwfl_Thread_Callbacks.set_initial_registers. + ARG must be a Dwfl_Thread *. Calls dwfl_thread_state_register_pc + if firstreg is -1 (indicating arch PC), dwfl_thread_state_registers + otherwise. */ +bool dwfl_set_initial_registers_thread (int firstreg, unsigned nregs, + const Dwarf_Word *regs, void *arg) + __nonnull_attribute__ (3, 4); + /* Iterate through the threads for a process. Returns zero if all threads have been processed by the callback, returns -1 on error, or the value of the callback when not DWARF_CB_OK. -1 returned on error will set dwfl_errno (). diff --git a/libdwfl/linux-pid-attach.c b/libdwfl/linux-pid-attach.c index 0eec1e88..2d35a8c6 100644 --- a/libdwfl/linux-pid-attach.c +++ b/libdwfl/linux-pid-attach.c @@ -1,5 +1,5 @@ /* Get Dwarf Frame state for target live PID process. - Copyright (C) 2013, 2014, 2015, 2018 Red Hat, Inc. + Copyright (C) 2013, 2014, 2015, 2018, 2025 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -304,9 +304,9 @@ pid_getthread (Dwfl *dwfl __attribute__ ((unused)), pid_t tid, /* Implement the ebl_set_initial_registers_tid setfunc callback. */ -static bool -pid_thread_state_registers_cb (int firstreg, unsigned nregs, - const Dwarf_Word *regs, void *arg) +bool +dwfl_set_initial_registers_thread (int firstreg, unsigned nregs, + const Dwarf_Word *regs, void *arg) { Dwfl_Thread *thread = (Dwfl_Thread *) arg; if (firstreg == -1) @@ -338,7 +338,7 @@ pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg) Dwfl_Process *process = thread->process; Ebl *ebl = process->ebl; return ebl_set_initial_registers_tid (ebl, tid, - pid_thread_state_registers_cb, thread); + dwfl_set_initial_registers_thread, thread); } static void -- 2.47.0