Skip to content

feat(libbboeos): Phase 4 — clang programs link against stub thunks#451

Merged
bboe merged 1 commit into
mainfrom
bboe/libbboeos-stubs
May 20, 2026
Merged

feat(libbboeos): Phase 4 — clang programs link against stub thunks#451
bboe merged 1 commit into
mainfrom
bboe/libbboeos-stubs

Conversation

@bboe
Copy link
Copy Markdown
Owner

@bboe bboe commented May 20, 2026

Summary

  • Adds tools/generate_libbboeos_stubs.py — walks FUNCTION_<NAME>_PTR entries in kernel/include/constants.asm and emits a one-jmp [absolute]-per-export .S file. Skips the legacy 13-entry block (those have both FUNCTION_DIE and FUNCTION_DIE_PTR and aren't libbboeos C exports).
  • Makefile compiles it to libbboeos_stubs.o (default target now all, which builds both libbboeos.a and the stubs).
  • ports/doom/build.py and tests/test_libbboeos_qemu.py link libbboeos_stubs.o before libbboeos.a. ld's archive pull rule (single-pass, satisfy-unresolved-only) means once the stubs define each libbboeos export, the corresponding string.o archive member is never pulled into the program.
  • Size win: bin/hello 12,682 → 10,922 (-1,760), bin/doom 659,942 → 658,182 (-1,760). The win is exactly sizeof(string.o) per binary, and scales as more libbboeos C sources land behind the pointer table.
  • Drive-by: fixes stale [bboeos libc] regex patterns in test_libbboeos_qemu.py (marker was renamed to [libbboeos] in an earlier phase but the test wasn't updated since it's not in CI).

Test plan

  • ./make_os.sh clean
  • tests/test_asm.py (42/42)
  • tests/test_programs.py (89/89)
  • tests/test_bboefs.py (6/6)
  • tests/test_archive.py (12/12)
  • tests/test_kernel_archive.py (12/12)
  • tests/test_cc_compatibility.py (57/57)
  • python3 -m pytest tests/unit/ (458/458)
  • tests/test_libbboeos_qemu.py (manual; passes with stubs)
  • python3 ports/doom/build.py succeeds, binary 658,182 bytes

🤖 Generated with Claude Code

Adds tools/generate_libbboeos_stubs.py that walks
kernel/include/constants.asm for every FUNCTION_<NAME>_PTR entry
without a matching FUNCTION_<NAME> legacy counterpart and emits a
.S file with one 6-byte `jmp [absolute]` thunk per export.

The Makefile compiles it to libbboeos_stubs.o, which is now linked
before libbboeos.a in ports/doom/build.py and the test_libbboeos_qemu
hello.c link.  Because ld is single-pass left-to-right and only
pulls archive members for unresolved symbols, the stubs satisfy
every libbboeos export first, so the corresponding archive member
(string.o + its bodies + rodata) is never pulled into the program.

Bin/hello drops from 12,682 to 10,922 bytes; bin/doom drops from
659,942 to 658,182.  Win scales as more libbboeos sources go
behind the FUNCTION_<NAME>_PTR table.

Also fixes the stale `[bboeos libc]` regex patterns in
test_libbboeos_qemu.py (the marker was renamed to `[libbboeos]`
in the libbboeos rename but the test wasn't updated since it's
not in CI).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bboe bboe force-pushed the bboe/libbboeos-stubs branch from 2f821de to 5f8a872 Compare May 20, 2026 22:08
@bboe bboe merged commit 06bd37e into main May 20, 2026
27 checks passed
@bboe bboe deleted the bboe/libbboeos-stubs branch May 20, 2026 22:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant