[repro, do not merge] MIPS delay-slot hflag leak via UC_HOOK_MEM_READ_UNMAPPED (#2272) - #2352
Draft
retrocpugeek wants to merge 1 commit into
Draft
Conversation
unicorn-engine#2272) Demonstrates that the spurious EXCP_RI from issue unicorn-engine#2272 is not specific to UC_TLB_VIRTUAL. In the ordinary soft-MMU, a memory access in a branch delay slot that faults on unmapped memory and is serviced by a UC_HOOK_MEM_READ_UNMAPPED hook (which maps the page and returns true) resumes in place after cputlb.c's cpu_restore_state() has re-applied the branch-delay hflags (MIPS_HFLAG_B / MIPS_HFLAG_BDS32) into the live env. The branch target is then decoded as if it sat in a delay slot, raising a spurious Reserved Instruction exception (surfaced as UC_ERR_EXCEPTION). This test asserts the correct behavior and therefore FAILS on current mainline; it is a standalone repro, deliberately kept out of the vtlb fix PR. Unlike the vtlb fill, that cpu_restore_state() call is deliberate (it honours the synced-PC contract for user hooks), so the proper fix is lower-level (clear the transient branch hflags after a resume-in-place restore) rather than dropping the call. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is a standalone repro, not a fix — please do not merge. It exists to make the bug easy to review/run. It accompanies the discussion on #2347.
What it shows
The spurious
EXCP_RIfrom #2272 is not specific toUC_TLB_VIRTUAL. The same branch-delay hflag leak is reachable in the ordinary soft-MMU through aUC_HOOK_MEM_READ_UNMAPPEDhook.The added test (
tests/unit/test_mips.c::test_mips_mem_read_unmapped_delay_slot_2272) runs a big-endian MIPS64 program whosebhas a load in its delay slot. The load faults on an unmapped page; aUC_HOOK_MEM_READ_UNMAPPEDhook maps the page and returnstrue, so the load resumes in place. Before the hook is called,cputlb.crunscpu_restore_state()to sync the PC (the documented hook contract), and on MIPS that re-applies the branch-delay hflags (MIPS_HFLAG_B/MIPS_HFLAG_BDS32) into the liveenv. Nothing clears them, so the branch target (itself abne) is decoded as if it sat in a delay slot and raises a spurious Reserved Instruction exception (surfaced asUC_ERR_EXCEPTION; intno 20 viaUC_HOOK_INTR).The test asserts the correct behavior and therefore fails on current mainline — that is the point of a repro:
Pre-mapping the page so no hook fires makes the same program complete correctly, isolating the cause to the hook-triggered
cpu_restore_state().Relationship to #2347
#2347 fixes the
UC_TLB_VIRTUALfill path by not restoring state on a successful fill. That does not cover this path:cputlb.c'scpu_restore_state()is deliberate (it honours the synced-PC contract for user hooks), so it can't simply be dropped. The proper fix is lower-level — clear the transient branch hflags after a resume-in-place restore (inrestore_state_to_opc()/ its MIPS callers) — which is a broader change than the #2347 regression fix. Filing this separately so the root cause is documented and runnable; happy to open a fix PR if the direction is agreed.🤖 Generated with Claude Code