FABRIC.md: item 4.5d in progress -- fortification fixed, putc/getc blocks completion

Attempting -O2 on amd64 surfaced two link-time findings, neither of which
was warnings the way 4.5d's own text anticipated:

1. Fixed: -O2 broke the link with __printf_chk/__memset_chk/__fread_chk/
   __snprintf_chk undefined references across five vendored word_source
   files. Root cause: those files unconditionally #include real glibc
   headers (no __STARKERNEL__ guard), which under Ubuntu's default
   _FORTIFY_SOURCE and -O2's __OPTIMIZE__ rewrite printf/etc. call sites to
   _chk variants that shim.c's freestanding backfill never provided --
   worked by accident at -O0 where the macros stay dormant. Fixed by adding
   -U_FORTIFY_SOURCE, the standard fix for this exact situation in
   freestanding/kernel builds.

2. Not fixed, blocking: with fortification disabled, plain putc/getc turned
   up as genuinely undefined -- shim.c never backfilled those, only printf/
   snprintf. -O0 doesn't need these symbols for reasons not fully
   established (GCC's -O2 function-splitting visibly clones at least one
   call site); this needs a real design decision (backfill shim.c vs. guard
   the call sites out of __STARKERNEL__ builds), not a mechanical flag.

Makefile.starkernel reverted to the committed -O0 state (the -O2 change was
uncommitted, so a plain git restore -- nothing broken landed in history).
4.5d stays open pending Finding 2's resolution.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-11 10:58:33 -04:00
co-authored by Claude Sonnet 5
parent c5d46858fb
commit 96ff2f6ae5
+36
View File
@@ -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 <stdio.h>`/`<stdlib.h>`/
> `<string.h>`/`<signal.h>` 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