From 4f807a669c6e72c6effe210a80987b594e8bd28a Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Thu, 4 Jun 2015 16:20:52 -0500 Subject: [PATCH 1/3] Fix TLS copying (size may still be wrong though) --- src/xenia/kernel/objects/xthread.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index 289f6e482..29df45f16 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -176,7 +176,9 @@ X_STATUS XThread::Create() { uint32_t tls_size = 32; // Default 32 (is this OK?) if (module && module->xex_header()) { const xe_xex2_header_t* header = module->xex_header(); - tls_size = header->tls_info.slot_count * header->tls_info.data_size; + + // FIXME: Is this correct? + tls_size = header->tls_info.data_size; } tls_address_ = memory()->SystemHeapAlloc(tls_size); @@ -190,8 +192,7 @@ X_STATUS XThread::Create() { const xe_xex2_header_t* header = module->xex_header(); // Copy in default TLS info. - // TODO(benvanik): is this correct? - memory()->Copy(tls_address_, header->tls_info.raw_data_address, tls_size); + memory()->Copy(tls_address_, header->tls_info.raw_data_address, header->tls_info.data_size); } else { memory()->Fill(tls_address_, tls_size, 0); } From 88672eff4f8a253e0c47ef368ace76c2d8cb549a Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Thu, 4 Jun 2015 16:21:25 -0500 Subject: [PATCH 2/3] InterlockedFlushSList and rewrote InterlockedPopEntrySList --- src/xenia/kernel/xboxkrnl_threading.cc | 40 +++++++++++++++----------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index 77b466ead..7a4fb63d9 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -1325,31 +1325,41 @@ SHIM_CALL KeRemoveQueueDpc_shim(PPCContext* ppc_context, xe::mutex global_list_mutex_; // http://www.nirsoft.net/kernel_struct/vista/SLIST_HEADER.html -SHIM_CALL InterlockedPopEntrySList_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t plist_ptr = SHIM_GET_ARG_32(0); - - XELOGD("InterlockedPopEntrySList(%.8X)", plist_ptr); +struct SLIST_HEADER { + xe::be next; + xe::be depth; + xe::be sequence; +}; +pointer_result_t InterlockedPopEntrySList(pointer_t plist_ptr) { std::lock_guard lock(global_list_mutex_); - uint8_t* p = kernel_state->memory()->TranslateVirtual(plist_ptr); - auto first = xe::load_and_swap(p); + uint32_t first = plist_ptr->next; if (first == 0) { // List empty! - SHIM_SET_RETURN_32(0); - return; + return 0; } - uint8_t* p2 = kernel_state->memory()->TranslateVirtual(first); - auto second = xe::load_and_swap(p2); + // Get the second element. + uint8_t* p = kernel_memory()->TranslateVirtual(first); + auto second = xe::load_and_swap(p); - // Now drop the first element - xe::store_and_swap(p, second); + plist_ptr->next = second; // Return the one we popped - SHIM_SET_RETURN_32(first); + return first; } +DECLARE_XBOXKRNL_EXPORT(InterlockedPopEntrySList, ExportTag::kImplemented); + +pointer_result_t InterlockedFlushSList(pointer_t plist_ptr) { + std::lock_guard lock(global_list_mutex_); + + uint32_t next = plist_ptr->next; + plist_ptr->next = 0; + + return next; +} +DECLARE_XBOXKRNL_EXPORT(InterlockedFlushSList, ExportTag::kImplemented); } // namespace kernel } // namespace xe @@ -1426,6 +1436,4 @@ void xe::kernel::xboxkrnl::RegisterThreadingExports( SHIM_SET_MAPPING("xboxkrnl.exe", KeInitializeDpc, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeInsertQueueDpc, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeRemoveQueueDpc, state); - - SHIM_SET_MAPPING("xboxkrnl.exe", InterlockedPopEntrySList, state); } From abacf136a046c605f4a475e79d1caa56e2f06155 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Thu, 4 Jun 2015 16:21:38 -0500 Subject: [PATCH 3/3] Protect page 0 with no access --- src/xenia/memory.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/xenia/memory.cc b/src/xenia/memory.cc index 5161d9464..fb9af7e7b 100644 --- a/src/xenia/memory.cc +++ b/src/xenia/memory.cc @@ -179,8 +179,7 @@ int Memory::Initialize() { heaps_.v00000000.AllocFixed( 0x00000000, 4096, 4096, kMemoryAllocationReserve | kMemoryAllocationCommit, - // 0u); - kMemoryProtectRead | kMemoryProtectWrite); + kMemoryProtectNoAccess); // GPU writeback. // 0xC... is physical, 0x7F... is virtual. We may need to overlay these.