Make XThread create a kernel object for itself
This commit is contained in:
parent
864e257474
commit
4c9cab4346
|
@ -143,6 +143,18 @@ uint8_t GetFakeCpuNumber(uint8_t proc_mask) {
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS XThread::Create() {
|
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.
|
// Allocate thread state block from heap.
|
||||||
// This is set as r13 for user code and some special inlined Win32 calls
|
// This is set as r13 for user code and some special inlined Win32 calls
|
||||||
// (like GetLastError/etc) will poke it directly.
|
// (like GetLastError/etc) will poke it directly.
|
||||||
|
@ -162,9 +174,6 @@ X_STATUS XThread::Create() {
|
||||||
return X_STATUS_NO_MEMORY;
|
return X_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set native info.
|
|
||||||
SetNativePointer(thread_state_address_, true);
|
|
||||||
|
|
||||||
auto module = kernel_state()->GetExecutableModule();
|
auto module = kernel_state()->GetExecutableModule();
|
||||||
|
|
||||||
// Allocate thread scratch.
|
// Allocate thread scratch.
|
||||||
|
@ -276,8 +285,6 @@ X_STATUS XThread::Create() {
|
||||||
xe::store_and_swap<uint32_t>(p + 0x16C, creation_params_.creation_flags);
|
xe::store_and_swap<uint32_t>(p + 0x16C, creation_params_.creation_flags);
|
||||||
xe::store_and_swap<uint32_t>(p + 0x17C, 1);
|
xe::store_and_swap<uint32_t>(p + 0x17C, 1);
|
||||||
|
|
||||||
SetNativePointer(thread_state_address_);
|
|
||||||
|
|
||||||
X_STATUS return_code = PlatformCreate();
|
X_STATUS return_code = PlatformCreate();
|
||||||
if (XFAILED(return_code)) {
|
if (XFAILED(return_code)) {
|
||||||
XELOGW("Unable to create platform thread (%.8X)", return_code);
|
XELOGW("Unable to create platform thread (%.8X)", return_code);
|
||||||
|
|
|
@ -60,6 +60,19 @@ struct XAPC {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// http://www.nirsoft.net/kernel_struct/vista/KTHREAD.html
|
||||||
|
struct X_THREAD {
|
||||||
|
X_DISPATCH_HEADER header;
|
||||||
|
xe::be<uint64_t> cycle_time;
|
||||||
|
xe::be<uint32_t> high_cycle_time; // FIXME: Needed?
|
||||||
|
xe::be<uint64_t> quantum_target;
|
||||||
|
xe::be<uint32_t> initial_stack_ptr;
|
||||||
|
xe::be<uint32_t> stack_limit_ptr;
|
||||||
|
xe::be<uint32_t> kernel_stack_ptr;
|
||||||
|
|
||||||
|
// This struct is actually quite long... so uh, not filling this out!
|
||||||
|
};
|
||||||
|
|
||||||
class XThread : public XObject {
|
class XThread : public XObject {
|
||||||
public:
|
public:
|
||||||
XThread(KernelState* kernel_state, uint32_t stack_size,
|
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 pcr_ptr() const { return pcr_address_; }
|
||||||
uint32_t thread_state_ptr() const { return thread_state_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_; }
|
cpu::ThreadState* thread_state() const { return thread_state_; }
|
||||||
uint32_t thread_id() const { return thread_id_; }
|
uint32_t thread_id() const { return thread_id_; }
|
||||||
uint32_t last_error();
|
uint32_t last_error();
|
||||||
|
@ -133,6 +148,7 @@ class XThread : public XObject {
|
||||||
uint32_t tls_address_;
|
uint32_t tls_address_;
|
||||||
uint32_t pcr_address_;
|
uint32_t pcr_address_;
|
||||||
uint32_t thread_state_address_;
|
uint32_t thread_state_address_;
|
||||||
|
uint32_t thread_object_address_; // Kernel object
|
||||||
cpu::ThreadState* thread_state_;
|
cpu::ThreadState* thread_state_;
|
||||||
|
|
||||||
std::string name_;
|
std::string name_;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/kernel/kernel_state.h"
|
#include "xenia/kernel/kernel_state.h"
|
||||||
#include "xenia/kernel/objects/xthread.h"
|
#include "xenia/kernel/objects/xthread.h"
|
||||||
|
#include "xenia/kernel/objects/xsemaphore.h"
|
||||||
#include "xenia/kernel/util/shim_utils.h"
|
#include "xenia/kernel/util/shim_utils.h"
|
||||||
#include "xenia/kernel/xboxkrnl_private.h"
|
#include "xenia/kernel/xboxkrnl_private.h"
|
||||||
#include "xenia/kernel/xobject.h"
|
#include "xenia/kernel/xobject.h"
|
||||||
|
@ -76,7 +77,7 @@ SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_context,
|
||||||
} break;*/
|
} break;*/
|
||||||
case XObject::kTypeThread: {
|
case XObject::kTypeThread: {
|
||||||
auto thread = object.get<XThread>();
|
auto thread = object.get<XThread>();
|
||||||
native_ptr = thread->thread_state_ptr();
|
native_ptr = thread->object_ptr();
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
assert_unhandled_case(object->type());
|
assert_unhandled_case(object->type());
|
||||||
|
@ -85,13 +86,18 @@ SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_context,
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case 0xD017BEEF: { // ExSemaphoreObjectType
|
case 0xD017BEEF: { // ExSemaphoreObjectType
|
||||||
|
assert(object->type() == XObject::kTypeSemaphore);
|
||||||
|
auto sem = object.get<XSemaphore>();
|
||||||
|
|
||||||
// TODO(benvanik): implement.
|
// TODO(benvanik): implement.
|
||||||
assert_unhandled_case(object_type_ptr);
|
assert_unhandled_case(object_type_ptr);
|
||||||
native_ptr = 0xDEADF00D;
|
native_ptr = 0xDEADF00D;
|
||||||
} break;
|
} break;
|
||||||
case 0xD01BBEEF: { // ExThreadObjectType
|
case 0xD01BBEEF: { // ExThreadObjectType
|
||||||
|
assert(object->type() == XObject::kTypeThread);
|
||||||
auto thread = object.get<XThread>();
|
auto thread = object.get<XThread>();
|
||||||
native_ptr = thread->thread_state_ptr();
|
|
||||||
|
native_ptr = thread->object_ptr();
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
assert_unhandled_case(object_type_ptr);
|
assert_unhandled_case(object_type_ptr);
|
||||||
|
|
Loading…
Reference in New Issue