nx_sovereign_runner.nx source
↩ module page · 98 lines · 3206 B
1// nx_sovereign_runner.nx -- read an ELF off disk via OUR fs primitive,
2// load it into OUR simulator, step every instruction in NishiLang.
3//
4// Demonstrates the full sovereign chain operating on a real file:
5// sys_read_file (NishiLang) read ELF bytes from disk
6// nx_loader_load (NishiLang) parse + place segments
7// nx_rv64_cpu_new (NishiLang) initialize CPU
8// nx_rv64_run (NishiLang) step every instruction
9//
10// Hardcoded path "/tmp/nx_sov_inner.elf" — caller stages the file
11// there before invoking. Once nx_argv is hooked up to main(), the
12// path becomes argv[1].
13//
14// Exits with:
15// 0 = ran successfully, propagates inner.exit_code via sys_exit
16// (so smoke script sees the inner program's exit code directly)
17// 1 = file read failed
18// 2 = loader rejected
19// 3 = simulator step error
20// 4 = simulator did not halt
21
22// nx_safety_envelope:
23// intended_use: AUTO_APPLIED -- primitive-specific tuning queued
24// sil_target: SIL1
25// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail]
26// verdict: NOT_YET_EVALUATED
27
28import "syscalls.nx"
29import "nx_loader.nx"
30import "nx_rv64_sim.nx"
31const K_MAGIC_16777216: i64 = 16777216
32const K_MAGIC_10000000: i64 = 10000000
33
34func main() -> i64 {
35 let path: *u8 = "/tmp/nx_sov_inner.elf"
36 let len_p: *i64 = (sys_mmap(8)) as *i64
37 len_p[0] = 0
38 let elf: *u8 = sys_read_file(path, len_p)
39 if elf == (0 as *u8) {
40 sys_write(2, "sovrun: read failed\n" as *u8, 20)
41 return 1
42 }
43 if len_p[0] <= 0 {
44 sys_write(2, "sovrun: empty file\n" as *u8, 19)
45 return 1
46 }
47
48 // 16 MB sim memory. Inner programs we run today fit easily.
49 let mem_size: i64 = K_MAGIC_16777216
50 let mem: *u8 = sys_mmap(mem_size)
51 let entry: i64 = nx_loader_load(elf, len_p[0], mem, mem_size)
52 if entry <= 0 {
53 sys_write(2, "sovrun: loader rejected\n" as *u8, 24)
54 return 2
55 }
56
57 let cpu: *NxRv64Cpu = nx_rv64_cpu_new(mem, mem_size, entry)
58 nx_rv64_cpu_set_sp(cpu, mem_size - 64)
59 // Generous cycle cap; theorem tests run thousands of insns.
60 let r: i64 = nx_rv64_run(cpu, K_MAGIC_10000000)
61 if r != 0 {
62 sys_write(2, "sovrun: step error\n" as *u8, 19)
63 return 3
64 }
65 if cpu.halted != 1 {
66 sys_write(2, "sovrun: cycle budget exceeded\n" as *u8, 30)
67 return 4
68 }
69
70 // Propagate inner exit code to outer process so smoke script sees it.
71 // Write the i64 exit_code value via a tiny manual decimal print.
72 sys_write(2, "sovrun: inner exited with code " as *u8, 31)
73 let digits: *u8 = sys_mmap(24)
74 var v: i64 = cpu.exit_code
75 if v < 0 { v = -v }
76 if v == 0 {
77 digits[0] = 48
78 sys_write(2, digits, 1)
79 }
80 if v > 0 {
81 var d: i64 = 0
82 while v > 0 {
83 digits[d] = (v - (v / 10) * 10) + 48
84 v = v / 10
85 d = d + 1
86 }
87 let rev: *u8 = sys_mmap(24)
88 var j: i64 = 0
89 while j < d {
90 rev[j] = digits[d - 1 - j]
91 j = j + 1
92 }
93 sys_write(2, rev, d)
94 }
95 sys_write(2, "\n" as *u8, 1)
96 let ec: i64 = cpu.exit_code
97 return ec
98}