From 4c9cab43463c7a0858ced0bc8785e76fbb05a64a Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Fri, 12 Jun 2015 19:02:17 -0500 Subject: [PATCH] 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);