blaise/compiler
Graeme Geldenhuys db85aba08d fix(freebsd): translate MAP_ANONYMOUS in the mmap leaf; read phdrs from ELF header
The FreeBSD cross-compile emulation lane (Step 8) booted real FreeBSD 14.x and
every cross-compiled binary — even a bare WriteLn — SIGSEGV'd. truss pinned it:

    mmap(0, 65536, RW, MAP_PRIVATE|0x20, -1, 0) ERR#9 'Bad file descriptor'

The shared allocator (runtime.mem) hardcodes the LINUX MAP_ANONYMOUS bit (0x20);
FreeBSD's MAP_ANON is 0x1000.  Without a recognised anon flag FreeBSD treated the
first heap arena as a file mapping on fd -1, returned EBADF, and the allocator
dereferenced the -errno result -> SIGSEGV.  This is exactly the runtime-only,
struct/syscall-flag class of bug host-side static ELF checks cannot see, and the
emulation lane caught it on its first run.

Fix: the FreeBSD mmap leaf translates the flag — if the Linux MAP_ANONYMOUS bit
(0x20) is set, clear it and set FreeBSD MAP_ANON (0x1000).  This keeps runtime.mem
OS-agnostic (one canonical, Linux-shaped flag set) and confines the divergence to
the per-OS syscall leaf, matching the Strategy-B link-time-swap design.  A flag
already carrying 0x1000 (e.g. runtime.start.static.freebsd's TLS mmap) passes
through untouched.

Also harden SetupTLS: read the program-header table directly from this binary's
own ELF header at the fixed non-PIE load base ($400000) instead of walking the
kernel auxv for AT_PHDR.  A non-PIE ET_EXEC always maps its header there, so this
is exact and self-contained (FreeBSD does supply AT_PHDR, but relying on it
coupled startup to the auxv layout for no benefit).

Verified on real FreeBSD 14.3: hello prints 'Hello' (exit 0); fileio round-trips
a file — write/read/stat/unlink — printing file-io-ok/exists-ok/done (exit 0),
validating the struct-stat offsets, the file syscall leaf AND the allocator on a
real kernel.  Linux unaffected (FreeBSD units are standalone): all four fixpoints
green, full suite 4029 tests under QBE-built and native-built runner.  The
freebsd-crosscheck emulation job (fileio fixture) is the standing regression
guard for the mmap path.
2026-07-01 23:01:46 +01:00
..
src fix(freebsd): translate MAP_ANONYMOUS in the mmap leaf; read phdrs from ELF header 2026-07-01 23:01:46 +01:00
project.xml refactor(rtl): relocate RTL units into the compiler tree (dotted-flat names) 2026-06-25 16:05:44 +01:00