From 52db23ce585e3395638e82af0608f5aa6ad014db Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 9 Sep 2026 10:13:45 -0400 Subject: [PATCH] shim: exhaustive configs must also turn off the FPU sampling detours Lane CR named all 27 template hooks off, passed check_shim_configs.py, and the shim installed six detours: the M0 asm stub and the FPU-force module's four sampling detours, on by default under keys that do not start with hook. The checker was exhaustive over the wrong list. It now requires fpu.sample_turn and fpu.sample_ticks off in an exhaustive config and names the M0 stub in its OK line. All five exhaustive configs amended; their past measurements stand because each was proved byte-neutral against a control. --- src/shim/shim.cfg.bupin | 6 ++++++ src/shim/shim.cfg.cbpin | 6 ++++++ src/shim/shim.cfg.crcompare | 6 ++++++ src/shim/shim.cfg.crreplace0 | 6 ++++++ src/shim/shim.cfg.crreplace1 | 6 ++++++ tools/check_shim_configs.py | 22 +++++++++++++++++++++- 6 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/shim/shim.cfg.bupin b/src/shim/shim.cfg.bupin index 1694c53..d538874 100644 --- a/src/shim/shim.cfg.bupin +++ b/src/shim/shim.cfg.bupin @@ -116,3 +116,9 @@ aiseed.values=32=156ebbbd,496=fe7b2826,512=0ed341d1,*=deadbeef # With `aiseed=pin` and no values the module logs "PIN MODE WITH NO PINS -- every seed passes # through unchanged, so this run is NOT pinned and must not be reported as one". Read that, and # the three `aiseed call=... pinned=1` lines, in shim.log before trusting any run. + +# The FPU-force module installs FOUR sampling detours by default, controlled by keys that +# do not start with hook. -- lane CR found a config naming all 27 template hooks still +# installed six detours. An exhaustive config turns these off explicitly. +fpu.sample_turn=off +fpu.sample_ticks=off diff --git a/src/shim/shim.cfg.cbpin b/src/shim/shim.cfg.cbpin index b02ffb0..94a9e12 100644 --- a/src/shim/shim.cfg.cbpin +++ b/src/shim/shim.cfg.cbpin @@ -73,3 +73,9 @@ aiseed=pin # The seeds run C3 (unpinned, same save, same guest, same build) observed for itself. Pinning # them reproduces a turn that actually happened rather than inventing one. aiseed.values=32=e70a4703,496=0c63ca36,512=372be4df + +# The FPU-force module installs FOUR sampling detours by default, controlled by keys that +# do not start with hook. -- lane CR found a config naming all 27 template hooks still +# installed six detours. An exhaustive config turns these off explicitly. +fpu.sample_turn=off +fpu.sample_ticks=off diff --git a/src/shim/shim.cfg.crcompare b/src/shim/shim.cfg.crcompare index 7c8b7f1..f236f66 100644 --- a/src/shim/shim.cfg.crcompare +++ b/src/shim/shim.cfg.crcompare @@ -33,3 +33,9 @@ research.replace_cascade=off trace.path=C:\SOTS\shim.trace.jsonl trace.inline_max=256 trace.flush=always + +# The FPU-force module installs FOUR sampling detours by default, controlled by keys that +# do not start with hook. -- lane CR found a config naming all 27 template hooks still +# installed six detours. An exhaustive config turns these off explicitly. +fpu.sample_turn=off +fpu.sample_ticks=off diff --git a/src/shim/shim.cfg.crreplace0 b/src/shim/shim.cfg.crreplace0 index d35df77..a626ed2 100644 --- a/src/shim/shim.cfg.crreplace0 +++ b/src/shim/shim.cfg.crreplace0 @@ -33,3 +33,9 @@ research.replace_cascade=off trace.path=C:\SOTS\shim.trace.jsonl trace.inline_max=256 trace.flush=always + +# The FPU-force module installs FOUR sampling detours by default, controlled by keys that +# do not start with hook. -- lane CR found a config naming all 27 template hooks still +# installed six detours. An exhaustive config turns these off explicitly. +fpu.sample_turn=off +fpu.sample_ticks=off diff --git a/src/shim/shim.cfg.crreplace1 b/src/shim/shim.cfg.crreplace1 index 0375cc8..d962e54 100644 --- a/src/shim/shim.cfg.crreplace1 +++ b/src/shim/shim.cfg.crreplace1 @@ -33,3 +33,9 @@ research.replace_cascade=on trace.path=C:\SOTS\shim.trace.jsonl trace.inline_max=256 trace.flush=always + +# The FPU-force module installs FOUR sampling detours by default, controlled by keys that +# do not start with hook. -- lane CR found a config naming all 27 template hooks still +# installed six detours. An exhaustive config turns these off explicitly. +fpu.sample_turn=off +fpu.sample_ticks=off diff --git a/tools/check_shim_configs.py b/tools/check_shim_configs.py index fe5e470..4870698 100644 --- a/tools/check_shim_configs.py +++ b/tools/check_shim_configs.py @@ -38,6 +38,12 @@ HOOK_RE = re.compile(r"^hook\.([^=]+)=") EXEMPT = {"Game::Foo"} EXEMPT_PREFIXES = ("Shim::SelfTest::",) +# Detours that are installed by default and are NOT template hooks. The FPU-force module's +# sampling keys accept exactly `on`/`off`. The M0 asm stub has no key at all and is always +# installed when `hooks != off`; it is mentioned in the OK line so nobody reads "27" as "all". +ALWAYS_ON_UNLESS_OFF = ("fpu.sample_turn", "fpu.sample_ticks") +UNNAMEABLE_DETOURS = ("Mars::Application::Initialize (M0 asm stub, always on unless hooks=off)",) + # Settings whose values legitimately end in a period or a path separator. PROSE_SAFE = ("path", "out", "dir", "file") @@ -82,6 +88,19 @@ def check(cfg, hooks): f"declares `# exhaustive` but does not name {len(missing)} registered hook(s), " "which therefore default ON: " + ", ".join(missing) ) + # Template hooks are not the only detours. Lane CR named all 27, passed this check, + # and the shim installed SIX: the M0 Application::Initialize asm stub (unconditional + # whenever hooks != off -- it cannot be named off, so it is reported, not required) + # and the FPU-force module's four sampling detours, which are ON BY DEFAULT and are + # controlled by keys that do not start with `hook.`. An exhaustive config must turn + # those off explicitly, or "exhaustive" is a claim about the wrong list. + kv = {l.split("=", 1)[0].strip(): l.split("=", 1)[1].strip() for l in settings if "=" in l} + for key in ALWAYS_ON_UNLESS_OFF: + if kv.get(key) != "off": + problems.append( + f"declares `# exhaustive` but `{key}` is not `off` (it defaults ON and installs " + "detours no `hook.` key names)" + ) return problems @@ -104,7 +123,8 @@ def main(): for f in failures: print(" " + f) return 1 - print(f"check_shim_configs: OK ({len(hooks)} registered hooks, {exhaustive} template(s) declared exhaustive)") + print(f"check_shim_configs: OK ({len(hooks)} template hooks + {len(ALWAYS_ON_UNLESS_OFF)} default-on " + f"FPU sampling keys + {len(UNNAMEABLE_DETOURS)} unnameable detour; {exhaustive} template(s) declared exhaustive)") return 0