Implementing thread state block access.

This commit is contained in:
Ben Vanik 2013-10-19 02:52:32 -07:00
parent 32a0045001
commit 6db8c6c961
6 changed files with 49 additions and 4 deletions

View File

@ -102,6 +102,10 @@ uint32_t XThread::GetCurrentThreadId(const uint8_t* thread_state_block) {
return XEGETUINT32BE(thread_state_block + 0x14C);
}
uint32_t XThread::thread_state() {
return thread_state_address_;
}
uint32_t XThread::thread_id() {
return thread_id_;
}
@ -135,6 +139,9 @@ X_STATUS XThread::Create() {
return X_STATUS_NO_MEMORY;
}
// Set native info.
SetNativePointer(thread_state_address_);
XModule* module = kernel_state()->GetExecutableModule();
// Allocate TLS block.

View File

@ -43,6 +43,7 @@ public:
static uint32_t GetCurrentThreadHandle();
static uint32_t GetCurrentThreadId(const uint8_t* thread_state_block);
uint32_t thread_state();
uint32_t thread_id();
uint32_t last_error();
void set_last_error(uint32_t error_code);

View File

@ -13,6 +13,7 @@
#include <xenia/kernel/modules/xboxkrnl/kernel_state.h>
#include <xenia/kernel/modules/xboxkrnl/xboxkrnl_private.h>
#include <xenia/kernel/modules/xboxkrnl/xobject.h>
#include <xenia/kernel/modules/xboxkrnl/objects/xthread.h>
using namespace xe;
@ -46,6 +47,14 @@ SHIM_CALL ObReferenceObjectByHandle_shim(
// TODO(benvanik): get native value, if supported.
uint32_t native_ptr = 0xDEADF00D;
switch (object_type_ptr) {
case 0xD01BBEEF: // ExThreadObjectType
{
XThread* thread = (XThread*)object;
native_ptr = thread->thread_state();
}
break;
}
if (out_object_ptr) {
SHIM_SET_MEM_32(out_object_ptr, native_ptr);

View File

@ -28,6 +28,7 @@ namespace xboxkrnl {
// r13 + 0x100: pointer to thread local state
// Thread local state:
// 0x058: kernel time
// 0x14C: thread id
// 0x150: if >0 then error states don't get set
// 0x160: last error
@ -136,7 +137,14 @@ SHIM_CALL ExCreateThread_shim(
uint32_t xeKeSetAffinityThread(void* thread_ptr, uint32_t affinity) {
// TODO(benvanik): implement.
KernelState* state = shared_kernel_state_;
XEASSERTNOTNULL(state);
XThread* thread = (XThread*)XObject::GetObject(state, thread_ptr);
if (thread) {
// TODO(benvanik): implement.
}
return affinity;
}
@ -151,9 +159,6 @@ SHIM_CALL KeSetAffinityThread_shim(
thread,
affinity);
// TODO(benvanik): expecting dummy values from ObReferenceObjectByHandle.
XEASSERT(thread == 0xDEADF00D);
void* thread_ptr = SHIM_MEM_ADDR(thread);
uint32_t result = xeKeSetAffinityThread(thread_ptr, affinity);
SHIM_SET_RETURN(result);

View File

@ -90,6 +90,28 @@ void XObject::UnlockType() {
xe_mutex_unlock(shared_kernel_state_->object_mutex_);
}
void XObject::SetNativePointer(uint32_t native_ptr) {
XObject::LockType();
DISPATCH_HEADER* header_be =
(DISPATCH_HEADER*)xe_memory_addr(kernel_state_->memory(), native_ptr);
DISPATCH_HEADER header;
header.type_flags = XESWAP32(header_be->type_flags);
header.signal_state = XESWAP32(header_be->signal_state);
header.wait_list_flink = XESWAP32(header_be->wait_list_flink);
header.wait_list_blink = XESWAP32(header_be->wait_list_blink);
XEASSERT(!(header.wait_list_blink & 0x1));
// Stash pointer in struct.
uint64_t object_ptr = reinterpret_cast<uint64_t>(this);
object_ptr |= 0x1;
header_be->wait_list_flink = XESWAP32((uint32_t)(object_ptr >> 32));
header_be->wait_list_blink = XESWAP32((uint32_t)(object_ptr & 0xFFFFFFFF));
XObject::UnlockType();
}
XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr) {
// Unfortunately the XDK seems to inline some KeInitialize calls, meaning
// we never see it and just randomly start getting passed events/timers/etc.

View File

@ -72,6 +72,7 @@ public:
protected:
Runtime* runtime();
xe_memory_ref memory(); // unretained
void SetNativePointer(uint32_t native_ptr);
private:
KernelState* kernel_state_;