windows-vm.sh (6131B)
1 #!/usr/bin/env bash 2 # Windows linked-image strip acceptance. Build hosted PE32+ programs for both 3 # shipped Windows architectures, preserve their loader imports exactly, and run 4 # the original/--strip-debug/--strip-all images in the provisioned Windows VM. 5 6 set -uo pipefail 7 8 ROOT=${KIT_TEST_ROOT:-$(cd "$(dirname "$0")/../.." && pwd)} 9 KIT=${KIT:-"$ROOT/build/kit"} 10 VM="$ROOT/scripts/windows_vm.sh" 11 HOST_CC=${KIT_WINDOWS_HOST_CC:-clang} 12 LLVM_OBJDUMP=${KIT_WINDOWS_LLVM_OBJDUMP:-llvm-objdump} 13 14 KIT_KIT_DIR="$ROOT/test/lib" 15 . "$ROOT/test/lib/kit_sh_kit.sh" 16 kit_report_init 17 kit_require_kit strip-windows-vm 18 kit_workdir strip-windows-vm 19 work=$KIT_WORK 20 21 for tool in "$HOST_CC" "$LLVM_OBJDUMP"; do 22 if ! command -v "$tool" >/dev/null 2>&1; then 23 kit_fail strip-windows-vm-tools "missing required tool: $tool" 24 kit_summary strip-windows-vm 25 kit_exit 26 fi 27 done 28 29 sdk_for_arch() { 30 local arch=$1 token triple candidate 31 case "$arch" in 32 x86_64) token=x64; triple=x86_64-w64-mingw32 ;; 33 aarch64) token=aarch64; triple=aarch64-w64-mingw32 ;; 34 *) return 1 ;; 35 esac 36 37 if [ -n "${KIT_SYSROOT:-}" ]; then 38 for candidate in "$KIT_SYSROOT/$triple" "$KIT_SYSROOT"; do 39 if [ -r "$candidate/include/windows.h" ] && 40 [ -r "$candidate/lib/libucrt.a" ]; then 41 printf '%s\n' "$candidate" 42 return 0 43 fi 44 done 45 fi 46 47 candidate=$("$ROOT/scripts/llvm_mingw_sysroot.sh" path "$token" 2>/dev/null) || 48 return 1 49 [ -r "$candidate/include/windows.h" ] && 50 [ -r "$candidate/lib/libucrt.a" ] || return 1 51 printf '%s\n' "$candidate" 52 } 53 54 import_dump() { 55 local input=$1 output=$2 56 "$KIT" objdump -p "$input" | 57 awk '/^[[:space:]]+DLL Name:/ || /^[[:space:]]+Name:/ { 58 sub(/^[[:space:]]+/, ""); print 59 }' > "$output" 60 } 61 62 section_dump() { 63 "$LLVM_OBJDUMP" -h "$1" > "$2" 64 } 65 66 assert_has_debug() { 67 local label=$1 dump=$2 68 if grep -E '(^|[[:space:],])\.debug_' "$dump" >/dev/null 2>&1; then 69 ok "$label" 70 else 71 printf 'expected a .debug_* section\n' > "$work/$label.diag" 72 not_ok "$label" "$work/$label.diag" 73 fi 74 } 75 76 assert_no_debug() { 77 local label=$1 dump=$2 78 if grep -E '(^|[[:space:],])\.debug_' "$dump" >/dev/null 2>&1; then 79 grep -E '(^|[[:space:],])\.debug_' "$dump" > "$work/$label.diag" 80 not_ok "$label" "$work/$label.diag" 81 else 82 ok "$label" 83 fi 84 } 85 86 run_guest() { 87 local label=$1 vm_arch=$2 exe=$3 88 local raw_out="$work/$label.out" raw_err="$work/$label.err" 89 local norm_out="$work/$label.normalized.out" 90 local norm_err="$work/$label.normalized.err" 91 92 if "$VM" run "$vm_arch" "$exe" strip-probe > "$raw_out" 2> "$raw_err"; then 93 ok "$label-status" 94 else 95 not_ok "$label-status" "$raw_err" 96 return 97 fi 98 99 tr -d '\r' < "$raw_out" > "$norm_out" 100 tr -d '\r' < "$raw_err" > "$norm_err" 101 same_file "$label-stdout" "$work/expected.out" "$norm_out" 102 same_file "$label-stderr" "$work/expected.err" "$norm_err" 103 } 104 105 printf 'strip-runtime-ok\nstrip-fini-ok\n' > "$work/expected.out" 106 printf 'strip-signal-ok\n' > "$work/expected.err" 107 108 for arch in x86_64 aarch64; do 109 case "$arch" in 110 x86_64) 111 target=x86_64-w64-windows-gnu 112 vm_arch=x64 113 label=x64 114 builtins_name=libclang_rt.builtins-x86_64.a 115 ;; 116 aarch64) 117 target=aarch64-w64-windows-gnu 118 vm_arch=aarch64 119 label=aarch64 120 builtins_name=libclang_rt.builtins-aarch64.a 121 ;; 122 esac 123 124 if ! sdk=$(sdk_for_arch "$arch"); then 125 kit_fail "$label-sysroot" "missing llvm-mingw UCRT sysroot" 126 continue 127 fi 128 builtins="$sdk/lib/windows/$builtins_name" 129 if [ ! -r "$builtins" ]; then 130 kit_fail "$label-builtins" "missing compiler-rt archive: $builtins" 131 continue 132 fi 133 134 original="$work/$label-original.exe" 135 debug="$work/$label-debug.exe" 136 all="$work/$label-all.exe" 137 138 # Use an independent producer: Kit-linked PE currently carries no linked 139 # DWARF sections, while clang/lld emits the /<string-table-offset> long names 140 # used by real llvm-mingw images. Kit remains the sole strip transformer. 141 run_ok "$label-build" "$HOST_CC" --target="$target" --sysroot="$sdk" \ 142 -fuse-ld=lld -nodefaultlibs -L"$sdk/lib/windows" -O1 -g -gdwarf-4 \ 143 -Wl,--subsystem,console "$ROOT/test/strip/windows_runtime.c" \ 144 -o "$original" \ 145 -lmingw32 "$builtins" -lmoldname -lmingwex -lmsvcrt -ladvapi32 \ 146 -lshell32 -luser32 -lkernel32 -lmingw32 "$builtins" -lmoldname \ 147 -lmingwex -lmsvcrt -lkernel32 148 [ -f "$original" ] || continue 149 150 run_ok "$label-sections-before" section_dump "$original" \ 151 "$work/$label-sections-before.txt" 152 assert_has_debug "$label-debug-present-before" \ 153 "$work/$label-sections-before.txt" 154 run_ok "$label-imports-before" import_dump "$original" \ 155 "$work/$label-imports-before.txt" 156 contains "$label-import-kernel32" "$work/$label-imports-before.txt" \ 157 "DLL Name: KERNEL32.dll" 158 contains "$label-import-writefile" "$work/$label-imports-before.txt" \ 159 "Name: WriteFile" 160 contains "$label-import-signal" "$work/$label-imports-before.txt" \ 161 "Name: signal" 162 contains "$label-import-raise" "$work/$label-imports-before.txt" \ 163 "Name: raise" 164 run_ok "$label-strip-debug" "$KIT" strip --strip-debug -o "$debug" \ 165 "$original" 166 run_ok "$label-strip-all" "$KIT" strip --strip-all -o "$all" "$original" 167 168 for variant in debug all; do 169 case "$variant" in 170 debug) image=$debug ;; 171 all) image=$all ;; 172 esac 173 [ -f "$image" ] || continue 174 run_ok "$label-$variant-sections" section_dump "$image" \ 175 "$work/$label-$variant-sections.txt" 176 assert_no_debug "$label-$variant-no-debug" \ 177 "$work/$label-$variant-sections.txt" 178 run_ok "$label-$variant-imports" import_dump "$image" \ 179 "$work/$label-$variant-imports.txt" 180 same_file "$label-$variant-imports-preserved" \ 181 "$work/$label-imports-before.txt" "$work/$label-$variant-imports.txt" 182 done 183 184 run_guest "$label-original-run" "$vm_arch" "$original" 185 [ ! -f "$debug" ] || run_guest "$label-debug-run" "$vm_arch" "$debug" 186 [ ! -f "$all" ] || run_guest "$label-all-run" "$vm_arch" "$all" 187 done 188 189 kit_summary strip-windows-vm 190 kit_exit