x64.sh (4899B)
1 #!/usr/bin/env bash 2 # test/smoke/x64.sh — end-to-end smoke test for the x64 podman/qemu path, on 3 # the shared Type-K mode-P kit (test/lib/kit_sh_kit.sh). 4 # 5 # Phase-1 of the multi-arch bring-up: prove the test/lib/exec_target.sh helper 6 # can build, queue, and run an x86_64-linux ELF before any kit-emitted x64 7 # bytes exist. Builds a tiny freestanding static executable with 8 # clang --target=x86_64-linux-gnu and pushes it through 9 # exec_target_run / exec_target_queue+flush, asserting exit code 42 on both 10 # paths. This is one inline program, so it is a single-scenario procedural 11 # suite (build, exec, assert rc) rather than a file-glob corpus. 12 # 13 # Skipped if clang lacks the x86_64-linux-gnu target, ld.lld is missing, or no 14 # runner (podman or qemu-x86_64) is available. Skip is treated as failure 15 # unless KIT_TEST_ALLOW_SKIP=1 (the shared kit_exit honors it). 16 17 set -u 18 19 ROOT="$(cd "$(dirname "$0")/../.." && pwd)" 20 BUILD_DIR="$ROOT/build/test/smoke-x64" 21 mkdir -p "$BUILD_DIR" 22 23 KIT_KIT_DIR="$ROOT/test/lib" 24 # shellcheck source=../lib/kit_sh_kit.sh 25 . "$ROOT/test/lib/kit_sh_kit.sh" 26 kit_report_init 27 28 # This harness's convention (preserved from the original smoke runner): a SKIP 29 # is a failure unless KIT_TEST_ALLOW_SKIP=1, so CI catches a degraded run. 30 KIT_SKIP_IS_FAILURE=1 31 32 # Mode-P suites are SERIAL and share one $work sandbox. 33 work="$BUILD_DIR" 34 35 # ---- detect prerequisites -------------------------------------------------- 36 37 CLANG_TARGET="--target=x86_64-linux-gnu" 38 have_clang_x64=0 39 if clang $CLANG_TARGET -c -x c - -o /dev/null < /dev/null 2>/dev/null; then 40 have_clang_x64=1 41 fi 42 43 # Cross-link wants an ELF-aware ld. On macOS the host /usr/bin/ld is 44 # Mach-O only; insist on lld. On a Linux x86_64 host the default host 45 # linker is fine but lld still works. 46 have_lld=0 47 command -v ld.lld >/dev/null 2>&1 && have_lld=1 48 49 # Variables expected by exec_target.sh. The aarch64 helper expects these 50 # names regardless of target arch — they describe the host detection 51 # rather than the target. For x64-only smoke we don't need QEMU_BIN. 52 have_qemu=0 53 QEMU_BIN="" 54 have_podman=0 55 command -v podman >/dev/null 2>&1 && have_podman=1 56 arch_raw="$(uname -m 2>/dev/null || true)" 57 is_aarch64=0 58 { [ "$arch_raw" = "aarch64" ] || [ "$arch_raw" = "arm64" ]; } && is_aarch64=1 59 export have_qemu QEMU_BIN have_podman is_aarch64 60 61 EXEC_TARGET_MOUNT_ROOT="$BUILD_DIR" 62 export EXEC_TARGET_MOUNT_ROOT 63 # shellcheck source=../lib/exec_target.sh 64 . "$ROOT/test/lib/exec_target.sh" 65 66 if [ $have_clang_x64 -eq 0 ]; then 67 skip_test "build" "clang --target=x86_64-linux-gnu unavailable" 68 kit_summary test-smoke-x64; kit_exit 69 fi 70 if [ $have_lld -eq 0 ]; then 71 skip_test "build" "ld.lld unavailable (needed for ELF cross-link)" 72 kit_summary test-smoke-x64; kit_exit 73 fi 74 if ! exec_target_supported x64; then 75 skip_test "exec" "no runner for x64 (podman or qemu-x86_64)" 76 kit_summary test-smoke-x64; kit_exit 77 fi 78 79 # ---- build a tiny freestanding x86_64 ELF ----------------------------------- 80 81 # Direct syscall in _start: SYS_exit_group on x86_64 is 231, exit code 82 # 42. No libc, no relocations, no PIE. The point is to exercise the 83 # harness pipeline (clang cross-compile -> podman/qemu run -> recorded 84 # rc), not to build a complete program. 85 SRC="$BUILD_DIR/smoke.c" 86 cat >"$SRC" <<'EOF' 87 __attribute__((noreturn)) void _start(void) { 88 register long rax __asm__("rax") = 231; /* sys_exit_group */ 89 register long rdi __asm__("rdi") = 42; 90 __asm__ volatile("syscall" : : "r"(rax), "r"(rdi) : "memory"); 91 __builtin_unreachable(); 92 } 93 EOF 94 95 EXE="$BUILD_DIR/smoke.exe" 96 if ! clang $CLANG_TARGET -fuse-ld=lld \ 97 -O1 -ffreestanding -fno-stack-protector \ 98 -fno-PIC -fno-pie -nostdlib -static \ 99 -Wl,-e,_start \ 100 "$SRC" -o "$EXE" 2>"$BUILD_DIR/build.err"; then 101 not_ok "build" "$BUILD_DIR/build.err" 102 kit_summary test-smoke-x64; kit_exit 103 fi 104 ok "build" 105 106 # ---- exec_target_run --------------------------------------------------------- 107 108 exec_target_run x64 "$EXE" "$BUILD_DIR/run.out" "$BUILD_DIR/run.err" 109 if [ "$RUN_RC" -eq 42 ]; then 110 ok "exec_target_run x64 (rc=42)" 111 else 112 echo "expected 42 got $RUN_RC; see $BUILD_DIR/run.err" > "$BUILD_DIR/run.diag" 113 not_ok "exec_target_run x64" "$BUILD_DIR/run.diag" 114 fi 115 116 # ---- exec_target_queue + flush ---------------------------------------------- 117 118 exec_target_queue x64 smoke "$EXE" \ 119 "$BUILD_DIR/q.out" "$BUILD_DIR/q.err" "$BUILD_DIR/q.rc" 120 exec_target_flush 121 if [ ! -f "$BUILD_DIR/q.rc" ]; then 122 echo "no rc file produced" > "$BUILD_DIR/q.diag" 123 not_ok "exec_target_queue+flush x64" "$BUILD_DIR/q.diag" 124 else 125 Q_RC="$(cat "$BUILD_DIR/q.rc")" 126 if [ "$Q_RC" -eq 42 ]; then 127 ok "exec_target_queue+flush x64 (rc=42)" 128 else 129 echo "expected 42 got $Q_RC; see $BUILD_DIR/q.err" > "$BUILD_DIR/q.diag" 130 not_ok "exec_target_queue+flush x64" "$BUILD_DIR/q.diag" 131 fi 132 fi 133 134 kit_summary test-smoke-x64 135 kit_exit