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}