diff --git a/FABRIC.md b/FABRIC.md index af2005e..3593a65 100644 --- a/FABRIC.md +++ b/FABRIC.md @@ -5535,6 +5535,42 @@ document and committing that amendment as its own item.* `-Wall -Werror -Wextra` standard. *Refs:* 4.5, 4.5c. + > **In progress 2026-08-11 — two link-time findings, neither anticipated by 4.5c/4.5d's + > own text (which expected new *warnings*, not link failures). amd64 attempted; blocked + > before completion; not yet tried on aarch64/riscv64.** + > + > **Finding 1, fixed:** adding bare `-O2` broke the amd64 link with dozens of + > `undefined reference to '__printf_chk'` / `__memset_chk` / `__fread_chk` / `__snprintf_chk` + > across `io_words.c`, `system_words.c`, `starforth_words.c`, + > `physics_benchmark_words.c`, `physics_pipelining_diagnostic_words.c`. Root cause: these + > vendored word_source files unconditionally `#include `/``/ + > ``/`` with no `__STARKERNEL__` guard (confirmed by reading + > `system_words.c:48-51`); `Makefile.starkernel` has no `-nostdinc`, so these resolve to + > real glibc headers, and `src/starkernel/vm/host/shim.c` provides freestanding `printf()`/ + > `snprintf()` to satisfy calls into this vendored code. At `-O0`, `__OPTIMIZE__` is + > undefined so glibc's default-on-Ubuntu `_FORTIFY_SOURCE` macros stay dormant and the + > plain symbol names resolve against `shim.c` — working by accident. At `-O2` those macros + > activate and rewrite call sites to the `_chk` variants, which `shim.c` never provided. + > **Fixed by adding `-U_FORTIFY_SOURCE` to `COMMON_CFLAGS`** — the standard, precedented + > fix for freestanding/kernel builds (Linux and most embedded kernels carry this exact + > flag for this exact reason). Verified: all `_chk` link errors gone after adding it. + > + > **Finding 2, NOT fixed, blocking this item:** with fortification disabled, a second, + > unrelated problem surfaced — plain (unfortified) `putc`/`getc` are genuinely undefined + > symbols. `shim.c` only backfills `printf`/`snprintf`, never `putc`/`getc`. Call sites: + > `profiler.c` (`profiler_print_hotspots`/`profiler_generate_report`), `io_words.c` + > (`io_word_key`), `system_words.c` (`system_word_words`/`system_word_vlist`). These same + > call sites do **not** break the `-O0` link — GCC's `-O2` function-splitting pass visibly + > clones some of them (`profiler_print_hotspots.part.0` in the linker error) and something + > about that changes which code the linker ends up pulling in; the exact mechanism by which + > `-O0` avoids needing these symbols is not established, only that it reproducibly does. + > Captain Bob's call 2026-08-11: **stop here, don't fix in-place** — this needs a real + > design decision (backfill freestanding `putc`/`getc` in `shim.c` matching the existing + > `printf`/`snprintf` pattern, versus guarding these call sites out of `__STARKERNEL__` + > builds entirely) rather than a mechanical flag. **`Makefile.starkernel` reverted to the + > committed `-O0` state** (the change was uncommitted, so a plain `git restore` — nothing + > broken is in the tree or history). 4.5d cannot complete until this is resolved. + - [ ] **4.5e — Three-arch acceptance boot with optimization enabled.** Depends on 4.5d. This is the actual gate, per CLAUDE.md's non-negotiable acceptance criteria — a kernel that has only ever been built and accepted at `-O0` has no track record at any other optimization