blaise/compiler
Graeme Geldenhuys 0824ed8a6b feat(freebsd): self-host on FreeBSD — runtime fixes + target-driven defines
Blaise now runs natively on FreeBSD and compiles+links working FreeBSD binaries
(fork/exec RTL sub-compiles, threaded incremental workers, internal assembler +
linker, freestanding runtime), and cross-compiles both directions (Linux<->
FreeBSD). Each of these was a real FreeBSD-only runtime bug exposed by running on
a real FreeBSD 14.3 kernel — invisible to host-side static checks:

  * fork(2) child return: FreeBSD returns the child in %rax=parent-pid with
    %edx=1 (child indicator); the raw leaf must zero %eax when %edx!=0, else the
    forked child runs the parent branch and never execve's its target (exit 127).
  * thread join teardown: the worker set its join word + umtx-WAKE while still on
    its own stack, so pthread_join munmap'd the shared stack/CB region out from
    under the still-live thread -> SIGSEGV. Fixed by passing the join word as
    thr_exit(state): the kernel does the suword+umtx-wake AFTER the thread leaves
    its stack, so the joiner only wakes once the stack is safe to free.
  * argc stack pad word: FreeBSD 16-aligns the entry %rsp and inserts a zero pad
    word below argc when the argv+envc pointer-count parity requires it, so argc
    is at [rsp] or [rsp+8]. _BlaiseStartC now detects and skips the pad word;
    previously an execve'd child with a different environment read the pad (0) as
    argc and reported "--source is required".

Target-driven OS conditional compilation (self-hosting requires HostTarget to be
correct on the produced binary):

  * The OS defines (LINUX/FREEBSD/WINDOWS/UNIX) now follow the resolved --target,
    not the compiler's build host. SeedPredefines seeds the host OS as a default
    (keeps direct-lexer callers/tests working) via compile-time IFDEF; the driver
    injects the target's OS symbol and AddDefinesTo / the unit loader replace the
    host-seeded OS symbols with it on every lexer (program + dep units).
  * HostTarget() reads {$IFDEF FREEBSD} etc., so a blaise built with
    --target freebsd bakes HostTarget=osFreeBSD — a FreeBSD-hosted blaise then
    defaults (no --target) to producing FreeBSD binaries. Verified both
    directions on the VM.

Usability:

  * blaise.cfg now supports rtl-src=<dir> (relative resolved against the config
    dir); a CLI --rtl-src overrides it. So a relocated binary can drop a
    blaise.cfg with unit-path= + rtl-src= and need no path flags. Tests:
    TConfigTests.TestParseRtlSrc_*.
  * --help documents the previously-undocumented --rtl-src flag and the
    blaise.cfg keys, and the --target line now shows the ACTUAL host default
    (TargetName(HostTarget())) instead of a hardcoded linux-x86_64 — correct on
    every host.

Verified: all four fixpoints green; full suite 4032 tests under QBE-built and
native-built runner; Linux self-host and Linux<->FreeBSD cross-compile confirmed;
FreeBSD self-host (blaise compiling+running a program) confirmed on FreeBSD 14.3.
2026-07-02 12:20:18 +01:00
..
src feat(freebsd): self-host on FreeBSD — runtime fixes + target-driven defines 2026-07-02 12:20:18 +01:00
project.xml refactor(rtl): relocate RTL units into the compiler tree (dotted-flat names) 2026-06-25 16:05:44 +01:00