From 751fb052d4b79b582984508bfc0074ad21e2de8a Mon Sep 17 00:00:00 2001 From: lumia-emu Date: Sun, 13 Sep 2026 12:15:25 +0000 Subject: [PATCH] S16v4: reject STUBV return --- docs/sbl-bringup.md | 2 ++ qemu/saimaa.c | 26 ++++++++++++++------------ tools/sbl_uni.py | 11 ++++++----- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/docs/sbl-bringup.md b/docs/sbl-bringup.md index 1163a99..5d5b82a 100644 --- a/docs/sbl-bringup.md +++ b/docs/sbl-bringup.md @@ -127,3 +127,5 @@ Патч 2B→2B в `b`. Биты 0,1,2 `[0x73A100]` pref-set (scaffold). - S16v3: `add sp,#8` перед `bx ip` (снимает helper-фрейм, пропущенный B66 — un-leak стека вниз). +- S16v4: отбраковка `ip==STUBV` (fill/maze — никогда legit return) → + default вместо возврата в maze (разрыв maze-B66 петли). diff --git a/qemu/saimaa.c b/qemu/saimaa.c index 066b380..5188d83 100644 --- a/qemu/saimaa.c +++ b/qemu/saimaa.c @@ -751,20 +751,22 @@ static void saimaa_machine_init(MachineState *machine) cpu_physical_memory_write(0x08006964 + k, &word, 4); } } - /* S16-stublet (b27, 50B @0x08006CC0): smart return for the - * B66 bx-ip chain. ip odd + top 8 => add sp,#8 (pop the - * helper frame B66 skipped!) + bx ip (legit pushed-lr, - * un-leaks the stack); else default (restore r7, jump poll - * resumption 0x8007779 via ip). */ + /* S16-stublet (b27, 64B @0x08006CC0): smart return for the + * B66 bx-ip chain. ip==STUBV (fill/maze, never legit) => + * default; ip odd + top 8 => add sp,#8 (pop the helper + * frame B66 skipped!) + bx ip (legit pushed-lr, un-leaks); + * else default (restore r7, jump poll resumption 0x8007779 + * via ip). */ { static const uint8_t s16[] = { - 0xdd, 0xf8, 0x04, 0xc0, 0x1c, 0xf0, 0x01, 0x0f, - 0x0b, 0xd0, 0x5f, 0xea, 0x1c, 0x63, 0x08, 0x2b, - 0x00, 0xd1, 0x02, 0xb0, 0x60, 0x47, 0x5f, 0xea, - 0x1c, 0x73, 0x08, 0x2b, 0x00, 0xd1, 0x60, 0x47, - 0x4a, 0xf2, 0x00, 0x07, 0xc0, 0xf2, 0x73, 0x07, - 0x47, 0xf2, 0x79, 0x7c, 0xc0, 0xf6, 0x00, 0x0c, - 0x60, 0x47, + 0xdd, 0xf8, 0x04, 0xc0, 0x46, 0xf6, 0x8d, 0x33, + 0xc0, 0xf6, 0x00, 0x03, 0x9c, 0x45, 0x0e, 0xd0, + 0x1c, 0xf0, 0x01, 0x0f, 0x0b, 0xd0, 0x5f, 0xea, + 0x1c, 0x63, 0x08, 0x2b, 0x01, 0xd1, 0x02, 0xb0, + 0x60, 0x47, 0x5f, 0xea, 0x1c, 0x73, 0x08, 0x2b, + 0x01, 0xd1, 0x02, 0xb0, 0x60, 0x47, 0x4a, 0xf2, + 0x00, 0x07, 0xc0, 0xf2, 0x73, 0x07, 0x47, 0xf2, + 0x79, 0x7c, 0xc0, 0xf6, 0x00, 0x0c, 0x60, 0x47, }; size_t k; for (k = 0; k < sizeof(s16); k += 4) { diff --git a/tools/sbl_uni.py b/tools/sbl_uni.py index a5228b5..09de194 100644 --- a/tools/sbl_uni.py +++ b/tools/sbl_uni.py @@ -393,14 +393,15 @@ def main(): mu.mem_write(0x08006964, bytes.fromhex( "04c09de50c309fe5002093e5022082e3002083e51eff2fe1" "00a17300")) - # S16-stublet (b27, 50B @0x08006CC0): smart return for B66 bx ip. - # ip odd + top 8 (code) => add sp,#8 (pop the helper frame it + # S16-stublet (b27, 64B @0x08006CC0): smart return for B66 bx ip. + # ip==STUBV (fill/maze, never a legit return) => default; + # ip odd + top 8 (code) => add sp,#8 (pop the helper frame B66 # skipped!) + bx ip (legit pushed-lr return, un-leaks the stack); # else default (restore r7, jump poll resumption 0x8007779). mu.mem_write(0x08006CC0, bytes.fromhex( - "ddf804c01cf0010f0bd05fea1c63082b00d102b06047" - "5fea1c73082b00d160474af20007c0f2730747f2797c" - "c0f6000c6047")) + "ddf804c046f68d33c0f600039c450ed01cf0010f0bd0" + "5fea1c63082b01d102b060475fea1c73082b01d102b0" + "60474af20007c0f2730747f2797cc0f6000c6047")) # stack zone fill (STUBV odd) mu.mem_write(0x085F0000, struct.pack("