kit

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

commit eab8230948b78b2c4f18922b1ad5956a72e2c392
parent 4595b0529150f7885e25e7231e0a0d1196c440fd
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Tue, 16 Jun 2026 14:41:28 -0700

test/buildcmds: cover kernel linker flags, map completeness, freestanding policy

52 new cases: --defsym (abs + alias, bad-form negative), --section-start /
-Tdata/-Tbss acceptance, --orphan-handling (+bad negative) / --fatal-warnings,
map LMA/discarded/unresolved + no-absolute-path-leak + cross-run determinism,
--cref (header/symbol/def-attribution/no-abspath), --print-memory-usage
(script-driven RAM/FLASH regions), and freestanding strict validation
(cross-arch object + DSO-input rejection in both build-exe and ld, plus a
same-arch no-false-positive case). build-exe and ld variants throughout.

Diffstat:
Mtest/buildcmds/run.sh | 161+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 161 insertions(+), 0 deletions(-)

diff --git a/test/buildcmds/run.sh b/test/buildcmds/run.sh @@ -317,5 +317,166 @@ run_fail be-wasm-exe-bad-entry "$KIT" build-exe -target wasm32-none \ contains be-wasm-exe-bad-entry-diag "$work/be-wasm-exe-bad-entry.err" \ "entry symbol" +# =========================================================================== +# build-exe / ld — kernel linker flags, map completeness, freestanding policy +# =========================================================================== + +# A bare freestanding _start used by the flag/policy tests below. +printf 'void _start(void){ for(;;){} }\nint mydata = 42;\n' > kstart.c + +# ---- --defsym: absolute literal + symbol alias ---------------------------- +# my_abs becomes an absolute symbol at 0x1234; my_alias takes _start's address. +run_ok be-defsym "$KIT" build-exe -target x86_64-linux -nostdlib -static -no-pie \ + --defsym my_abs=0x1234 --defsym my_alias=_start \ + --symbols defsym.sym kstart.c -o defsym.elf +contains be-defsym-abs defsym.sym "0000000000001234 A my_abs" +# my_alias takes _start's address (the alias inherits the target's placement, +# so it rebases to the same final address _start carries). +_start_addr=$(grep -E ' T _start$' defsym.sym | cut -d' ' -f1) +if grep -qE "^$_start_addr . my_alias\$" defsym.sym; then ok be-defsym-alias; else + { echo "my_alias != _start ($_start_addr)"; cat defsym.sym; } \ + > "$work/be-defsym-alias.diag" + not_ok be-defsym-alias "$work/be-defsym-alias.diag" +fi +# defsym via ld too. +run_ok be-ld-report-kstart "$KIT" build-obj -target x86_64-linux \ + kstart.c -o kstart.o +run_ok ld-defsym "$KIT" ld -nostdlib -static -no-pie \ + --defsym ld_abs=0x4321 --symbols lddefsym.sym kstart.o -o lddefsym.elf +contains ld-defsym-abs lddefsym.sym "0000000000004321 A ld_abs" +# --defsym with no value is rejected. +run_fail be-defsym-bad "$KIT" build-exe -target x86_64-linux -nostdlib -static \ + -no-pie --defsym broken kstart.c -o defsymbad.elf +contains be-defsym-bad-diag "$work/be-defsym-bad.err" "NAME=EXPR" + +# ---- --section-start / -Tdata / -Tbss: per-section address overrides ------- +# These are accepted (best-effort placement; -Ttext / a linker script give +# exact addresses). Assert acceptance + determinism rather than an exact vaddr. +run_ok be-section-start "$KIT" build-exe -target x86_64-linux -nostdlib \ + -static -no-pie --section-start=.text=0x500000 -Tdata 0x600000 \ + --map secstart.map kstart.c -o secstart.elf +contains be-section-start-text secstart.map "vaddr=0x50" +contains be-section-start-data secstart.map "vaddr=0x60" +run_ok ld-tbss "$KIT" ld -nostdlib -static -no-pie -Tdata 0x600000 \ + kstart.o -o tbss.elf +run_ok ld-section-start "$KIT" ld -nostdlib -static -no-pie \ + --section-start=.text=0x700000 kstart.o -o secstart2.elf + +# ---- --orphan-handling / --fatal-warnings: parse + plumb ------------------- +run_ok be-orphan "$KIT" build-exe -target x86_64-linux -nostdlib -static \ + -no-pie --orphan-handling=warn kstart.c -o orphan.elf +run_fail be-orphan-bad "$KIT" build-exe -target x86_64-linux -nostdlib \ + -static -no-pie --orphan-handling=nonsense kstart.c -o orphanbad.elf +contains be-orphan-bad-diag "$work/be-orphan-bad.err" "orphan-handling" +run_ok be-fatal-warnings "$KIT" build-exe -target x86_64-linux -nostdlib \ + -static -no-pie --fatal-warnings kstart.c -o fatal.elf +run_ok ld-orphan "$KIT" ld -nostdlib -static -no-pie --orphan-handling=error \ + kstart.o -o ldorphan.elf + +# ---- map completeness: LMA, discarded, unresolved, normalized paths -------- +run_ok be-map-complete "$KIT" build-exe -target x86_64-linux -nostdlib \ + -static -no-pie --gc-sections -ffunction-sections \ + --map complete.map kstart.c -o complete.elf +contains be-map-has-lma complete.map "lma=0x" +contains be-map-has-discarded complete.map "discarded" +contains be-map-has-unresolved complete.map "unresolved" +# No absolute host path leaks into the map (paths are normalized to basenames). +if grep -qE 'input=/|input=.:[\\/]' complete.map; then + { echo "absolute path leaked into map"; grep input= complete.map; } \ + > "$work/be-map-no-abspath.diag" + not_ok be-map-no-abspath "$work/be-map-no-abspath.diag" +else + ok be-map-no-abspath +fi +# The map is deterministic across two identical links. +run_ok be-map-det1 "$KIT" build-exe -target x86_64-linux -nostdlib -static \ + -no-pie --map det1.map kstart.c -o det1.elf +run_ok be-map-det2 "$KIT" build-exe -target x86_64-linux -nostdlib -static \ + -no-pie --map det2.map kstart.c -o det2.elf +same_file be-map-deterministic det1.map det2.map + +# ---- --cref: cross-reference table (deterministic, basenames only) --------- +printf 'int xref_helper(void);\nvoid _start(void){ xref_helper(); for(;;){} }\n' \ + > xmain.c +printf 'int xref_helper(void){ return 9; }\n' > xhelp.c +run_ok be-cref "$KIT" build-exe -target x86_64-linux -nostdlib -static -no-pie \ + --cref cref.out xmain.c xhelp.c -o cref.elf +contains be-cref-header cref.out "cross reference table" +contains be-cref-symbol cref.out "xref_helper" +if grep -qE '^ def /|^ ref /' cref.out; then + { echo "absolute path leaked into cref"; cat cref.out; } \ + > "$work/be-cref-no-abspath.diag" + not_ok be-cref-no-abspath "$work/be-cref-no-abspath.diag" +else + ok be-cref-no-abspath +fi +# cref via ld attributes def/ref to the right object basenames. +run_ok ld-cref-objs "$KIT" build-obj -target x86_64-linux xmain.c -o xmain.o +run_ok ld-cref-objs2 "$KIT" build-obj -target x86_64-linux xhelp.c -o xhelp.o +run_ok ld-cref "$KIT" ld -nostdlib -static -no-pie --cref ldcref.out \ + xmain.o xhelp.o -o ldcref.elf +# xref_helper is defined in xhelp.o, referenced from xmain.o. +if awk '/^xref_helper$/{f=1;next} f&&/^ def xhelp.o$/{ok=1} f&&/^[^ ]/&&!/^xref_helper$/{f=0} END{exit !ok}' ldcref.out; then + ok ld-cref-def +else + cp ldcref.out "$work/ld-cref-def.diag"; not_ok ld-cref-def "$work/ld-cref-def.diag" +fi + +# ---- --print-memory-usage: per-MEMORY-region summary (script-driven) ------- +cat > memuse.ld <<'LDEOF' +MEMORY { + RAM (rwx) : ORIGIN = 0x80000000, LENGTH = 0x100000 + FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x40000 +} +SECTIONS { + . = 0x80000000; + .text : { *(.text*) } + .data : { *(.data*) } + .bss : { *(.bss*) } +} +LDEOF +printf 'void _start(void){for(;;){}}\nint memd=7;\n' > memk.c +run_ok be-memuse "$KIT" build-exe -target riscv64-none-elf -ffreestanding \ + -nostdlib -static -no-pie -T memuse.ld --print-memory-usage memk.c \ + -o memk.elf +contains be-memuse-header "$work/be-memuse.out" "Memory region" +contains be-memuse-ram "$work/be-memuse.out" "RAM" +contains be-memuse-flash "$work/be-memuse.out" "FLASH" +run_ok be-memuse-obj "$KIT" build-obj -target riscv64-none-elf -ffreestanding \ + -nostdlib memk.c -o memk.o +run_ok ld-memuse "$KIT" ld -T memuse.ld --print-memory-usage memk.o -o memkld.elf +contains ld-memuse-header "$work/ld-memuse.out" "Memory region" + +# ---- freestanding strict validation (build-exe + ld) ----------------------- +# A foreign-arch object in a freestanding link is rejected (the link target's +# arch is authoritative; a silent mis-link is a hard error). +run_ok fs-x64-obj "$KIT" build-obj -target x86_64-none-elf -ffreestanding \ + -nostdlib kstart.c -o fs_x64.o +printf 'int other(void){return 1;}\n' > fsother.c +run_ok fs-aa64-obj "$KIT" build-obj -target aarch64-none-elf -ffreestanding \ + -nostdlib fsother.c -o fs_aa64.o +run_fail fs-cross-arch-ld "$KIT" ld -o fscross.elf fs_x64.o fs_aa64.o +contains fs-cross-arch-ld-diag "$work/fs-cross-arch-ld.err" \ + "does not match the link target" +run_fail fs-cross-arch-be "$KIT" build-exe -target x86_64-none-elf \ + -ffreestanding -nostdlib -static -no-pie kstart.c fs_aa64.o -o fscross2.elf +contains fs-cross-arch-be-diag "$work/fs-cross-arch-be.err" \ + "does not match the link target" +# A DSO (shared object) input into a freestanding link is rejected. The fixture +# libc.so is an ET_DYN x86_64 shared object copied in locally. +if [ -f "$repo_root/test/driver/fixtures/libc.so" ]; then + cp "$repo_root/test/driver/fixtures/libc.so" . + run_fail fs-dso-ld "$KIT" ld -o fsdso.elf fs_x64.o libc.so + contains fs-dso-ld-diag "$work/fs-dso-ld.err" "DSO" + run_fail fs-dso-be "$KIT" build-exe -target x86_64-none-elf -ffreestanding \ + -nostdlib -static -no-pie kstart.c libc.so -o fsdso2.elf + contains fs-dso-be-diag "$work/fs-dso-be.err" "DSO" +else + skip_test fs-dso-ld "no libc.so fixture" + skip_test fs-dso-be "no libc.so fixture" +fi +# A same-arch freestanding link still succeeds (no false positive). +run_ok fs-same-arch-ok "$KIT" ld -o fsok.elf fs_x64.o + kit_summary build-driver kit_exit