snapshot: preserve the uncommitted Canary instrumentation (not authored here)
Some checks failed
Orchestrator / Commit Message Validation (push) Has been skipped
Orchestrator / Lint (push) Failing after 2m0s
Orchestrator / Windows (x86-64) (push) Has been skipped
Orchestrator / Linux (x86-64) (push) Has been skipped
Orchestrator / Create Release (push) Has been skipped

Working-tree snapshot taken 2026-07-28 so this work is not lost. To be clear
about provenance: NONE of this was written in the session that committed it —
it is pre-existing uncommitted work on phase-a-tracing, last committed 2026-07-09,
from the xenia-rs decoder/deadlock investigation. It is recorded verbatim, not
reviewed and not tested.

Contents: 24 tracked modifications (ppc_emit_memory, xex_module, object_table,
shim_utils, xboxkrnl threading/rtl, xevent/xobject/xthread, memory) plus the
untracked probe sources audit_68_host_mem_watch, audit_69_event_signal_watch,
audit_70_semaphore_release_watch, phase_b_snapshot, and cmake/toolchains.

Deliberately excluded: build-cross/ (51 GB of build output) and
vkd3d-proton.cache. Note third_party/snappy is a submodule pointer change whose
target may not be pushed anywhere, so this branch is a preservation record rather
than a guaranteed-buildable tree.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-28 20:03:33 +00:00
parent a154309022
commit 30d05ee97b
34 changed files with 2981 additions and 32 deletions

View File

@@ -10,6 +10,7 @@
#include "xenia/kernel/xobject.h"
#include "xenia/base/byte_stream.h"
#include "xenia/kernel/event_log.h"
#include "xenia/kernel/kernel_state.h"
#include "xenia/kernel/util/shim_utils.h"
#include "xenia/kernel/xboxkrnl/xboxkrnl_private.h"
@@ -429,6 +430,15 @@ object_ref<XObject> XObject::GetNativeObject(KernelState* kernel_state,
// First use, create new.
// https://www.nirsoft.net/kernel_struct/vista/KOBJECTS.html
XObject* object = nullptr;
// Phase C+18: bracket the wrapper ctor + AddHandle path with a
// host-TLS flag so the centralized `ObjectTable::AddHandle` emit
// hook short-circuits its per-thread `handle.create`. We emit a
// shared-global `handle.create` explicitly below with a SID keyed
// on `(native_ptr, object_type)` — scheduling-invariant across
// engines/threads. See `event_log.h`/`event_log.cc` C+18 helpers
// and ours's `ensure_dispatcher_object`.
phase_a::SetInGetNativeObject(true);
uint32_t schema_object_type = phase_a::kObjUnknown;
switch (as_type) {
case 0: // EventNotificationObject
case 1: // EventSynchronizationObject
@@ -436,12 +446,14 @@ object_ref<XObject> XObject::GetNativeObject(KernelState* kernel_state,
auto ev = new XEvent(kernel_state);
ev->InitializeNative(native_ptr, header);
object = ev;
schema_object_type = phase_a::kObjEvent;
} break;
case 2: // MutantObject
{
auto mutant = new XMutant(kernel_state);
mutant->InitializeNative(native_ptr, header);
object = mutant;
schema_object_type = phase_a::kObjMutant;
} break;
case 5: // SemaphoreObject
{
@@ -450,6 +462,7 @@ object_ref<XObject> XObject::GetNativeObject(KernelState* kernel_state,
// Can't report failure to the guest at late initialization:
assert_true(success);
object = sem;
schema_object_type = phase_a::kObjSemaphore;
} break;
case 3: // ProcessObject
case 4: // QueueObject
@@ -468,10 +481,24 @@ object_ref<XObject> XObject::GetNativeObject(KernelState* kernel_state,
assert_always();
result = nullptr;
}
phase_a::SetInGetNativeObject(false);
// Stash pointer in struct.
// FIXME: This assumes the object contains a dispatch header (some don't!)
if (object) {
StashHandle(header, object->handle());
// Phase C+18: emit the shared-global `handle.create` here, AFTER
// StashHandle, with the deterministic SID. The `native_ptr` is
// already a guest VA (`X_DISPATCH_HEADER*`) so a host-pointer cast
// to uint32_t is meaningful in canary's memory model only when the
// value is the guest address — translate via the same memory base.
if (phase_a::IsEnabled()) {
uint32_t guest_ptr =
kernel_state->memory()->HostToGuestVirtual(native_ptr);
const std::string& name = object->name();
phase_a::EmitHandleCreateSharedGlobal(
guest_ptr, schema_object_type, object->handle(),
name.empty() ? nullptr : name.c_str());
}
}
result = object;
}