#!/usr/bin/env bash # Phase 6.2 UBSan-min smoke probe: build + link + run under MAME. # # Usage: # bash tests/ubsan/runUbsanProbe.sh # # What this verifies: # - clang accepts -fsanitize=undefined -fsanitize-minimal-runtime on # the w65816 target. # - The three exercised UB kinds (add-overflow / shift-out-of-bounds / # divrem-overflow) instrument as expected — the handler-fired byte # flips inside the per-kind handler override. # - The recovering minimal runtime returns to the caller cleanly, so # the probe continues writing sentinels past each UB site. # - runtime/ubsan.o links + resolves the other 22 handler kinds without # pulling in console code that the probe doesn't need. set -eu SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" OUT="$SCRIPT_DIR/build" RT="$PROJECT_ROOT/runtime" cd "$SCRIPT_DIR" rm -rf "$OUT" bash "$SCRIPT_DIR/build.sh" # Link. crt0.o + the probe + ubsan.o + libgcc.o (for the i16 div+rem # helpers triggerDivByZero needs). We deliberately do NOT link libc.o # — the probe sets memory sentinels directly, doesn't call printf, and # pulling libc.o in would also pull snprintf.o (~9 KB) for no benefit. "$PROJECT_ROOT/tools/link816" -o ubsanProbe.bin \ --text-base 0x1000 --bss-base 0xA000 --map ubsanProbe.map \ "$RT/crt0.o" \ "$OUT/ubsanProbe.o" \ "$RT/ubsan.o" \ "$RT/libgcc.o" ls -la ubsanProbe.bin echo "" # Sentinels: # $025000 = 0xC0DE add-overflow handler fired # $025002 = 0xC0DF shift-out-of-bounds handler fired # $025004 = 0xC0E0 divrem-overflow handler fired # $025006 = 0xC0DA all three recovered and main reached its tail bash "$PROJECT_ROOT/scripts/runInMame.sh" \ "$SCRIPT_DIR/ubsanProbe.bin" \ --check 0x025000=C0DE 0x025002=C0DF 0x025004=C0E0 0x025006=C0DA