kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

Bug B — -O1 one-shot compile+link against an archive drops a local .Lkit_ro.N

Status: FIXED. The sqlite:O1 and yyjson:O1 builds now succeed; yyjson is green end-to-end at both opt levels. (sqlite then trips a separate, previously masked -O1 runtime fault — see sqlite-o1-runtime-segfault.md.) Fix: src/link/link_resolve.c + src/link/link_reloc_layout.c. The one-shot path links the just-compiled object in memory; a file-format emitter runs obj_sweep_dead and omits removed (tombstoned) entries when it writes, but the in-memory builder still holds them, and the linker walked them by raw id without honoring the removed bit. A deferred-but-never-materialized local rodata constant (obj_symbol_defer leaves .Lkit_ro.N a removed local SK_OBJ when its function is optimized away at -O1) therefore survived as an undefined local, and a dead reloc against one tripped "reloc references unmapped symbol". The resolver now skips removed symbols and the reloc passes skip dead relocs against them — matching exactly what a serialized-then-reread object presents. Regression: test/driver/run.shcc-o1-oneshot-deferred-rodata.


Original report (kept for the root-cause record):

Component: linker / one-shot compile+link object handling at -O1 (src/link/, interaction with the in-invocation compiled object's local .Lkit_ro rodata symbols). Severity: kit cc main.c libfoo.a -o app at -O1 fails on real archives.

Symptom

fatal: link: undefined reference to '.Lkit_ro.119'    # sqlite (shell.c + libsqlite3.a)
fatal: link: undefined reference to '.Lkit_ro.0'      # yyjson (use_yyjson.c + libyyjson.a)

.Lkit_ro.N are kit's local (file-scope) read-only-data labels, numbered from 0 per object. The reference is reported undefined even though the symbol is defined locally in the archive member:

$ kit nm sqlite3.o | grep '.Lkit_ro.119'
0000000000007ad5 d .Lkit_ro.119          # 'd' = local data, present

Reproduce

make provision-ecosystem          # once (network)
KIT=build/kit
SDK="$(xcrun --sdk macosx --show-sdk-path)"
SQ="$(sh scripts/ecosystem.sh srcdir sqlite)"
DEFS="-DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION"

$KIT cc -O1 --sysroot "$SDK" $DEFS -I "$SQ" -c "$SQ/sqlite3.c" -o /tmp/sqlite3.o
$KIT ar rcs /tmp/libsqlite3.a /tmp/sqlite3.o

# FAILS: one-shot — compile the driver source AND link the archive together:
$KIT cc -O1 --sysroot "$SDK" $DEFS -I "$SQ" "$SQ/shell.c" /tmp/libsqlite3.a -lc -o /tmp/sqlite3

# WORKS: pre-compile the driver to .o first, then link:
$KIT cc -O1 --sysroot "$SDK" $DEFS -I "$SQ" -c "$SQ/shell.c" -o /tmp/shell.o
$KIT cc -O1 --sysroot "$SDK" $DEFS /tmp/shell.o /tmp/libsqlite3.a -lc -o /tmp/sqlite3   # exit 0

What is and isn't affected

Notes for digging