diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 9aace5b6d1..474b603c9f 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -249,6 +249,27 @@ u64 PPUThread::FastCall(u64 addr, u64 rtoc, u64 arg1, u64 arg2, u64 arg3, u64 ar return GPR[3]; } +u64 PPUThread::FastCall2(u64 addr, u64 rtoc) +{ + auto old_status = m_status; + auto old_PC = PC; + auto old_LR = LR; + auto old_rtoc = GPR[2]; + + PC = addr; + GPR[2] = rtoc; + LR = Emu.m_ppu_thr_stop; + + Task(); + + GPR[2] = old_rtoc; + LR = old_LR; + PC = old_PC; + m_status = old_status; + + return GPR[3]; +} + void PPUThread::FastStop() { m_status = Stopped; diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 15c1a95339..5a5e0bbf58 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -843,6 +843,7 @@ public: virtual void InitRegs(); virtual u64 GetFreeStackSize() const; u64 FastCall(u64 addr, u64 rtoc, u64 arg1 = 0, u64 arg2 = 0, u64 arg3 = 0, u64 arg4 = 0, u64 arg5 = 0, u64 arg6 = 0, u64 arg7 = 0, u64 arg8 = 0); + u64 FastCall2(u64 addr, u64 rtoc); void FastStop(); protected: diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 4df6ff55a3..9fe3523fb2 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -210,6 +210,7 @@ public: } else { + assert(!addr); return 0; } } diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index 78b5d4ba8d..4df65edb73 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -6,13 +6,19 @@ #include #include "ModuleManager.h" -u32 getFunctionId(const std::string& name) +u32 getFunctionId(const char* name) { const char* suffix = "\x67\x59\x65\x99\x04\x25\x04\x90\x56\x64\x27\x49\x94\x89\x74\x1A"; // Symbol name suffix - std::string input = name + suffix; - unsigned char output[20]; + u8 output[20]; + + // Compute SHA-1 hash + sha1_context ctx; + + sha1_starts(&ctx); + sha1_update(&ctx, (const u8*)name, strlen(name)); + sha1_update(&ctx, (const u8*)suffix, strlen(suffix)); + sha1_finish(&ctx, output); - sha1((unsigned char*)input.c_str(), input.length(), output); // Compute SHA-1 hash return (u32&)output[0]; } diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index a7835db354..3d610a0e7f 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -110,11 +110,11 @@ public: } template __forceinline void AddFunc(u32 id, T func); - template __forceinline void AddFunc(const std::string& name, T func); + template __forceinline void AddFunc(const char* name, T func); template __forceinline void AddFuncSub(const char group[8], const u64 ops[], const char* name, T func); }; -u32 getFunctionId(const std::string& name); +u32 getFunctionId(const char* name); template __forceinline void Module::AddFunc(u32 id, T func) @@ -123,7 +123,7 @@ __forceinline void Module::AddFunc(u32 id, T func) } template -__forceinline void Module::AddFunc(const std::string& name, T func) +__forceinline void Module::AddFunc(const char* name, T func) { AddFunc(getFunctionId(name), func); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index ab2a31d936..22d2ba3586 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -2209,6 +2209,15 @@ void cellSync_init() libsre = Memory.PRXMem.AllocAlign(sizeof(libsre_data), 4096); memcpy(Memory + libsre, libsre_data, sizeof(libsre_data)); libsre_rtoc = libsre + 0x399B0; + +#define FIX_IMPORT(addr, func) \ + Memory.Write32((addr), 0x3d600000 | (getFunctionId(#func) >> 16)); /* lis r11, (func_id >> 16) */\ + Memory.Write32((addr), 0x616b0000 | (getFunctionId(#func) & 0xffff)); /* ori r11, (func_id & 0xffff) */\ + Memory.Write64((addr), 0x440000024e800020ull) /* sc + blr */ + + + +#undef FIX_IMPORT }); #endif } diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index e962354efe..4dfa98be25 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -82,13 +82,6 @@ s64 sys_prx_exitspawn_with_level() return CELL_OK; } -s64 sys_strlen(u32 addr) -{ - const std::string& str = Memory.ReadString(addr); - sysPrxForUser->Log("sys_strlen(0x%x - \"%s\")", addr, str.c_str()); - return str.length(); -} - int sys_spu_elf_get_information(u32 elf_img, mem32_t entry, mem32_t nseg) { sysPrxForUser->Warning("sys_spu_elf_get_information(elf_img=0x%x, entry_addr=0x%x, nseg_addr=0x%x", elf_img, entry.GetAddr(), nseg.GetAddr()); @@ -155,23 +148,89 @@ int sys_raw_spu_image_load(int id, mem_ptr_t img) return CELL_OK; } -s32 _sys_memset(u32 addr, s32 value, u32 size) +u32 _sys_memset(u32 addr, s32 value, u32 size) { sysPrxForUser->Log("_sys_memset(addr=0x%x, value=%d, size=%d)", addr, value, size); memset(Memory + addr, value, size); - return CELL_OK; + return addr; +} + +u32 _sys_memcpy(u32 dest, u32 source, u32 size) +{ + sysPrxForUser->Log("_sys_memcpy(dest=0x%x, source=0x%x, size=%d)", dest, source, size); + + memcpy(Memory + dest, Memory + source, size); + return dest; +} + +s32 _sys_memcmp(u32 addr1, u32 addr2, u32 size) +{ + sysPrxForUser->Log("_sys_memcmp(addr1=0x%x, addr2=0x%x, size=%d)", addr1, addr2, size); + + return memcmp(Memory + addr1, Memory + addr2, size); +} + +s32 _sys_strlen(u32 addr) +{ + sysPrxForUser->Log("_sys_strlen(addr=0x%x)", addr); + + return strlen((char*)(Memory + addr)); +} + +s32 _sys_strncmp(u32 str1, u32 str2, s32 max) +{ + sysPrxForUser->Log("_sys_strncmp(str1=0x%x, str2=0x%x, max=%d)", str1, str2, max); + + return strncmp((char*)(Memory + str1), (char*)(Memory + str2), max); +} + +u32 _sys_strcat(u32 dest, u32 source) +{ + sysPrxForUser->Log("_sys_strcat(dest=0x%x, source=0x%x)", dest, source); + + assert(Memory.RealToVirtualAddr(strcat((char*)(Memory + dest), (char*)(Memory + source))) == dest); + return dest; +} + +u32 _sys_strncat(u32 dest, u32 source, u32 len) +{ + sysPrxForUser->Log("_sys_strncat(dest=0x%x, source=0x%x, len=%d)", dest, source, len); + + assert(Memory.RealToVirtualAddr(strncat((char*)(Memory + dest), (char*)(Memory + source), len)) == dest); + return dest; +} + +u32 _sys_strcpy(u32 dest, u32 source) +{ + sysPrxForUser->Log("_sys_strcpy(dest=0x%x, source=0x%x)", dest, source); + + assert(Memory.RealToVirtualAddr(strcpy((char*)(Memory + dest), (char*)(Memory + source))) == dest); + return dest; +} + +u32 _sys_strncpy(u32 dest, u32 source, u32 len) +{ + sysPrxForUser->Log("_sys_strncpy(dest=0x%x, source=0x%x, len=%d)", dest, source, len); + + if (!dest || !source) + { + return 0; + } + + assert(Memory.RealToVirtualAddr(strncpy((char*)(Memory + dest), (char*)(Memory + source), len)) == dest); + return dest; } void sysPrxForUser_init() { - sysPrxForUser->AddFunc(0x744680a2, sys_initialize_tls); + REG_FUNC(sysPrxForUser, sys_initialize_tls); - sysPrxForUser->AddFunc(0x2f85c0ef, sys_lwmutex_create); - sysPrxForUser->AddFunc(0xc3476d0c, sys_lwmutex_destroy); - sysPrxForUser->AddFunc(0x1573dc3f, sys_lwmutex_lock); - sysPrxForUser->AddFunc(0xaeb78725, sys_lwmutex_trylock); - sysPrxForUser->AddFunc(0x1bc200f4, sys_lwmutex_unlock); + REG_FUNC(sysPrxForUser, sys_lwmutex_create); + REG_FUNC(sysPrxForUser, sys_lwmutex_destroy); + REG_FUNC(sysPrxForUser, sys_lwmutex_lock); + REG_FUNC(sysPrxForUser, sys_lwmutex_trylock); + REG_FUNC(sysPrxForUser, sys_lwmutex_unlock); sysPrxForUser->AddFunc(0x8461e528, sys_time_get_system_time); @@ -199,8 +258,6 @@ void sysPrxForUser_init() sysPrxForUser->AddFunc(0xaa6d9bff, sys_prx_load_module_on_memcontainer); sysPrxForUser->AddFunc(0xa2c7ba64, sys_prx_exitspawn_with_level); - sysPrxForUser->AddFunc(0x2d36462b, sys_strlen); - sysPrxForUser->AddFunc(0x35168520, sys_heap_malloc); //sysPrxForUser->AddFunc(0xaede4b03, sys_heap_free); //sysPrxForUser->AddFunc(0x8a561d92, sys_heap_delete_heap); @@ -236,5 +293,12 @@ void sysPrxForUser_init() sysPrxForUser->AddFunc(0x67f9fedb, sys_game_process_exitspawn2); sysPrxForUser->AddFunc(0xfc52a7a9, sys_game_process_exitspawn); - sysPrxForUser->AddFunc(0x68b9b011, _sys_memset); + REG_FUNC(sysPrxForUser, _sys_memset); + REG_FUNC(sysPrxForUser, _sys_memcpy); + REG_FUNC(sysPrxForUser, _sys_memcmp); + REG_FUNC(sysPrxForUser, _sys_strlen); + REG_FUNC(sysPrxForUser, _sys_strncmp); + REG_FUNC(sysPrxForUser, _sys_strcat); + REG_FUNC(sysPrxForUser, _sys_strncat); + REG_FUNC(sysPrxForUser, _sys_strncpy); } diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h index d32efb69c5..3dc3697ce9 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h @@ -13,6 +13,3 @@ struct HeapInfo { } }; - -// SysCalls -s32 _sys_memset(u32 addr, s32 value, u32 num); diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index ae82066d4e..19668aaba0 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -132,3 +132,5 @@ public: #define REG_SUB(module, group, name, ...) \ static const u64 name ## _table[] = {__VA_ARGS__ , 0}; \ module->AddFuncSub(group, name ## _table, #name, name) + +#define REG_FUNC(module, name) module->AddFunc(getFunctionId(#name), name) \ No newline at end of file