code wiki / _hdl_build / nx_dc_core.nx
nx_dc_core.nx source
↩ module page · 192 lines · 7212 B
1// nx_dc_core.nx -- DUAL-LANE COMPARE CORE (mainless; R1-T1-002). One corpus
2// program through BOTH toolchains, exit codes compared:
3// lane A = the CURRENT sovereign chain via the durable runner
4// (_offc/nx_sov_build_run.elf <name>; retry guard included)
5// lane B = the KNOWN-GOOD frozen compiler (_offc/nx_cc_known_good.elf,
6// benchmark/oracle use only per law) + the same nxasm + run
7// AGREE = same rc. DISAGREE = a finding (one lane computes wrong values --
8// the context-sensitive miscompile class this instrument exists to catch):
9// the source is COPIED to runtime/_hdl_build/_dgbug<idx>.nx (lane-buildable
10// by basename = ready-made T2 fix-corpus rows) + a DIFFBUG row. Lane rc
11// 3/4 (compile/asm fail) compares like any rc: both-fail-alike = AGREE
12// (consistent refusal), one-fails = DISAGREE (a divergence finding).
13// Findings are SUCCESS (exit 0 + rows); only unwritable logs are infra RED.
14// Per-idx scratch paths (/tmp/_dcb<idx>.s/.elf): same program = same bytes,
15// so rewrites are stale-tail-safe by determinism (LM-022 discipline).
16// license_tier: ORIGINAL
17
18import "nx_syscalls.nx"
19import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
20const K_MAGIC_4096: i64 = 4096
21const K_MAGIC_8192: i64 = 8192
22
23func dc_w(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 }
24// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
25// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
26// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
27// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
28func dc_wn(fd: i64, v: i64) -> i64 { nxi_fd(fd, v); return 0 }
29
30func dc_cat(dst: *u8, off: i64, s: *u8) -> i64 {
31 var i: i64 = 0
32 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 }
33 dst[off + i] = 0 as u8
34 return off + i
35}
36
37func dc_catn(dst: *u8, off: i64, v: i64) -> i64 {
38 var m: i64 = v
39 if m < 0 { m = 0 }
40 let t: *u8 = sys_mmap(28)
41 var k: i64 = 0
42 if m == 0 { t[0] = 48 as u8; k = 1 }
43 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
44 var o: i64 = off
45 var i: i64 = 0
46 while i < k { dst[o] = t[k - 1 - i]; o = o + 1; i = i + 1 }
47 dst[o] = 0 as u8
48 return o
49}
50
51// spawn elf w/ up to 2 args; stdout->rout fd if >=0, stderr muted; rc/128+sig
52func dc_spawn(elf: *u8, a1: *u8, a2: *u8, rout: i64) -> i64 {
53 let pid: i64 = sys_fork()
54 if pid == 0 {
55 let dn: i64 = sys_openat_wr("/dev/null" as *u8, 0x1a4)
56 if rout >= 0 { sys_dup3(rout, 1, 0) } else { if dn >= 0 { sys_dup3(dn, 1, 0) } }
57 if dn >= 0 { sys_dup3(dn, 2, 0) }
58 let argv: *i64 = sys_mmap(40) as *i64
59 argv[0] = elf as i64
60 argv[1] = a1 as i64
61 argv[2] = a2 as i64
62 argv[3] = 0
63 let envp: *i64 = sys_mmap(16) as *i64
64 envp[0] = 0
65 sys_execve(elf, argv, envp)
66 sys_exit(127)
67 }
68 let st: *i64 = sys_mmap(16) as *i64
69 sys_wait4(pid, st, 0)
70 let sig: i64 = st[0] & 0x7f
71 if sig != 0 { return 128 + sig }
72 return (st[0] >> 8) & 0xff
73}
74
75func dc_filesize(path: *u8) -> i64 {
76 let fd: i64 = sys_openat_rd(path)
77 if fd < 0 { return 0 }
78 let buf: *u8 = sys_mmap(K_MAGIC_4096)
79 var total: i64 = 0
80 var n: i64 = sys_read(fd, buf, K_MAGIC_4096)
81 while n > 0 { total = total + n; n = sys_read(fd, buf, K_MAGIC_4096) }
82 sys_close(fd)
83 return total
84}
85
86// lane A: the durable sovereign runner on a corpus basename
87func dc_lane_a(name: *u8) -> i64 {
88 let neg: i64 = 0 - 1
89 return dc_spawn("_offc/nx_sov_build_run.elf" as *u8, name, 0 as *u8, neg)
90}
91
92// lane B: known-good cc -> .s (retry the empty-.s quirk) -> nxasm -> run
93func dc_lane_b(src: *u8, spath: *u8, elfpath: *u8) -> i64 {
94 var sbytes: i64 = 0
95 var tries: i64 = 0
96 while tries < 4 {
97 let sfd: i64 = sys_openat_wr(spath, 0x1a4)
98 if sfd < 0 { return 0 - 1 }
99 let rc_c: i64 = dc_spawn("_offc/nx_cc_known_good.elf" as *u8, src, 0 as *u8, sfd)
100 sys_close(sfd)
101 sbytes = dc_filesize(spath)
102 if rc_c == 0 { if sbytes > 128 { tries = 4 } }
103 if tries != 4 { tries = tries + 1 }
104 }
105 if sbytes <= 128 { return 3 }
106 let neg: i64 = 0 - 1
107 let rc_a: i64 = dc_spawn("_offc/nxasm_x86_main.elf" as *u8, spath, elfpath, neg)
108 if rc_a != 0 { return 4 }
109 return dc_spawn(elfpath, 0 as *u8, 0 as *u8, neg)
110}
111
112func dc_copy(src: *u8, dst: *u8) -> i64 {
113 let buf: *u8 = sys_mmap(K_MAGIC_8192)
114 let fa: i64 = sys_openat_rd(src)
115 if fa < 0 { return 0 }
116 let fb: i64 = sys_openat_wr(dst, 0x1a4)
117 if fb < 0 { sys_close(fa); return 0 }
118 var n: i64 = sys_read(fa, buf, K_MAGIC_8192)
119 while n > 0 {
120 var off: i64 = 0
121 while off < n {
122 let w: i64 = sys_write(fb, buf + off, n - off)
123 if w <= 0 { off = n } else { off = off + w }
124 }
125 n = sys_read(fa, buf, K_MAGIC_8192)
126 }
127 sys_close(fa)
128 sys_close(fb)
129 return 1
130}
131
132// compare corpus program <prefix><idx>: rows to lfd+stdout.
133// returns 0 AGREE, 1 DISAGREE (repro filed), negative infra failure.
134func dc_one(prefix: *u8, idx: i64, lfd: i64) -> i64 {
135 let nm: *u8 = sys_mmap(96)
136 var o: i64 = dc_cat(nm, 0, prefix)
137 o = dc_catn(nm, o, idx)
138 let src: *u8 = sys_mmap(256)
139 var so: i64 = dc_cat(src, 0, "runtime/_hdl_build/" as *u8)
140 so = dc_cat(src, so, nm)
141 so = dc_cat(src, so, ".nx" as *u8)
142 let spath: *u8 = sys_mmap(128)
143 var po: i64 = dc_cat(spath, 0, "/tmp/_dcb" as *u8)
144 po = dc_catn(spath, po, idx)
145 po = dc_cat(spath, po, ".s" as *u8)
146 let epath: *u8 = sys_mmap(128)
147 po = dc_cat(epath, 0, "/tmp/_dcb" as *u8)
148 po = dc_catn(epath, po, idx)
149 po = dc_cat(epath, po, ".elf" as *u8)
150
151 let ra: i64 = dc_lane_a(nm)
152 let rb: i64 = dc_lane_b(src, spath, epath)
153 if rb < 0 { return 0 - 1 }
154
155 var verdict: *u8 = "AGREE" as *u8
156 var dis: i64 = 0
157 if ra != rb { verdict = "DISAGREE" as *u8; dis = 1 }
158 var p: i64 = 0
159 while p < 2 {
160 var fd: i64 = 1
161 if p == 1 { fd = lfd }
162 if fd >= 0 {
163 dc_w(fd, "DIFFCMP idx=" as *u8); dc_wn(fd, idx)
164 dc_w(fd, " rcA=" as *u8); dc_wn(fd, ra)
165 dc_w(fd, " rcB=" as *u8); dc_wn(fd, rb)
166 dc_w(fd, " verdict=" as *u8); dc_w(fd, verdict)
167 dc_w(fd, "\n" as *u8)
168 }
169 p = p + 1
170 }
171 if dis == 1 {
172 let bug: *u8 = sys_mmap(256)
173 var bo: i64 = dc_cat(bug, 0, "runtime/_hdl_build/_dgbug" as *u8)
174 bo = dc_catn(bug, bo, idx)
175 bo = dc_cat(bug, bo, ".nx" as *u8)
176 dc_copy(src, bug)
177 var p2: i64 = 0
178 while p2 < 2 {
179 var fd2: i64 = 1
180 if p2 == 1 { fd2 = lfd }
181 if fd2 >= 0 {
182 dc_w(fd2, "DIFFBUG idx=" as *u8); dc_wn(fd2, idx)
183 dc_w(fd2, " rcA=" as *u8); dc_wn(fd2, ra)
184 dc_w(fd2, " rcB=" as *u8); dc_wn(fd2, rb)
185 dc_w(fd2, " repro=" as *u8); dc_w(fd2, bug)
186 dc_w(fd2, "\n" as *u8)
187 }
188 p2 = p2 + 1
189 }
190 }
191 return dis
192}