kit

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

commit 1efa2147dd0ec3bd57642a4c5b232dd9939ef80e
parent 4548dddafb2cc83dc09923a26c7780f25ad2222f
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Thu, 16 Jul 2026 10:45:54 -0700

test: close hosted target and RISC-V audit gates

Diffstat:
Mmk/test.mk | 22++++++++++++++++++++--
Mtest/api/target_test.c | 14++++++++++++++
Mtest/audit/release/modules/standalone.sh | 45+++++++++++++++++++++++++++++++++++++++++++++
Mtest/cross/cases/native_activity.c | 9+++++++++
Atest/driver/native_macos_sdk.sh | 165+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtest/driver/run.sh | 8+++++---
Atest/driver/targets.sh | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/link/compat-driver.sh | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/link/riscv-flags.sh | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtest/tier1/cross/run.sh | 37+++++++++++++++++++++++++++----------
10 files changed, 566 insertions(+), 15 deletions(-)

diff --git a/mk/test.mk b/mk/test.mk @@ -71,6 +71,8 @@ TEST_TARGETS = \ test-driver-cpio \ test-driver-cas \ test-driver-cc \ + test-driver-targets \ + test-driver-native-macos-sdk \ test-driver-stack-protector \ test-driver-help \ test-driver-build \ @@ -109,6 +111,8 @@ TEST_TARGETS = \ test-libc-musl \ test-libc-musl-rv64 \ test-link \ + test-link-compat \ + test-link-riscv-flags \ test-link-reloc-uleb128 \ test-link-reloc-desc \ test-link-reloc-apply \ @@ -334,7 +338,7 @@ test-images: test-cf-corpus-selftest: @bash test/lib/kit_corpus_selftest.sh -test-driver: test-driver-help test-driver-cc test-driver-stack-protector test-driver-build test-driver-build-coord test-driver-ar test-driver-cpio test-driver-cas test-driver-strip test-driver-objcopy test-driver-objdump test-driver-pkg test-driver-strings test-driver-tools test-driver-diagnostics test-driver-wasm +test-driver: test-driver-help test-driver-cc test-driver-targets test-driver-native-macos-sdk test-driver-stack-protector test-driver-build test-driver-build-coord test-driver-ar test-driver-cpio test-driver-cas test-driver-strip test-driver-objcopy test-driver-objdump test-driver-pkg test-driver-strings test-driver-tools test-driver-diagnostics test-driver-wasm test-driver-help: bin @KIT=$(abspath $(BIN)) sh test/driver/help_uniform.sh @@ -342,6 +346,12 @@ test-driver-help: bin test-driver-cc: bin @KIT=$(abspath $(BIN)) sh test/driver/run.sh +test-driver-targets: bin + @KIT=$(abspath $(BIN)) sh test/driver/targets.sh + +test-driver-native-macos-sdk: bin + @KIT=$(abspath $(BIN)) sh test/driver/native_macos_sdk.sh + test-driver-stack-protector: bin @KIT=$(abspath $(BIN)) sh test/driver/stack_protector.sh @@ -1056,10 +1066,18 @@ test-coff-windows-vm: bin rt-x86_64-pc-windows rt-aarch64-windows windows-ucrt-s # The parse/asm/macho harnesses select a cross-target via KIT_TEST_ARCH # (default aa64); the link rt dependency is resolved through the shared # _TEST_RT_<arch> map defined above (near test-rt-runtime). -test-link: lib $(ROUNDTRIP_BIN) $(ROUNDTRIP_BIN_MACHO) $(LINK_EXE_RUNNER) \ +test-link-compat: bin $(LINK_COMPAT_TEST_BIN) + $(LINK_COMPAT_TEST_BIN) + KIT=$(abspath $(BIN)) sh test/link/compat-driver.sh + +test-link-riscv-flags: bin + KIT=$(abspath $(BIN)) sh test/link/riscv-flags.sh + +test-link: bin $(ROUNDTRIP_BIN) $(ROUNDTRIP_BIN_MACHO) $(LINK_EXE_RUNNER) \ $(JIT_RUNNER) $(LINK_SCRIPT_TEST_BIN) $(LINK_COMPAT_TEST_BIN) $(LINK_SCRIPT_TEST_BIN) $(LINK_COMPAT_TEST_BIN) + KIT=$(abspath $(BIN)) sh test/link/compat-driver.sh bash test/link/run.sh # x64 ELF link/reloc-application coverage. test-link defaults to aa64, so diff --git a/test/api/target_test.c b/test/api/target_test.c @@ -297,6 +297,20 @@ static void check_target_profile_registry(void) { "registry distinguishes Linux libc profiles"); EXPECT(kit_target_profile_lookup("wasm32-wasi") != NULL, "compiled-in Wasm profile is registered"); + EXPECT((kit_target_profile_lookup("linux-glibc-aa64")->capabilities & + KIT_TARGET_CAP_SHARED) != 0 && + (kit_target_profile_lookup("android-aa64")->capabilities & + KIT_TARGET_CAP_SHARED) != 0, + "ELF hosted profiles advertise shipped shared linking"); + EXPECT((kit_target_profile_lookup("windows-aa64")->capabilities & + KIT_TARGET_CAP_SHARED) == 0 && + (kit_target_profile_lookup("windows-x64")->capabilities & + KIT_TARGET_CAP_SHARED) == 0 && + (kit_target_profile_lookup("macos-aa64")->capabilities & + KIT_TARGET_CAP_SHARED) == 0 && + (kit_target_profile_lookup("macos-x64")->capabilities & + KIT_TARGET_CAP_SHARED) == 0, + "Mach-O/COFF profiles do not advertise rejected shared output"); EXPECT(kit_target_profile_lookup("definitely-not-a-target") == NULL, "unknown profile is absent"); EXPECT(KIT_TARGET_PROFILE_REGISTRY_VERSION == 1u, diff --git a/test/audit/release/modules/standalone.sh b/test/audit/release/modules/standalone.sh @@ -171,6 +171,51 @@ audit_standalone_support_discovery() { audit_expect_exit 0 audit_expect_stderr_empty fi + + # An explicit bad root is authoritative even though the copied release has + # a valid sibling support tree. + audit_case_step_exec invalid-explicit-support \ + "$AUDIT_STANDALONE_RELOC/bin/kit" cc \ + --support-dir "$CASE_DIR/work/missing support" \ + -c "$AUDIT_STANDALONE_SOURCE_DIR/native sdk malloc.c" \ + -o "$CASE_DIR/artifacts/invalid-explicit.o" + audit_expect_exit 1 + audit_expect_stderr_nonempty + if grep -F -q "support dir not found" "$CASE_ACTIVE_DIR/stderr"; then + audit_check_pass "invalid explicit support root is diagnosed" + else + audit_check_fail "invalid explicit support root diagnostic is missing" + fi + if [ ! -e "$CASE_DIR/artifacts/invalid-explicit.o" ]; then + audit_check_pass "invalid explicit support root produced no output" + else + audit_check_fail "invalid explicit support root produced output" + fi + + # Put otherwise-valid support layouts in the invocation cwd, but run an + # orphaned binary whose executable-relative candidates are both absent. + # Canonical discovery must fail rather than revive the removed cwd/source- + # checkout fallbacks. + mkdir -p "$CASE_DIR/work/orphan/bin" + cp "$AUDIT_STANDALONE_RELOC/bin/kit" "$CASE_DIR/work/orphan/bin/kit" + ln -s "$AUDIT_STANDALONE_RELOC/support" "$CASE_DIR/work/support" + ln -s "$AUDIT_STANDALONE_RELOC/support/rt" "$CASE_DIR/work/rt" + audit_case_step_exec no-cwd-fallback "$CASE_DIR/work/orphan/bin/kit" cc \ + -c "$AUDIT_STANDALONE_SOURCE_DIR/native sdk malloc.c" \ + -o "$CASE_DIR/artifacts/orphan.o" + audit_expect_exit 1 + audit_expect_stderr_nonempty + if grep -F -q "support dir not found" "$CASE_ACTIVE_DIR/stderr"; then + audit_check_pass "orphaned binary ignores cwd support/source trees" + else + audit_check_fail "orphaned binary used cwd support/source fallback" + fi + if [ ! -e "$CASE_DIR/artifacts/orphan.o" ]; then + audit_check_pass "orphaned binary produced no output" + else + audit_check_fail "orphaned binary unexpectedly produced output" + fi + audit_expect_file_empty "$CASE_DIR/artifacts/sentinel.log" audit_case_finish } diff --git a/test/cross/cases/native_activity.c b/test/cross/cases/native_activity.c @@ -1,6 +1,15 @@ #include <android/native_activity.h> #include <stddef.h> +#ifndef __ANDROID_API__ +#error "Android hosted profile must define __ANDROID_API__" +#endif +#ifdef KIT_EXPECT_ANDROID_API +#if __ANDROID_API__ != KIT_EXPECT_ANDROID_API +#error "Android hosted profile selected the wrong API level" +#endif +#endif + void ANativeActivity_onCreate(ANativeActivity* activity, void* saved_state, size_t saved_state_size) { (void)saved_state; diff --git a/test/driver/native_macos_sdk.sh b/test/driver/native_macos_sdk.sh @@ -0,0 +1,165 @@ +#!/bin/sh +# Native macOS hosted-SDK policy and precedence acceptance (KIT-P0-002). + +set -u + +script_dir=$(CDPATH= cd -- "$(dirname "$0")" && pwd) +repo_root=$(CDPATH= cd -- "$script_dir/../.." && pwd) +KIT=${KIT:-$repo_root/build/kit} +KIT_KIT_DIR=$repo_root/test/lib +. "$repo_root/test/lib/kit_sh_kit.sh" + +kit_require_kit native-macos-sdk +kit_report_init +kit_workdir native-macos-sdk +work=$KIT_WORK + +if [ "$(uname -s 2>/dev/null || printf unknown)" != Darwin ]; then + skip_test native-macos-sdk "requires a Darwin host with a macOS SDK" + kit_summary native-macos-sdk + kit_exit +fi + +mkdir -p "$work/sentinel-bin" +cat > "$work/sentinel-bin/xcrun" <<'EOF' +#!/bin/sh +printf 'xcrun invoked: %s\n' "$*" >> "$KIT_XCRUN_SENTINEL_LOG" +exit 99 +EOF +chmod +x "$work/sentinel-bin/xcrun" +: > "$work/xcrun.log" +isolated_path=$work/sentinel-bin:/usr/bin:/bin + +cat > "$work/hosted.c" <<'EOF' +#include <stdlib.h> +#ifndef __APPLE__ +#error native macOS hosted predefines are missing +#endif +int kit_native_sdk_marker = 2026060; +int main(void) { + void *p = malloc(8); + if (!p) return 1; + free(p); + return 0; +} +EOF +cat > "$work/freestanding.c" <<'EOF' +int kit_freestanding_probe(void) { return 0; } +EOF +cat > "$work/start.c" <<'EOF' +void _start(void) {} +EOF + +run_ok print-internal /usr/bin/env -u KIT_SYSROOT \ + PATH="$isolated_path" KIT_XCRUN_SENTINEL_LOG="$work/xcrun.log" \ + "$KIT" cc -print-sysroot +internal_sdk=$(sed -n '1p' "$work/print-internal.out") +if [ -n "$internal_sdk" ] && [ -d "$internal_sdk" ]; then + ok internal-sdk-exists +else + printf 'reported SDK: %s\n' "$internal_sdk" > "$work/internal-sdk.diag" + not_ok internal-sdk-exists "$work/internal-sdk.diag" +fi + +run_ok print-env /usr/bin/env KIT_SYSROOT="$internal_sdk" \ + PATH="$isolated_path" KIT_XCRUN_SENTINEL_LOG="$work/xcrun.log" \ + "$KIT" cc -print-sysroot +if [ "$(sed -n '1p' "$work/print-env.out")" = "$internal_sdk" ]; then + ok env-sysroot-precedence +else + not_ok env-sysroot-precedence "$work/print-env.out" +fi + +explicit_sdk="$work/Explicit SDK With Spaces" +ln -s "$internal_sdk" "$explicit_sdk" +run_ok print-explicit /usr/bin/env KIT_SYSROOT="$internal_sdk" \ + PATH="$isolated_path" KIT_XCRUN_SENTINEL_LOG="$work/xcrun.log" \ + "$KIT" cc --sysroot "$explicit_sdk" -print-sysroot +if [ "$(sed -n '1p' "$work/print-explicit.out")" = "$explicit_sdk" ]; then + ok explicit-sysroot-wins +else + not_ok explicit-sysroot-wins "$work/print-explicit.out" +fi +run_ok explicit-root-compile-link /usr/bin/env KIT_SYSROOT="$internal_sdk" \ + PATH="$isolated_path" KIT_XCRUN_SENTINEL_LOG="$work/xcrun.log" \ + "$KIT" cc --sysroot "$explicit_sdk" "$work/hosted.c" \ + -o "$work/explicit-root-program" +run_ok explicit-root-run "$work/explicit-root-program" + +run_fail invalid-explicit-no-fallback /usr/bin/env KIT_SYSROOT="$internal_sdk" \ + PATH="$isolated_path" KIT_XCRUN_SENTINEL_LOG="$work/xcrun.log" \ + "$KIT" cc --sysroot "$work/missing-sdk" -print-sysroot +contains invalid-explicit-diagnostic "$work/invalid-explicit-no-fallback.err" \ + "sysroot not found: $work/missing-sdk" + +for row in 'aa64 aarch64-apple-darwin' 'x64 x86_64-apple-darwin'; do + set -- $row + tag=$1 + target=$2 + common_env="PATH=$isolated_path" + : "$common_env" + + run_ok "$tag-cc" /usr/bin/env -u KIT_SYSROOT \ + PATH="$isolated_path" KIT_XCRUN_SENTINEL_LOG="$work/xcrun.log" \ + "$KIT" cc -target "$target" "$work/hosted.c" \ + -o "$work/$tag-cc-program" + run_ok "$tag-check" /usr/bin/env -u KIT_SYSROOT \ + PATH="$isolated_path" KIT_XCRUN_SENTINEL_LOG="$work/xcrun.log" \ + "$KIT" check -target "$target" "$work/hosted.c" + run_ok "$tag-cpp" /usr/bin/env -u KIT_SYSROOT \ + PATH="$isolated_path" KIT_XCRUN_SENTINEL_LOG="$work/xcrun.log" \ + "$KIT" cpp -target "$target" "$work/hosted.c" \ + -o "$work/$tag-hosted.i" + contains "$tag-cpp-marker" "$work/$tag-hosted.i" \ + "kit_native_sdk_marker" + run_ok "$tag-build-obj" /usr/bin/env -u KIT_SYSROOT \ + PATH="$isolated_path" KIT_XCRUN_SENTINEL_LOG="$work/xcrun.log" \ + "$KIT" build-obj -target "$target" "$work/hosted.c" \ + -o "$work/$tag-build.o" + run_ok "$tag-build-lib" /usr/bin/env -u KIT_SYSROOT \ + PATH="$isolated_path" KIT_XCRUN_SENTINEL_LOG="$work/xcrun.log" \ + "$KIT" build-lib -target "$target" "$work/hosted.c" \ + -o "$work/lib$tag.a" + run_ok "$tag-build-exe" /usr/bin/env -u KIT_SYSROOT \ + PATH="$isolated_path" KIT_XCRUN_SENTINEL_LOG="$work/xcrun.log" \ + "$KIT" build-exe -target "$target" "$work/hosted.c" \ + -o "$work/$tag-build-program" +done + +run_ok native-cc-run "$work/aa64-cc-program" +run_ok native-build-exe-run "$work/aa64-build-program" + +# Both freestanding opt-outs must avoid SDK resolution even when KIT_SYSROOT +# is an invalid authoritative value. +run_ok freestanding-opt-out /usr/bin/env KIT_SYSROOT="$work/missing-sdk" \ + PATH="$isolated_path" KIT_XCRUN_SENTINEL_LOG="$work/xcrun.log" \ + "$KIT" cc -target aarch64-apple-darwin -ffreestanding -nostdinc \ + -c "$work/freestanding.c" -o "$work/freestanding.o" + +run_ok direct-ld-object /usr/bin/env -u KIT_SYSROOT \ + PATH="$isolated_path" KIT_XCRUN_SENTINEL_LOG="$work/xcrun.log" \ + "$KIT" cc -target aarch64-apple-darwin -ffreestanding -nostdinc \ + -c "$work/start.c" -o "$work/start.o" +run_ok direct-ld-unhosted /usr/bin/env KIT_SYSROOT="$work/missing-sdk" \ + PATH="$isolated_path" KIT_XCRUN_SENTINEL_LOG="$work/xcrun.log" \ + "$KIT" ld -e _start "$work/start.o" -o "$work/direct-ld" +run_fail direct-ld-hosted-needs-sdk /usr/bin/env \ + KIT_SYSROOT="$work/missing-sdk" PATH="$isolated_path" \ + KIT_XCRUN_SENTINEL_LOG="$work/xcrun.log" \ + "$KIT" ld -lc -e _start "$work/start.o" -o "$work/direct-ld-hosted" +contains direct-ld-hosted-sdk-diagnostic \ + "$work/direct-ld-hosted-needs-sdk.err" "sysroot not found" + +run_fail cross-os-does-not-borrow-sdk /usr/bin/env -u KIT_SYSROOT \ + PATH="$isolated_path" KIT_XCRUN_SENTINEL_LOG="$work/xcrun.log" \ + "$KIT" cc -target aarch64-linux-gnu -lc "$work/hosted.c" \ + -o "$work/cross-linux" + +if [ ! -s "$work/xcrun.log" ]; then + ok no-xcrun-dependency +else + not_ok no-xcrun-dependency "$work/xcrun.log" +fi + +kit_summary native-macos-sdk +kit_exit diff --git a/test/driver/run.sh b/test/driver/run.sh @@ -504,6 +504,7 @@ fi # (independent of a native SDK). The Linux expansion uses the standard FHS # sysroot layout: libc/kernel headers under <sysroot>/usr/include (plus the # glibc multiarch subdir) and libraries under <sysroot>/usr/lib. +mkdir -p "$work/sr" if KIT_SYSROOT="$work/sr" "$KIT" cc -print-search-dirs -lc -target x86_64-linux \ > "$work/cc-searchdirs.out" 2> "$work/cc-searchdirs.err" && grep -q "$work/sr/usr/lib" "$work/cc-searchdirs.out" && @@ -516,11 +517,12 @@ else fi # ---- cc -print-sysroot echoes the effective explicit sysroot ---- -if [ "$("$KIT" cc -print-sysroot --sysroot /opt/sdkx 2>/dev/null)" = "/opt/sdkx" ] && - [ "$(KIT_SYSROOT=/opt/sdky "$KIT" cc -print-sysroot 2>/dev/null)" = "/opt/sdky" ]; then +mkdir -p "$work/sdkx" "$work/sdky" +if [ "$("$KIT" cc -print-sysroot --sysroot "$work/sdkx" 2>/dev/null)" = "$work/sdkx" ] && + [ "$(KIT_SYSROOT="$work/sdky" "$KIT" cc -print-sysroot 2>/dev/null)" = "$work/sdky" ]; then ok "cc-print-sysroot" else - "$KIT" cc -print-sysroot --sysroot /opt/sdkx > "$work/cc-psysroot.diag" 2>&1 + "$KIT" cc -print-sysroot --sysroot "$work/sdkx" > "$work/cc-psysroot.diag" 2>&1 not_ok "cc-print-sysroot" "$work/cc-psysroot.diag" fi diff --git a/test/driver/targets.sh b/test/driver/targets.sh @@ -0,0 +1,105 @@ +#!/bin/sh +# Public target-profile registry and `kit targets` acceptance (KIT-P1-001). + +set -u + +script_dir=$(CDPATH= cd -- "$(dirname "$0")" && pwd) +repo_root=$(CDPATH= cd -- "$script_dir/../.." && pwd) +KIT=${KIT:-$repo_root/build/kit} +KIT_KIT_DIR=$repo_root/test/lib +. "$repo_root/test/lib/kit_sh_kit.sh" + +kit_require_kit driver-targets +kit_report_init +kit_workdir driver-targets +work=$KIT_WORK + +audited='linux-glibc-aa64 linux-glibc-x64 linux-glibc-rv64 +linux-musl-aa64 linux-musl-x64 linux-musl-rv64 +freebsd-aa64 freebsd-x64 freebsd-rv64 +windows-aa64 windows-x64 android-aa64 macos-aa64 macos-x64 +freestanding-aa64 freestanding-x64 freestanding-rv64 freestanding-rv32 +freestanding-arm32' + +run_ok tsv "$KIT" targets --format=tsv +if awk -F '\t' ' + NR == 1 { if ($0 != "# kit-targets-v1") exit 1; next } + NR == 2 { + if ($0 != "selector\ttriple\tarch\tos\tobject\thosted\tlibc\tsysroot\tcapabilities\tprovisioning") exit 1 + next + } + NF != 10 { exit 1 } + { if (seen[$1]++) exit 1; records++ } + END { if (records < 19) exit 1 } + ' "$work/tsv.out"; then + ok tsv-schema-and-unique-records +else + not_ok tsv-schema-and-unique-records "$work/tsv.out" +fi + +for selector in $audited; do + if awk -F '\t' -v want="$selector" '$1 == want { found = 1 } + END { exit found ? 0 : 1 }' "$work/tsv.out"; then + ok "registry-$selector" + else + not_ok "registry-$selector" "$work/tsv.out" + fi +done + +if awk -F '\t' '$1 == "wasm32-wasi" { wasi = 1 } + $1 == "wasm32-freestanding" { bare = 1 } + END { exit wasi && bare ? 0 : 1 }' "$work/tsv.out"; then + ok registry-compiled-wasm-extras +else + not_ok registry-compiled-wasm-extras "$work/tsv.out" +fi + +if awk -F '\t' ' + NR <= 2 { next } + $1 ~ /^(windows|macos|ios)/ && ("," $9 ",") ~ /,shared,/ { exit 1 } + $1 ~ /^(linux-(glibc|musl)|freebsd)-/ && + ("," $9 ",") !~ /,shared,/ { exit 1 } + $1 == "android-aa64" && ("," $9 ",") !~ /,shared,/ { exit 1 } + ' "$work/tsv.out"; then + ok registry-shared-capability-matches-driver +else + not_ok registry-shared-capability-matches-driver "$work/tsv.out" +fi + +run_ok triples "$KIT" targets --format=triple +if awk -F '\t' 'NR > 2 { print $2 }' "$work/tsv.out" | + cmp -s - "$work/triples.out"; then + ok triple-format-matches-registry +else + not_ok triple-format-matches-registry "$work/triples.out" +fi + +run_ok human "$KIT" targets +contains human-header "$work/human.out" "CAPABILITIES [PROVISION]" +contains human-separates-provisioning "$work/human.out" "[sysroot]" + +run_ok detail-selector "$KIT" targets linux-glibc-aa64 +run_ok detail-triple "$KIT" targets aarch64-linux-gnu +same_file detail-selector-and-triple \ + "$work/detail-selector.out" "$work/detail-triple.out" +for field in architecture os object-format pointer hosted-model libc-model \ + sysroot-model capabilities provisioning; do + contains "detail-$field" "$work/detail-selector.out" "$field:" +done + +run_ok hosted-list /usr/bin/env KIT="$KIT" "$repo_root/scripts/hosted.sh" list +if [ "$(wc -l < "$work/hosted-list.out" | tr -d ' ')" -eq 19 ]; then + ok hosted-list-count +else + not_ok hosted-list-count "$work/hosted-list.out" +fi +for selector in $audited; do + if grep -Fx "$selector" "$work/hosted-list.out" >/dev/null 2>&1; then + ok "hosted-list-$selector" + else + not_ok "hosted-list-$selector" "$work/hosted-list.out" + fi +done + +kit_summary driver-targets +kit_exit diff --git a/test/link/compat-driver.sh b/test/link/compat-driver.sh @@ -0,0 +1,67 @@ +#!/bin/sh +# Driver-side target selection checks for the public link-session +# compatibility boundary (KIT-P0-004). The C unit covers raw bytes, +# in-memory builders, archives, and DSO inputs for ELF/Mach-O/COFF; this +# focused shell layer pins explicit -target authority and implicit first-input +# inference in `kit ld`. + +set -u + +script_dir=$(CDPATH= cd -- "$(dirname "$0")" && pwd) +repo_root=$(CDPATH= cd -- "$script_dir/../.." && pwd) +KIT=${KIT:-$repo_root/build/kit} +KIT_KIT_DIR=$repo_root/test/lib +. "$repo_root/test/lib/kit_sh_kit.sh" + +kit_require_kit link-compat-driver +kit_report_init +kit_workdir link-compat-driver +work=$KIT_WORK + +fixture=$repo_root/test/cross/cases/exit.c + +run_ok x64-object "$KIT" cc -target x86_64-none-elf -ffreestanding \ + -c "$fixture" -o "$KIT_WORK/x64.o" +run_ok aa64-object "$KIT" cc -target aarch64-none-elf -ffreestanding \ + -c "$fixture" -o "$KIT_WORK/aa64.o" + +# An explicit target is authoritative. This used to be overwritten by the +# first object immediately before the public link session was created. +run_fail explicit-target-authoritative "$KIT" ld \ + -target aarch64-none-elf -r -o "$KIT_WORK/explicit-mismatch.o" \ + "$KIT_WORK/x64.o" +contains explicit-target-names-input \ + "$KIT_WORK/explicit-target-authoritative.err" "$KIT_WORK/x64.o" +contains explicit-target-expected-arch \ + "$KIT_WORK/explicit-target-authoritative.err" "expected arch=aarch64" +contains explicit-target-actual-arch \ + "$KIT_WORK/explicit-target-authoritative.err" "got arch=x86_64" + +run_ok explicit-target-match "$KIT" ld -target aarch64-none-elf -r \ + -o "$KIT_WORK/explicit-match.o" "$KIT_WORK/aa64.o" + +# Without -target, the first target-bearing object selects the effective +# target and the same public boundary rejects a later disagreement. +run_fail inferred-first-target "$KIT" ld -r \ + -o "$KIT_WORK/inferred-mismatch.o" "$KIT_WORK/x64.o" "$KIT_WORK/aa64.o" +contains inferred-first-names-input "$KIT_WORK/inferred-first-target.err" \ + "$KIT_WORK/aa64.o" +contains inferred-first-expected-arch "$KIT_WORK/inferred-first-target.err" \ + "expected arch=x86_64" +contains inferred-first-actual-arch "$KIT_WORK/inferred-first-target.err" \ + "got arch=aarch64" + +# Archive validation must inspect every member before symbol selection, so a +# foreign second member cannot hide behind an unreferenced archive entry. +run_ok mixed-archive "$KIT" ar rcs "$KIT_WORK/libmixed.a" \ + "$KIT_WORK/x64.o" "$KIT_WORK/aa64.o" +run_fail archive-foreign-member "$KIT" ld -target x86_64-none-elf -r \ + --whole-archive "$KIT_WORK/libmixed.a" \ + -o "$KIT_WORK/archive-mismatch.o" +contains archive-names-container "$KIT_WORK/archive-foreign-member.err" \ + "$KIT_WORK/libmixed.a" +contains archive-names-member "$KIT_WORK/archive-foreign-member.err" \ + "aa64.o" + +kit_summary link-compat-driver +kit_exit diff --git a/test/link/riscv-flags.sh b/test/link/riscv-flags.sh @@ -0,0 +1,109 @@ +#!/bin/sh +# RISC-V psABI ELF e_flags merge/oracle coverage (KIT-P1-004). + +set -u + +script_dir=$(CDPATH= cd -- "$(dirname "$0")" && pwd) +repo_root=$(CDPATH= cd -- "$script_dir/../.." && pwd) +KIT=${KIT:-$repo_root/build/kit} +KIT_KIT_DIR=$repo_root/test/lib +. "$repo_root/test/lib/kit_sh_kit.sh" + +kit_require_kit riscv-flags +kit_report_init +kit_workdir riscv-flags +work=$KIT_WORK + +READELF=$(command -v llvm-readelf 2>/dev/null || command -v readelf 2>/dev/null || true) +if [ -z "$READELF" ]; then + skip_test riscv-flags "llvm-readelf/readelf is required as the independent oracle" + kit_summary riscv-flags + kit_exit +fi + +main_src=$repo_root/test/tier1/kitchen/cross/shared_main.c +dep_src=$repo_root/test/tier1/kitchen/cross/shared_dep.c + +check_flags() { + label=$1 + file=$2 + want=$3 + if "$READELF" -h "$file" > "$work/$label.readelf" \ + 2> "$work/$label.readelf.err" && + grep -E "Flags:[[:space:]]*$want([,[:space:]]|$)" \ + "$work/$label.readelf" >/dev/null 2>&1; then + ok "$label" + else + { + printf 'expected ELF flags %s\n' "$want" + sed 's/^/readelf: /' "$work/$label.readelf" 2>/dev/null + sed 's/^/err: /' "$work/$label.readelf.err" 2>/dev/null + } > "$work/$label.diag" + not_ok "$label" "$work/$label.diag" + fi +} + +build_variant() { + tag=$1 + triple=$2 + march=$3 + mabi=$4 + want=$5 + + run_ok "$tag-main" "$KIT" cc -target "$triple" -march="$march" \ + -mabi="$mabi" -ffreestanding -c "$main_src" -o "$work/$tag-main.o" + run_ok "$tag-dep" "$KIT" cc -target "$triple" -march="$march" \ + -mabi="$mabi" -ffreestanding -c "$dep_src" -o "$work/$tag-dep.o" + run_ok "$tag-relocatable" "$KIT" ld -r -o "$work/$tag-merged.o" \ + "$work/$tag-main.o" "$work/$tag-dep.o" + check_flags "$tag-relocatable-flags" "$work/$tag-merged.o" "$want" + run_ok "$tag-final" "$KIT" cc -target "$triple" -march="$march" \ + -mabi="$mabi" -nostdlib -Wl,-e,main "$work/$tag-main.o" \ + "$work/$tag-dep.o" -o "$work/$tag.elf" + check_flags "$tag-final-flags" "$work/$tag.elf" "$want" +} + +build_variant rv32-soft riscv32-none-elf \ + rv32imac_zicsr_zifencei ilp32 0x1 +build_variant rv32-single riscv32-none-elf \ + rv32imafc_zicsr_zifencei ilp32f 0x3 +build_variant rv64-soft riscv64-none-elf \ + rv64imac_zicsr_zifencei lp64 0x1 +build_variant rv64-double riscv64-none-elf \ + rv64imafdc_zicsr_zifencei lp64d 0x5 + +run_fail rv32-mixed-float "$KIT" ld -r -o "$work/rv32-mixed.o" \ + "$work/rv32-soft-main.o" "$work/rv32-single-dep.o" +contains rv32-mixed-names-first "$work/rv32-mixed-float.err" \ + "rv32-soft-main.o" +contains rv32-mixed-float-diagnostic "$work/rv32-mixed-float.err" \ + "float ABI mismatch" + +run_fail rv64-mixed-float "$KIT" ld -r -o "$work/rv64-mixed.o" \ + "$work/rv64-soft-main.o" "$work/rv64-double-dep.o" +contains rv64-mixed-names-first "$work/rv64-mixed-float.err" \ + "rv64-soft-main.o" +contains rv64-mixed-float-diagnostic "$work/rv64-mixed-float.err" \ + "float ABI mismatch" + +# RVC is a mergeable presence bit. A non-C object remains unmarked on its own, +# then combining it with a C-enabled peer retains RVC in partial and final +# links while preserving the agreed double-float ABI. +run_ok rv64-double-noc-main "$KIT" cc -target riscv64-none-elf \ + -march=rv64imafd_zicsr_zifencei -mabi=lp64d -ffreestanding \ + -c "$main_src" -o "$work/rv64-double-noc-main.o" +check_flags rv64-double-noc-object-flags \ + "$work/rv64-double-noc-main.o" 0x4 +run_ok rv64-rvc-merge-relocatable "$KIT" ld -r \ + -o "$work/rv64-rvc-merged.o" "$work/rv64-double-noc-main.o" \ + "$work/rv64-double-dep.o" +check_flags rv64-rvc-merge-relocatable-flags \ + "$work/rv64-rvc-merged.o" 0x5 +run_ok rv64-rvc-merge-final "$KIT" cc -target riscv64-none-elf \ + -march=rv64imafdc_zicsr_zifencei -mabi=lp64d -nostdlib -Wl,-e,main \ + "$work/rv64-double-noc-main.o" "$work/rv64-double-dep.o" \ + -o "$work/rv64-rvc-merged.elf" +check_flags rv64-rvc-merge-final-flags "$work/rv64-rvc-merged.elf" 0x5 + +kit_summary riscv-flags +kit_exit diff --git a/test/tier1/cross/run.sh b/test/tier1/cross/run.sh @@ -134,23 +134,40 @@ hosted_lane() { fi } +android_api_lane() { + local sysroot="$1" api="$2" label="android-aa64:api$2" triple dir pp obj so + triple="aarch64-linux-android$api" + dir="$WORK/$label" + mkdir -p "$dir" + pp="$dir/native_activity.i" + obj="$dir/native_activity.o" + so="$dir/libkit_native_activity.so" + run_cmd "$label:cpp" "$dir/cpp.log" \ + "$KIT" cpp -target "$triple" --sysroot "$sysroot" \ + -DKIT_EXPECT_ANDROID_API="$api" "$CASES/native_activity.c" -o "$pp" || return 0 + run_cmd "$label:cc" "$dir/cc.log" \ + "$KIT" cc -target "$triple" --sysroot "$sysroot" -O1 -fPIC \ + -DKIT_EXPECT_ANDROID_API="$api" -c "$CASES/native_activity.c" -o "$obj" || return 0 + run_cmd "$label:ld" "$dir/ld.log" \ + "$KIT" cc -target "$triple" --sysroot "$sysroot" -shared \ + "$obj" -landroid -o "$so" || return 0 + if [ -s "$pp" ] && [ -s "$so" ]; then + kit_pass "$label" + else + kit_fail "$label" "preprocessed/shared artifact missing" + fi +} + android_lane() { - local token=android-aa64 label=android-aa64 sysroot dir obj so + local token=android-aa64 label=android-aa64 sysroot match_selector "$token" || return 0 sysroot="$(hosted_path "$token")" if [ -z "$sysroot" ] || [ ! -d "$sysroot" ]; then kit_skip "$label" "Android NDK sysroot not provisioned; run: make provision TARGET=$token" return 0 fi - dir="$WORK/$label" - mkdir -p "$dir" - obj="$dir/native_activity.o" - so="$dir/libkit_native_activity.so" - run_cmd "$label:cc" "$dir/cc.log" \ - "$HOSTED" cc "$token" -O1 -fPIC -c "$CASES/native_activity.c" -o "$obj" || return 0 - run_cmd "$label:ld" "$dir/ld.log" \ - "$HOSTED" cc "$token" -shared "$obj" -landroid -o "$so" || return 0 - if [ -s "$so" ]; then kit_pass "$label"; else kit_fail "$label" "shared object missing"; fi + android_api_lane "$sysroot" 21 + android_api_lane "$sysroot" 35 android_shared_lane "$sysroot" }