feat(cc): extern-call fallback for libbboeos exports#448
Merged
Conversation
a7b6efd to
6c176e9
Compare
Phase 3 step 2 of the shared-libbboeos design. cc.py's Call AST
visitor previously raised `unknown function: <name>` whenever a
called identifier wasn't a builtin / user function / function
pointer / inline body. When the called name matches a defined
`FUNCTION_<NAME>_PTR` constant in `kernel/include/constants.asm`
under `--target user`, emit a cdecl indirect call through the
libbboeos pointer table.
The self-hosted assembler in `user/programs/asm.c` gains the
matching `call [absolute]` form (FF 15 abs32 / FF 16 abs16) so the
existing `tests/test_asm.py` NASM-vs-self-host byte-equivalence
harness keeps clean across the seven programs that now use the new
emission.
Per-program `strcmp` reimplementations in
`user/programs/{fd_helpers,ls,pipe_consumer,pipe_producer,
pipe_spam,shell,sort}.c` are deleted — those calls now resolve to
the libbboeos shared `strcmp` via `FUNCTION_STRCMP_PTR`.
Kernel-mode compilation keeps the strict unknown-function error
(the kernel must not reach into the user shared blob).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6c176e9 to
a27b4d5
Compare
8 tasks
bboe
added a commit
that referenced
this pull request
May 20, 2026
Add memchr/memcmp/memcpy/memmove/memset/strcasecmp/strcat/strchr/ strcmp/strcpy/strdup/strerror/strlen/strncasecmp/strncat/strncmp/ strncpy/strrchr/strstr to the libbboeos pointer table. Phase 4 clang-built consumers (and future cc.py callers needing a non-builtin string fn) can now dispatch through [FUNCTION_<NAME>_PTR] instead of statically linking each body. cc.py-built programs are unchanged: the builtin path (rep movsb / repne scasb) still wins for memcpy/memcmp/memset/strlen because the extern-dispatch path only fires when no builtin matches. Relocates FUNCTION_POINTER_TABLE from FUNCTION_TABLE + 0x800 to + 0xE00 so .libbboeos.text + .rodata (~2.8 KB with all 18 new bodies pulled in) doesn't overlap the table. The whole user-space rebuilds against the new offset on each make_os.sh run, so the block sorts cleanly alphabetically — strcmp slides from PR #448's pinned offset 52 into its natural slot at +84. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 3 step 2 of the shared-libbboeos design (spec). cc.py's `Call` AST visitor previously raised `unknown function: ` whenever a called identifier wasn't a builtin / user function / function pointer / inline body. When the called name matches a defined `FUNCTION__PTR` constant in `kernel/include/constants.asm` under `--target user`, emit a cdecl indirect call through the libbboeos pointer table:
```
push ... push
call [FUNCTION__PTR]
add esp, N * 4
```
The pointer table lives at user-virt `0x10800` in the libbboeos blob (populated by `user/libbboeos/libbboeos.ld`'s `LONG()` entries); each `FUNCTION__PTR` is the absolute address of its slot. Same clobber accounting as a user-function call (full register-pool caller-saves charged) so the auto-pin allocator schedules around the call site correctly.
Self-host assembler
The self-hosted assembler in `user/programs/asm.c` gains the matching `call [absolute]` form — `FF 15 abs32` under bits=32, `FF 16 abs16` under bits=16 — so `tests/test_asm.py`'s NASM-vs-self-host byte-equivalence harness keeps clean across the seven programs that now use the new emission.
Cleanups
Per-program `strcmp` reimplementations in:
…are deleted; those calls now resolve to the libbboeos shared `strcmp` via `FUNCTION_STRCMP_PTR`.
Kernel-mode compilation keeps the strict unknown-function error (the kernel must not reach into the user shared blob).
Test plan
🤖 Generated with Claude Code