code wiki / (root) / nx_nxld.nx

nx_nxld.nx

buildroot/runtime/nx_nxld.nx

27171 B760 linesdepth 3pulls 3 transitivereach 1 importersview sourcekind tooltopic nxld
docsdependenciesstructsconstsfunctions

about

nxld.nx -- Nishi sovereign linker. Replaces gcc-ld in verify.sh. Reads RV64 object files (ELF relocatable), resolves symbols across them, and produces a statically-linked RV64 Linux ELF executable. Scope (v0.0.1): - Single-output static linking (no .so / dynamic linking) - RV64 only (Sv39 virtual memory layout) - ELF relocations: R_RISCV_64, R_RISCV_BRANCH, R_RISCV_JAL, R_RISCV_CALL, R_RISCV_HI20, R_RISCV_LO12_I, R_RISCV_LO12_S, R_RISCV_PCREL_HI20, R_RISCV_PCREL_LO12_I - Single .text section + single .data section + single .bss - Entry point = _start (RV64 Linux convention) - Output base vaddr = 0x10000 (matches elf_writer.nx) Out of scope (v0.0.1): - Section ordering directives - Linker scripts - LTO bytecode handling - Position-independent code - Garbage collection of unreferenced sections - Debug info preservation (DWARF stripped) These are deliberate v0.0.1 limits. v0.1.0 closes them. Pipeline: 1. Open + parse each input ELF (header, sections, symbols, relocs) 2. Group sections by type: .text, .data, .bss 3. Resolve undefined symbols across input objects 4. Lay out output sections (text starts at 0x10000 + 0x1000 header) 5. Apply relocations now that final addresses are known 6. Build output ELF (header + program headers + sections) 7. Write to output file

dependencies 2 imports · 1 importers

nx_syscalls.nx elf_writer.nx nx_nxld.nx nx_nxld_main.nx

imports: nx_syscalls.nxelf_writer.nx

imported by: nx_nxld_main.nx

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main sys_mmap nxld_open read_u16_le read_u64_le read_u32_le sec_name_eq nxld_symbol_count nxld_read_symbol nxld_symbol_count ↻ read_u32_le ↻ read_u16_le ↻ read_u64_le ↻ nxld_reloc_count nxld_read_reloc nxld_reloc_count ↻ read_u64_le ↻ nxld_layout nxld_apply_one patch_b_imm write_u32_le patch_j_imm split_hi20 split_lo12 split_hi20 ↻ patch_u_imm patch_i_imm patch_s_imm

structs

81struct ElfObject
102struct Symbol
347struct Reloc

consts

46const ELF_MAGIC0: i64 = 0x7F
47const ELF_MAGIC1: i64 = 0x45 // 'E'
48const ELF_MAGIC2: i64 = 0x4C // 'L'
49const ELF_MAGIC3: i64 = 0x46 // 'F'
50const EI_CLASS64: i64 = 2
51const EI_DATA2LSB: i64 = 1
52const ET_EXEC: i64 = 2
53const ET_REL: i64 = 1
54const EM_RISCV: i64 = 0xF3
56const SHT_NULL: i64 = 0
57const SHT_PROGBITS: i64 = 1
58const SHT_SYMTAB: i64 = 2
59const SHT_STRTAB: i64 = 3
60const SHT_RELA: i64 = 4
61const SHT_NOBITS: i64 = 8
63const PT_LOAD: i64 = 1
64const PF_R: i64 = 4
65const PF_W: i64 = 2
66const PF_X: i64 = 1
69const R_RISCV_64: i64 = 2
70const R_RISCV_BRANCH: i64 = 16
71const R_RISCV_JAL: i64 = 17
72const R_RISCV_CALL: i64 = 18
73const R_RISCV_PCREL_HI20: i64 = 23
74const R_RISCV_PCREL_LO12_I: i64 = 24
75const R_RISCV_HI20: i64 = 26
76const R_RISCV_LO12_I: i64 = 27
77const R_RISCV_LO12_S: i64 = 28
252const SYMBOL_BYTES: i64 = 24
253const STN_UNDEF: i64 = 0
254const STB_LOCAL: i64 = 0
255const STB_GLOBAL: i64 = 1
256const STB_WEAK: i64 = 2
257const STT_NOTYPE: i64 = 0
258const STT_OBJECT: i64 = 1
259const STT_FUNC: i64 = 2
260const STT_SECTION: i64 = 3
345const RELOC_BYTES: i64 = 24
578const NXLD_BASE_VADDR: i64 = 0x10000
579const NXLD_HEADER_BYTES: i64 = 120 // 64 ELF hdr + 56 phdr

functions

114func read_u16_le(buf: *u8, off: i64) -> i64
118func read_u32_le(buf: *u8, off: i64) -> i64
128func read_u64_le(buf: *u8, off: i64) -> i64
142func sec_name_eq(np: *u8, lit: *u8, lit_len: i64) -> i64
called by 1: nxld_open
154func nxld_open(obj: *ElfObject, base: *u8, length: i64) -> i64
264func nxld_symbol_count(obj: *ElfObject) -> i64
272func nxld_read_symbol(obj: *ElfObject, idx: i64, sym: *Symbol) -> i64
304func sym_name_eq(np: *u8, np_len: i64, lit: *u8, lit_len: i64) -> i64
called by 1: nxld_find_symbol
316func nxld_find_symbol(obj: *ElfObject, name: *u8, name_len: i64) -> i64
356func nxld_reloc_count(obj: *ElfObject) -> i64
363func nxld_read_reloc(obj: *ElfObject, idx: i64, r: *Reloc) -> i64
406func write_u32_le(buf: *u8, off: i64, v: i64) -> i64
called by 1: nxld_apply_one
416func patch_i_imm(word: i64, imm: i64) -> i64
called by 1: nxld_apply_one
424func patch_s_imm(word: i64, imm: i64) -> i64
called by 1: nxld_apply_one
432func patch_u_imm(word: i64, imm_hi: i64) -> i64
called by 1: nxld_apply_one
438func patch_j_imm(word: i64, imm: i64) -> i64
called by 1: nxld_apply_one
449func patch_b_imm(word: i64, imm: i64) -> i64
called by 1: nxld_apply_one
462func split_hi20(value: i64) -> i64
465func split_lo12(value: i64) -> i64
called by 1: nxld_apply_one calls 1: split_hi20
472func nxld_apply_one(r: *Reloc, text_buf: *u8, text_vaddr: i64,
581func nxld_layout(obj: *ElfObject, syms_pool: *Symbol, n_syms: i64,
called by 2: nxld_linkmain
675func main() -> i64