The GCC driver relocates its install prefix from argv[0]. crt1
hardcoded argv[0] as "prog", so make_relative_prefix cwd-joined it
and computed exec prefixes relative to the current directory
(0:/users/admin/../libexec/gcc/...), and because the computed
gcc_exec_prefix is non-NULL the standard /sdk prefixes were never
searched. cc1plus was unreachable from anywhere except (by accident
of the path arithmetic) 0:/sdk/bin. sdk-diag proved the kernel and
libc layers all worked; only the driver's self-relocation was lost.
New SYS_GETEXECPATH (151) returns the absolute path the process was
spawned from (Process::name); crt1 uses it for argv[0] with a "prog"
fallback. With a real argv[0], make_relative_prefix computes
0:/sdk/bin/../libexec/gcc/ from any cwd. Native GCC relinked against
the new crt1; sdk-diag ships in the SDK as a permanent probe; the
montauk.h TCC mirror gains the wrapper (checker enforced it).
Co-Authored-By: Claude Fable 5 <[email protected]>
Groundwork for the GCC driver: a compiler driver must spawn cc1/as/ld
and know whether each stage succeeded.
Kernel: the scheduler keeps an exit-code ledger (pid -> code; pids are
monotonic so entries never alias), published during teardown right
before waiters wake. SYS_EXIT records main()'s return value, SYS_KILL
records 256+SIGKILL, and the exception handler records 256+signal
mapped from the fault vector (#PF/#GP -> SIGSEGV, #DE/FP -> SIGFPE,
#UD -> SIGILL). SYS_WAITPID now returns the code: 0..255 for a normal
exit, 256+signal for a violent death. Process args grow from 256
bytes to 4 KiB (cc1 invocations do not fit in 256), with crt1 now
parsing up to 255 argv entries from a static buffer.
libc: new spawn.h with posix_spawn/posix_spawnp over SYS_SPAWN -
libiberty's pex layer has a posix_spawn backend, so GCC's driver works
without fork. argv is joined into the kernel args string (spaces in
arguments rejected; no kernel quoting), envp is not transferred, and
non-empty file actions fail loudly with ENOTSUP until the kernel can
redirect stdio on spawn. waitpid() now decodes real POSIX status and
the sys/wait.h macros distinguish exited from signaled children.
Shell: prints [exit code N] after nonzero exits and [terminated by
signal N] for killed or crashed children.
Verified on the OS: cat on a missing file reports exit code 1; a
window-close (clean exit 0) stays silent as it should.
Co-Authored-By: Claude Fable 5 <[email protected]>
Add tear-free scanout to the Intel GPU driver: a second kernel-allocated
scanout buffer, DSPASURF flips latched at vblank, and a vblank interrupt
delivered over MSI (Gen 11+ master/display/pipe IRQ chain) with a
monotonic vblank counter and WaitVblank().
Expose it as SYS_FBFLIP (150): index selects the front buffer, -1
queries support, flags bit0 waits for the flip to latch. fb_map() now
maps buffer 1 right after buffer 0 when flipping is available, and
gui::Framebuffer draws to the off-screen buffer and flips with vsync,
falling back to the direct copy when unsupported.
Scanout is restored to buffer 0 when the flip-owning process exits and
on panic, so the terminal and panic box never land on the invisible
buffer.
Co-Authored-By: Claude Fable 5 <[email protected]>