code wiki / (root) / nx_chkarith_gate.nx

nx_chkarith_gate.nx source

↩ module page · 169 lines · 8729 B

1// nx_chkarith_gate.nx -- GATE for LN1 checked integer arithmetic (lang.plan rung LN1, symbol 2// chk_add_overflow). The rung's done-rule: i64 add and mul trap or refuse on overflow under a 3// declared mode (--chkarith); an overflowing add TRAPS; an in-range program is byte-identical 4// to today under the default (nothing is emitted unless the flag is on -- the equivalence net 5// nx_cc_equiv_gate is the byte ruler for that half, this gate is the behaviour ruler). 6// Subjects: the toolchain compiler (argv[1], default the live builder) + runtime/nx_checked_arith.nx 7// + runtime/nx_checked_arith_const.nx. 8// 9// Driver = nx_ccgate_lib (the ONE compiler-gate driver, extracted from the LN3 gate): data captures in 10// /tmp/nxchk/, RUNNABLES under _build/ (NAS /tmp is noexec), per-pid paths, phase exit codes PRINTED 11// before the teeth. 12// 13// Usage: nx_chkarith_gate [compiler_elf] (CWD = the tree root, like nx_cc_equiv_gate) 14// license_tier: ORIGINAL No hw writes (Rule 26). 15import "nx_syscalls.nx" 16import "nx_gate_verdict.nx" 17import "nx_ccgate_lib.nx" 18 19const CG_TRAP: i64 = 72 // NX_TRAP_OVERFLOW -- the injected trap's exit_group code 20 21func main(argc: i64, argv: *i64) -> i64 { 22 var cc: *u8 = "_offc/nx_cc_sovereign.elf\x00" 23 if argc >= 2 { cc = argv[1] as *u8 } 24 let CG_FLAG_CHKARITH: *u8 = "--chkarith\x00" 25 ccg_anchor_root() 26 sys_mkdir("/tmp/nxchk\x00" as *u8, CCG_MODE_X) 27 let pid: i64 = ccg_pid() 28 29 let p_ds: *u8 = ccg_path("/tmp/nxchk/d_\x00" as *u8, pid, ".s\x00" as *u8) 30 let p_de: *u8 = ccg_path("/tmp/nxchk/d_\x00" as *u8, pid, ".err\x00" as *u8) 31 let p_delf: *u8 = ccg_path("_build/nxchk_d_\x00" as *u8, pid, ".elf\x00" as *u8) 32 let p_cs: *u8 = ccg_path("/tmp/nxchk/c_\x00" as *u8, pid, ".s\x00" as *u8) 33 let p_ce: *u8 = ccg_path("/tmp/nxchk/c_\x00" as *u8, pid, ".err\x00" as *u8) 34 let p_celf: *u8 = ccg_path("_build/nxchk_c_\x00" as *u8, pid, ".elf\x00" as *u8) 35 let p_kds: *u8 = ccg_path("/tmp/nxchk/kd_\x00" as *u8, pid, ".s\x00" as *u8) 36 let p_kde: *u8 = ccg_path("/tmp/nxchk/kd_\x00" as *u8, pid, ".err\x00" as *u8) 37 let p_kdelf: *u8 = ccg_path("_build/nxchk_kd_\x00" as *u8, pid, ".elf\x00" as *u8) 38 let p_kcs: *u8 = ccg_path("/tmp/nxchk/kc_\x00" as *u8, pid, ".s\x00" as *u8) 39 let p_kce: *u8 = ccg_path("/tmp/nxchk/kc_\x00" as *u8, pid, ".err\x00" as *u8) 40 let p_kcelf: *u8 = ccg_path("_build/nxchk_kc_\x00" as *u8, pid, ".elf\x00" as *u8) 41 let p_asm: *u8 = ccg_path("_build/nxchk_asm_\x00" as *u8, pid, ".elf\x00" as *u8) 42 let p_wds: *u8 = ccg_path("/tmp/nxchk/wd_\x00" as *u8, pid, ".s\x00" as *u8) 43 let p_wde: *u8 = ccg_path("/tmp/nxchk/wd_\x00" as *u8, pid, ".err\x00" as *u8) 44 let p_wdelf: *u8 = ccg_path("_build/nxchk_wd_\x00" as *u8, pid, ".elf\x00" as *u8) 45 let p_wks: *u8 = ccg_path("/tmp/nxchk/wk_\x00" as *u8, pid, ".s\x00" as *u8) 46 let p_wke: *u8 = ccg_path("/tmp/nxchk/wk_\x00" as *u8, pid, ".err\x00" as *u8) 47 let p_wkelf: *u8 = ccg_path("_build/nxchk_wk_\x00" as *u8, pid, ".elf\x00" as *u8) 48 49 let ctr: *i64 = gv_ctr() 50 gv_head("=== nx_chkarith_gate -- LN1 checked integer arithmetic: --chkarith traps i64 + - * overflow (72), accepts in-range, exempts __wrap_*, refuses const overflow at compile time ===" as *u8) 51 52 let fix: *u8 = "runtime/nx_checked_arith.nx\x00" 53 let cfx: *u8 = "runtime/nx_checked_arith_const.nx\x00" 54 let wfx: *u8 = "runtime/nx_checked_arith_wrap.nx\x00" 55 56 // -- default-mode builds: the hazard record (everything wraps and survives) -- 57 let bd: i64 = ccg_build(cc, 0 as *u8, fix, p_ds, p_delf, p_de, p_asm) 58 var t1: i64 = 0 59 if bd == 0 { t1 = 1 } 60 gv_check("T1 fixture-compiles-under-default (organ is a normal citizen of the tree)" as *u8, t1, ctr) 61 var d_ok: i64 = 0 - 1 62 var d_add: i64 = 0 - 1 63 var d_sub: i64 = 0 - 1 64 var d_mul: i64 = 0 - 1 65 var d_mm: i64 = 0 - 1 66 if bd == 0 { 67 d_ok = ccg_phase(p_delf, "ok\x00" as *u8) 68 d_add = ccg_phase(p_delf, "add\x00" as *u8) 69 d_sub = ccg_phase(p_delf, "sub\x00" as *u8) 70 d_mul = ccg_phase(p_delf, "mul\x00" as *u8) 71 d_mm = ccg_phase(p_delf, "mulmin\x00" as *u8) 72 } 73 // wrap-intrinsic witness, default mode -- its OWN build: a pre-LN1 compiler has no __wrap_*, 74 // and keeping it out of the main fixture is what makes the bite attributable tooth by tooth. 75 let bw: i64 = ccg_build(cc, 0 as *u8, wfx, p_wds, p_wdelf, p_wde, p_asm) 76 var d_wr: i64 = 0 - 1 77 if bw == 0 { d_wr = ccg_phase(p_wdelf, "x\x00" as *u8) } 78 ccg_val("d_build_rc" as *u8, bd) 79 ccg_val("w_build_rc" as *u8, bw) 80 ccg_val("d_ok_exit" as *u8, d_ok) 81 ccg_val("d_add_exit" as *u8, d_add) 82 ccg_val("d_sub_exit" as *u8, d_sub) 83 ccg_val("d_mul_exit" as *u8, d_mul) 84 ccg_val("d_mulmin_exit" as *u8, d_mm) 85 ccg_val("d_wrap_exit" as *u8, d_wr) 86 var t2: i64 = 0 87 if d_ok == 0 { t2 = 1 } 88 gv_check("T2 default-inrange-control-exit0" as *u8, t2, ctr) 89 var t3: i64 = 0 90 if d_add == 0 { t3 = 1 } 91 gv_check("T3 neg-control-default-ADD-wraps-and-survives (anti-vacuity: the add T9 must trap demonstrably executes and wraps to MIN)" as *u8, t3, ctr) 92 var t4: i64 = 0 93 if d_sub == 0 { t4 = 1 } 94 gv_check("T4 neg-control-default-SUB-wraps-and-survives" as *u8, t4, ctr) 95 var t5: i64 = 0 96 if d_mul == 0 { t5 = 1 } 97 gv_check("T5 neg-control-default-MUL-wraps-to-zero-and-survives" as *u8, t5, ctr) 98 var t6: i64 = 0 99 if d_mm == 0 { t6 = 1 } 100 gv_check("T6 neg-control-default-MIN-times-minus1-wraps-and-survives" as *u8, t6, ctr) 101 var t7: i64 = 0 102 if d_wr == 0 { t7 = 1 } 103 gv_check("T7 default-wrap-intrinsics-reproduce-wrapped-values" as *u8, t7, ctr) 104 105 // -- chkarith-mode builds -- 106 let bk: i64 = ccg_build(cc, CG_FLAG_CHKARITH, fix, p_kds, p_kdelf, p_kde, p_asm) 107 var t8: i64 = 0 108 if bk == 0 { t8 = 1 } 109 gv_check("T8 fixture-compiles-under-chkarith (runtime legs are legal source either mode)" as *u8, t8, ctr) 110 var k_ok: i64 = 0 - 1 111 var k_add: i64 = 0 - 1 112 var k_sub: i64 = 0 - 1 113 var k_mul: i64 = 0 - 1 114 var k_mm: i64 = 0 - 1 115 if bk == 0 { 116 k_ok = ccg_phase(p_kdelf, "ok\x00" as *u8) 117 k_add = ccg_phase(p_kdelf, "add\x00" as *u8) 118 k_sub = ccg_phase(p_kdelf, "sub\x00" as *u8) 119 k_mul = ccg_phase(p_kdelf, "mul\x00" as *u8) 120 k_mm = ccg_phase(p_kdelf, "mulmin\x00" as *u8) 121 } 122 let bwk: i64 = ccg_build(cc, CG_FLAG_CHKARITH, wfx, p_wks, p_wkelf, p_wke, p_asm) 123 var k_wr: i64 = 0 - 1 124 if bwk == 0 { k_wr = ccg_phase(p_wkelf, "x\x00" as *u8) } 125 ccg_val("k_build_rc" as *u8, bk) 126 ccg_val("wk_build_rc" as *u8, bwk) 127 ccg_val("k_ok_exit" as *u8, k_ok) 128 ccg_val("k_add_exit" as *u8, k_add) 129 ccg_val("k_sub_exit" as *u8, k_sub) 130 ccg_val("k_mul_exit" as *u8, k_mul) 131 ccg_val("k_mulmin_exit" as *u8, k_mm) 132 ccg_val("k_wrap_exit" as *u8, k_wr) 133 var t9: i64 = 0 134 if k_ok == 0 { t9 = 1 } 135 gv_check("T9 chkarith-inrange-control-exit0 (a deny mode that refuses everything fails HERE; every checker branch taken in-range in one program)" as *u8, t9, ctr) 136 var t10: i64 = 0 137 if k_add == CG_TRAP { t10 = 1 } 138 gv_check("T10 chkarith-ADD-overflow-traps-72 (CWE-190, the rung's done-rule)" as *u8, t10, ctr) 139 var t11: i64 = 0 140 if k_sub == CG_TRAP { t11 = 1 } 141 gv_check("T11 chkarith-SUB-overflow-traps-72" as *u8, t11, ctr) 142 var t12: i64 = 0 143 if k_mul == CG_TRAP { t12 = 1 } 144 gv_check("T12 chkarith-MUL-overflow-traps-72" as *u8, t12, ctr) 145 var t13: i64 = 0 146 if k_mm == CG_TRAP { t13 = 1 } 147 gv_check("T13 chkarith-MIN-times-minus1-traps-72-not-SIGFPE (the checker's own division is branched around)" as *u8, t13, ctr) 148 var t14: i64 = 0 149 if k_wr == 0 { t14 = 1 } 150 gv_check("T14 chkarith-wrap-intrinsics-exempt-exit0 (__wrap_add/sub/mul do not trap)" as *u8, t14, ctr) 151 152 // -- compile-time leg -- 153 let cd: i64 = ccg_build(cc, 0 as *u8, cfx, p_cs, p_celf, p_ce, p_asm) 154 var t15: i64 = 0 155 if cd == 0 { t15 = 1 } 156 gv_check("T15 neg-control-const-overflow-compiles-under-default (the hazard record still builds)" as *u8, t15, ctr) 157 let ck: i64 = ccg_build(cc, CG_FLAG_CHKARITH, cfx, p_kcs, p_kcelf, p_kce, p_asm) 158 ccg_val("cd_build_rc" as *u8, cd) 159 ccg_val("ck_build_rc" as *u8, ck) 160 var t16: i64 = 0 161 if ck != 0 { t16 = 1 } 162 gv_check("T16 chkarith-const-overflow-refused-at-compile-time" as *u8, t16, ctr) 163 let t17: i64 = ccg_file_has(p_kce, "capability=checked-arith-const-overflow\x00" as *u8) 164 gv_check("T17 refusal-names-the-checked-arith-rule (not some other error wearing the refusal)" as *u8, t17, ctr) 165 166 let rc: i64 = gv_verdict("CHKARITH-LN1" as *u8, ctr, "chkarith declared mode" as *u8) 167 sys_exit(rc) 168 return rc 169}