nx_pe_compile_win_io.nx
buildroot/runtime/nx_pe_compile_win_io.nx
about
nx_pe_compile_win_io.nx -- W3b-1: nxc2-compiled NishiLang -> native Windows PE
that performs REAL kernel32 console I/O before running the compiled code.
The docker-replacement ladder's first I/O rung. The W3 keystone (nx_pe_compile_win)
proved a leaf compiled `main` RUNS native (1 import: ExitProcess, arg in ecx). This rung
GENERALIZES the compiled-organ PE to an N-entry kernel32 import table (3 imports:
GetStdHandle, WriteFile, ExitProcess) and exercises the full MS-x64 ABI (rcx/rdx/r8/r9 +
a 5th stack arg + 0x20 shadow + 16-byte alignment) by writing a banner to stdout via
WriteFile -- THEN running the nxc2-compiled `main` and exiting with its return value.
entry stub (machine code, RVA 0x1000):
sub rsp, 0x38
mov ecx, -11 ; STD_OUTPUT_HANDLE
call [rip+GetStdHandle]
mov rcx, rax ; arg1 = handle
lea rdx, [rip+MSG] ; arg2 = banner ptr (.rdata RVA 0x2000)
mov r8d, <MSGLEN> ; arg3 = byte count
xor r9, r9 ; arg4 = NULL (lpNumberOfBytesWritten)
mov qword [rsp+0x20], 0 ; arg5 = NULL (lpOverlapped) -- stack arg
call [rip+WriteFile]
call main ; <-- nxc2-COMPILED code, result in eax
mov ecx, eax
call [rip+ExitProcess] ; exit(main())
int3
The first 49 stub bytes are BYTE-IDENTICAL to the run-proven nx_pe_emit_hello stub; only the
tail (xor ecx,ecx;call ExitProcess) is swapped for (call main;mov ecx,eax;call ExitProcess) and
the compiled code is appended after the stub. The header/section/.idata layout is the proven
hello layout verbatim (same 3 kernel32 imports). MSG length is data-driven (copied from a literal).
PIPELINE (build WSL sovereign, run native): src.nx
-> ./_offc/nx_compile_x86_native.elf <src> > /tmp/nxwin.s
-> ./_offc/nx_sov_build_run.elf nx_pe_compile_win_io (reads /tmp/nxwin.s)
-> _offc/nx_win_compiled_io.exe -> run native on Windows 11.
HONEST SCOPE: the I/O call is issued by the entry STUB, not yet by the compiled code itself.
The compiled code's OUTPUT (its return -> exit code) is the no-false-green witness that real
codegen ran; the banner is the witness that native kernel32 I/O ran. The remaining W3b work
(W3b-2): the compiler/a thunk so an I/O organ's OWN sys_write maps to this WriteFile path.
Replicates nxpcw_assemble_main from nx_pe_compile_win (reuses axc_pass, no shared-assembler edit;
dependencies 3 imports · 0 importers
imports: nx_syscalls.nxnxasm_x86.nxnx_pe_writer.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 47 | const NXIO_CODE_CAP: i64 = 1048576 // 1 MiB assembled code |
| 48 | const NXIO_FILE_SIZE: i64 = 0x800 // headers + .text + .rdata + .idata (4 file-aligned chunks) |
| 49 | const NXIO_STUB_LEN: i64 = 63 // I/O stub: 49 proven hello bytes + (call main;mov;call exit;int3) |
| 50 | const NXIO_TEXT_CAP: i64 = 0x200 // one .text file chunk (stub + compiled code) |
| 51 | const NXIO_RVA_TEXT: i64 = 0x1000 |
| 52 | const NXIO_RVA_RDATA: i64 = 0x2000 |
| 53 | const NXIO_RVA_IDATA: i64 = 0x3000 |
| 54 | const NXIO_FOFF_TEXT: i64 = 0x200 |
| 55 | const NXIO_FOFF_RDATA:i64 = 0x400 |
| 56 | const NXIO_FOFF_IDATA:i64 = 0x600 |
functions
| 61 | func nxio_assemble_main(src: *u8, n: i64, out: *u8, out_cap: i64, p_main: *i64) -> i64 |
| 96 | func nxio_put_str(buf: *u8, off: i64, s: *u8) -> i64 called by 1: nxio_emit_pe |
| 108 | func nxio_emit_pe(buf: *u8, code: *u8, code_len: i64, main_off: i64) -> i64 |
| 226 | func main() -> i64 |