mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00

Nolibc supports the x32 ABI on x86. Add a testcase to make sure the support stays functional. QEMU user does not have support for x32, so skip the test there. Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> Acked-by: Willy Tarreau <w@1wt.eu> Link: https://lore.kernel.org/r/20250712-nolibc-x32-v1-2-6d81cb798710@weissschuh.net
216 lines
4.8 KiB
Bash
Executable file
216 lines
4.8 KiB
Bash
Executable file
#!/bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
|
|
# Test runner for nolibc tests
|
|
|
|
set -e
|
|
|
|
trap 'echo Aborting...' 'ERR'
|
|
|
|
crosstool_version=13.2.0
|
|
hostarch=x86_64
|
|
nproc=$(( $(nproc) + 2))
|
|
cache_dir="${XDG_CACHE_HOME:-"$HOME"/.cache}"
|
|
download_location="${cache_dir}/crosstools/"
|
|
build_location="$(realpath "${cache_dir}"/nolibc-tests/)"
|
|
perform_download=0
|
|
test_mode=system
|
|
werror=1
|
|
llvm=
|
|
all_archs=(
|
|
i386 x86_64 x32
|
|
arm64 arm armthumb
|
|
mips32le mips32be mipsn32le mipsn32be mips64le mips64be
|
|
ppc ppc64 ppc64le
|
|
riscv32 riscv64
|
|
s390x s390
|
|
loongarch
|
|
sparc32 sparc64
|
|
m68k
|
|
sh4
|
|
)
|
|
archs="${all_archs[@]}"
|
|
|
|
TEMP=$(getopt -o 'j:d:c:b:a:m:pelh' -n "$0" -- "$@")
|
|
|
|
eval set -- "$TEMP"
|
|
unset TEMP
|
|
|
|
print_usage() {
|
|
cat <<EOF
|
|
Run nolibc testsuite for multiple architectures with crosstools
|
|
|
|
Usage:
|
|
$0 [options] <architectures>
|
|
|
|
Known architectures:
|
|
${archs}
|
|
|
|
Options:
|
|
-j [N] Allow N jobs at once (default: ${nproc})
|
|
-p Allow download of toolchains
|
|
-d [DIR] Download location for toolchains (default: ${download_location})
|
|
-c [VERSION] Version of toolchains to use (default: ${crosstool_version})
|
|
-a [ARCH] Host architecture of toolchains to use (default: ${hostarch})
|
|
-b [DIR] Build location (default: ${build_location})
|
|
-m [MODE] Test mode user/system (default: ${test_mode})
|
|
-e Disable -Werror
|
|
-l Build with LLVM/clang
|
|
EOF
|
|
}
|
|
|
|
while true; do
|
|
case "$1" in
|
|
'-j')
|
|
nproc="$2"
|
|
shift 2; continue ;;
|
|
'-p')
|
|
perform_download=1
|
|
shift; continue ;;
|
|
'-d')
|
|
download_location="$2"
|
|
shift 2; continue ;;
|
|
'-c')
|
|
crosstool_version="$2"
|
|
shift 2; continue ;;
|
|
'-a')
|
|
hostarch="$2"
|
|
shift 2; continue ;;
|
|
'-b')
|
|
build_location="$(realpath "$2")"
|
|
shift 2; continue ;;
|
|
'-m')
|
|
test_mode="$2"
|
|
shift 2; continue ;;
|
|
'-e')
|
|
werror=0
|
|
shift; continue ;;
|
|
'-l')
|
|
llvm=1
|
|
shift; continue ;;
|
|
'-h')
|
|
print_usage
|
|
exit 0
|
|
;;
|
|
'--')
|
|
shift; break ;;
|
|
*)
|
|
echo 'Internal error!' >&2; exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
if [[ -n "$*" ]]; then
|
|
archs="$*"
|
|
fi
|
|
|
|
crosstool_arch() {
|
|
case "$1" in
|
|
arm64) echo aarch64;;
|
|
armthumb) echo arm;;
|
|
ppc) echo powerpc;;
|
|
ppc64) echo powerpc64;;
|
|
ppc64le) echo powerpc64;;
|
|
riscv) echo riscv64;;
|
|
loongarch) echo loongarch64;;
|
|
mips*) echo mips;;
|
|
s390*) echo s390;;
|
|
sparc*) echo sparc64;;
|
|
x32*) echo x86_64;;
|
|
*) echo "$1";;
|
|
esac
|
|
}
|
|
|
|
crosstool_abi() {
|
|
case "$1" in
|
|
arm | armthumb) echo linux-gnueabi;;
|
|
*) echo linux;;
|
|
esac
|
|
}
|
|
|
|
download_crosstool() {
|
|
arch="$(crosstool_arch "$1")"
|
|
abi="$(crosstool_abi "$1")"
|
|
|
|
archive_name="${hostarch}-gcc-${crosstool_version}-nolibc-${arch}-${abi}.tar.gz"
|
|
url="https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/${hostarch}/${crosstool_version}/${archive_name}"
|
|
archive="${download_location}${archive_name}"
|
|
stamp="${archive}.stamp"
|
|
|
|
[ -f "${stamp}" ] && return
|
|
|
|
echo "Downloading crosstools ${arch} ${crosstool_version}"
|
|
mkdir -p "${download_location}"
|
|
curl -o "${archive}" --fail --continue-at - "${url}"
|
|
tar -C "${download_location}" -xf "${archive}"
|
|
touch "${stamp}"
|
|
}
|
|
|
|
# capture command output, print it on failure
|
|
# mimics chronic(1) from moreutils
|
|
function swallow_output() {
|
|
if ! OUTPUT="$("$@" 2>&1)"; then
|
|
echo "$OUTPUT"
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
test_arch() {
|
|
arch=$1
|
|
ct_arch=$(crosstool_arch "$arch")
|
|
ct_abi=$(crosstool_abi "$1")
|
|
|
|
if [ ! -d "${download_location}gcc-${crosstool_version}-nolibc/${ct_arch}-${ct_abi}/bin/." ]; then
|
|
echo "No toolchain found in ${download_location}gcc-${crosstool_version}-nolibc/${ct_arch}-${ct_abi}."
|
|
echo "Did you install the toolchains or set the correct arch ? Rerun with -h for help."
|
|
return 1
|
|
fi
|
|
|
|
cross_compile=$(realpath "${download_location}gcc-${crosstool_version}-nolibc/${ct_arch}-${ct_abi}/bin/${ct_arch}-${ct_abi}-")
|
|
build_dir="${build_location}/${arch}"
|
|
if [ "$werror" -ne 0 ]; then
|
|
CFLAGS_EXTRA="$CFLAGS_EXTRA -Werror"
|
|
fi
|
|
MAKE=(make -f Makefile.nolibc -j"${nproc}" XARCH="${arch}" CROSS_COMPILE="${cross_compile}" LLVM="${llvm}" O="${build_dir}")
|
|
|
|
case "$test_mode" in
|
|
'system')
|
|
test_target=run
|
|
;;
|
|
'user')
|
|
test_target=run-user
|
|
;;
|
|
*)
|
|
echo "Unknown mode $test_mode"
|
|
exit 1
|
|
esac
|
|
printf '%-15s' "$arch:"
|
|
if [ "$arch" = "s390" ] && ([ "$llvm" = "1" ] || [ "$test_mode" = "user" ]); then
|
|
echo "Unsupported configuration"
|
|
return
|
|
fi
|
|
if [ "$arch" = "m68k" -o "$arch" = "sh4" ] && [ "$llvm" = "1" ]; then
|
|
echo "Unsupported configuration"
|
|
return
|
|
fi
|
|
if [ "$arch" = "x32" ] && [ "$test_mode" = "user" ]; then
|
|
echo "Unsupported configuration"
|
|
return
|
|
fi
|
|
|
|
mkdir -p "$build_dir"
|
|
swallow_output "${MAKE[@]}" defconfig
|
|
swallow_output "${MAKE[@]}" CFLAGS_EXTRA="$CFLAGS_EXTRA" "$test_target" V=1
|
|
cp run.out run.out."${arch}"
|
|
"${MAKE[@]}" report | grep passed
|
|
}
|
|
|
|
if [ "$perform_download" -ne 0 ]; then
|
|
for arch in $archs; do
|
|
download_crosstool "$arch"
|
|
done
|
|
fi
|
|
|
|
for arch in $archs; do
|
|
test_arch "$arch"
|
|
done
|