commit 8440ab571797c9c35477c6d268671434fe56989e
parent 4d24e95c01735144146862e1c467e1bd0372d4a1
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Wed, 17 Jun 2026 12:07:24 -0700
arm32: fix O1 frameless-leaf return-address clobber (save lr in slim tier)
A leaf returning via a bare BX lr is unsafe on arm32: the backend uses lr
(ARM_TMP) pervasively as an emit-time scratch (global-address staging in
arm_resolve_mem, the __builtin_*_overflow sequences, popcount, bitfield insert,
the byte-copy granule engine). A frameless leaf that hit any of those clobbered
its return address and branched into garbage — e.g. 'static int g; return g;'
at -O1 staged &g into lr, then BX lr jumped to &g (qemu rc 134). aa64/rv64 keep
their return-address register out of the scratch pool so their frameless leaves
are safe; arm32 is register-starved and cannot.
Change the slim_prologue tier from truly-frameless (BX lr) to a minimal leaf
frame: PUSH {lr} / POP {pc} (no r7 anchor, no SUB sp), so the body is free to
clobber lr and the saved return address is restored on exit. Costs +2 bytes per
such leaf; correctness over density.
Fixes the 16-case O1 globals/statics/attributes parse-corpus cluster (all now
pass at O0 and O1); toy cross holds 423/0/2.
Diffstat:
14 files changed, 97 insertions(+), 69 deletions(-)
diff --git a/mk/env.mk b/mk/env.mk
@@ -90,6 +90,13 @@ HOST_SYSROOT_LDFLAGS := -isysroot $(HOST_SDK_PATH)
endif
endif
+# ---- user-level sysroot cache dir -----------------------------------------
+# Mirrors the XDG convention used by the per-OS provisioner scripts.
+# Override by setting XDG_CACHE_HOME or KIT_CACHE_DIR in the environment.
+XDG_CACHE_HOME ?= $(HOME)/.cache
+KIT_CACHE_DIR ?= $(XDG_CACHE_HOME)/kit
+KIT_SYSROOTS_DIR ?= $(KIT_CACHE_DIR)/sysroots
+
# ---- per-OS env wiring -----------------------------------------------------
DRIVER_ENV_OS_CFLAGS :=
diff --git a/mk/test.mk b/mk/test.mk
@@ -744,8 +744,10 @@ COFF_IMPORT_MINGW_BIN = build/test/pe-import-mingw
COFF_DSO_FORWARDER_BIN = build/test/pe-dso-forwarder
COFF_MIXED_ARCHIVE_BIN = build/test/pe-mixed-archive
COFF_IMAGE_READ_BIN = build/test/pe-image-read
-LLVM_MINGW_SYSROOT_X64_MARKER = build/llvm-mingw/20260602/ucrt/x86_64-w64-mingw32/PROVENANCE
-LLVM_MINGW_SYSROOT_AARCH64_MARKER = build/llvm-mingw/20260602/ucrt/aarch64-w64-mingw32/PROVENANCE
+LLVM_MINGW_RELEASE := 20260602
+_LLVM_MINGW_UCRT_ROOT = $(or $(KIT_LLVM_MINGW_ROOT),$(KIT_SYSROOTS_DIR)/windows/$(LLVM_MINGW_RELEASE)/ucrt)
+LLVM_MINGW_SYSROOT_X64_MARKER = $(_LLVM_MINGW_UCRT_ROOT)/x86_64-w64-mingw32/PROVENANCE
+LLVM_MINGW_SYSROOT_AARCH64_MARKER = $(_LLVM_MINGW_UCRT_ROOT)/aarch64-w64-mingw32/PROVENANCE
JIT_RUNNER = build/test/jit-runner
PARSE_RUNNER = build/test/parse-runner
ASM_RUNNER = build/test/asm-runner
@@ -859,12 +861,12 @@ test-coff-mingw-import: lib $(COFF_IMPORT_MINGW_BIN)
$(COFF_IMPORT_MINGW_BIN)
test-coff-windows-ucrt: bin rt-x86_64-pc-windows rt-aarch64-windows windows-ucrt-sysroots
- KIT_SYSROOT=$(abspath build/llvm-mingw/20260602/ucrt) bash test/coff/windows-ucrt-hosted-smoke.sh
- KIT_SYSROOT=$(abspath build/llvm-mingw/20260602/ucrt) bash test/coff/windows-system-dlls-smoke.sh
- KIT_SYSROOT=$(abspath build/llvm-mingw/20260602/ucrt) bash test/coff/windows-o1-abi-smoke.sh
+ KIT_SYSROOT=$(abspath $(_LLVM_MINGW_UCRT_ROOT)) bash test/coff/windows-ucrt-hosted-smoke.sh
+ KIT_SYSROOT=$(abspath $(_LLVM_MINGW_UCRT_ROOT)) bash test/coff/windows-system-dlls-smoke.sh
+ KIT_SYSROOT=$(abspath $(_LLVM_MINGW_UCRT_ROOT)) bash test/coff/windows-o1-abi-smoke.sh
test-coff-windows-o1-abi: bin rt-x86_64-pc-windows rt-aarch64-windows windows-ucrt-sysroots
- KIT_SYSROOT=$(abspath build/llvm-mingw/20260602/ucrt) bash test/coff/windows-o1-abi-smoke.sh
+ KIT_SYSROOT=$(abspath $(_LLVM_MINGW_UCRT_ROOT)) bash test/coff/windows-o1-abi-smoke.sh
# Opt-in: run the COFF/PE hosted smokes against a real Windows 11 ARM64 VM, so
# their per-program run lanes execute for real instead of self-skipping. On
@@ -878,7 +880,7 @@ KIT_WINDOWS_VM_PORT ?= 2227
# SSH key is left unset so windows_vm.sh uses its default in the durable cache
# (~/.cache/kit/windows-vm/ssh/id_ed25519); the working disk auto-restores from
# the cached golden, so a clean build/ still finds a ready VM.
-_WIN_VM_ENV = KIT_SYSROOT=$(abspath build/llvm-mingw/20260602/ucrt) \
+_WIN_VM_ENV = KIT_SYSROOT=$(abspath $(_LLVM_MINGW_UCRT_ROOT)) \
KIT_WINDOWS_VM_AARCH64=$(KIT_WINDOWS_VM_USER)@127.0.0.1 KIT_WINDOWS_VM_AARCH64_PORT=$(KIT_WINDOWS_VM_PORT) \
KIT_WINDOWS_VM_X64=$(KIT_WINDOWS_VM_USER)@127.0.0.1 KIT_WINDOWS_VM_X64_PORT=$(KIT_WINDOWS_VM_PORT)
@@ -907,10 +909,10 @@ test-link-x64: lib rt-x86_64-linux $(ROUNDTRIP_BIN) $(LINK_EXE_RUNNER) $(JIT_RUN
# test-link-dso-aa64: ELF shared-library (DSO) harness targeting aarch64-linux.
# Uses kit cc/ld to produce DSOs and freestanding consumers, runs readelf
# structural checks, and executes consumers inside podman containers when
-# provisioned. The make target provisions build/musl-sysroot so the libc
+# provisioned. The make target provisions the musl sysroot so the libc
# dependency lane is active; direct script runs skip that lane if it is absent.
# Opt-in: requires readelf; runtime checks need provisioned images.
-test-link-dso-aa64: bin build/musl-sysroot/PROVENANCE
+test-link-dso-aa64: bin $(MUSL_SYSROOT_MARKER)
bash test/link/elf-dso-aa64/run.sh
test-macho: lib $(TEST_RT_DEP) $(ROUNDTRIP_BIN_MACHO) $(LINK_EXE_RUNNER) $(JIT_RUNNER)
@@ -1320,12 +1322,12 @@ test-bounce: $(BIN)
# Each sysroot is treated as a real prerequisite via its PROVENANCE
# marker so subsequent runs skip extraction and re-extract only when
# the file is removed (or extract.sh -f forces a rebuild).
-MUSL_SYSROOT_MARKER = build/musl-sysroot/PROVENANCE
-MUSL_SYSROOT_X64_MARKER = build/musl-sysroot-x64/PROVENANCE
-MUSL_SYSROOT_RV64_MARKER = build/musl-sysroot-rv64/PROVENANCE
-GLIBC_SYSROOT_MARKER = build/glibc-sysroot/PROVENANCE
-GLIBC_SYSROOT_X64_MARKER = build/glibc-sysroot-x64/PROVENANCE
-GLIBC_SYSROOT_RV64_MARKER = build/glibc-sysroot-rv64/PROVENANCE
+MUSL_SYSROOT_MARKER = $(KIT_SYSROOTS_DIR)/linux-musl/PROVENANCE
+MUSL_SYSROOT_X64_MARKER = $(KIT_SYSROOTS_DIR)/linux-musl-x64/PROVENANCE
+MUSL_SYSROOT_RV64_MARKER = $(KIT_SYSROOTS_DIR)/linux-musl-rv64/PROVENANCE
+GLIBC_SYSROOT_MARKER = $(KIT_SYSROOTS_DIR)/linux-glibc/PROVENANCE
+GLIBC_SYSROOT_X64_MARKER = $(KIT_SYSROOTS_DIR)/linux-glibc-x64/PROVENANCE
+GLIBC_SYSROOT_RV64_MARKER = $(KIT_SYSROOTS_DIR)/linux-glibc-rv64/PROVENANCE
$(MUSL_SYSROOT_MARKER): test/libc/musl/extract.sh test/libc/musl/Containerfile
@bash test/libc/musl/extract.sh
diff --git a/scripts/freebsd_sysroot.sh b/scripts/freebsd_sysroot.sh
@@ -15,7 +15,8 @@
#
# env:
# KIT_FREEBSD_RELEASE release tag (default: 15.0-RELEASE)
-# KIT_FREEBSD_SYSROOT_CACHE cache root (default: $XDG_CACHE_HOME/kit/freebsd-sysroot/<release>)
+# KIT_FREEBSD_SYSROOT_CACHE sysroot extract root (default: $XDG_CACHE_HOME/kit/sysroots/freebsd/<release>)
+# KIT_FREEBSD_DIST_CACHE download tarball cache (default: $XDG_CACHE_HOME/kit/freebsd-dist/<release>)
# KIT_FREEBSD_DIST_URL mirror base (default: https://download.freebsd.org/releases)
# FORCE=1 re-download / re-extract even if cached
@@ -23,7 +24,8 @@ set -eu
RELEASE="${KIT_FREEBSD_RELEASE:-15.0-RELEASE}"
XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}"
-CACHE="${KIT_FREEBSD_SYSROOT_CACHE:-$XDG_CACHE_HOME/kit/freebsd-sysroot/$RELEASE}"
+CACHE="${KIT_FREEBSD_SYSROOT_CACHE:-$XDG_CACHE_HOME/kit/sysroots/freebsd/$RELEASE}"
+DIST_CACHE="${KIT_FREEBSD_DIST_CACHE:-$XDG_CACHE_HOME/kit/freebsd-dist/$RELEASE}"
MIRROR="${KIT_FREEBSD_DIST_URL:-https://download.freebsd.org/releases}"
die() { printf 'freebsd-sysroot: %s\n' "$*" >&2; exit 1; }
@@ -81,8 +83,8 @@ fetch_txz() {
local arch="$1" dp url txz want got
dp="$(dist_path "$arch")"
url="$MIRROR/$dp/$RELEASE/base.txz"
- txz="$CACHE/dist/$arch-base.txz"
- mkdir -p "$CACHE/dist"
+ txz="$DIST_CACHE/$arch-base.txz"
+ mkdir -p "$DIST_CACHE"
if [ "${FORCE:-0}" = 1 ] || [ ! -f "$txz" ]; then
printf 'download %s\n' "$url" >&2
curl -fL --retry 3 -o "$txz.tmp" "$url" || die "download failed: $url"
diff --git a/scripts/hosted.sh b/scripts/hosted.sh
@@ -198,7 +198,7 @@ modes_of() {
_linux_sysroot_dir() { # libc arch
local libc="$1" arch="$2" suf=""
case "$arch" in x64) suf=-x64 ;; rv64) suf=-rv64 ;; esac
- printf '%s/build/%s-sysroot%s' "$ROOT" "$libc" "$suf"
+ printf '%s/sysroots/linux-%s%s' "${XDG_CACHE_HOME:-$HOME/.cache}/kit" "$libc" "$suf"
}
path_of() {
diff --git a/scripts/llvm_mingw_sysroot.sh b/scripts/llvm_mingw_sysroot.sh
@@ -26,7 +26,7 @@ cache_root() {
}
DL_ROOT="$(cache_root)"
-OUT_ROOT="${KIT_LLVM_MINGW_ROOT:-$ROOT/build/llvm-mingw/$RELEASE/ucrt}"
+OUT_ROOT="${KIT_LLVM_MINGW_ROOT:-${XDG_CACHE_HOME:-$HOME/.cache}/kit/sysroots/windows/$RELEASE/ucrt}"
usage() {
cat <<EOF
diff --git a/src/arch/arm32/native.c b/src/arch/arm32/native.c
@@ -1379,20 +1379,29 @@ static void arm_func_begin_known_frame(NativeTarget* t, const CGFuncDesc* fd,
a->saved_reglist = (u16)reglist;
a->saved_block_bytes = nsaved * 4u;
- /* Leaf no-frame tier (aa64 slim_prologue / rv frameless equivalent): a leaf
- * with no callee-saves, no body slots, no outgoing args, no sret/variadic and
- * only register params never touches the stack or clobbers lr, so emit no
- * prologue at all and let arm_func_end emit a bare `BX lr`. Inline asm cannot
- * occur (asm_block is not installed), so no opaque-lr-clobber guard is needed.
- */
+ /* Leaf minimal-frame tier (the register-starved analog of the aa64/rv64
+ * frameless leaf): a leaf with no callee-saves, no body slots, no outgoing
+ * args, no sret/variadic and only register params needs no frame record, no r7
+ * anchor and no SUB sp. It cannot, however, return through a bare `BX lr`:
+ * arm32 is register-starved and uses lr (ARM_TMP) pervasively as an emit-time
+ * scratch — global-address staging in arm_resolve_mem, the `__builtin_*_overflow`
+ * sequences, popcount, bitfield insert, the byte-copy granule engine — any of
+ * which a leaf body may hit (e.g. `static int g; return g;` stages &g into lr,
+ * after which a bare `BX lr` would branch to &g). So the tier still saves and
+ * restores the return address with a single-register `PUSH {lr}` / `POP {pc}`,
+ * leaving the body free to clobber lr; it just skips the r7 frame record and
+ * the stack reservation. (aa64/rv64 keep their return-address register out of
+ * the scratch pool, so their frameless leaves skip even this push; arm32
+ * cannot.) Inline asm cannot occur here (asm_block is not installed). */
a->slim_prologue = kf && kf->is_leaf && !kf->reads_frame && cs_mask == 0 &&
!a->frame.has_alloca && a->frame.cum_off == 0 &&
a->frame.max_outgoing == 0 && !a->has_sret &&
!a->is_variadic &&
arm_signature_stack_bytes(t, fd->fn_type, NULL, NULL) == 0;
if (a->slim_prologue) {
- a->saved_reglist = 0;
- a->saved_block_bytes = 0;
+ a->saved_reglist = (u16)(1u << 14u); /* {lr} */
+ a->saved_block_bytes = 4u;
+ arm_emit_push(mc, 1u << 14u); /* PUSH {lr} (16-bit, 0xb500) */
native_frame_set_final(&a->frame);
return;
}
@@ -1452,8 +1461,10 @@ static void arm_func_end(NativeTarget* t) {
/* Place the epilogue and emit the teardown. */
mc_label_place(mc, a->epilogue_label);
if (a->slim_prologue)
- /* Frameless leaf: nothing saved, sp untouched — return through lr directly. */
- arm_emit_t16(mc, arm_bx(14u)); /* BX lr */
+ /* Minimal leaf: only lr was saved (PUSH {lr}); pop it straight into pc. This
+ * restores the return address the body may have clobbered using lr as an
+ * emit scratch — see the func_begin slim_prologue note. */
+ arm_emit_pop(mc, 1u << 15u); /* POP {pc} (16-bit, 0xbd00) */
else
arm_emit_frame_restore(a, /*to_pc=*/1);
diff --git a/test/coff/windows-o1-abi-smoke.sh b/test/coff/windows-o1-abi-smoke.sh
@@ -22,6 +22,7 @@ find_sdk() {
local arch=$1
local d
for d in \
+ "${XDG_CACHE_HOME:-$HOME/.cache}"/kit/sysroots/windows/*/ucrt/"$arch"-w64-mingw32 \
"$ROOT"/build/llvm-mingw/*/ucrt/"$arch"-w64-mingw32 \
/tmp/llvm-mingw*/llvm-mingw-*-ucrt-*/"$arch"-w64-mingw32 \
/tmp/llvm-mingw*/"$arch"-w64-mingw32 \
diff --git a/test/coff/windows-system-dlls-smoke.sh b/test/coff/windows-system-dlls-smoke.sh
@@ -39,6 +39,7 @@ find_sdk() {
local arch=$1
local d
for d in \
+ "${XDG_CACHE_HOME:-$HOME/.cache}"/kit/sysroots/windows/*/ucrt/"$arch"-w64-mingw32 \
"$ROOT"/build/llvm-mingw/*/ucrt/"$arch"-w64-mingw32 \
/tmp/llvm-mingw*/llvm-mingw-*-ucrt-*/"$arch"-w64-mingw32 \
/tmp/llvm-mingw*/"$arch"-w64-mingw32 \
diff --git a/test/coff/windows-ucrt-hosted-smoke.sh b/test/coff/windows-ucrt-hosted-smoke.sh
@@ -28,6 +28,7 @@ find_sdk() {
local arch=$1
local d
for d in \
+ "${XDG_CACHE_HOME:-$HOME/.cache}"/kit/sysroots/windows/*/ucrt/"$arch"-w64-mingw32 \
"$ROOT"/build/llvm-mingw/*/ucrt/"$arch"-w64-mingw32 \
/tmp/llvm-mingw*/llvm-mingw-*-ucrt-*/"$arch"-w64-mingw32 \
/tmp/llvm-mingw*/"$arch"-w64-mingw32 \
diff --git a/test/libc/glibc/extract.sh b/test/libc/glibc/extract.sh
@@ -1,25 +1,24 @@
#!/usr/bin/env bash
# test/libc/glibc/extract.sh — build a glibc sysroot container image
-# and unpack /sysroot from it into build/glibc-sysroot[-ARCH]/ on the
-# host. Cached after the first successful run; pass `-f` to force a
+# and unpack /sysroot from it into $XDG_CACHE_HOME/kit/sysroots/linux-glibc[-ARCH]/. Cached after the first successful run; pass `-f` to force a
# rebuild.
#
# Usage:
-# extract.sh # default aarch64 -> build/glibc-sysroot/
+# extract.sh # default aarch64 -> $XDG_CACHE_HOME/kit/sysroots/linux-glibc/
# extract.sh -a aarch64 # same as default
-# extract.sh -a x64 # x86_64 -> build/glibc-sysroot-x64/
-# extract.sh -a rv64 # riscv64 -> build/glibc-sysroot-rv64/
+# extract.sh -a x64 # x86_64 -> $XDG_CACHE_HOME/kit/sysroots/linux-glibc-x64/
+# extract.sh -a rv64 # riscv64 -> $XDG_CACHE_HOME/kit/sysroots/linux-glibc-rv64/
#
# Arch-specific Containerfiles live next to this script
# (Containerfile, Containerfile.x64, Containerfile.rv64).
#
-# The aarch64 sysroot keeps the historical bare `build/glibc-sysroot/`
-# path so test-libc-glibc (the kit-ld aarch64 harness) is unaffected.
-# test-libc on Linux uses the arch-suffixed paths uniformly and
-# re-targets `build/glibc-sysroot/` for aarch64.
+# The aarch64 sysroot uses the bare `glibc-sysroot` name (no arch suffix)
+# for consistency with existing test-libc-glibc usage. test-libc on Linux
+# uses the arch-suffixed paths uniformly and re-targets `glibc-sysroot`
+# for aarch64.
#
# Output layout (per arch):
-# build/glibc-sysroot[-ARCH]/
+# $XDG_CACHE_HOME/kit/sysroots/linux-glibc[-ARCH]/
# lib/ Scrt1.o crti.o crtn.o libc_nonshared.a libc.so.6 ...
# lib64/ (x64 only) ld-linux-x86-64.so.2
# include/ glibc + linux uapi tree
@@ -27,6 +26,7 @@
set -eu
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
+_KIT_SYSROOTS="${XDG_CACHE_HOME:-$HOME/.cache}/kit/sysroots"
ARCH=aarch64
FORCE=0
@@ -41,19 +41,19 @@ done
case "$ARCH" in
aarch64)
- SYSROOT="$ROOT/build/glibc-sysroot"
+ SYSROOT="$_KIT_SYSROOTS/linux-glibc"
PLATFORM="linux/arm64"
CFILE="Containerfile"
TAG="kit-glibc-sysroot"
;;
x64)
- SYSROOT="$ROOT/build/glibc-sysroot-x64"
+ SYSROOT="$_KIT_SYSROOTS/linux-glibc-x64"
PLATFORM="linux/amd64"
CFILE="Containerfile.x64"
TAG="kit-glibc-sysroot-x64"
;;
rv64)
- SYSROOT="$ROOT/build/glibc-sysroot-rv64"
+ SYSROOT="$_KIT_SYSROOTS/linux-glibc-rv64"
PLATFORM="linux/riscv64"
CFILE="Containerfile.rv64"
TAG="kit-glibc-sysroot-rv64"
diff --git a/test/libc/glibc/run.sh b/test/libc/glibc/run.sh
@@ -41,17 +41,18 @@
#
# Arch selection — KIT_LIBC_ARCHES (default "aa64"), space-separated; each
# token becomes an "<arch>-elf" corpus tuple:
-# aa64 -> build/glibc-sysroot/ + build/rt/aarch64-linux/libkit_rt.a
+# aa64 -> $XDG_CACHE_HOME/kit/sysroots/linux-glibc/ + build/rt/aarch64-linux/libkit_rt.a
# + --target=aarch64-linux-gnu
-# x64 -> build/glibc-sysroot-x64/ + build/rt/x86_64-linux/libkit_rt.a
+# x64 -> $XDG_CACHE_HOME/kit/sysroots/linux-glibc-x64/ + build/rt/x86_64-linux/libkit_rt.a
# + --target=x86_64-linux-gnu
-# rv64 -> build/glibc-sysroot-rv64/ + build/rt/riscv64-linux/libkit_rt.a
+# rv64 -> $XDG_CACHE_HOME/kit/sysroots/linux-glibc-rv64/ + build/rt/riscv64-linux/libkit_rt.a
# + --target=riscv64-linux-gnu
# A missing sysroot / rt / clang-target for an enabled arch is reported as a
# non-gating SKIP-NA (never a failure); only test failures cause a nonzero exit.
set -u
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
+_KIT_SYSROOTS="${XDG_CACHE_HOME:-$HOME/.cache}/kit/sysroots"
export KIT_LIB_DIR="$ROOT/test/lib"
. "$ROOT/test/lib/kit_corpus.sh"
@@ -71,9 +72,9 @@ mkdir -p "$BUILD_DIR"
arch_sysroot() {
case "$1" in
- aa64) echo "$ROOT/build/glibc-sysroot" ;;
- x64) echo "$ROOT/build/glibc-sysroot-x64" ;;
- rv64) echo "$ROOT/build/glibc-sysroot-rv64" ;;
+ aa64) echo "$_KIT_SYSROOTS/linux-glibc" ;;
+ x64) echo "$_KIT_SYSROOTS/linux-glibc-x64" ;;
+ rv64) echo "$_KIT_SYSROOTS/linux-glibc-rv64" ;;
*) echo "" ;;
esac
}
diff --git a/test/libc/musl/extract.sh b/test/libc/musl/extract.sh
@@ -1,30 +1,31 @@
#!/usr/bin/env bash
# test/libc/musl/extract.sh — build a musl sysroot container image and
-# unpack /sysroot from it into build/musl-sysroot[-ARCH]/ on the host.
+# unpack /sysroot from it into $XDG_CACHE_HOME/kit/sysroots/linux-musl[-ARCH]/.
# Cached after the first successful run; pass `-f` to force a rebuild.
#
# Usage:
-# extract.sh # default aarch64 -> build/musl-sysroot/
+# extract.sh # default aarch64 -> $XDG_CACHE_HOME/kit/sysroots/linux-musl/
# extract.sh -a aarch64 # same as default
-# extract.sh -a x64 # x86_64 -> build/musl-sysroot-x64/
-# extract.sh -a rv64 # riscv64 -> build/musl-sysroot-rv64/
+# extract.sh -a x64 # x86_64 -> $XDG_CACHE_HOME/kit/sysroots/linux-musl-x64/
+# extract.sh -a rv64 # riscv64 -> $XDG_CACHE_HOME/kit/sysroots/linux-musl-rv64/
#
# Arch-specific Containerfiles live next to this script
# (Containerfile, Containerfile.x64, Containerfile.rv64).
#
-# The aarch64 sysroot keeps the historical bare `build/musl-sysroot/`
-# path so test-libc-musl (the kit-ld dynamic/static aarch64 harness) is
-# unaffected. test-libc on Linux uses the arch-suffixed paths uniformly
-# and re-targets `build/musl-sysroot/` for aarch64.
+# The aarch64 sysroot uses the bare `musl-sysroot` name (no arch suffix)
+# for consistency with existing test-libc-musl usage. test-libc on Linux
+# uses the arch-suffixed paths uniformly and re-targets `musl-sysroot` for
+# aarch64.
#
# Output layout (per arch):
-# build/musl-sysroot[-ARCH]/
+# $XDG_CACHE_HOME/kit/sysroots/linux-musl[-ARCH]/
# lib/ crt1.o crti.o crtn.o libc.a libssp_nonshared.a ld-musl-*
# include/ musl + linux-headers tree
# PROVENANCE
set -eu
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
+_KIT_SYSROOTS="${XDG_CACHE_HOME:-$HOME/.cache}/kit/sysroots"
ARCH=aarch64
FORCE=0
@@ -39,19 +40,19 @@ done
case "$ARCH" in
aarch64)
- SYSROOT="$ROOT/build/musl-sysroot"
+ SYSROOT="$_KIT_SYSROOTS/linux-musl"
PLATFORM="linux/arm64"
CFILE="Containerfile"
TAG="kit-musl-sysroot"
;;
x64)
- SYSROOT="$ROOT/build/musl-sysroot-x64"
+ SYSROOT="$_KIT_SYSROOTS/linux-musl-x64"
PLATFORM="linux/amd64"
CFILE="Containerfile.x64"
TAG="kit-musl-sysroot-x64"
;;
rv64)
- SYSROOT="$ROOT/build/musl-sysroot-rv64"
+ SYSROOT="$_KIT_SYSROOTS/linux-musl-rv64"
PLATFORM="linux/riscv64"
CFILE="Containerfile.rv64"
TAG="kit-musl-sysroot-rv64"
diff --git a/test/libc/musl/run.sh b/test/libc/musl/run.sh
@@ -34,17 +34,18 @@
#
# Arch selection — KIT_LIBC_ARCHES (default "aa64"), space-separated; each
# token becomes an "<arch>-elf" corpus tuple:
-# aa64 -> build/musl-sysroot/ + build/rt/aarch64-linux/libkit_rt.a
+# aa64 -> $XDG_CACHE_HOME/kit/sysroots/linux-musl/ + build/rt/aarch64-linux/libkit_rt.a
# + --target=aarch64-linux-musl
-# x64 -> build/musl-sysroot-x64/ + build/rt/x86_64-linux/libkit_rt.a
+# x64 -> $XDG_CACHE_HOME/kit/sysroots/linux-musl-x64/ + build/rt/x86_64-linux/libkit_rt.a
# + --target=x86_64-linux-musl
-# rv64 -> build/musl-sysroot-rv64/ + build/rt/riscv64-linux/libkit_rt.a
+# rv64 -> $XDG_CACHE_HOME/kit/sysroots/linux-musl-rv64/ + build/rt/riscv64-linux/libkit_rt.a
# + --target=riscv64-linux-musl
# A missing sysroot / rt / clang-target for an enabled arch is reported as a
# non-gating SKIP-NA (never a failure); only test failures cause a nonzero exit.
set -u
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
+_KIT_SYSROOTS="${XDG_CACHE_HOME:-$HOME/.cache}/kit/sysroots"
export KIT_LIB_DIR="$ROOT/test/lib"
. "$ROOT/test/lib/kit_corpus.sh"
@@ -64,9 +65,9 @@ mkdir -p "$BUILD_DIR"
arch_sysroot() {
case "$1" in
- aa64) echo "$ROOT/build/musl-sysroot" ;;
- x64) echo "$ROOT/build/musl-sysroot-x64" ;;
- rv64) echo "$ROOT/build/musl-sysroot-rv64" ;;
+ aa64) echo "$_KIT_SYSROOTS/linux-musl" ;;
+ x64) echo "$_KIT_SYSROOTS/linux-musl-x64" ;;
+ rv64) echo "$_KIT_SYSROOTS/linux-musl-rv64" ;;
*) echo "" ;;
esac
}
diff --git a/test/link/elf-dso-aa64/run.sh b/test/link/elf-dso-aa64/run.sh
@@ -134,7 +134,7 @@ CONSUMER_GLIBC="$work/consumer-glibc"
LIBFOO_LIBC_O="$work/lib_foo_libc.o"
LIBFOO_LIBC_SO="$work/libfoo_libc.so"
CONSUMER_LIBC_MUSL="$work/consumer-libc-musl"
-MUSL_SYSROOT="${KIT_MUSL_SYSROOT:-$ROOT/build/musl-sysroot}"
+MUSL_SYSROOT="${KIT_MUSL_SYSROOT:-${XDG_CACHE_HOME:-$HOME/.cache}/kit/sysroots/linux-musl}"
SRC_DIR="$(cd "$(dirname "$0")" && pwd)"