glebpom opened PR #13975 from glebpom:jit-x64-far-call-veneers to bytecodealliance:main:
Summary
Route out-of-range x86_64 direct calls and tail jumps in
cranelift-jit
through veneers.No prior issue or external discussion.
Motivation
X86CallPCRel4uses a signed 32-bit PC-relative displacement. A custom
JITMemoryProvidermay place separately allocated functions more than ±2 GiB
apart, causing relocation processing to panic when converting the displacement
toi32.AArch64 already handles the corresponding situation by routing an out-of-range
call through a veneer. This applies the same approach to x86_64.Implementation
- Reserve a worst-case veneer slot for each
X86CallPCRel4relocation.Redirect out-of-range calls and tail jumps through a
jmp qword ptr [rip]veneer containing the absolute target address.Use an exact 16-byte veneer slot, sufficient for both AArch64 and x86_64.
Reserve
X86CallPCRel4for control transfers by changing RIP-relative
address materialization to useX86PCRel4.Teach the x86_64 text-section builder to resolve
X86PCRel4relocations.- Fix the AArch64 veneer bounds assertion.
- Update x86_64 filetest and object-relocation expectations.
This does not add long-range support for
X86PCRel4address materialization.
Those relocations still require the target to be withinrel32range; a branch
veneer cannot preserve the semantics of an address-producing instruction.Testing
The JIT integration test uses a custom memory provider to place functions on
opposite sides of a reserved address range. It covers:
- A compiler-generated call with a negative out-of-range displacement.
- A tail jump with a positive out-of-range displacement.
- A mixture of one near and two far calls.
- Multiple densely packed veneers.
- Veneer instructions, absolute targets, and allocation sizing.
- Execution of the resulting JIT code.
Additional tests verify:
LoadExtNameemitsX86PCRel4.MachTextSectionBuilderresolves that relocation correctly.ELF, Mach-O, and COFF objects use non-branch relocations for address
materialization.Updated x86_64 filetest output.
Commands run:
cargo test -p cranelift-codegen --libcargo test -p cranelift-jitcargo test -p cranelift-objectcargo test -p cranelift-tools --test filetests -- --nocapturecargo clippy -p cranelift-codegen -p cranelift-jit -p cranelift-object --tests -- -D warningscargo fmt --all -- --checkAI-assisted development
Claude Code assisted with the initial implementation. OpenAI Codex assisted
with auditing the fix, recovering and evaluating stashed work, strengthening
the tests, and validating the final changes.All AI-assisted code and text were reviewed by the human contributor, who
understands the changes and accepts full responsibility for the contribution.
glebpom edited PR #13975:
Summary
Route out-of-range x86_64 direct calls and tail jumps in
cranelift-jit
through veneers.No prior issue or external discussion.
Motivation
Fixes #4000.
X86CallPCRel4uses a signed 32-bit PC-relative displacement. As reported in
#4000, separately allocated JIT functions can be placed more than ±2 GiB apart,
causingfinalize_definitionsto panic when the relocation displacement cannot
be converted toi32.The problem was also observed in a real workload in Nervix while compiling Roto
UDFs. The CI run intermittently failed with bothTryFromIntError(NegOverflow)
andTryFromIntError(PosOverflow):
https://github.com/nervix-io/nervix/actions/runs/30129378927/job/89600292950?pr=57#step:17:56674Issue #4000 suggested veneers as a possible solution. AArch64 already uses them
for out-of-range calls, so this change applies the same approach to x86_64.Implementation
- Reserve a worst-case veneer slot for each
X86CallPCRel4relocation.Redirect out-of-range calls and tail jumps through a
jmp qword ptr [rip]veneer containing the absolute target address.Use an exact 16-byte veneer slot, sufficient for both AArch64 and x86_64.
Reserve
X86CallPCRel4for control transfers by changing RIP-relative
address materialization to useX86PCRel4.Teach the x86_64 text-section builder to resolve
X86PCRel4relocations.- Fix the AArch64 veneer bounds assertion.
- Update x86_64 filetest and object-relocation expectations.
This does not add long-range support for
X86PCRel4address materialization.
Those relocations still require the target to be withinrel32range; a branch
veneer cannot preserve the semantics of an address-producing instruction.Testing
The JIT integration test uses a custom memory provider to place functions on
opposite sides of a reserved address range. It covers:
- A compiler-generated call with a negative out-of-range displacement.
- A tail jump with a positive out-of-range displacement.
- A mixture of one near and two far calls.
- Multiple densely packed veneers.
- Veneer instructions, absolute targets, and allocation sizing.
- Execution of the resulting JIT code.
Additional tests verify:
LoadExtNameemitsX86PCRel4.MachTextSectionBuilderresolves that relocation correctly.ELF, Mach-O, and COFF objects use non-branch relocations for address
materialization.Updated x86_64 filetest output.
Commands run:
cargo test -p cranelift-codegen --libcargo test -p cranelift-jitcargo test -p cranelift-objectcargo test -p cranelift-tools --test filetests -- --nocapturecargo clippy -p cranelift-codegen -p cranelift-jit -p cranelift-object --tests -- -D warningscargo fmt --all -- --checkAI-assisted development
Claude Code assisted with the initial implementation. OpenAI Codex assisted
with auditing the fix, recovering and evaluating stashed work, strengthening
the tests, and validating the final changes.All AI-assisted code and text were reviewed by the human contributor, who
understands the changes and accepts full responsibility for the contribution.
glebpom has marked PR #13975 as ready for review.
glebpom requested wasmtime-compiler-reviewers for a review on PR #13975.
glebpom requested fitzgen for a review on PR #13975.
github-actions[bot] added the label cranelift on PR #13975.
github-actions[bot] added the label cranelift:module on PR #13975.
github-actions[bot] added the label cranelift:area:x64 on PR #13975.
glebpom converted PR #13975 cranelift-jit: route out-of-range x86_64 calls through veneers to a draft.
Last updated: Jul 29 2026 at 05:03 UTC