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* backend_data() const { return backend_data_; }
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_; }
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_);
bool manual_reset;
switch (header.type_flags >> 24) {
switch ((header.type_flags >> 24) & 0xFF) {
case 0x00: // EventNotificationObject (manual reset)
manual_reset = true;
break;

View File

@ -91,7 +91,7 @@ XThread* XThread::GetCurrentThread() {
XThread::EnterCriticalRegion();
thread = shared_kernel_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;
current_thread_tls = thread;
}
@ -137,7 +137,7 @@ X_STATUS XThread::Create() {
// 0x160: last error
// So, at offset 0x100 we have a 4b pointer to offset 200, then have the
// structure.
thread_state_address_ = memory()->SystemHeapAlloc(2048);
thread_state_address_ = memory()->SystemHeapAlloc(0xAB0);
if (!thread_state_address_) {
XELOGW("Unable to allocate thread state block");
return X_STATUS_NO_MEMORY;
@ -169,21 +169,43 @@ X_STATUS XThread::Create() {
// Setup the thread state block (last error/etc).
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_);
FILETIME t;
GetSystemTimeAsFileTime(&t);
xe::store_and_swap<uint64_t>(
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 + 0x148, thread_state_address_ + 0x144);
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 + 0x158, thread_state_address_ + 0x154);
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.
// This is thread safe.
@ -191,6 +213,14 @@ X_STATUS XThread::Create() {
new ThreadState(kernel_state()->processor(), thread_id_, 0,
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();
if (XFAILED(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() {
bool suspended = creation_params_.creation_flags & 0x1;
thread_handle_ =
CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)XThreadStartCallbackWin32, this,
suspended ? CREATE_SUSPENDED : 0, NULL);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)XThreadStartCallbackWin32,
this, suspended ? CREATE_SUSPENDED : 0, NULL);
if (!thread_handle_) {
uint32_t last_error = GetLastError();
// TODO(benvanik): translate?
@ -289,7 +318,7 @@ X_STATUS XThread::PlatformCreate() {
pthread_attr_init(&attr);
// 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;
if (creation_params_.creation_flags & 0x1) {
@ -428,9 +457,8 @@ void XThread::DeliverAPCs(void* data) {
// kernel_routine(apc_address, &normal_routine, &normal_context,
// &system_arg1, &system_arg2)
uint64_t kernel_args[] = {
apc_address, thread->scratch_address_ + 0,
thread->scratch_address_ + 4, thread->scratch_address_ + 8,
thread->scratch_address_ + 12,
apc_address, thread->scratch_address_ + 0, thread->scratch_address_ + 4,
thread->scratch_address_ + 8, thread->scratch_address_ + 12,
};
processor->ExecuteInterrupt(0, kernel_routine, 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) {
std::lock_guard<std::mutex> lock(kernel_state_->object_mutex());
auto header_be =
auto header =
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.
uint64_t object_ptr = reinterpret_cast<uint64_t>(this);
object_ptr |= 0x1;
header_be->wait_list_flink = xe::byte_swap((uint32_t)(object_ptr >> 32));
header_be->wait_list_blink =
xe::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF));
header->wait_list_flink = (uint32_t)(object_ptr >> 32);
header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF);
}
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());
DISPATCH_HEADER* header_be = (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);
auto header = reinterpret_cast<DISPATCH_HEADER*>(native_ptr);
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.
uint64_t object_ptr = ((uint64_t)header.wait_list_flink << 32) |
((header.wait_list_blink) & ~0x1);
uint64_t object_ptr = ((uint64_t)header->wait_list_flink << 32) |
((header->wait_list_blink) & ~0x1);
XObject* object = reinterpret_cast<XObject*>(object_ptr);
// TODO(benvanik): assert nothing has been changed in the struct.
return object;
@ -212,19 +201,19 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
case 1: // EventSynchronizationObject
{
XEvent* ev = new XEvent(kernel_state);
ev->InitializeNative(native_ptr, header);
ev->InitializeNative(native_ptr, *header);
object = ev;
} break;
case 2: // MutantObject
{
XMutant* mutant = new XMutant(kernel_state);
mutant->InitializeNative(native_ptr, header);
mutant->InitializeNative(native_ptr, *header);
object = mutant;
} break;
case 5: // SemaphoreObject
{
XSemaphore* sem = new XSemaphore(kernel_state);
sem->InitializeNative(native_ptr, header);
sem->InitializeNative(native_ptr, *header);
object = sem;
} break;
case 3: // ProcessObject
@ -248,9 +237,8 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
// Stash pointer in struct.
uint64_t object_ptr = reinterpret_cast<uint64_t>(object);
object_ptr |= 0x1;
header_be->wait_list_flink = xe::byte_swap((uint32_t)(object_ptr >> 32));
header_be->wait_list_blink =
xe::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF));
header->wait_list_flink = (uint32_t)(object_ptr >> 32);
header->wait_list_blink = (uint32_t)(object_ptr & 0xFFFFFFFF);
return object;
}

View File

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