Merge xobj-stashhandle/p0-canary-mirror

This commit is contained in:
MechaCat02
2026-05-07 21:06:28 +02:00

View File

@@ -3094,6 +3094,12 @@ fn ensure_dispatcher_object(state: &mut KernelState, mem: &GuestMemory, ptr: u32
_ => return,
};
state.objects.insert(ptr, obj);
// Mirror canary `XObject::StashHandle` (xobject.h:253-256): on first
// adoption, stamp the X_DISPATCH_HEADER's wait_list with the kXObjSignature
// fourcc 'X','E','N','\0' (flink_ptr) and the stash handle (blink_ptr).
// Game code reads these to recognize already-adopted dispatchers.
mem.write_u32(ptr + 0x08, 0x58454E00);
mem.write_u32(ptr + 0x0C, ptr);
}
/// Set `gpr[3]` on a just-woken HW thread to reflect which handle in its
@@ -4601,6 +4607,35 @@ mod tests {
write_dispatcher_header(&mut mem, ptr, 2, 0); // Mutant — unsupported
ensure_dispatcher_object(&mut state, &mem, ptr);
assert!(!state.objects.contains_key(&ptr), "no shadow for unknown type");
// No StashHandle stamp on an ignored dispatcher.
assert_eq!(mem.read_u32(ptr + 0x08), 0);
assert_eq!(mem.read_u32(ptr + 0x0C), 0);
}
/// Mirror canary `XObject::StashHandle` (xobject.h:253-256): on first
/// adoption of a guest dispatcher, +0x08 must hold the 'X','E','N','\0'
/// fourcc and +0x0C must hold the stash handle.
#[test]
fn ensure_dispatcher_object_stamps_xen_signature_and_handle() {
let (mut ctx, mut mem, mut state) = fresh();
let kevent_ptr = SCRATCH_BASE + 0x700;
write_dispatcher_header(&mut mem, kevent_ptr, 1, 0); // synchronization
// Pre-condition: zeros at +0x08 / +0x0C.
assert_eq!(mem.read_u32(kevent_ptr + 0x08), 0);
assert_eq!(mem.read_u32(kevent_ptr + 0x0C), 0);
ctx.gpr[3] = kevent_ptr as u64;
ke_set_event(&mut ctx, &mut mem, &mut state);
// Post-condition: kXObjSignature ('X','E','N','\0') + stash handle.
assert_eq!(
mem.read_u32(kevent_ptr + 0x08),
0x58454E00,
"wait_list.flink_ptr must hold kXObjSignature 'XEN\\0'"
);
assert_eq!(
mem.read_u32(kevent_ptr + 0x0C),
kevent_ptr,
"wait_list.blink_ptr must hold stash handle (== guest dispatcher ptr)"
);
}
/// `KePulseEvent` on a manual-reset event must wake every parked waiter