nx_pe_compile_win_gui.nx
buildroot/runtime/nx_pe_compile_win_gui.nx
about
nx_pe_compile_win_gui.nx -- GUI-R0 keystone: emits nish_gui.nx as a native Windows PE with a
sovereign Win32 FFI so NishiLang can drive user32/gdi32 (open a window, push a framebuffer).
Imports (ONE contiguous IAT, indexed by FFI id = slot index; per-DLL counts come from each
descriptor's OriginalFirstThunk/INT, so the IAT needs no inter-DLL null splits):
kernel32 slots 0-6: ExitProcess GetProcessHeap HeapAlloc GetStdHandle WriteFile Sleep GetModuleHandleA
user32 slots 7-17: RegisterClassExA CreateWindowExA ShowWindow PeekMessageA TranslateMessage
DispatchMessageA DefWindowProcA GetDC ReleaseDC IsWindow LoadCursorA
gdi32 slot 18: SetDIBitsToDevice
Redirected shims: sys_mmap->HeapAlloc(zeroed), sys_write->WriteFile, sys_exit->ExitProcess,
sys_sleep_ms->Sleep, win32->FFI-marshalled-call, win32addr->IAT-address-of.
Same proven PE machinery as nx_pe_compile_win_nish.nx (writable .text for statics, RIP-relative
code at the image base, MS-x64 thunks). lineage_id: substrate_pe_compile_win_gui_v1
dependencies 3 imports · 1 importers
imports: nx_syscalls.nxnxasm_x86.nxnx_pe_writer.nx
imported by: nx_pe_compile_win_game.nx
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 20 | const GI_CODE_CAP: i64 = 0x300000 |
| 21 | const GI_STUB_LEN: i64 = 18 // sub/call main/mov ecx/call exit/int3 |
| 22 | const GI_THUNK_SLACK: i64 = 0x1000 |
| 23 | const GI_FOFF_TEXT: i64 = 0x200 |
| 24 | const GI_RVA_TEXT: i64 = 0x1000 |
| 25 | const GI_IDATA_FSZ: i64 = 0x600 |
| 28 | const GI_DESC_K: i64 = 0x00 // kernel32 import descriptor (20) |
| 29 | const GI_DESC_U: i64 = 0x14 // user32 (20) |
| 30 | const GI_DESC_G: i64 = 0x28 // gdi32 (20) |
| 31 | const GI_DESC_K2: i64 = 0x3C // 2nd kernel32 descriptor (ReadFile @ slot 19, additive) |
| 32 | const GI_DESC_K3: i64 = 0x50 // 3rd kernel32 descriptor (CreateFileA/CreateProcessA/WaitForSingleObject/CloseHandle @ slots 20-23) |
| 33 | const GI_DESC_U2: i64 = 0x64 // 2nd user32 descriptor (GetClientRect @ slot 24, additive for live resize) |
| 34 | const GI_DESC_N: i64 = 0x78 // null (20) |
| 35 | const GI_IAT: i64 = 0x8C // 25 slots contiguous (200B) -> ends 0x154 |
| 36 | const GI_INT_K: i64 = 0x154 // kernel32 INT: 7+null (64) |
| 37 | const GI_INT_U: i64 = 0x194 // user32 INT: 11+null (96) |
| 38 | const GI_INT_G: i64 = 0x1F4 // gdi32 INT: 1+null (16) |
| 39 | const GI_INT_K2: i64 = 0x204 // kernel32#2 INT: 1+null (16) |
| 40 | const GI_INT_K3: i64 = 0x214 // kernel32#3 INT: 4+null (40) |
| 41 | const GI_INT_U2: i64 = 0x23C // user32#2 INT: 1+null (16) |
| 42 | const GI_NAMES: i64 = 0x24C |
| 44 | const GI_IMGBASE_LO: i64 = 0x40000000 |
| 45 | const GI_IMGBASE_HI: i64 = 0x1 |
| 46 | const GI_IMGBASE: i64 = 5368709120 // 0x1_4000_0000 |
functions
| 48 | func gi_align(x: i64, a: i64) -> i64 { return ((x + a - 1) / a) * a } |
| 49 | func gi_rva(foff: i64) -> i64 { return GI_RVA_TEXT + (foff - GI_FOFF_TEXT) } |
| 50 | func gi_ec(buf: *u8, foff: i64, iat_rva: i64) -> i64 |
| 55 | func gi_redir(buf: *u8, shim_off: i64, thunk_rva: i64) -> i64 |
| 62 | func gi_put_name(buf: *u8, foff: i64, s: *u8) -> i64 |
| 71 | func gi_put_str(buf: *u8, foff: i64, s: *u8) -> i64 called by 1: gi_emit_pe |
| 77 | func gi_lbloff(src: *u8, lo: *i64, ll: *i64, la: *i64, n: i64, nm: *u8) -> i64 |
| 82 | func gi_assemble(src: *u8, n: i64, out: *u8, out_cap: i64, off: *i64) -> i64 |
| 115 | func gi_emit_pe(buf: *u8, code: *u8, code_len: i64, off: *i64, text_fsz: i64, rva_idata: i64) -> i64 |
| 350 | func main() -> i64 |