code wiki / _hdl_build / nx_kill_portable.nx

nx_kill_portable.nx source

↩ module page · 29 lines · 1648 B

1// nx_kill_portable.nx -- kill(2) that works under BOTH compiler lanes. 2// 3// nx_syscalls' nx_kill hardcodes rv64 129 and relies on the SOVEREIGN 4// compiler's rv64->x86 __syscall translation (129->62). The C-bootstrap 5// compiler has NO translator, so 129 hits x86 rt_sigqueueinfo and fails 6// silently -- gates hung on wait4 of children that never died, daemons 7// leaked after every teardown (landmine #5, 2026-06-10). 8// 9// This helper uses the @ifdef pattern (same as SYS_GETDENTS64) so the kg 10// lane emits the raw x86 number. SOVEREIGN-RE-GATE NOTE: 62 collides 11// with rv64 lseek in the translator -- when the compiler lane re-blesses, 12// either the translator learns to skip translation under TARGET_X86_64 or 13// this helper switches back to 129 there. Tracked in the landmine doc. 14// license_tier: ORIGINAL 15 16// MEASURED 2026-06-10 (landmine doc item 5): constants fed to __syscall go 17// through the compiler's rv64->x86 table (x86ctx_rv64_to_x86_64_syscall). 18// nx_cc_known_good is a FROZEN pre-2026-06-06 binary whose baked table 19// lacks kill (129->62): 129 passed through to x86 rt_sigqueueinfo (EFAULT) 20// and a literal 62 hit the stale row 62->8 = lseek (EBADF). The backend's 21// documented escape hatch: RUNTIME-COMPUTED numbers are loaded AS-IS in 22// BOTH compiler lanes -- so a raw x86_64 number through a memory load is 23// the portable form for every x86 deployment (RV64 targets would need 129; 24// none are live). 25func nxk_kill(pid: i64, sig: i64) -> i64 { 26 let nb: *i64 = sys_mmap(8) as *i64 27 nb[0] = 62 // x86_64 kill, untranslated by design 28 return __syscall(nb[0], pid, sig, 0, 0, 0, 0) 29}