kit

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

commit b930f6ac494f8af3d271859633d313b6729238b6
parent ae86141c1caddb69705fdacbbbd3419e822cbdb9
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Fri, 29 May 2026 13:58:30 -0700

rv64 link: route far calls through JIT call stubs

rv64's LinkArchDesc left needs_jit_call_stub NULL, so the JIT call-stub pass
(layout_jit_call_stubs) returned early and never redirected calls. A direct
R_RV_CALL (AUIPC+JALR) reaches only +/-2GiB, so an external SK_ABS target (a
host libc symbol at an arbitrary address) farther than that from the JIT code
region made link_reloc_apply panic 'RV CALL out of range' instead of routing
through a stub. aa64 (CALL26, +/-128MiB) and x64 both wire this safety net.

Add rv64_is_branch_reloc (R_RV_CALL/R_PLT32) and set needs_jit_call_stub. No
new stub emitter is needed: the existing rv64_emit_iplt_stub (AUIPC+LD+JR)
reaches an arbitrary host address via its in-image slot, which is what the
generic stub pass uses. test-rv64-jit + test-smoke-rv64 + test-link green.

Diffstat:
Msrc/arch/rv64/link.c | 12++++++++++++
1 file changed, 12 insertions(+), 0 deletions(-)

diff --git a/src/arch/rv64/link.c b/src/arch/rv64/link.c @@ -75,6 +75,17 @@ static u32 rv64_emit_iplt_stub(u8* dst, u64 stub_vaddr, u64 slot_vaddr, return 0u; } +/* A direct rv64 call (R_RV_CALL = AUIPC+JALR) reaches only ±2GiB. In the JIT, + * an external SK_ABS target (a host libc symbol resolved to an arbitrary + * address) can lie farther than that from the JIT-allocated code region, where + * link_reloc_apply would panic "RV CALL out of range". Reporting these as + * branch relocs routes them through the JIT call-stub pass, which reuses + * emit_iplt_stub (AUIPC+LD+JR) to reach an arbitrary address held in an + * in-image slot — the same safety net aa64 and x64 already wire. */ +static int rv64_is_branch_reloc(RelocKind kind) { + return kind == R_RV_CALL || kind == R_PLT32; +} + const LinkArchDesc link_arch_rv64 = { .plt0_size = RV64_PLT0_SIZE, .plt_entry_size = RV64_PLT_ENTRY_SIZE, @@ -84,4 +95,5 @@ const LinkArchDesc link_arch_rv64 = { .emit_plt0 = rv64_emit_plt0, .emit_plt_entry = rv64_emit_plt_entry, .emit_iplt_stub = rv64_emit_iplt_stub, + .needs_jit_call_stub = rv64_is_branch_reloc, };