# tests/ubsan — UBSan-min smoke probe (Phase 6.2)

Nine-case probe that exercises the `-fsanitize=undefined
-fsanitize-minimal-runtime` instrumentation end-to-end on the W65816
target:

| Kind                   | UB                              | Sentinel             |
|------------------------|----------------------------------|----------------------|
| `add-overflow`         | i16 `INT_MAX + 1`                | `$025000=0xC0DE`     |
| `shift-out-of-bounds`  | u16 `1 << 17`                    | `$025002=0xC0DF`     |
| `divrem-overflow`      | i16 `n / 0`                      | `$025004=0xC0E0`     |
| `sub-overflow`         | i16 `INT_MIN - 1`                | `$025006=0xC0E1`     |
| `mul-overflow`         | i16 `INT_MAX * 2`                | `$025008=0xC0E2`     |
| `negate-overflow`      | i16 `-INT_MIN`                   | `$02500A=0xC0E3`     |
| `pointer-overflow`     | `(char*)0xFFFFFFF0 + 0x40`       | `$02500C=0xC0E4`     |
| `load-invalid-value`   | `_Bool` loaded from byte = 2     | `$02500E=0xC0E5`     |
| `out-of-bounds`        | `arr[idx>=N]` on static array    | `$025010=0xC0E6`     |
| (liveness)             | tail of `main` reached           | `$025012=0xC0DA`     |

The probe ships strong override defs for the nine `__ubsan_handle_*_minimal`
recovering handlers it exercises; the remaining handlers are pulled in
from `runtime/ubsan.o` so any extra UB site clang emits (e.g. constant-
fold overflow at `-O2`) still resolves cleanly.

## Build + run

```
bash tests/ubsan/runUbsanProbe.sh
```

Expected output:
```
MAME-READ addr=0x025000 val=0xc0de
MAME-READ addr=0x025002 val=0xc0df
MAME-READ addr=0x025004 val=0xc0e0
MAME-READ addr=0x025006 val=0xc0e1
MAME-READ addr=0x025008 val=0xc0e2
MAME-READ addr=0x02500a val=0xc0e3
MAME-READ addr=0x02500c val=0xc0e4
MAME-READ addr=0x02500e val=0xc0e5
MAME-READ addr=0x025010 val=0xc0e6
MAME-READ addr=0x025012 val=0xc0da
MAME OK: 10 reads matched
```

## What this probe is NOT

- It is **not** a verification of the UBSan diagnostic format (the
  per-kind `"ubsan: <kind> by 0x<pc>\n"` line emitted by
  `runtime/src/ubsan.c::reportError`).  The probe deliberately
  overrides the handlers so it can verify the *call edge* without
  pulling in console code.  A separate diagnostic-format probe would
  link `libc.o` + `libcGno.o` + GNO crt0 and assert on stderr.
- It is **not** a sweep of all 25 handler kinds.  The kinds covered
  are all the cheap-to-trigger recoverable handlers that clang emits
  at `-O2` for the W65816 target.  Aborting-only kinds (e.g.
  `builtin_unreachable_minimal`, `missing_return_minimal`) cannot be
  exercised here because returning from the handler after the IR
  `unreachable` is itself UB.  Float-cast-overflow / VLA-not-positive
  / type-mismatch / CFI / Objective-C kinds are linked but not
  triggered.

## Files

- `ubsanProbe.c`             — the probe itself
- `build.sh`                  — compiles with `-fsanitize=undefined -fsanitize-minimal-runtime`
- `runUbsanProbe.sh`          — build + link + run under MAME with `--check`
- `ubsanProbe.manifest.json`  — segment layout + check sentinel descriptor
