35 static constexpr size_t pointer_size = 4;
38 static constexpr uint32_t sp_reg = dwarf::arm32::sp;
40 static constexpr uint32_t lr_reg = dwarf::arm32::lr;
42 static constexpr uint32_t ra_reg = lr_reg;
44 static constexpr uint32_t fp_reg = dwarf::arm32::fp;
71 static constexpr ptrdiff_t fp_slot_offset = -4;
72 static constexpr ptrdiff_t ra_slot_offset = 0;
86 return reg == fp_reg || reg == 7;
89 [[nodiscard]]
static constexpr uintptr_t
normalize_pc(uintptr_t raw_ra)
noexcept {
91 return raw_ra & ~static_cast<uintptr_t>(1);
111 if (reg_ctx && reg_ctx.read(dwarf::arm32::cpsr, cpsr)) {
112 constexpr uint32_t thumb_bit = 0x20U;
113 return (cpsr & thumb_bit) != 0U ? 7U : fp_reg;
148 ptrdiff_t &out_ra_slot_offset)
noexcept {
150 if (reg_ctx && reg_ctx.read(dwarf::arm32::cpsr, cpsr)) {
151 constexpr uint32_t thumb_bit = 0x20U;
152 if ((cpsr & thumb_bit) != 0U)
155 out_fp_slot_offset = fp_slot_offset;
156 out_ra_slot_offset = ra_slot_offset;
176 static constexpr size_t pointer_size = 8;
179 static constexpr uint32_t sp_reg = dwarf::aarch64::sp;
181 static constexpr uint32_t ra_reg = dwarf::aarch64::lr;
183 static constexpr uint32_t fp_reg = dwarf::aarch64::fp;
185 static constexpr ptrdiff_t fp_slot_offset = 0;
186 static constexpr ptrdiff_t ra_slot_offset = 8;
201 [[nodiscard]]
static constexpr uintptr_t
normalize_pc(uintptr_t raw_ra)
noexcept {
202 if constexpr (
sizeof(uintptr_t) <
sizeof(uint64_t))
203 return raw_ra & ~
static_cast<uintptr_t
>(1);
205 const uint64_t pc =
static_cast<uint64_t
>(raw_ra) & ~UINT64_C(1);
208 const bool is_kernel = (pc & (UINT64_C(1) << 63)) != 0;
211 return static_cast<uintptr_t
>((pc & UINT64_C(0x0000FFFFFFFFFFFF)) | UINT64_C(0xFFFF000000000000));
214 return static_cast<uintptr_t
>(pc & UINT64_C(0x0000FFFFFFFFFFFF));
234 static constexpr size_t pointer_size = 4;
237 static constexpr uint32_t sp_reg = dwarf::riscv::sp;
239 static constexpr uint32_t ra_reg = dwarf::riscv::ra;
241 static constexpr uint32_t fp_reg = dwarf::riscv::fp;
246 static constexpr ptrdiff_t fp_slot_offset = 0;
247 static constexpr ptrdiff_t ra_slot_offset = 4;
262 [[nodiscard]]
static constexpr uintptr_t
normalize_pc(uintptr_t raw_ra)
noexcept {
return raw_ra; }
280 static constexpr size_t pointer_size = 8;
283 static constexpr uint32_t sp_reg = dwarf::riscv::sp;
285 static constexpr uint32_t ra_reg = dwarf::riscv::ra;
287 static constexpr uint32_t fp_reg = dwarf::riscv::fp;
289 static constexpr ptrdiff_t fp_slot_offset = 0;
290 static constexpr ptrdiff_t ra_slot_offset = 8;
305 [[nodiscard]]
static constexpr uintptr_t
normalize_pc(uintptr_t raw_ra)
noexcept {
return raw_ra; }
323 static constexpr size_t pointer_size = 4;
326 static constexpr uint32_t sp_reg = dwarf::x86::sp;
328 static constexpr uint32_t ra_reg = dwarf::x86::pc;
330 static constexpr uint32_t fp_reg = dwarf::x86::fp;
335 static constexpr ptrdiff_t fp_slot_offset = 0;
336 static constexpr ptrdiff_t ra_slot_offset = 4;
351 [[nodiscard]]
static constexpr uintptr_t
normalize_pc(uintptr_t raw_ra)
noexcept {
return raw_ra; }
369 static constexpr size_t pointer_size = 8;
372 static constexpr uint32_t sp_reg = dwarf::x86_64::sp;
374 static constexpr uint32_t ra_reg = dwarf::x86_64::pc;
376 static constexpr uint32_t fp_reg = dwarf::x86_64::fp;
378 static constexpr ptrdiff_t fp_slot_offset = 0;
379 static constexpr ptrdiff_t ra_slot_offset = 8;
394 [[nodiscard]]
static constexpr uintptr_t
normalize_pc(uintptr_t raw_ra)
noexcept {
return raw_ra; }
405template <
typename AbiTraits>
407 std::void_t<decltype(AbiTraits::resolve_fp_reg(std::declval<register_context_ref>()))>>
417template <
typename AbiTraits>
419 AbiTraits, std::void_t<decltype(AbiTraits::resolve_frame_slot_offsets(
420 std::declval<register_context_ref>(), std::declval<ptrdiff_t &>(), std::declval<ptrdiff_t &>()))>>
440 return AbiTraits::resolve_fp_reg(reg_ctx);
442 return AbiTraits::fp_reg;
465template <
typename AbiTraits>
467 ptrdiff_t &out_ra_slot_offset)
noexcept {
469 return AbiTraits::resolve_frame_slot_offsets(reg_ctx, out_fp_slot_offset, out_ra_slot_offset);
471 out_fp_slot_offset = AbiTraits::fp_slot_offset;
472 out_ra_slot_offset = AbiTraits::ra_slot_offset;
478 static_assert(
sizeof(
typename Traits::register_type) == Traits::pointer_size,
479 "AbiTraits error: register_type size must exactly match pointer_size!");
481 static_assert(Traits::pointer_size == 4 || Traits::pointer_size == 8,
482 "AbiTraits error: pointer_size must be either 4 (32-bit) or 8 (64-bit)!");
Zero-allocation, type-erased handle for inspecting and modifying CPU registers from a frame context.
Definition register_context.hpp:118
#define MICROFMT_API_CLASS
Definition compat.hpp:181
uint32_t resolve_fp_register(register_context_ref reg_ctx) noexcept
Resolves the frame-pointer register to use for AbiTraits.
Definition dwarf_abi.hpp:438
bool resolve_frame_slot_offsets(register_context_ref reg_ctx, ptrdiff_t &out_fp_slot_offset, ptrdiff_t &out_ra_slot_offset) noexcept
Resolves the FP-relative saved-FP/saved-RA slot offsets to use for AbiTraits's naive FP-chain walking...
Definition dwarf_abi.hpp:466
DWARF unwind ABI traits for AArch64 (64-bit ARM).
Definition dwarf_abi.hpp:168
static constexpr uintptr_t normalize_pc(uintptr_t raw_ra) noexcept
Definition dwarf_abi.hpp:201
uint64_t register_type
Register value width.
Definition dwarf_abi.hpp:170
static constexpr bool is_frame_pointer_register(uint32_t reg) noexcept
Reports whether a register is a frame pointer.
Definition dwarf_abi.hpp:199
static constexpr bool is_return_address_register(uint32_t reg) noexcept
Reports whether a register holds the return address.
Definition dwarf_abi.hpp:193
DWARF unwind ABI traits for ARM / Thumb (32-bit EABI).
Definition dwarf_abi.hpp:27
static uint32_t resolve_fp_reg(register_context_ref reg_ctx) noexcept
Resolves which register actually holds the frame pointer for the current instruction set state.
Definition dwarf_abi.hpp:109
static constexpr bool is_frame_pointer_register(uint32_t reg) noexcept
Reports whether a register is a frame pointer.
Definition dwarf_abi.hpp:85
static constexpr bool is_return_address_register(uint32_t reg) noexcept
Reports whether a register holds the return address.
Definition dwarf_abi.hpp:79
uint32_t register_type
Register value width.
Definition dwarf_abi.hpp:29
static bool resolve_frame_slot_offsets(register_context_ref reg_ctx, ptrdiff_t &out_fp_slot_offset, ptrdiff_t &out_ra_slot_offset) noexcept
Resolves the FP-relative saved-FP/saved-RA slot offsets for the current instruction-set state,...
Definition dwarf_abi.hpp:147
static constexpr uintptr_t normalize_pc(uintptr_t raw_ra) noexcept
Definition dwarf_abi.hpp:89
Definition dwarf_abi.hpp:403
Definition dwarf_abi.hpp:415
Definition dwarf_registers.hpp:384
Definition dwarf_registers.hpp:612
Definition dwarf_registers.hpp:825
Definition dwarf_registers.hpp:211
Definition dwarf_registers.hpp:121
Base template for architecture-specific GDB register traits.
Definition gdb_registers.hpp:110
DWARF unwind ABI traits for RISC-V 32-bit (RV32).
Definition dwarf_abi.hpp:226
static constexpr uintptr_t normalize_pc(uintptr_t raw_ra) noexcept
Definition dwarf_abi.hpp:262
uint32_t register_type
Register value width.
Definition dwarf_abi.hpp:228
static constexpr bool is_return_address_register(uint32_t reg) noexcept
Reports whether a register holds the return address.
Definition dwarf_abi.hpp:254
static constexpr bool is_frame_pointer_register(uint32_t reg) noexcept
Reports whether a register is a frame pointer.
Definition dwarf_abi.hpp:260
DWARF unwind ABI traits for RISC-V 64-bit (RV64).
Definition dwarf_abi.hpp:272
uint64_t register_type
Register value width.
Definition dwarf_abi.hpp:274
static constexpr bool is_frame_pointer_register(uint32_t reg) noexcept
Reports whether a register is a frame pointer.
Definition dwarf_abi.hpp:303
static constexpr bool is_return_address_register(uint32_t reg) noexcept
Reports whether a register holds the return address.
Definition dwarf_abi.hpp:297
static constexpr uintptr_t normalize_pc(uintptr_t raw_ra) noexcept
Definition dwarf_abi.hpp:305
Definition dwarf_abi.hpp:477
static constexpr bool value
Definition dwarf_abi.hpp:484
DWARF unwind ABI traits for x86-64 (AMD64 / x86_64).
Definition dwarf_abi.hpp:361
static constexpr bool is_frame_pointer_register(uint32_t reg) noexcept
Reports whether a register is a frame pointer.
Definition dwarf_abi.hpp:392
static constexpr bool is_return_address_register(uint32_t reg) noexcept
Reports whether a register holds the return address.
Definition dwarf_abi.hpp:386
uint64_t register_type
Register value width.
Definition dwarf_abi.hpp:363
static constexpr uintptr_t normalize_pc(uintptr_t raw_ra) noexcept
Definition dwarf_abi.hpp:394
DWARF unwind ABI traits for x86 (32-bit IA-32).
Definition dwarf_abi.hpp:315
static constexpr uintptr_t normalize_pc(uintptr_t raw_ra) noexcept
Definition dwarf_abi.hpp:351
static constexpr bool is_frame_pointer_register(uint32_t reg) noexcept
Reports whether a register is a frame pointer.
Definition dwarf_abi.hpp:349
uint32_t register_type
Register value width.
Definition dwarf_abi.hpp:317
static constexpr bool is_return_address_register(uint32_t reg) noexcept
Reports whether a register holds the return address.
Definition dwarf_abi.hpp:343