Repository navigation
v5.0.0 — Self-hosted toolchain (Linux ELF substrate)
Rail produces its own aarch64 Linux ELF binaries. Encoder, assembler, static linker, and ELF writer are pure Rail. For the supported subset of inputs, the build pipeline invokes no external as, ld, or codesign.
What ships
| Module | Lines | Role |
|---|---|---|
jit/arm64.rail |
+200 | 23 new encoders for the Linux mnemonic set (ldrb/strb imm/reg-offset/post-index, clz, neg, cmn imm+reg, rev, rev16, fneg, frinta, fcvt s_d / d_s, tbnz, stp/ldp pre/post-index, add/sub imm, asr/lsr/lsl imm). 31/31 byte-verified against as. |
stdlib/elf.rail |
175 | Elf64 writer for static aarch64 binaries (one PT_LOAD for tiny, three for full text+data+bss-via-memsz). |
tools/v5/elf_asm.rail |
567 | Section-aware ARM64 assembler + static linker. Two-pass: pass 1 builds (name, section, offset) label table; layout resolves to vaddrs; pass 2 emits bytes with adrp/:lo12: symbol resolution. Handles .text/.data/.bss/.rodata/.section __DATA,__mod_init_func (skipped), .quad/.byte/.long/.ascii/.asciz/.space/.comm/.p2align/.align, plus writeback stp/ldp variants and the adrp+add :lo12: symbol-load idiom. |
tools/v5/compile_elf_full.rail |
80 | Driver: source .s → 3-pass pipeline → multi-segment ELF. Patches e_entry to _start. |
End-to-end verified on aarch64 Linux (Pi Zero 2 W)
| Program | ELF size | Result |
|---|---|---|
exit42_linux.s |
132 B | exit 42 |
fib_linux.s |
204 B | exit(fib(10)) = 55 |
hello_linux.s |
4105 B | prints "v5 lives\n", exit 9 (adrp + add :lo12: + write syscall) |
bss_test_linux.s |
4096 B | BSS counter loop, exit 7 |
Each binary's .text bytes are byte-equivalent to canonical as + ld output. Pipeline invokes neither external assembler nor linker.
compile.rail Linux pipeline fixes (precursor)
Two long-standing bugs in build_linux fixed: duplicate-symbol awk strip ran only on macOS-cross (now runs on Linux too, list broadened to cover the _rail_* runtime helpers that linux_libc.s redefines), and the macOS-only .section __DATA,__mod_init_func block is now stripped. tools/linux_libc.s gains _memcpy and _fmod — the two libSystem references with no Linux-side definition.
Tag-readiness checklist
-
compile.rail's real Linux output traverses the new pipeline → byte-equivalent ELF - Linux ELF substrate verified on aarch64 hardware
- 176 encoders byte-verified against
as(89 + 56 + 31) - No regression on
./rail_native test(136/140; 4 pre-existing tensor failures) - No regression on
./rail_native selfbyte-identical fixed point - CHANGELOG.md v5.0.0 entry
- Leak guard CI green
Deferred
- Pi self-host of
./rail_native testvia Rail-only build — current GC layout reserves 1.2 GB BSS, exceeding Pi Zero 2 W RAM. Heap-size knob is v5.1 scope. - macOS Mach-O end-to-end with dyld stubs — Phase 4b covered the libSystem-free subset; stub-aware Mach-O (LC_LOAD_DYLIB, indirect symbol table, __stubs, __got, bind opcodes) is ~1500 more lines. Tracked as v5.2.
🤖 Generated with Claude Code