Thread state updates.
This commit is contained in:
parent
88596611d1
commit
8d4f54e240
|
@ -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_; }
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue