From 864e257474458815e9324e772dbb651cb2603b65 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 12 Jun 2015 18:59:08 -0500 Subject: [PATCH 01/10] DISPATCH_HEADER -> X_DISPATCH_HEADER --- src/xenia/kernel/objects/xevent.cc | 2 +- src/xenia/kernel/objects/xevent.h | 2 +- src/xenia/kernel/objects/xmutant.cc | 2 +- src/xenia/kernel/objects/xmutant.h | 2 +- src/xenia/kernel/objects/xsemaphore.cc | 2 +- src/xenia/kernel/objects/xsemaphore.h | 2 +- src/xenia/kernel/xobject.cc | 4 ++-- src/xenia/kernel/xobject.h | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/xenia/kernel/objects/xevent.cc b/src/xenia/kernel/objects/xevent.cc index f1e7a39d5..3a6fd9a9c 100644 --- a/src/xenia/kernel/objects/xevent.cc +++ b/src/xenia/kernel/objects/xevent.cc @@ -28,7 +28,7 @@ void XEvent::Initialize(bool manual_reset, bool initial_state) { native_handle_ = CreateEvent(NULL, manual_reset, initial_state, NULL); } -void XEvent::InitializeNative(void* native_ptr, DISPATCH_HEADER& header) { +void XEvent::InitializeNative(void* native_ptr, X_DISPATCH_HEADER& header) { assert_null(native_handle_); bool manual_reset; diff --git a/src/xenia/kernel/objects/xevent.h b/src/xenia/kernel/objects/xevent.h index 68c06044f..9def93869 100644 --- a/src/xenia/kernel/objects/xevent.h +++ b/src/xenia/kernel/objects/xevent.h @@ -22,7 +22,7 @@ class XEvent : public XObject { virtual ~XEvent(); void Initialize(bool manual_reset, bool initial_state); - void InitializeNative(void* native_ptr, DISPATCH_HEADER& header); + void InitializeNative(void* native_ptr, X_DISPATCH_HEADER& header); int32_t Set(uint32_t priority_increment, bool wait); int32_t Pulse(uint32_t priority_increment, bool wait); diff --git a/src/xenia/kernel/objects/xmutant.cc b/src/xenia/kernel/objects/xmutant.cc index 006697def..a26e8c79f 100644 --- a/src/xenia/kernel/objects/xmutant.cc +++ b/src/xenia/kernel/objects/xmutant.cc @@ -27,7 +27,7 @@ void XMutant::Initialize(bool initial_owner) { native_handle_ = CreateMutex(NULL, initial_owner ? TRUE : FALSE, NULL); } -void XMutant::InitializeNative(void* native_ptr, DISPATCH_HEADER& header) { +void XMutant::InitializeNative(void* native_ptr, X_DISPATCH_HEADER& header) { assert_null(native_handle_); // Haven't seen this yet, but it's possible. diff --git a/src/xenia/kernel/objects/xmutant.h b/src/xenia/kernel/objects/xmutant.h index bc62a1b53..359970209 100644 --- a/src/xenia/kernel/objects/xmutant.h +++ b/src/xenia/kernel/objects/xmutant.h @@ -22,7 +22,7 @@ class XMutant : public XObject { virtual ~XMutant(); void Initialize(bool initial_owner); - void InitializeNative(void* native_ptr, DISPATCH_HEADER& header); + void InitializeNative(void* native_ptr, X_DISPATCH_HEADER& header); X_STATUS ReleaseMutant(uint32_t priority_increment, bool abandon, bool wait); diff --git a/src/xenia/kernel/objects/xsemaphore.cc b/src/xenia/kernel/objects/xsemaphore.cc index 72d473d96..a1b81f33f 100644 --- a/src/xenia/kernel/objects/xsemaphore.cc +++ b/src/xenia/kernel/objects/xsemaphore.cc @@ -27,7 +27,7 @@ void XSemaphore::Initialize(int32_t initial_count, int32_t maximum_count) { native_handle_ = CreateSemaphore(NULL, initial_count, maximum_count, NULL); } -void XSemaphore::InitializeNative(void* native_ptr, DISPATCH_HEADER& header) { +void XSemaphore::InitializeNative(void* native_ptr, X_DISPATCH_HEADER& header) { assert_null(native_handle_); // NOT IMPLEMENTED diff --git a/src/xenia/kernel/objects/xsemaphore.h b/src/xenia/kernel/objects/xsemaphore.h index fd693d72a..856d4227d 100644 --- a/src/xenia/kernel/objects/xsemaphore.h +++ b/src/xenia/kernel/objects/xsemaphore.h @@ -22,7 +22,7 @@ class XSemaphore : public XObject { virtual ~XSemaphore(); void Initialize(int32_t initial_count, int32_t maximum_count); - void InitializeNative(void* native_ptr, DISPATCH_HEADER& header); + void InitializeNative(void* native_ptr, X_DISPATCH_HEADER& header); int32_t ReleaseSemaphore(int32_t release_count); diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index 850bb8c0c..eb9c64e7d 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -165,7 +165,7 @@ void XObject::SetNativePointer(uint32_t native_ptr, bool uninitialized) { std::lock_guard lock(kernel_state_->object_mutex()); auto header = - kernel_state_->memory()->TranslateVirtual(native_ptr); + kernel_state_->memory()->TranslateVirtual(native_ptr); // Memory uninitialized, so don't bother with the check. if (!uninitialized) { @@ -195,7 +195,7 @@ object_ref XObject::GetNativeObject(KernelState* kernel_state, std::lock_guard lock(kernel_state->object_mutex()); - auto header = reinterpret_cast(native_ptr); + auto header = reinterpret_cast(native_ptr); if (as_type == -1) { as_type = (header->type_flags >> 24) & 0xFF; diff --git a/src/xenia/kernel/xobject.h b/src/xenia/kernel/xobject.h index 751eff15c..cebd70c68 100644 --- a/src/xenia/kernel/xobject.h +++ b/src/xenia/kernel/xobject.h @@ -33,7 +33,7 @@ typedef struct { xe::be signal_state; xe::be wait_list_flink; xe::be wait_list_blink; -} DISPATCH_HEADER; +} X_DISPATCH_HEADER; class XObject { public: From 4c9cab43463c7a0858ced0bc8785e76fbb05a64a Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 12 Jun 2015 19:02:17 -0500 Subject: [PATCH 02/10] Make XThread create a kernel object for itself --- src/xenia/kernel/objects/xthread.cc | 17 ++++++++++++----- src/xenia/kernel/objects/xthread.h | 16 ++++++++++++++++ src/xenia/kernel/xboxkrnl_ob.cc | 10 ++++++++-- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index 0222443e1..720e28489 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -143,6 +143,18 @@ uint8_t GetFakeCpuNumber(uint8_t proc_mask) { } X_STATUS XThread::Create() { + // Thread kernel object + // TODO: This is supposed to be preceded by X_OBJECT_HEADER, need to see if + // that's absolutely necessary. + thread_object_address_ = memory()->SystemHeapAlloc(sizeof(X_THREAD)); + if (!thread_object_address_) { + XELOGW("Unable to allocate thread object"); + return X_STATUS_NO_MEMORY; + } + + // Set native info. + SetNativePointer(thread_object_address_, true); + // Allocate thread state block from heap. // This is set as r13 for user code and some special inlined Win32 calls // (like GetLastError/etc) will poke it directly. @@ -162,9 +174,6 @@ X_STATUS XThread::Create() { return X_STATUS_NO_MEMORY; } - // Set native info. - SetNativePointer(thread_state_address_, true); - auto module = kernel_state()->GetExecutableModule(); // Allocate thread scratch. @@ -276,8 +285,6 @@ X_STATUS XThread::Create() { xe::store_and_swap(p + 0x16C, creation_params_.creation_flags); xe::store_and_swap(p + 0x17C, 1); - SetNativePointer(thread_state_address_); - X_STATUS return_code = PlatformCreate(); if (XFAILED(return_code)) { XELOGW("Unable to create platform thread (%.8X)", return_code); diff --git a/src/xenia/kernel/objects/xthread.h b/src/xenia/kernel/objects/xthread.h index ee2f441d0..ea2cd9cd7 100644 --- a/src/xenia/kernel/objects/xthread.h +++ b/src/xenia/kernel/objects/xthread.h @@ -60,6 +60,19 @@ struct XAPC { } }; +// http://www.nirsoft.net/kernel_struct/vista/KTHREAD.html +struct X_THREAD { + X_DISPATCH_HEADER header; + xe::be cycle_time; + xe::be high_cycle_time; // FIXME: Needed? + xe::be quantum_target; + xe::be initial_stack_ptr; + xe::be stack_limit_ptr; + xe::be kernel_stack_ptr; + + // This struct is actually quite long... so uh, not filling this out! +}; + class XThread : public XObject { public: XThread(KernelState* kernel_state, uint32_t stack_size, @@ -74,6 +87,8 @@ class XThread : public XObject { uint32_t pcr_ptr() const { return pcr_address_; } uint32_t thread_state_ptr() const { return thread_state_address_; } + uint32_t object_ptr() const { return thread_object_address_; } + cpu::ThreadState* thread_state() const { return thread_state_; } uint32_t thread_id() const { return thread_id_; } uint32_t last_error(); @@ -133,6 +148,7 @@ class XThread : public XObject { uint32_t tls_address_; uint32_t pcr_address_; uint32_t thread_state_address_; + uint32_t thread_object_address_; // Kernel object cpu::ThreadState* thread_state_; std::string name_; diff --git a/src/xenia/kernel/xboxkrnl_ob.cc b/src/xenia/kernel/xboxkrnl_ob.cc index a3f154865..3a082132c 100644 --- a/src/xenia/kernel/xboxkrnl_ob.cc +++ b/src/xenia/kernel/xboxkrnl_ob.cc @@ -10,6 +10,7 @@ #include "xenia/base/logging.h" #include "xenia/kernel/kernel_state.h" #include "xenia/kernel/objects/xthread.h" +#include "xenia/kernel/objects/xsemaphore.h" #include "xenia/kernel/util/shim_utils.h" #include "xenia/kernel/xboxkrnl_private.h" #include "xenia/kernel/xobject.h" @@ -76,7 +77,7 @@ SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_context, } break;*/ case XObject::kTypeThread: { auto thread = object.get(); - native_ptr = thread->thread_state_ptr(); + native_ptr = thread->object_ptr(); } break; default: { assert_unhandled_case(object->type()); @@ -85,13 +86,18 @@ SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_context, } } break; case 0xD017BEEF: { // ExSemaphoreObjectType + assert(object->type() == XObject::kTypeSemaphore); + auto sem = object.get(); + // TODO(benvanik): implement. assert_unhandled_case(object_type_ptr); native_ptr = 0xDEADF00D; } break; case 0xD01BBEEF: { // ExThreadObjectType + assert(object->type() == XObject::kTypeThread); auto thread = object.get(); - native_ptr = thread->thread_state_ptr(); + + native_ptr = thread->object_ptr(); } break; default: { assert_unhandled_case(object_type_ptr); From f96657ef7cd822a1067fed2c1f7c4a192a23ef98 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 12 Jun 2015 19:47:28 -0500 Subject: [PATCH 03/10] Fixup DISPATCH_HEADER type_flags to its parts --- src/xenia/kernel/objects/xevent.cc | 2 +- src/xenia/kernel/xobject.cc | 2 +- src/xenia/kernel/xobject.h | 21 ++++++++++++++++++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/xenia/kernel/objects/xevent.cc b/src/xenia/kernel/objects/xevent.cc index 3a6fd9a9c..8ef30bfd1 100644 --- a/src/xenia/kernel/objects/xevent.cc +++ b/src/xenia/kernel/objects/xevent.cc @@ -32,7 +32,7 @@ void XEvent::InitializeNative(void* native_ptr, X_DISPATCH_HEADER& header) { assert_null(native_handle_); bool manual_reset; - switch ((header.type_flags >> 24) & 0xFF) { + switch (header.type) { case 0x00: // EventNotificationObject (manual reset) manual_reset = true; break; diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index eb9c64e7d..ffb409ef2 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -198,7 +198,7 @@ object_ref XObject::GetNativeObject(KernelState* kernel_state, auto header = reinterpret_cast(native_ptr); if (as_type == -1) { - as_type = (header->type_flags >> 24) & 0xFF; + as_type = header->type; } if (header->wait_list_blink & 0x1) { diff --git a/src/xenia/kernel/xobject.h b/src/xenia/kernel/xobject.h index cebd70c68..2c8a2fdf4 100644 --- a/src/xenia/kernel/xobject.h +++ b/src/xenia/kernel/xobject.h @@ -29,7 +29,26 @@ class object_ref; // http://www.nirsoft.net/kernel_struct/vista/DISPATCHER_HEADER.html typedef struct { - xe::be type_flags; + struct { + uint8_t type; + + union { + uint8_t abandoned; + uint8_t absolute; + uint8_t npx_irql; + uint8_t signalling; + }; + union { + uint8_t size; + uint8_t hand; + }; + union { + uint8_t inserted; + uint8_t debug_active; + uint8_t dpc_active; + }; + }; + xe::be signal_state; xe::be wait_list_flink; xe::be wait_list_blink; From a0a8b7ec3735312a5173c2cb81e4fe9352d7c00b Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 12 Jun 2015 19:48:24 -0500 Subject: [PATCH 04/10] Add X_OBJECT_HEADER and X_OBJECT_CREATE_INFORMATION --- src/xenia/kernel/xobject.h | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/xenia/kernel/xobject.h b/src/xenia/kernel/xobject.h index 2c8a2fdf4..2a6fd5049 100644 --- a/src/xenia/kernel/xobject.h +++ b/src/xenia/kernel/xobject.h @@ -54,6 +54,42 @@ typedef struct { xe::be wait_list_blink; } X_DISPATCH_HEADER; +// http://www.nirsoft.net/kernel_struct/vista/OBJECT_HEADER.html +struct X_OBJECT_HEADER { + xe::be pointer_count; + union { + xe::be handle_count; + xe::be next_to_free; + }; + xe::be object_type_ptr; + uint8_t name_info_offset; + uint8_t handle_info_offset; + uint8_t quota_info_offset; + uint8_t flags; + union { + xe::be object_create_info; // X_OBJECT_CREATE_INFORMATION + xe::be quota_block_charged; + }; + xe::be security_descriptor; + + // Object lives after this header. + // (There's actually a body field here which is the object itself) +}; + +struct X_OBJECT_CREATE_INFORMATION { + xe::be attributes; + xe::be root_directory_ptr; + xe::be parse_context_ptr; + xe::be probe_mode; + xe::be paged_pool_charge; + xe::be non_paged_pool_charge; + xe::be security_descriptor_charge; + xe::be security_descriptor; + xe::be security_qos_ptr; + + // Security QoS here (SECURITY_QUALITY_OF_SERVICE) too! +}; + class XObject { public: enum Type { From bdcadeffe584f680385d8031470c58611cb73b96 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 12 Jun 2015 20:09:47 -0500 Subject: [PATCH 05/10] XObject CreateNative --- src/xenia/kernel/objects/xthread.cc | 10 ++----- src/xenia/kernel/objects/xthread.h | 2 -- src/xenia/kernel/xboxkrnl_ob.cc | 6 ++-- src/xenia/kernel/xobject.cc | 43 ++++++++++++++++++++++++++++- src/xenia/kernel/xobject.h | 9 ++++++ 5 files changed, 58 insertions(+), 12 deletions(-) diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index 720e28489..6192a3456 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -144,17 +144,13 @@ uint8_t GetFakeCpuNumber(uint8_t proc_mask) { X_STATUS XThread::Create() { // Thread kernel object - // TODO: This is supposed to be preceded by X_OBJECT_HEADER, need to see if - // that's absolutely necessary. - thread_object_address_ = memory()->SystemHeapAlloc(sizeof(X_THREAD)); - if (!thread_object_address_) { + // This call will also setup the native pointer for us. + uint8_t* guest_object = CreateNative(sizeof(X_THREAD)); + if (!guest_object) { XELOGW("Unable to allocate thread object"); return X_STATUS_NO_MEMORY; } - // Set native info. - SetNativePointer(thread_object_address_, true); - // Allocate thread state block from heap. // This is set as r13 for user code and some special inlined Win32 calls // (like GetLastError/etc) will poke it directly. diff --git a/src/xenia/kernel/objects/xthread.h b/src/xenia/kernel/objects/xthread.h index ea2cd9cd7..a97d85182 100644 --- a/src/xenia/kernel/objects/xthread.h +++ b/src/xenia/kernel/objects/xthread.h @@ -87,7 +87,6 @@ class XThread : public XObject { uint32_t pcr_ptr() const { return pcr_address_; } uint32_t thread_state_ptr() const { return thread_state_address_; } - uint32_t object_ptr() const { return thread_object_address_; } cpu::ThreadState* thread_state() const { return thread_state_; } uint32_t thread_id() const { return thread_id_; } @@ -148,7 +147,6 @@ class XThread : public XObject { uint32_t tls_address_; uint32_t pcr_address_; uint32_t thread_state_address_; - uint32_t thread_object_address_; // Kernel object cpu::ThreadState* thread_state_; std::string name_; diff --git a/src/xenia/kernel/xboxkrnl_ob.cc b/src/xenia/kernel/xboxkrnl_ob.cc index 3a082132c..65f8a8f4e 100644 --- a/src/xenia/kernel/xboxkrnl_ob.cc +++ b/src/xenia/kernel/xboxkrnl_ob.cc @@ -77,7 +77,7 @@ SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_context, } break;*/ case XObject::kTypeThread: { auto thread = object.get(); - native_ptr = thread->object_ptr(); + native_ptr = thread->guest_object(); } break; default: { assert_unhandled_case(object->type()); @@ -89,6 +89,8 @@ SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_context, assert(object->type() == XObject::kTypeSemaphore); auto sem = object.get(); + native_ptr = sem->guest_object(); + // TODO(benvanik): implement. assert_unhandled_case(object_type_ptr); native_ptr = 0xDEADF00D; @@ -97,7 +99,7 @@ SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_context, assert(object->type() == XObject::kTypeThread); auto thread = object.get(); - native_ptr = thread->object_ptr(); + native_ptr = thread->guest_object(); } break; default: { assert_unhandled_case(object_type_ptr); diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index ffb409ef2..e65d979e4 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -24,7 +24,9 @@ XObject::XObject(KernelState* kernel_state, Type type) handle_ref_count_(0), pointer_ref_count_(1), type_(type), - handle_(X_INVALID_HANDLE_VALUE) { + handle_(X_INVALID_HANDLE_VALUE), + guest_object_ptr_(0), + allocated_guest_object_(false) { // Added pointer check to support usage without a kernel_state if (kernel_state != nullptr) { kernel_state->object_table()->AddHandle(this, &handle_); @@ -34,6 +36,11 @@ XObject::XObject(KernelState* kernel_state, Type type) XObject::~XObject() { assert_zero(handle_ref_count_); assert_zero(pointer_ref_count_); + + if (allocated_guest_object_) { + uint32_t ptr = guest_object_ptr_ - sizeof(X_OBJECT_HEADER); + memory()->SystemHeapFree(ptr); + } } Emulator* XObject::emulator() const { return kernel_state_->emulator_; } @@ -161,6 +168,38 @@ X_STATUS XObject::WaitMultiple(uint32_t count, XObject** objects, return result; } +uint8_t* XObject::CreateNative(uint32_t size) { + std::lock_guard lock(kernel_state_->object_mutex()); + + uint32_t total_size = size + sizeof(X_OBJECT_HEADER); + + auto mem = memory()->SystemHeapAlloc(total_size); + if (!mem) { + // Out of memory! + return nullptr; + } + + allocated_guest_object_ = true; + memory()->Zero(mem, total_size); + guest_object_ptr_ = mem + sizeof(X_OBJECT_HEADER); + SetNativePointer(guest_object_ptr_, true); + + auto header = memory()->TranslateVirtual(mem); + + auto creation_info = + memory()->SystemHeapAlloc(sizeof(X_OBJECT_CREATE_INFORMATION)); + if (creation_info) { + memory()->Zero(creation_info, sizeof(X_OBJECT_CREATE_INFORMATION)); + + // Set it up in the header. + // Some kernel method is accessing this struct and dereferencing a member. + // With our current definition that member is non_paged_pool_charge. + header->object_create_info = creation_info; + } + + return memory()->TranslateVirtual(guest_object_ptr_); +} + void XObject::SetNativePointer(uint32_t native_ptr, bool uninitialized) { std::lock_guard lock(kernel_state_->object_mutex()); @@ -173,6 +212,7 @@ void XObject::SetNativePointer(uint32_t native_ptr, bool uninitialized) { } // Stash pointer in struct. + // FIXME: This assumes the object has a dispatch header (some don't!) uint64_t object_ptr = reinterpret_cast(this); object_ptr |= 0x1; header->wait_list_flink = (uint32_t)(object_ptr >> 32); @@ -251,6 +291,7 @@ object_ref XObject::GetNativeObject(KernelState* kernel_state, } // Stash pointer in struct. + // FIXME: This assumes the object contains a dispatch header (some don't!) uint64_t object_ptr = reinterpret_cast(object); object_ptr |= 0x1; header->wait_list_flink = (uint32_t)(object_ptr >> 32); diff --git a/src/xenia/kernel/xobject.h b/src/xenia/kernel/xobject.h index 2a6fd5049..e2a12119c 100644 --- a/src/xenia/kernel/xobject.h +++ b/src/xenia/kernel/xobject.h @@ -76,6 +76,7 @@ struct X_OBJECT_HEADER { // (There's actually a body field here which is the object itself) }; +// http://www.nirsoft.net/kernel_struct/vista/OBJECT_CREATE_INFORMATION.html struct X_OBJECT_CREATE_INFORMATION { xe::be attributes; xe::be root_directory_ptr; @@ -114,6 +115,7 @@ class XObject { Type type(); X_HANDLE handle() const; const std::string& name() const { return name_; } + uint32_t guest_object() const { return guest_object_ptr_; } void RetainHandle(); bool ReleaseHandle(); @@ -149,6 +151,8 @@ class XObject { virtual void* GetWaitHandle() { return 0; } protected: + // Creates the kernel object for guest code to use. Typically not needed. + uint8_t* CreateNative(uint32_t size); void SetNativePointer(uint32_t native_ptr, bool uninitialized = false); static uint32_t TimeoutTicksToMs(int64_t timeout_ticks); @@ -162,6 +166,11 @@ class XObject { Type type_; X_HANDLE handle_; std::string name_; // May be zero length. + + // Guest pointer for kernel object. Remember: X_OBJECT_HEADER precedes this + // if we allocated it! + uint32_t guest_object_ptr_; + bool allocated_guest_object_; }; template From b7aabd7860bb352ba21adb4b15bc1966d0128cf7 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 12 Jun 2015 21:31:00 -0500 Subject: [PATCH 06/10] XSemaphore now calls CreateNative --- src/xenia/kernel/objects/xsemaphore.cc | 2 ++ src/xenia/kernel/objects/xsemaphore.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/xenia/kernel/objects/xsemaphore.cc b/src/xenia/kernel/objects/xsemaphore.cc index a1b81f33f..4f39b09a7 100644 --- a/src/xenia/kernel/objects/xsemaphore.cc +++ b/src/xenia/kernel/objects/xsemaphore.cc @@ -24,6 +24,8 @@ XSemaphore::~XSemaphore() { void XSemaphore::Initialize(int32_t initial_count, int32_t maximum_count) { assert_null(native_handle_); + CreateNative(sizeof(X_SEMAPHORE)); + native_handle_ = CreateSemaphore(NULL, initial_count, maximum_count, NULL); } diff --git a/src/xenia/kernel/objects/xsemaphore.h b/src/xenia/kernel/objects/xsemaphore.h index 856d4227d..289ee9de9 100644 --- a/src/xenia/kernel/objects/xsemaphore.h +++ b/src/xenia/kernel/objects/xsemaphore.h @@ -16,6 +16,10 @@ namespace xe { namespace kernel { +struct X_SEMAPHORE { + // TODO: Make this not empty! +}; + class XSemaphore : public XObject { public: XSemaphore(KernelState* kernel_state); From 3bd5dc011cf2065fb3e9508044f5799db37d7830 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 12 Jun 2015 21:35:49 -0500 Subject: [PATCH 07/10] Free the object creation info on destruction --- src/xenia/kernel/xobject.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index e65d979e4..077a3e112 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -39,6 +39,13 @@ XObject::~XObject() { if (allocated_guest_object_) { uint32_t ptr = guest_object_ptr_ - sizeof(X_OBJECT_HEADER); + auto header = memory()->TranslateVirtual(ptr); + + // Free the object creation info + if (header->object_create_info) { + memory()->SystemHeapFree(header->object_create_info); + } + memory()->SystemHeapFree(ptr); } } From 4e74db8e51a59530d7dd2caf48694322ab4cd22b Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 12 Jun 2015 22:43:37 -0500 Subject: [PATCH 08/10] Add the dispatch header to X_SEMAPHORE --- src/xenia/kernel/objects/xsemaphore.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xenia/kernel/objects/xsemaphore.h b/src/xenia/kernel/objects/xsemaphore.h index 289ee9de9..97dbc7942 100644 --- a/src/xenia/kernel/objects/xsemaphore.h +++ b/src/xenia/kernel/objects/xsemaphore.h @@ -17,6 +17,7 @@ namespace xe { namespace kernel { struct X_SEMAPHORE { + X_DISPATCH_HEADER header; // TODO: Make this not empty! }; From 3e7870fb39c3a064ce4c0869a4dae87c888952f4 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 12 Jun 2015 22:46:19 -0500 Subject: [PATCH 09/10] Make SetNativePointer setup the guest pointer --- src/xenia/kernel/xobject.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index 077a3e112..29639316f 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -188,8 +188,7 @@ uint8_t* XObject::CreateNative(uint32_t size) { allocated_guest_object_ = true; memory()->Zero(mem, total_size); - guest_object_ptr_ = mem + sizeof(X_OBJECT_HEADER); - SetNativePointer(guest_object_ptr_, true); + SetNativePointer(mem + sizeof(X_OBJECT_HEADER), true); auto header = memory()->TranslateVirtual(mem); @@ -210,6 +209,9 @@ uint8_t* XObject::CreateNative(uint32_t size) { void XObject::SetNativePointer(uint32_t native_ptr, bool uninitialized) { std::lock_guard lock(kernel_state_->object_mutex()); + // If hit: We've already setup the native ptr with CreateNative! + assert_zero(guest_object_ptr_); + auto header = kernel_state_->memory()->TranslateVirtual(native_ptr); @@ -224,6 +226,8 @@ void XObject::SetNativePointer(uint32_t native_ptr, bool uninitialized) { object_ptr |= 0x1; header->wait_list_flink = (uint32_t)(object_ptr >> 32); header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF); + + guest_object_ptr_ = native_ptr; } object_ref XObject::GetNativeObject(KernelState* kernel_state, From 9376ed3f01538384c646ee71e32ea87412a265aa Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sat, 13 Jun 2015 00:33:24 -0500 Subject: [PATCH 10/10] Whoops --- src/xenia/kernel/xboxkrnl_ob.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl_ob.cc b/src/xenia/kernel/xboxkrnl_ob.cc index 65f8a8f4e..a3ddc4507 100644 --- a/src/xenia/kernel/xboxkrnl_ob.cc +++ b/src/xenia/kernel/xboxkrnl_ob.cc @@ -90,10 +90,6 @@ SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_context, auto sem = object.get(); native_ptr = sem->guest_object(); - - // TODO(benvanik): implement. - assert_unhandled_case(object_type_ptr); - native_ptr = 0xDEADF00D; } break; case 0xD01BBEEF: { // ExThreadObjectType assert(object->type() == XObject::kTypeThread);