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:
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,
};