Thread state updates.

This commit is contained in:
Ben Vanik 2015-05-16 01:45:56 -07:00
parent 88596611d1
commit 8d4f54e240
5 changed files with 61 additions and 45 deletions

View File

@ -32,7 +32,7 @@ class ThreadState {
void set_name(const std::string& value) { name_ = value; } void set_name(const std::string& value) { name_ = value; }
void* backend_data() const { return backend_data_; } void* backend_data() const { return backend_data_; }
uint32_t stack_address() const { return stack_address_; } uint32_t stack_address() const { return stack_address_; }
size_t stack_size() const { return stack_size_; } uint32_t stack_size() const { return stack_size_; }
uint32_t thread_state_address() const { return thread_state_address_; } uint32_t thread_state_address() const { return thread_state_address_; }
xe::cpu::frontend::PPCContext* context() const { return context_; } xe::cpu::frontend::PPCContext* context() const { return context_; }

View File

@ -31,7 +31,7 @@ void XEvent::InitializeNative(void* native_ptr, DISPATCH_HEADER& header) {
assert_null(handle_); assert_null(handle_);
bool manual_reset; bool manual_reset;
switch (header.type_flags >> 24) { switch ((header.type_flags >> 24) & 0xFF) {
case 0x00: // EventNotificationObject (manual reset) case 0x00: // EventNotificationObject (manual reset)
manual_reset = true; manual_reset = true;
break; break;

View File

@ -91,7 +91,7 @@ XThread* XThread::GetCurrentThread() {
XThread::EnterCriticalRegion(); XThread::EnterCriticalRegion();
thread = shared_kernel_thread_; thread = shared_kernel_thread_;
if (!thread) { if (!thread) {
thread = new XThread(KernelState::shared(), 32 * 1024, 0, 0, 0, 0); thread = new XThread(KernelState::shared(), 256 * 1024, 0, 0, 0, 0);
shared_kernel_thread_ = thread; shared_kernel_thread_ = thread;
current_thread_tls = thread; current_thread_tls = thread;
} }
@ -137,7 +137,7 @@ X_STATUS XThread::Create() {
// 0x160: last error // 0x160: last error
// So, at offset 0x100 we have a 4b pointer to offset 200, then have the // So, at offset 0x100 we have a 4b pointer to offset 200, then have the
// structure. // structure.
thread_state_address_ = memory()->SystemHeapAlloc(2048); thread_state_address_ = memory()->SystemHeapAlloc(0xAB0);
if (!thread_state_address_) { if (!thread_state_address_) {
XELOGW("Unable to allocate thread state block"); XELOGW("Unable to allocate thread state block");
return X_STATUS_NO_MEMORY; return X_STATUS_NO_MEMORY;
@ -169,21 +169,43 @@ X_STATUS XThread::Create() {
// Setup the thread state block (last error/etc). // Setup the thread state block (last error/etc).
uint8_t* p = memory()->TranslateVirtual(thread_state_address_); uint8_t* p = memory()->TranslateVirtual(thread_state_address_);
xe::store_and_swap<uint32_t>(p + 0x000, tls_address_); xe::store_and_swap<uint32_t>(p + 0x000, 6);
xe::store_and_swap<uint32_t>(p + 0x008, thread_state_address_ + 0x008);
xe::store_and_swap<uint32_t>(p + 0x00C, thread_state_address_ + 0x008);
xe::store_and_swap<uint32_t>(p + 0x010, thread_state_address_ + 0x010);
xe::store_and_swap<uint32_t>(p + 0x014, thread_state_address_ + 0x010);
xe::store_and_swap<uint32_t>(p + 0x040, thread_state_address_ + 0x018 + 8);
xe::store_and_swap<uint32_t>(p + 0x044, thread_state_address_ + 0x018 + 8);
xe::store_and_swap<uint32_t>(p + 0x048, thread_state_address_);
xe::store_and_swap<uint32_t>(p + 0x04C, thread_state_address_ + 0x018);
xe::store_and_swap<uint16_t>(p + 0x054, 0x102);
xe::store_and_swap<uint16_t>(p + 0x056, 1);
xe::store_and_swap<uint32_t>(p + 0x068, tls_address_);
xe::store_and_swap<uint8_t>(p + 0x06C, 0);
xe::store_and_swap<uint32_t>(p + 0x074, thread_state_address_ + 0x074);
xe::store_and_swap<uint32_t>(p + 0x078, thread_state_address_ + 0x074);
xe::store_and_swap<uint32_t>(p + 0x07C, thread_state_address_ + 0x07C);
xe::store_and_swap<uint32_t>(p + 0x080, thread_state_address_ + 0x07C);
xe::store_and_swap<uint8_t>(p + 0x08B, 1);
// D4 = APC
// FC = semaphore (ptr, 0, 2)
// A88 = APC
// 18 = timer
xe::store_and_swap<uint32_t>(p + 0x09C, 0xFDFFD7FF);
xe::store_and_swap<uint32_t>(p + 0x100, thread_state_address_); xe::store_and_swap<uint32_t>(p + 0x100, thread_state_address_);
FILETIME t; FILETIME t;
GetSystemTimeAsFileTime(&t); GetSystemTimeAsFileTime(&t);
xe::store_and_swap<uint64_t>( xe::store_and_swap<uint64_t>(
p + 0x130, ((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime); p + 0x130, ((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime);
xe::store_and_swap<uint32_t>(p + 0x144, thread_state_address_ + 0x144); xe::store_and_swap<uint32_t>(p + 0x144, thread_state_address_ + 0x144);
xe::store_and_swap<uint32_t>(p + 0x148, thread_state_address_ + 0x144); xe::store_and_swap<uint32_t>(p + 0x148, thread_state_address_ + 0x144);
xe::store_and_swap<uint32_t>(p + 0x14C, thread_id_); xe::store_and_swap<uint32_t>(p + 0x14C, thread_id_);
xe::store_and_swap<uint32_t>(p + 0x150, 0); // ? xe::store_and_swap<uint32_t>(p + 0x150, creation_params_.start_address);
xe::store_and_swap<uint32_t>(p + 0x154, thread_state_address_ + 0x154); xe::store_and_swap<uint32_t>(p + 0x154, thread_state_address_ + 0x154);
xe::store_and_swap<uint32_t>(p + 0x158, thread_state_address_ + 0x154); xe::store_and_swap<uint32_t>(p + 0x158, thread_state_address_ + 0x154);
xe::store_and_swap<uint32_t>(p + 0x160, 0); // last error xe::store_and_swap<uint32_t>(p + 0x160, 0); // last error
xe::store_and_swap<uint32_t>(p + 0x16C, creation_params_.creation_flags);
xe::store_and_swap<uint32_t>(p + 0x17C, 1);
// Allocate processor thread state. // Allocate processor thread state.
// This is thread safe. // This is thread safe.
@ -191,6 +213,14 @@ X_STATUS XThread::Create() {
new ThreadState(kernel_state()->processor(), thread_id_, 0, new ThreadState(kernel_state()->processor(), thread_id_, 0,
creation_params_.stack_size, thread_state_address_); creation_params_.stack_size, thread_state_address_);
xe::store_and_swap<uint32_t>(
p + 0x05C, thread_state_->stack_address() + thread_state_->stack_size());
xe::store_and_swap<uint32_t>(p + 0x060, thread_state_->stack_address());
xe::store_and_swap<uint32_t>(
p + 0x0D0, thread_state_->stack_address() + thread_state_->stack_size());
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);
@ -242,9 +272,8 @@ static uint32_t __stdcall XThreadStartCallbackWin32(void* param) {
X_STATUS XThread::PlatformCreate() { X_STATUS XThread::PlatformCreate() {
bool suspended = creation_params_.creation_flags & 0x1; bool suspended = creation_params_.creation_flags & 0x1;
thread_handle_ = thread_handle_ =
CreateThread(NULL, 0, CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)XThreadStartCallbackWin32,
(LPTHREAD_START_ROUTINE)XThreadStartCallbackWin32, this, this, suspended ? CREATE_SUSPENDED : 0, NULL);
suspended ? CREATE_SUSPENDED : 0, NULL);
if (!thread_handle_) { if (!thread_handle_) {
uint32_t last_error = GetLastError(); uint32_t last_error = GetLastError();
// TODO(benvanik): translate? // TODO(benvanik): translate?
@ -289,7 +318,7 @@ X_STATUS XThread::PlatformCreate() {
pthread_attr_init(&attr); pthread_attr_init(&attr);
// TODO(benvanik): this shouldn't be necessary // TODO(benvanik): this shouldn't be necessary
//pthread_attr_setstacksize(&attr, creation_params_.stack_size); // pthread_attr_setstacksize(&attr, creation_params_.stack_size);
int result_code; int result_code;
if (creation_params_.creation_flags & 0x1) { if (creation_params_.creation_flags & 0x1) {
@ -428,9 +457,8 @@ void XThread::DeliverAPCs(void* data) {
// kernel_routine(apc_address, &normal_routine, &normal_context, // kernel_routine(apc_address, &normal_routine, &normal_context,
// &system_arg1, &system_arg2) // &system_arg1, &system_arg2)
uint64_t kernel_args[] = { uint64_t kernel_args[] = {
apc_address, thread->scratch_address_ + 0, apc_address, thread->scratch_address_ + 0, thread->scratch_address_ + 4,
thread->scratch_address_ + 4, thread->scratch_address_ + 8, thread->scratch_address_ + 8, thread->scratch_address_ + 12,
thread->scratch_address_ + 12,
}; };
processor->ExecuteInterrupt(0, kernel_routine, kernel_args, processor->ExecuteInterrupt(0, kernel_routine, kernel_args,
xe::countof(kernel_args)); xe::countof(kernel_args));

View File

@ -154,22 +154,16 @@ X_STATUS XObject::WaitMultiple(uint32_t count, XObject** objects,
void XObject::SetNativePointer(uint32_t native_ptr) { void XObject::SetNativePointer(uint32_t native_ptr) {
std::lock_guard<std::mutex> lock(kernel_state_->object_mutex()); std::lock_guard<std::mutex> lock(kernel_state_->object_mutex());
auto header_be = auto header =
kernel_state_->memory()->TranslateVirtual<DISPATCH_HEADER*>(native_ptr); kernel_state_->memory()->TranslateVirtual<DISPATCH_HEADER*>(native_ptr);
DISPATCH_HEADER header;
header.type_flags = xe::byte_swap(header_be->type_flags);
header.signal_state = xe::byte_swap(header_be->signal_state);
header.wait_list_flink = xe::byte_swap(header_be->wait_list_flink);
header.wait_list_blink = xe::byte_swap(header_be->wait_list_blink);
assert_true(!(header.wait_list_blink & 0x1)); assert_true(!(header->wait_list_blink & 0x1));
// Stash pointer in struct. // Stash pointer in struct.
uint64_t object_ptr = reinterpret_cast<uint64_t>(this); uint64_t object_ptr = reinterpret_cast<uint64_t>(this);
object_ptr |= 0x1; object_ptr |= 0x1;
header_be->wait_list_flink = xe::byte_swap((uint32_t)(object_ptr >> 32)); header->wait_list_flink = (uint32_t)(object_ptr >> 32);
header_be->wait_list_blink = header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF);
xe::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF));
} }
XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
@ -185,21 +179,16 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
std::lock_guard<std::mutex> lock(kernel_state->object_mutex()); std::lock_guard<std::mutex> lock(kernel_state->object_mutex());
DISPATCH_HEADER* header_be = (DISPATCH_HEADER*)native_ptr; auto header = reinterpret_cast<DISPATCH_HEADER*>(native_ptr);
DISPATCH_HEADER header;
header.type_flags = xe::byte_swap(header_be->type_flags);
header.signal_state = xe::byte_swap(header_be->signal_state);
header.wait_list_flink = xe::byte_swap(header_be->wait_list_flink);
header.wait_list_blink = xe::byte_swap(header_be->wait_list_blink);
if (as_type == -1) { if (as_type == -1) {
as_type = (header.type_flags >> 24) & 0xFF; as_type = (header->type_flags >> 24) & 0xFF;
} }
if (header.wait_list_blink & 0x1) { if (header->wait_list_blink & 0x1) {
// Already initialized. // Already initialized.
uint64_t object_ptr = ((uint64_t)header.wait_list_flink << 32) | uint64_t object_ptr = ((uint64_t)header->wait_list_flink << 32) |
((header.wait_list_blink) & ~0x1); ((header->wait_list_blink) & ~0x1);
XObject* object = reinterpret_cast<XObject*>(object_ptr); XObject* object = reinterpret_cast<XObject*>(object_ptr);
// TODO(benvanik): assert nothing has been changed in the struct. // TODO(benvanik): assert nothing has been changed in the struct.
return object; return object;
@ -212,19 +201,19 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
case 1: // EventSynchronizationObject case 1: // EventSynchronizationObject
{ {
XEvent* ev = new XEvent(kernel_state); XEvent* ev = new XEvent(kernel_state);
ev->InitializeNative(native_ptr, header); ev->InitializeNative(native_ptr, *header);
object = ev; object = ev;
} break; } break;
case 2: // MutantObject case 2: // MutantObject
{ {
XMutant* mutant = new XMutant(kernel_state); XMutant* mutant = new XMutant(kernel_state);
mutant->InitializeNative(native_ptr, header); mutant->InitializeNative(native_ptr, *header);
object = mutant; object = mutant;
} break; } break;
case 5: // SemaphoreObject case 5: // SemaphoreObject
{ {
XSemaphore* sem = new XSemaphore(kernel_state); XSemaphore* sem = new XSemaphore(kernel_state);
sem->InitializeNative(native_ptr, header); sem->InitializeNative(native_ptr, *header);
object = sem; object = sem;
} break; } break;
case 3: // ProcessObject case 3: // ProcessObject
@ -248,9 +237,8 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
// Stash pointer in struct. // Stash pointer in struct.
uint64_t object_ptr = reinterpret_cast<uint64_t>(object); uint64_t object_ptr = reinterpret_cast<uint64_t>(object);
object_ptr |= 0x1; object_ptr |= 0x1;
header_be->wait_list_flink = xe::byte_swap((uint32_t)(object_ptr >> 32)); header->wait_list_flink = (uint32_t)(object_ptr >> 32);
header_be->wait_list_blink = header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF);
xe::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF));
return object; return object;
} }

View File

@ -20,10 +20,10 @@ namespace kernel {
// http://www.nirsoft.net/kernel_struct/vista/DISPATCHER_HEADER.html // http://www.nirsoft.net/kernel_struct/vista/DISPATCHER_HEADER.html
typedef struct { typedef struct {
uint32_t type_flags; xe::be<uint32_t> type_flags;
uint32_t signal_state; xe::be<uint32_t> signal_state;
uint32_t wait_list_flink; xe::be<uint32_t> wait_list_flink;
uint32_t wait_list_blink; xe::be<uint32_t> wait_list_blink;
} DISPATCH_HEADER; } DISPATCH_HEADER;
class XObject { class XObject {