diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_hal.cc b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_hal.cc index 38c15e7f4..b19a4e645 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_hal.cc +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_hal.cc @@ -24,22 +24,32 @@ namespace kernel { namespace xboxkrnl { -SHIM_CALL HalReturnToFirmware_shim( - xe_ppc_state_t* ppc_state, KernelState* state) { +void xeHalReturnToFirmware(uint32_t routine) { + KernelState* state = shared_kernel_state_; + XEASSERTNOTNULL(state); + // void // IN FIRMWARE_REENTRY Routine // Routine must be 1 'HalRebootRoutine' + XEASSERT(routine == 1); + + // TODO(benvank): diediedie much more gracefully + // Not sure how to blast back up the stack in LLVM without exceptions, though. + XELOGE("Game requested shutdown via HalReturnToFirmware"); + exit(0); +} + + +SHIM_CALL HalReturnToFirmware_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { uint32_t routine = SHIM_GET_ARG_32(0); XELOGD( "HalReturnToFirmware(%d)", routine); - // TODO(benvank): diediedie much more gracefully - // Not sure how to blast back up the stack in LLVM without exceptions, though. - XELOGE("Game requested shutdown via HalReturnToFirmware"); - exit(0); + xeHalReturnToFirmware(routine); } diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_hal.h b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_hal.h index 39994d8d4..3ae93d971 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_hal.h +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_hal.h @@ -21,6 +21,7 @@ namespace kernel { namespace xboxkrnl { +void xeHalReturnToFirmware(uint32_t routine); } // namespace xboxkrnl diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_memory.cc b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_memory.cc index bed256013..d3ccc5596 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_memory.cc +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_memory.cc @@ -85,6 +85,7 @@ X_STATUS xeNtAllocateVirtualMemory( return X_STATUS_SUCCESS; } + // TODO(benvanik): remove state parameter. SHIM_CALL NtAllocateVirtualMemory_shim( xe_ppc_state_t* ppc_state, KernelState* state) { @@ -113,6 +114,7 @@ SHIM_CALL NtAllocateVirtualMemory_shim( SHIM_SET_RETURN(result); } + X_STATUS xeNtFreeVirtualMemory( uint32_t* base_addr_ptr, uint32_t* region_size_ptr, uint32_t free_type, uint32_t unknown) { @@ -145,6 +147,7 @@ X_STATUS xeNtFreeVirtualMemory( return X_STATUS_SUCCESS; } + SHIM_CALL NtFreeVirtualMemory_shim( xe_ppc_state_t* ppc_state, KernelState* state) { uint32_t base_addr_ptr = SHIM_GET_ARG_32(0); diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_module.cc b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_module.cc index 07d6bdf6e..43b87e01a 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_module.cc +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_module.cc @@ -33,25 +33,20 @@ namespace xboxkrnl { // } -SHIM_CALL XexCheckExecutablePrivilege_shim( - xe_ppc_state_t* ppc_state, KernelState* state) { +int xeXexCheckExecutablePriviledge(uint32_t privilege) { + KernelState* state = shared_kernel_state_; + XEASSERTNOTNULL(state); + // BOOL // DWORD Privilege - uint32_t privilege = SHIM_GET_ARG_32(0); - - XELOGD( - "XexCheckExecutablePrivilege(%.8X)", - privilege); - // Privilege is bit position in xe_xex2_system_flags enum - so: // Privilege=6 -> 0x00000040 -> XEX_SYSTEM_INSECURE_SOCKETS uint32_t mask = 1 << privilege; XModule* module = state->GetExecutableModule(); if (!module) { - SHIM_SET_RETURN(0); - return; + return 0; } xe_xex2_ref xex = module->xex(); @@ -61,16 +56,49 @@ SHIM_CALL XexCheckExecutablePrivilege_shim( xe_xex2_release(xex); module->Release(); + return result; +} + + +SHIM_CALL XexCheckExecutablePrivilege_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { + uint32_t privilege = SHIM_GET_ARG_32(0); + + XELOGD( + "XexCheckExecutablePrivilege(%.8X)", + privilege); + + int result = xeXexCheckExecutablePriviledge(privilege); + SHIM_SET_RETURN(result); } +int xeXexGetModuleHandle(const char* module_name, + X_HANDLE* module_handle_ptr) { + KernelState* state = shared_kernel_state_; + XEASSERTNOTNULL(state); + + // BOOL + // LPCSZ ModuleName + // LPHMODULE ModuleHandle + + XModule* module = state->GetModule(module_name); + if (!module) { + return 0; + } + + // NOTE: we don't retain the handle for return. + *module_handle_ptr = module->handle(); + + module->Release(); + + return 1; +} + + SHIM_CALL XexGetModuleHandle_shim( xe_ppc_state_t* ppc_state, KernelState* state) { - // BOOL - // LPCSZ ModuleName - // LPHMODULE ModuleHandle - uint32_t module_name_ptr = SHIM_GET_ARG_32(0); const char* module_name = (const char*)SHIM_MEM_ADDR(module_name_ptr); uint32_t module_handle_ptr = SHIM_GET_ARG_32(1); @@ -79,17 +107,13 @@ SHIM_CALL XexGetModuleHandle_shim( "XexGetModuleHandle(%s, %.8X)", module_name, module_handle_ptr); - XModule* module = state->GetModule(module_name); - if (!module) { - SHIM_SET_RETURN(0); - return; + X_HANDLE module_handle = 0; + int result = xeXexGetModuleHandle(module_name, &module_handle); + if (result) { + SHIM_SET_MEM_32(module_handle_ptr, module_handle); } - // NOTE: we don't retain the handle for return. - SHIM_SET_MEM_32(module_handle_ptr, module->handle()); - SHIM_SET_RETURN(1); - - module->Release(); + SHIM_SET_RETURN(result); } diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_module.h b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_module.h index 5e0714b65..ed71dd097 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_module.h +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_module.h @@ -21,7 +21,10 @@ namespace kernel { namespace xboxkrnl { +int xeXexCheckExecutablePriviledge(uint32_t privilege); +int xeXexGetModuleHandle(const char* module_name, + X_HANDLE* module_handle_ptr); } // namespace xboxkrnl diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.cc b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.cc index 955a71884..ef22a3a3d 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.cc @@ -28,23 +28,18 @@ namespace xboxkrnl { // http://msdn.microsoft.com/en-us/library/ff561778 -SHIM_CALL RtlCompareMemory_shim( - xe_ppc_state_t* ppc_state, KernelState* state) { +uint32_t xeRtlCompareMemory(uint32_t source1_ptr, uint32_t source2_ptr, + uint32_t length) { + KernelState* state = shared_kernel_state_; + XEASSERTNOTNULL(state); + // SIZE_T // _In_ const VOID *Source1, // _In_ const VOID *Source2, // _In_ SIZE_T Length - uint32_t source1 = SHIM_GET_ARG_32(0); - uint32_t source2 = SHIM_GET_ARG_32(1); - uint32_t length = SHIM_GET_ARG_32(2); - - XELOGD( - "RtlCompareMemory(%.8X, %.8X, %d)", - source1, source2, length); - - uint8_t* p1 = SHIM_MEM_ADDR(source1); - uint8_t* p2 = SHIM_MEM_ADDR(source2); + uint8_t* p1 = IMPL_MEM_ADDR(source1_ptr); + uint8_t* p2 = IMPL_MEM_ADDR(source2_ptr); // Note that the return value is the number of bytes that match, so it's best // we just do this ourselves vs. using memcmp. @@ -57,31 +52,41 @@ SHIM_CALL RtlCompareMemory_shim( } } - SHIM_SET_RETURN(c); + return c; } -// http://msdn.microsoft.com/en-us/library/ff552123 -SHIM_CALL RtlCompareMemoryUlong_shim( + +SHIM_CALL RtlCompareMemory_shim( xe_ppc_state_t* ppc_state, KernelState* state) { + uint32_t source1 = SHIM_GET_ARG_32(0); + uint32_t source2 = SHIM_GET_ARG_32(1); + uint32_t length = SHIM_GET_ARG_32(2); + + XELOGD( + "RtlCompareMemory(%.8X, %.8X, %d)", + source1, source2, length); + + uint32_t result = xeRtlCompareMemory(source1, source2, length); + SHIM_SET_RETURN(result); +} + + +// http://msdn.microsoft.com/en-us/library/ff552123 +uint32_t xeRtlCompareMemoryUlong(uint32_t source_ptr, uint32_t length, + uint32_t pattern) { + KernelState* state = shared_kernel_state_; + XEASSERTNOTNULL(state); + // SIZE_T // _In_ PVOID Source, // _In_ SIZE_T Length, // _In_ ULONG Pattern - uint32_t source = SHIM_GET_ARG_32(0); - uint32_t length = SHIM_GET_ARG_32(1); - uint32_t pattern = SHIM_GET_ARG_32(2); - - XELOGD( - "RtlCompareMemoryUlong(%.8X, %d, %.8X)", - source, length, pattern); - - if ((source % 4) || (length % 4)) { - SHIM_SET_RETURN(0); - return; + if ((source_ptr % 4) || (length % 4)) { + return 0; } - uint8_t* p = SHIM_MEM_ADDR(source); + uint8_t* p = IMPL_MEM_ADDR(source_ptr); // Swap pattern. // TODO(benvanik): ensure byte order of pattern is correct. @@ -97,17 +102,50 @@ SHIM_CALL RtlCompareMemoryUlong_shim( } } - SHIM_SET_RETURN(c); + return c; } -// http://msdn.microsoft.com/en-us/library/ff552263 -SHIM_CALL RtlFillMemoryUlong_shim( + +SHIM_CALL RtlCompareMemoryUlong_shim( xe_ppc_state_t* ppc_state, KernelState* state) { + uint32_t source = SHIM_GET_ARG_32(0); + uint32_t length = SHIM_GET_ARG_32(1); + uint32_t pattern = SHIM_GET_ARG_32(2); + + XELOGD( + "RtlCompareMemoryUlong(%.8X, %d, %.8X)", + source, length, pattern); + + uint32_t result = xeRtlCompareMemoryUlong(source, length, pattern); + SHIM_SET_RETURN(result); +} + + +// http://msdn.microsoft.com/en-us/library/ff552263 +void xeRtlFillMemoryUlong(uint32_t destination_ptr, uint32_t length, + uint32_t pattern) { + KernelState* state = shared_kernel_state_; + XEASSERTNOTNULL(state); + // VOID // _Out_ PVOID Destination, // _In_ SIZE_T Length, // _In_ ULONG Pattern + // NOTE: length must be % 4, so we can work on uint32s. + uint32_t* p = (uint32_t*)IMPL_MEM_ADDR(destination_ptr); + + // TODO(benvanik): ensure byte order is correct - we're writing back the + // swapped arg value. + + for (uint32_t n = 0; n < length / 4; n++, p++) { + *p = pattern; + } +} + + +SHIM_CALL RtlFillMemoryUlong_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { uint32_t destination = SHIM_GET_ARG_32(0); uint32_t length = SHIM_GET_ARG_32(1); uint32_t pattern = SHIM_GET_ARG_32(2); @@ -116,15 +154,7 @@ SHIM_CALL RtlFillMemoryUlong_shim( "RtlFillMemoryUlong(%.8X, %d, %.8X)", destination, length, pattern); - // NOTE: length must be % 4, so we can work on uint32s. - uint32_t* p = (uint32_t*)SHIM_MEM_ADDR(destination); - - // TODO(benvanik): ensure byte order is correct - we're writing back the - // swapped arg value. - - for (uint32_t n = 0; n < length / 4; n++, p++) { - *p = pattern; - } + xeRtlFillMemoryUlong(destination, length, pattern); } diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.h b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.h index becfa6ddf..84e98ff44 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.h +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.h @@ -21,7 +21,14 @@ namespace kernel { namespace xboxkrnl { +uint32_t xeRtlCompareMemory(uint32_t source1_ptr, uint32_t source2_ptr, + uint32_t length); +uint32_t xeRtlCompareMemoryUlong(uint32_t source_ptr, uint32_t length, + uint32_t pattern); + +void xeRtlFillMemoryUlong(uint32_t destination_ptr, uint32_t length, + uint32_t pattern); } // namespace xboxkrnl diff --git a/src/xenia/kernel/shim_utils.h b/src/xenia/kernel/shim_utils.h index e79c84516..2b8d1a015 100644 --- a/src/xenia/kernel/shim_utils.h +++ b/src/xenia/kernel/shim_utils.h @@ -29,12 +29,6 @@ namespace kernel { shim_data, \ (xe_kernel_export_shim_fn)export_name##_shim, \ NULL); -#define SHIM_SET_MAPPING_WITH_IMPL(library_name, export_name, shim_data) \ - export_resolver->SetFunctionMapping( \ - library_name, ordinals::##export_name, \ - shim_data, \ - (xe_kernel_export_shim_fn)export_name##_shim, \ - (xe_kernel_export_impl_fn)export_name##_impl); #define SHIM_MEM_ADDR(a) (ppc_state->membase + a) @@ -53,6 +47,9 @@ namespace kernel { #define SHIM_SET_RETURN(v) SHIM_SET_GPR_64(3, v) +#define IMPL_MEM_ADDR(a) xe_memory_addr(state->memory(), a) + + } // namespace kernel } // namespace xe