verify.sh (3329B)
1 #!/bin/sh 2 set -eu 3 4 . "$(dirname "$0")/config.sh" 5 unset MUSLLVM_SYSROOT 6 cc="$PREFIX/bin/$TARGET-cc" 7 cxx="$PREFIX/bin/$TARGET-c++" 8 readelf="$PREFIX/bin/$TARGET-readelf" 9 work="$BUILD_DIR/verify" 10 loader="$SYSROOT/lib/ld-musl-$ARCH.so.1" 11 for program in "$cc" "$cxx" "$readelf"; do 12 [ -x "$program" ] || die "toolchain is incomplete: $program" 13 done 14 15 run() 16 { 17 if [ -n "$RUNNER" ]; then "$RUNNER" "$@"; else "$@"; fi 18 } 19 20 mkdir -p "$work" 21 "$cc" -std=c99 -Werror -c "$PROOT/tests/hello.c" -o "$work/hello-c.o" 22 "$cxx" -std=c++20 -Werror -c "$PROOT/tests/hello.cpp" -o "$work/hello-cxx.o" 23 "$cc" -std=c99 -O2 -pthread "$PROOT/tests/hello.c" -o "$work/hello-c" 24 "$cc" -std=c99 -O2 -pthread -static "$PROOT/tests/hello.c" -o "$work/hello-c-static" 25 "$cxx" -std=c++20 -O2 -pthread "$PROOT/tests/hello.cpp" -o "$work/hello-cxx" 26 "$cxx" -std=c++20 -O2 -pthread -static "$PROOT/tests/hello.cpp" -o "$work/hello-cxx-static" 27 "$cxx" -std=c++20 -O2 -pthread -static-pie "$PROOT/tests/hello.cpp" -o "$work/hello-cxx-static-pie" 28 29 cmake -S "$PROOT/tests/cmake" -B "$work/cmake" -G Ninja \ 30 -DCMAKE_TOOLCHAIN_FILE="$PREFIX/share/musllvm/toolchain.cmake" 31 cmake --build "$work/cmake" --parallel "$JOBS" 32 33 static='hello-c-static hello-cxx-static hello-cxx-static-pie cmake/hello-cxx-static' 34 dynamic='hello-c hello-cxx cmake/hello-c cmake/hello-cxx' 35 for program in $static $dynamic; do 36 "$readelf" -h "$work/$program" > "$work/$program.header" 37 grep -F "$ELF_MACHINE" "$work/$program.header" >/dev/null || die "wrong ELF machine: $program" 38 "$readelf" -l "$work/$program" > "$work/$program.segments" 39 "$readelf" -d "$work/$program" > "$work/$program.dynamic" 40 if grep -E 'libc\.so\.6|libstdc\+\+|libgcc_s|ld-linux' "$work/$program.dynamic" "$work/$program.segments"; then 41 die "host runtime dependency in $program" 42 fi 43 case " $static " in 44 *" $program "*) 45 if grep -E 'INTERP|NEEDED' "$work/$program.segments" "$work/$program.dynamic"; then 46 die "static executable has dynamic dependencies: $program" 47 fi ;; 48 *) 49 grep -F "/lib/ld-musl-$ARCH.so.1" "$work/$program.segments" >/dev/null || 50 die "wrong dynamic loader in $program" 51 grep -F GNU_RELRO "$work/$program.segments" >/dev/null && 52 grep -E 'BIND_NOW|FLAGS.* NOW' "$work/$program.dynamic" >/dev/null || 53 die "hardening defaults missing from $program" ;; 54 esac 55 done 56 grep -E 'Type: +DYN' "$work/hello-cxx-static-pie.header" >/dev/null || 57 die "static-pie executable is not position independent" 58 59 for language in c c++; do 60 compiler=$cc 61 [ "$language" = c ] || compiler=$cxx 62 CPATH=/usr/include CPLUS_INCLUDE_PATH=/usr/include LIBRARY_PATH=/usr/lib \ 63 "$compiler" -E -v -x "$language" /dev/null > /dev/null 2> "$work/$language.includes" 64 if grep -E '^ /usr/(local/)?include([ /]|$)|^ /usr/.*/c\+\+' "$work/$language.includes"; then 65 die "host headers found in $language search path" 66 fi 67 done 68 69 host_arch=$(uname -m) 70 if [ "$host_arch" = "$ARCH" ] || [ -n "$RUNNER" ]; then 71 for program in $static; do 72 run "$work/$program" 73 done 74 for program in $dynamic; do 75 run "$loader" --library-path "$SYSROOT/usr/lib:$SYSROOT/lib" "$work/$program" 76 done 77 else 78 printf 'Execution skipped for %s on %s; set RUNNER=qemu-%s to run the programs.\n' "$ARCH" "$host_arch" "$ARCH" 79 fi 80 printf 'Verified %s: static, static-pie and dynamic C and C++, -Werror compiles, target ELF, isolated headers, and CMake\n' "$TARGET"