Skip to main content

Module linker

Module linker 

Source
Expand description

ELF → PVM2 (raw RV+C+custom-0 bytes) linker.

Pipeline:

  1. Concatenate code sections at their ELF vaddr offsets (typical LLD PIE output places each function in its own .text.<sym>).
  2. Resolve AUIPC pairs. Data references (an auipc paired with a load/store/addi of a low-memory address) fold to absolute lui+lo12 — data is relocated to its runtime address in [DATA_BASE, …) (the ELF’s [0, extent) data layout shifted up by DATA_BASE), unrelated to where code maps. Code references (R_RISCV_CALL_PLT and code-targeting PCREL_HI20) stay native auipc+jalr/addi: code is mapped at CODE_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).
  3. Replace standard ECALL markers. The guest convention is csrrw x0, 0x800/0x801, x0 followed by ecall; the marker slot becomes a NOP and the ecall a custom-0 ecall.jar / ecalli.
  4. 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. jalr targets are validated against that set at runtime; the linker never emits a trusted target table (the recompiler runs untrusted code).
  5. 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/jalr are standard PVM2 instructions and are accepted; x3/x4 are valid runtime GPRs but outside the hot-register ABI this linker emits.
  6. Emit Image with the raw code bytes in [Image::code], mapped read-only at the fixed CODE_BASE by the runtime. The recompiler consumes the raw bytes directly.

Functions§

link_elf
Link an RV ELF into a PVM2 [Image]. [Image::code] holds the raw RV+C+custom-0 bytes, mapped read-only at CODE_BASE by the runtime.