Expand description
ELF → PVM2 (raw RV+C+custom-0 bytes) linker.
Pipeline:
- Concatenate code sections at their ELF vaddr offsets (typical
LLD PIE output places each function in its own
.text.<sym>). - Resolve AUIPC pairs. Data references (an
auipcpaired with a load/store/addi of a low-memory address) fold to absolutelui+lo12 — data is relocated to its runtime address in[DATA_BASE, …)(the ELF’s[0, extent)data layout shifted up byDATA_BASE), unrelated to where code maps. Code references (R_RISCV_CALL_PLTand code-targetingPCREL_HI20) stay nativeauipc+jalr/addi: code is mapped atCODE_BASE, so the PC-relative computation lands on the right code VA. Kept pairs are re-encoded after step 4 if fallthrough injection shifts the layout (LUI is absolute, so injection-stable, and needs no fixup). - Replace standard ECALL markers. The guest convention is
csrrw x0, 0x800/0x801, x0followed byecall; the marker slot becomes a NOP and theecalla custom-0ecall.jar/ecalli. - Inject fallthrough markers before branch/jal/endpoint targets
that aren’t already post-terminator, so the predecoder’s strict
basic-block-start set — derived purely from the instruction stream
— covers every reachable jump target.
jalrtargets are validated against that set at runtime; the linker never emits a trusted target table (the recompiler runs untrusted code). - Validate producer output: no x3/x4 use, no remaining standard
ecall/ebreak, no CSR / atomic / FP / custom-1 / privileged encodings (see~/docs/pvm-isa/05-pvm2-rv-diff.md).auipc/jalrare standard PVM2 instructions and are accepted; x3/x4 are valid runtime GPRs but outside the hot-register ABI this linker emits. - Emit Image with the raw code bytes in [
Image::code], mapped read-only at the fixedCODE_BASEby the runtime. The recompiler consumes the raw bytes directly.