backtrace.h (2793B)
1 #ifndef KIT_DRIVER_BACKTRACE_H 2 #define KIT_DRIVER_BACKTRACE_H 3 4 #include <kit/arch.h> 5 #include <kit/core.h> 6 #include <kit/dwarf.h> 7 #include <kit/jit.h> 8 #include <stddef.h> 9 #include <stdint.h> 10 11 /* Frame-pointer-chain backtrace shared by `kit dbg` (fault stop + `bt`) and 12 * `kit run` (in-process crash guard). 13 * 14 * kit keeps a frame pointer on every backend and never omits it, so each 15 * prologue stores a uniform frame record — fp[0] = caller fp, fp[1] = saved 16 * return address (in units of void*). Walking that chain needs only a way to 17 * read target memory plus the frame-pointer register value; no .eh_frame, no 18 * CFI program (the CFI stepper, kit_dwarf_unwind_step, deliberately takes no 19 * memory provider and so cannot self-unwind a spilled return address). This is 20 * the same walk rt/lib/stack/backtrace.c performs in-process, lifted to the 21 * tool side with a caller-supplied memory reader. */ 22 23 /* The frame-pointer register's DWARF index for `arch` (aarch64 x29 = 29, 24 * x86-64 rbp = 6, riscv s0 = 8), or -1 if the arch keeps no walkable FP. */ 25 int driver_bt_fp_dwarf_reg(KitArchKind arch); 26 27 /* Pointer width in bytes for `arch` (8 for the 64-bit native targets, 4 for 28 * rv32), or 0 if unsupported. */ 29 int driver_bt_ptr_size(KitArchKind arch); 30 31 /* Advance one frame: given the current frame pointer `fp`, read the saved 32 * return address (fp[1]) and caller frame pointer (fp[0]) through `read`. 33 * Returns 1 and fills *ra_out / *next_fp_out for a valid caller frame; returns 34 * 0 at the chain terminator or on garbage (null/non-increasing/misaligned fp, 35 * null return address, or a failed read) — mirroring __kit_backtrace's guards. 36 */ 37 int driver_bt_fp_step(KitArchKind arch, KitDwarfReadMemFn read, void* read_user, 38 uint64_t fp, uint64_t* ra_out, uint64_t* next_fp_out); 39 40 /* Line sink: receives one NUL-terminated, newline-free frame line. */ 41 typedef void (*DriverBtEmit)(void* user, const char* line); 42 43 typedef struct DriverBtCtx { 44 KitJit* jit; /* optional: symbol names + runtime->image PC xlate */ 45 KitDebugInfo* dwarf; /* optional: file:line + func-name fallback */ 46 DriverBtEmit emit; /* line sink (required) */ 47 void* emit_user; 48 } DriverBtCtx; 49 50 /* Symbolize a captured list of return addresses (innermost first, as produced 51 * by the FP walk) and emit one line per frame via ctx->emit: 52 * #0 0x401136 <bt_leaf+0x12> at addr2line_prog.c:51:3 53 * Frames with no symbol/line degrade to "#N 0xADDR". Used by `kit run`, which 54 * must capture the chain inside its fault handler — before the post-longjmp 55 * stack is reused — and symbolize it afterward in normal context. */ 56 void driver_backtrace_print_pcs(const DriverBtCtx* ctx, const uint64_t* pcs, 57 int n); 58 59 #endif /* KIT_DRIVER_BACKTRACE_H */