diff --git a/.gitmodules b/.gitmodules index 98e43d8..1d9ae4e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,10 +1,6 @@ [submodule "thirdparty/vcpkg"] path = thirdparty/vcpkg url = https://github.com/microsoft/vcpkg -[submodule "tools/XenonRecomp"] - path = tools/XenonRecomp - url = https://github.com/CRACKbomber/XenonRecomp.git - branch = impl-opcodes [submodule "thirdparty/ddspp"] path = thirdparty/ddspp url = https://github.com/redorav/ddspp.git @@ -56,3 +52,6 @@ [submodule "thirdparty/json"] path = thirdparty/json url = https://github.com/nlohmann/json +[submodule "tools/XenonRecomp"] + path = tools/XenonRecomp + url = https://github.com/EOT-RecompTest/XenonRecomp.git diff --git a/Reference/X360TDocs/system_Synchronous_and_Asynchronous_Swaps_Xbox_360.pdf b/Reference/X360TDocs/system_Synchronous_and_Asynchronous_Swaps_Xbox_360.pdf new file mode 100644 index 0000000..9e24fb1 Binary files /dev/null and b/Reference/X360TDocs/system_Synchronous_and_Asynchronous_Swaps_Xbox_360.pdf differ diff --git a/Reference/X360TDocs/system_USB_Storage_Device_Support_on_Xbox_360.pdf b/Reference/X360TDocs/system_USB_Storage_Device_Support_on_Xbox_360.pdf new file mode 100644 index 0000000..ed3760a Binary files /dev/null and b/Reference/X360TDocs/system_USB_Storage_Device_Support_on_Xbox_360.pdf differ diff --git a/Reference/X360TDocs/system_XGD3_content_integrity_verfication_overview.pdf b/Reference/X360TDocs/system_XGD3_content_integrity_verfication_overview.pdf new file mode 100644 index 0000000..b027acb Binary files /dev/null and b/Reference/X360TDocs/system_XGD3_content_integrity_verfication_overview.pdf differ diff --git a/Reference/X360TDocs/system_Xbox_360_Dump_Debugging.pdf b/Reference/X360TDocs/system_Xbox_360_Dump_Debugging.pdf new file mode 100644 index 0000000..4e2442b Binary files /dev/null and b/Reference/X360TDocs/system_Xbox_360_Dump_Debugging.pdf differ diff --git a/Reference/X360TDocs/system_Xbox_360_build_profiling_best_practices.pdf b/Reference/X360TDocs/system_Xbox_360_build_profiling_best_practices.pdf new file mode 100644 index 0000000..f6f7bb9 Binary files /dev/null and b/Reference/X360TDocs/system_Xbox_360_build_profiling_best_practices.pdf differ diff --git a/Reference/X360TDocs/system_coding_for_multiple_cores.pdf b/Reference/X360TDocs/system_coding_for_multiple_cores.pdf new file mode 100644 index 0000000..379cf66 Binary files /dev/null and b/Reference/X360TDocs/system_coding_for_multiple_cores.pdf differ diff --git a/Reference/X360TDocs/system_developing_with_xbox_360_unified_storage.pdf b/Reference/X360TDocs/system_developing_with_xbox_360_unified_storage.pdf new file mode 100644 index 0000000..2ce08f8 Binary files /dev/null and b/Reference/X360TDocs/system_developing_with_xbox_360_unified_storage.pdf differ diff --git a/Reference/X360TDocs/system_game_disc_caching.pdf b/Reference/X360TDocs/system_game_disc_caching.pdf new file mode 100644 index 0000000..99122a2 Binary files /dev/null and b/Reference/X360TDocs/system_game_disc_caching.pdf differ diff --git a/Reference/X360TDocs/system_intro_multithread_programming.pdf b/Reference/X360TDocs/system_intro_multithread_programming.pdf new file mode 100644 index 0000000..507f12d Binary files /dev/null and b/Reference/X360TDocs/system_intro_multithread_programming.pdf differ diff --git a/Reference/X360TDocs/system_lockless_programming.pdf b/Reference/X360TDocs/system_lockless_programming.pdf new file mode 100644 index 0000000..f3beea7 Binary files /dev/null and b/Reference/X360TDocs/system_lockless_programming.pdf differ diff --git a/Reference/X360TDocs/system_secure_game_design_fundamental_concepts.pdf b/Reference/X360TDocs/system_secure_game_design_fundamental_concepts.pdf new file mode 100644 index 0000000..d93442a Binary files /dev/null and b/Reference/X360TDocs/system_secure_game_design_fundamental_concepts.pdf differ diff --git a/Reference/X360TDocs/system_security_best_practices.pdf b/Reference/X360TDocs/system_security_best_practices.pdf new file mode 100644 index 0000000..4aab464 Binary files /dev/null and b/Reference/X360TDocs/system_security_best_practices.pdf differ diff --git a/Reference/X360TDocs/system_vmx128_overview.pdf b/Reference/X360TDocs/system_vmx128_overview.pdf new file mode 100644 index 0000000..f503da8 Binary files /dev/null and b/Reference/X360TDocs/system_vmx128_overview.pdf differ diff --git a/Reference/X360TDocs/system_xbox_360_compiler_technology.pdf b/Reference/X360TDocs/system_xbox_360_compiler_technology.pdf new file mode 100644 index 0000000..51f5944 Binary files /dev/null and b/Reference/X360TDocs/system_xbox_360_compiler_technology.pdf differ diff --git a/Reference/X360TDocs/system_xbox_360_cpu_best_practices.pdf b/Reference/X360TDocs/system_xbox_360_cpu_best_practices.pdf new file mode 100644 index 0000000..c5820ef Binary files /dev/null and b/Reference/X360TDocs/system_xbox_360_cpu_best_practices.pdf differ diff --git a/Reference/X360TDocs/system_xbox_360_cpu_caches.pdf b/Reference/X360TDocs/system_xbox_360_cpu_caches.pdf new file mode 100644 index 0000000..81fa6c4 Binary files /dev/null and b/Reference/X360TDocs/system_xbox_360_cpu_caches.pdf differ diff --git a/Reference/X360TDocs/system_xbox_360_cpu_data_alignment.pdf b/Reference/X360TDocs/system_xbox_360_cpu_data_alignment.pdf new file mode 100644 index 0000000..324789b Binary files /dev/null and b/Reference/X360TDocs/system_xbox_360_cpu_data_alignment.pdf differ diff --git a/Reference/X360TDocs/system_xbox_360_cpu_overview.pdf b/Reference/X360TDocs/system_xbox_360_cpu_overview.pdf new file mode 100644 index 0000000..ff67e34 Binary files /dev/null and b/Reference/X360TDocs/system_xbox_360_cpu_overview.pdf differ diff --git a/Reference/X360TDocs/system_xbox_360_hw_overview.pdf b/Reference/X360TDocs/system_xbox_360_hw_overview.pdf new file mode 100644 index 0000000..e9750d9 Binary files /dev/null and b/Reference/X360TDocs/system_xbox_360_hw_overview.pdf differ diff --git a/Reference/X360TDocs/system_xbox_360_memory_copy_functions.pdf b/Reference/X360TDocs/system_xbox_360_memory_copy_functions.pdf new file mode 100644 index 0000000..623a4f9 Binary files /dev/null and b/Reference/X360TDocs/system_xbox_360_memory_copy_functions.pdf differ diff --git a/Reference/X360TDocs/system_xbox_360_memory_page_sizes.pdf b/Reference/X360TDocs/system_xbox_360_memory_page_sizes.pdf new file mode 100644 index 0000000..054eaf2 Binary files /dev/null and b/Reference/X360TDocs/system_xbox_360_memory_page_sizes.pdf differ diff --git a/reblue/kernel/imports.cpp b/reblue/kernel/imports.cpp index 0f8ba21..6abfbb7 100644 --- a/reblue/kernel/imports.cpp +++ b/reblue/kernel/imports.cpp @@ -278,8 +278,8 @@ GUEST_FUNCTION_HOOK(__imp__IoSynchronousDeviceIoControlRequest, reblue::kernel:: GUEST_FUNCTION_HOOK(__imp__ObOpenObjectByName, reblue::kernel::ObOpenObjectByName); GUEST_FUNCTION_HOOK(__imp__ObReferenceObjectByName, reblue::kernel::ObReferenceObjectByName); -// GUEST_FUNCTION_HOOK(sub_824694A0, reblue::kernel::RtlAllocateHeap); -// GUEST_FUNCTION_HOOK(sub_82469D88, reblue::kernel::RtlFreeHeap); +GUEST_FUNCTION_HOOK(sub_82255F00, reblue::kernel::RtlAllocateHeap); +GUEST_FUNCTION_HOOK(sub_822567F8, reblue::kernel::RtlFreeHeap); // GUEST_FUNCTION_HOOK(sub_8246A070, reblue::kernel::RtlReAllocateHeap); // GUEST_FUNCTION_HOOK(sub_82468738, reblue::kernel::RtlSizeHeap); // GUEST_FUNCTION_HOOK(sub_82466CC8, reblue::kernel::XAllocMem); @@ -289,7 +289,7 @@ GUEST_FUNCTION_HOOK(__imp__ObReferenceObjectByName, reblue::kernel::ObReferenceO // native memory operations // GUEST_FUNCTION_HOOK(sub_826C0480, memmove); // GUEST_FUNCTION_HOOK(sub_826BF770, memcpy); -// GUEST_FUNCTION_HOOK(sub_826BFCF0, memset); +GUEST_FUNCTION_HOOK(sub_8233eaf00, memset); @@ -315,7 +315,7 @@ GUEST_FUNCTION_STUB(__imp__swprintf); #define GUEST__D3DDevice_CreateTexture sub_8246D420 #define GUEST__D3DDevice_SetTexture sub_8246D788 #define GUEST__LockTextureRect sub_8246D408 -#define GUEST__D3DDevice_CreatePixelShader sub_8247D840 +#define GUEST__D3DDevice_CreatePixelShader sub_82238290 #define GUEST__D3DDevice_SetPixelShader sub_8247BF68 #define GUEST__D3DDevice_CreateIndexBuffer sub_82481310 #define GUEST__D3DIndexBuffer_Lock sub_824813C0 @@ -419,4 +419,4 @@ GUEST_FUNCTION_STUB(GUEST__D3DDevice_SetPrediction); // D3DDevice_SetPredication GUEST_FUNCTION_STUB(GUEST__D3DXFilterTexture); // D3DXFilterTexture GUEST_FUNCTION_STUB(GUEST__D3DDevice_Release); // D3DDevice_Release GUEST_FUNCTION_STUB(sub_82466ED8); -*/ \ No newline at end of file +*/ diff --git a/reblue/kernel/obj/guest_heap.cpp b/reblue/kernel/obj/guest_heap.cpp index 54d041d..3564823 100644 --- a/reblue/kernel/obj/guest_heap.cpp +++ b/reblue/kernel/obj/guest_heap.cpp @@ -16,9 +16,33 @@ void GuestHeap::Init() void* GuestHeap::Alloc(size_t size) { + size = std::max(1, size); + size_t alignment = 0x10000; + std::lock_guard lock(mutex); - return o1heapAllocate(heap, std::max(1, size)); + void* ptr = o1heapAllocate(heap, size + alignment); + if (!ptr) + { + O1HeapDiagnostics diag = o1heapGetDiagnostics(heap); + LOGF_ERROR( + "GuestHeap::Alloc failed size=0x{:X} align=0x{:X} cap=0x{:X} alloc=0x{:X} oom={}", + size, + alignment, + diag.capacity, + diag.allocated, + diag.oom_count); + return nullptr; + } + + size_t aligned = ((size_t)ptr + alignment) & ~(alignment - 1); + + *((void**)aligned - 1) = ptr; + *((size_t*)aligned - 2) = size + O1HEAP_ALIGNMENT; + + return (void*)aligned; + + // return o1heapAllocate(heap1, std::max(1, size)); } void* GuestHeap::AllocPhysical(size_t size, size_t alignment) @@ -29,12 +53,32 @@ void* GuestHeap::AllocPhysical(size_t size, size_t alignment) std::lock_guard lock(physicalMutex); void* ptr = o1heapAllocate(physicalHeap, size + alignment); + if (!ptr) + { + O1HeapDiagnostics diag = o1heapGetDiagnostics(physicalHeap); + LOGF_ERROR( + "GuestHeap::AllocPhysical failed size=0x{:X} align=0x{:X} cap=0x{:X} alloc=0x{:X} oom={}", + size, + alignment, + diag.capacity, + diag.allocated, + diag.oom_count); + return nullptr; + } + size_t aligned = ((size_t)ptr + alignment) & ~(alignment - 1); *((void**)aligned - 1) = ptr; *((size_t*)aligned - 2) = size + O1HEAP_ALIGNMENT; + void* result = (void*)aligned; + LOGF_UTILITY( + "GuestHeap::AllocPhysical size=0x{:X} align=0x{:X} -> ptr={} aligned={}", + size, + alignment, + result, + ((reinterpret_cast(result) & (alignment - 1)) == 0) ? "yes" : "no"); - return (void*)aligned; + return result; } void GuestHeap::Free(void* ptr) diff --git a/reblue/kernel/obj/guest_memory.cpp b/reblue/kernel/obj/guest_memory.cpp index 1b3dbdf..e7bea8b 100644 --- a/reblue/kernel/obj/guest_memory.cpp +++ b/reblue/kernel/obj/guest_memory.cpp @@ -1,10 +1,12 @@ #include +#include #include "guest_memory.h" using namespace reblue::kernel; GuestMemory::GuestMemory() { + bool lowMemProtected = false; #ifdef _WIN32 base = (uint8_t*)VirtualAlloc((void*)0x100000000ull, PPC_MEMORY_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); @@ -14,8 +16,19 @@ GuestMemory::GuestMemory() if (base == nullptr) return; - DWORD oldProtect; - VirtualProtect(base, 4096, PAGE_NOACCESS, &oldProtect); + // Protect the first page to catch null pointer dereferences, as done in + // reference implementations such as Fable2, Bluedragon and Xenia. + // This mirrors the behaviour of the console which marks the first 64 KiB + // as inaccessible. Since some titles legitimately use low addresses, + // protection is now opt-in via the REBLUE_ENABLE_LOW_MEM_PROTECTION + // environment variable. + if (const char* enable = getenv("REBLUE_ENABLE_LOW_MEM_PROTECTION"); + enable && strcmp(enable, "1") == 0) + { + DWORD oldProtect; + VirtualProtect(base, 4096, PAGE_NOACCESS, &oldProtect); + lowMemProtected = true; + } #else base = (uint8_t*)mmap((void*)0x100000000ull, PPC_MEMORY_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); @@ -25,9 +38,23 @@ GuestMemory::GuestMemory() if (base == nullptr) return; - mprotect(base, 4096, PROT_NONE); + // Mirror the behaviour on POSIX hosts. Reference projects also protect + // the first page to help catch null pointer bugs. Protection is now + // opt-in via the REBLUE_ENABLE_LOW_MEM_PROTECTION environment variable + // for titles that deliberately touch low addresses. + if (const char* enable = getenv("REBLUE_ENABLE_LOW_MEM_PROTECTION"); + enable && strcmp(enable, "1") == 0) + { + mprotect(base, 4096, PROT_NONE); + lowMemProtected = true; + } #endif + LOGF_UTILITY( + "Guest memory base={} low-mem-protection={}", + static_cast(base), + lowMemProtected ? "enabled" : "disabled"); + for (size_t i = 0; PPCFuncMappings[i].guest != 0; i++) { if (PPCFuncMappings[i].host != nullptr) diff --git a/rebluelib/ppc.zip b/rebluelib/ppc.zip new file mode 100644 index 0000000..e0bbfb4 Binary files /dev/null and b/rebluelib/ppc.zip differ diff --git a/tools/XenonRecomp b/tools/XenonRecomp index 69c6728..a69e0b5 160000 --- a/tools/XenonRecomp +++ b/tools/XenonRecomp @@ -1 +1 @@ -Subproject commit 69c6728f961b3a146d4136b1c86ecbc4c2b6eb37 +Subproject commit a69e0b5827626053bab9ab88659ad38b41b739ac