kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit b741e2c5b1dfa6bffa2e0a4a4723e602d8919208
parent 85b11149946e7dc2f7f1a039aa3e4c389be4c962
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Fri, 29 May 2026 13:36:15 -0700

x64/rv64: emit named parameters and locals in .debug_info

Both backends set frame_slot_debug_loc = NULL, so the shared producer's
nd_local_debug_loc returned 0 and api_debug_emit_source_locals skipped every
parameter and local: x64/rv64 -g objects had DW_TAG_formal_parameter DIEs
with only DW_AT_type (no name, no location) and zero DW_TAG_variable DIEs, so
gdb/lldb could not print arguments or locals by name. Only aa64 implemented
the hook (doc/DBG_TODO.md:153 tracked bringing x64/rv64 to parity).

Implement x64_frame_slot_debug_loc and rv_frame_slot_debug_loc as mirrors of
aa_frame_slot_debug_loc, reporting the frame-pointer-relative slot offset
(x64: -off off RBP; rv64: rv_s0_off_slot off s0) — the same convention aa64
uses and that the hosted dbg snapshot consumes (frame base seeded to the FP
register).

Verified: x64/rv64 -g now emit named params a/b and locals x/y with
DW_OP_fbreg locations, byte-identical to aa64 (only DW_AT_high_pc differs,
reflecting per-arch code size). test-debug + test-dbg green.

Diffstat:
Msrc/arch/rv64/native.c | 18+++++++++++++++++-
Msrc/arch/x64/native.c | 18+++++++++++++++++-
2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/src/arch/rv64/native.c b/src/arch/rv64/native.c @@ -1190,6 +1190,22 @@ static NativeFrameSlot rv_frame_slot(NativeTarget* t, return native_frame_slot_alloc(&rv_of(t)->frame, d); } +static int rv_frame_slot_debug_loc(NativeTarget* t, NativeFrameSlot slot, + CGDebugLoc* out) { + RvNativeTarget* a = rv_of(t); + RvNativeSlot* s; + if (!out) return 0; + memset(out, 0, sizeof *out); + if (slot == NATIVE_FRAME_SLOT_NONE || slot > a->frame.nslots) return 0; + s = rv_slot_get(a, slot); + out->kind = CG_DEBUG_LOC_FRAME; + /* rv64 slots are addressed s0/fp-relative (rv_s0_off_slot); the hosted dbg + * snapshot seeds the frame base with s0, matching aa64's FP-relative + * convention. */ + out->v.frame_ofs = rv_s0_off_slot(s); + return 1; +} + static void rv_func_begin_common(NativeTarget* t, const CGFuncDesc* fd) { RvNativeTarget* a = rv_of(t); MCEmitter* mc = t->mc; @@ -3216,7 +3232,7 @@ NativeTarget* rv64_native_target_new(Compiler* c, ObjBuilder* obj, t->store_zero_reg = RV_ZERO; t->func_end = rv_func_end; t->frame_slot = rv_frame_slot; - t->frame_slot_debug_loc = NULL; + t->frame_slot_debug_loc = rv_frame_slot_debug_loc; t->bind_param = rv_bind_native_param; t->label_new = rv_label_new; t->label_place = rv_label_place; diff --git a/src/arch/x64/native.c b/src/arch/x64/native.c @@ -1369,6 +1369,22 @@ static NativeFrameSlot x64_frame_slot(NativeTarget* t, return native_frame_slot_alloc(&x64_of(t)->frame, d); } +static int x64_frame_slot_debug_loc(NativeTarget* t, NativeFrameSlot slot, + CGDebugLoc* out) { + X64NativeTarget* a = x64_of(t); + X64NativeSlot* s; + if (!out) return 0; + memset(out, 0, sizeof *out); + if (slot == NATIVE_FRAME_SLOT_NONE || slot > a->frame.nslots) return 0; + s = x64_slot_get(a, slot); + out->kind = CG_DEBUG_LOC_FRAME; + /* x64 slots live at RBP - off (exactly how the memory-operand path addresses + * them). The hosted dbg snapshot seeds the frame base with RBP, so report + * the RBP-relative offset — mirroring aa64's FP-relative convention. */ + out->v.frame_ofs = -(i32)s->off; + return 1; +} + /* xmm save area base (rbp-relative). XMM saves are 16-aligned. */ static u32 x64_xmm_base(const X64NativeTarget* a, u32 cs_fp) { if (cs_fp == 0) return a->frame.cum_off; @@ -3747,7 +3763,7 @@ NativeTarget* x64_native_target_new(Compiler* c, ObjBuilder* obj, t->has_store_zero_reg = 0; t->func_end = x64_func_end; t->frame_slot = x64_frame_slot; - t->frame_slot_debug_loc = NULL; + t->frame_slot_debug_loc = x64_frame_slot_debug_loc; t->bind_param = x64_bind_native_param; t->label_new = x64_label_new; t->label_place = x64_label_place;