From 120e09f8e73cb9c1c065a0960f188475a57b7294 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 24 May 2015 21:01:57 -0700 Subject: [PATCH] XObject::GetObject->GetNativeObject --- src/xenia/kernel/xboxkrnl_ob.cc | 2 +- src/xenia/kernel/xboxkrnl_threading.cc | 59 ++++++++++++-------------- src/xenia/kernel/xobject.cc | 21 ++++----- src/xenia/kernel/xobject.h | 11 ++++- 4 files changed, 48 insertions(+), 45 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl_ob.cc b/src/xenia/kernel/xboxkrnl_ob.cc index 71cbcc68c..bba6fb052 100644 --- a/src/xenia/kernel/xboxkrnl_ob.cc +++ b/src/xenia/kernel/xboxkrnl_ob.cc @@ -118,7 +118,7 @@ SHIM_CALL ObDereferenceObject_shim(PPCContext* ppc_state, KernelState* state) { } void* object_ptr = SHIM_MEM_ADDR(native_ptr); - XObject* object = XObject::GetObject(state, object_ptr); + auto object = XObject::GetNativeObject(state, object_ptr); if (object) { object->Release(); } diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index 98da73484..2d644e4ce 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -176,8 +176,8 @@ SHIM_CALL KeResumeThread_shim(PPCContext* ppc_state, KernelState* state) { XELOGD("KeResumeThread(%.8X)", thread_ptr); X_STATUS result; - XThread* thread = - (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); + auto thread = + XObject::GetNativeObject(state, SHIM_MEM_ADDR(thread_ptr)); if (thread) { result = thread->Resume(); } @@ -215,8 +215,8 @@ SHIM_CALL KeSetAffinityThread_shim(PPCContext* ppc_state, KernelState* state) { XELOGD("KeSetAffinityThread(%.8X, %.8X)", thread_ptr, affinity); - XThread* thread = - (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); + auto thread = + XObject::GetNativeObject(state, SHIM_MEM_ADDR(thread_ptr)); if (thread) { thread->SetAffinity(affinity); } @@ -232,8 +232,8 @@ SHIM_CALL KeQueryBasePriorityThread_shim(PPCContext* ppc_state, int32_t priority = 0; - XThread* thread = - (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); + auto thread = + XObject::GetNativeObject(state, SHIM_MEM_ADDR(thread_ptr)); if (thread) { priority = thread->QueryPriority(); } @@ -259,8 +259,7 @@ SHIM_CALL KeSetBasePriorityThread_shim(PPCContext* ppc_state, // Log it in case this is the source of any problems in the future XELOGD("KeSetBasePriorityThread - Interpreting thread ptr as handle!"); } else { - thread = (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); - thread->Retain(); + thread = XObject::GetNativeObject(state, SHIM_MEM_ADDR(thread_ptr)).release(); } if (thread) { @@ -279,8 +278,8 @@ SHIM_CALL KeSetDisableBoostThread_shim(PPCContext* ppc_state, XELOGD("KeSetDisableBoostThread(%.8X, %.8X)", thread_ptr, disabled); - XThread* thread = - (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); + auto thread = + XObject::GetNativeObject(state, SHIM_MEM_ADDR(thread_ptr)); if (thread) { // Uhm? } @@ -490,8 +489,7 @@ SHIM_CALL KeSetEvent_shim(PPCContext* ppc_state, KernelState* state) { void* event_ptr = SHIM_MEM_ADDR(event_ref); - XEvent* ev = (XEvent*)XObject::GetObject(state, event_ptr); - assert_not_null(ev); + auto ev = XObject::GetNativeObject(state, event_ptr); if (!ev) { SHIM_SET_RETURN_64(0); return; @@ -533,8 +531,7 @@ SHIM_CALL KePulseEvent_shim(PPCContext* ppc_state, KernelState* state) { int32_t result = 0; void* event_ptr = SHIM_MEM_ADDR(event_ref); - XEvent* ev = (XEvent*)XObject::GetObject(state, event_ptr); - assert_not_null(ev); + auto ev = XObject::GetNativeObject(state, event_ptr); if (ev) { result = ev->Pulse(increment, !!wait); } @@ -570,8 +567,7 @@ SHIM_CALL KeResetEvent_shim(PPCContext* ppc_state, KernelState* state) { XELOGD("KeResetEvent(%.8X)", event_ref); void* event_ptr = SHIM_MEM_ADDR(event_ref); - XEvent* ev = (XEvent*)XEvent::GetObject(state, event_ptr); - assert_not_null(ev); + auto ev = XObject::GetNativeObject(state, event_ptr); if (!ev) { SHIM_SET_RETURN_64(0); return; @@ -613,7 +609,7 @@ SHIM_CALL NtCreateSemaphore_shim(PPCContext* ppc_state, KernelState* state) { AssertNoNameCollision(state, obj_attributes_ptr); } - XSemaphore* sem = new XSemaphore(state); + auto sem = object_ref(new XSemaphore(state)); sem->Initialize(count, limit); // obj_attributes may have a name inside of it, if != NULL. @@ -637,9 +633,8 @@ SHIM_CALL KeInitializeSemaphore_shim(PPCContext* ppc_state, XELOGD("KeInitializeSemaphore(%.8X, %d, %d)", semaphore_ref, count, limit); void* semaphore_ptr = SHIM_MEM_ADDR(semaphore_ref); - XSemaphore* sem = (XSemaphore*)XSemaphore::GetObject(state, semaphore_ptr, - 5 /* SemaphoreObject */); - assert_not_null(sem); + auto sem = XObject::GetNativeObject(state, semaphore_ptr, + 5 /* SemaphoreObject */); if (!sem) { return; } @@ -657,8 +652,7 @@ SHIM_CALL KeReleaseSemaphore_shim(PPCContext* ppc_state, KernelState* state) { adjustment, wait); void* semaphore_ptr = SHIM_MEM_ADDR(semaphore_ref); - XSemaphore* sem = (XSemaphore*)XSemaphore::GetObject(state, semaphore_ptr); - assert_not_null(sem); + auto sem = XObject::GetNativeObject(state, semaphore_ptr); if (!sem) { SHIM_SET_RETURN_64(0); return; @@ -848,7 +842,8 @@ SHIM_CALL KeWaitForSingleObject_shim(PPCContext* ppc_state, XELOGD("KeWaitForSingleObject(%.8X, %.8X, %.8X, %.1X, %.8X)", object_ptr, wait_reason, processor_mode, alertable, timeout_ptr); - XObject* object = XObject::GetObject(state, SHIM_MEM_ADDR(object_ptr)); + auto object = + XObject::GetNativeObject(state, SHIM_MEM_ADDR(object_ptr)); if (!object) { // The only kind-of failure code. SHIM_SET_RETURN_32(X_STATUS_ABANDONED_WAIT_0); @@ -906,11 +901,11 @@ SHIM_CALL KeWaitForMultipleObjects_shim(PPCContext* ppc_state, X_STATUS result = X_STATUS_SUCCESS; - XObject** objects = (XObject**)alloca(sizeof(XObject*) * count); + std::vector> objects(count); for (uint32_t n = 0; n < count; n++) { uint32_t object_ptr_ptr = SHIM_MEM_32(objects_ptr + n * 4); void* object_ptr = SHIM_MEM_ADDR(object_ptr_ptr); - objects[n] = XObject::GetObject(state, object_ptr); + objects[n] = XObject::GetNativeObject(state, object_ptr); if (!objects[n]) { SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER); return; @@ -918,9 +913,9 @@ SHIM_CALL KeWaitForMultipleObjects_shim(PPCContext* ppc_state, } uint64_t timeout = timeout_ptr ? SHIM_MEM_64(timeout_ptr) : 0; - result = XObject::WaitMultiple(count, objects, wait_type, wait_reason, - processor_mode, alertable, - timeout_ptr ? &timeout : NULL); + result = XObject::WaitMultiple( + count, reinterpret_cast(objects.data()), wait_type, + wait_reason, processor_mode, alertable, timeout_ptr ? &timeout : nullptr); SHIM_SET_RETURN_32(result); } @@ -1150,8 +1145,8 @@ SHIM_CALL KeInsertQueueApc_shim(PPCContext* ppc_state, KernelState* state) { priority_increment); uint32_t thread_ptr = SHIM_MEM_32(apc_ptr + 4); - XThread* thread = - (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); + auto thread = + XObject::GetNativeObject(state, SHIM_MEM_ADDR(thread_ptr)); if (!thread) { SHIM_SET_RETURN_64(0); return; @@ -1192,8 +1187,8 @@ SHIM_CALL KeRemoveQueueApc_shim(PPCContext* ppc_state, KernelState* state) { bool result = false; uint32_t thread_ptr = SHIM_MEM_32(apc_ptr + 4); - XThread* thread = - (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); + auto thread = + XObject::GetNativeObject(state, SHIM_MEM_ADDR(thread_ptr)); if (!thread) { SHIM_SET_RETURN_64(0); return; diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index 5b1e6e27b..e6a7c69d9 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -175,10 +175,9 @@ void XObject::SetNativePointer(uint32_t native_ptr, bool uninitialized) { header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF); } -XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, - int32_t as_type) { - assert_not_null(native_ptr); - +object_ref XObject::GetNativeObject(KernelState* kernel_state, + void* native_ptr, + int32_t as_type) { // Unfortunately the XDK seems to inline some KeInitialize calls, meaning // we never see it and just randomly start getting passed events/timers/etc. // Luckily it seems like all other calls (Set/Reset/Wait/etc) are used and @@ -202,28 +201,28 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, ((header->wait_list_blink) & ~0x1); XObject* object = reinterpret_cast(object_ptr); // TODO(benvanik): assert nothing has been changed in the struct. - return object; + return retain_object(object); } else { // First use, create new. // http://www.nirsoft.net/kernel_struct/vista/KOBJECTS.html - XObject* object = NULL; + XObject* object = nullptr; switch (as_type) { case 0: // EventNotificationObject case 1: // EventSynchronizationObject { - XEvent* ev = new XEvent(kernel_state); + auto ev = new XEvent(kernel_state); ev->InitializeNative(native_ptr, *header); object = ev; } break; case 2: // MutantObject { - XMutant* mutant = new XMutant(kernel_state); + auto mutant = new XMutant(kernel_state); mutant->InitializeNative(native_ptr, *header); object = mutant; } break; case 5: // SemaphoreObject { - XSemaphore* sem = new XSemaphore(kernel_state); + auto sem = new XSemaphore(kernel_state); sem->InitializeNative(native_ptr, *header); object = sem; } break; @@ -251,7 +250,9 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, header->wait_list_flink = (uint32_t)(object_ptr >> 32); header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF); - return object; + // NOTE: we are double-retaining, as the object is implicitly created and + // can never be released. + return retain_object(object); } } diff --git a/src/xenia/kernel/xobject.h b/src/xenia/kernel/xobject.h index b94fc6b39..751eff15c 100644 --- a/src/xenia/kernel/xobject.h +++ b/src/xenia/kernel/xobject.h @@ -81,8 +81,15 @@ class XObject { uint32_t processor_mode, uint32_t alertable, uint64_t* opt_timeout); - static XObject* GetObject(KernelState* kernel_state, void* native_ptr, - int32_t as_type = -1); + static object_ref GetNativeObject(KernelState* kernel_state, + void* native_ptr, + int32_t as_type = -1); + template + static object_ref GetNativeObject(KernelState* kernel_state, + void* native_ptr, int32_t as_type = -1) { + return object_ref(reinterpret_cast( + GetNativeObject(kernel_state, native_ptr, as_type).release())); + } virtual void* GetWaitHandle() { return 0; }