From fed1418c0eb921a0f6f7359c6bb468aba3f31bcb Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 19 Feb 2015 16:47:53 +0300 Subject: [PATCH] Loader fix --- rpcs3/Emu/SysCalls/Modules.cpp | 5 ++- rpcs3/Emu/SysCalls/Modules/cellSync.cpp | 9 ----- rpcs3/Emu/SysCalls/Modules/cellSync.h | 27 +++++++++++-- rpcs3/Loader/ELF64.cpp | 54 ++++++++++++++++++++++--- 4 files changed, 76 insertions(+), 19 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index 7c038025ca..523f572c59 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -1,7 +1,9 @@ #include "stdafx.h" +#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" +#include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/Static.h" #include "Emu/SysCalls/CB_FUNC.h" #include "Crypto/sha1.h" @@ -84,7 +86,8 @@ void execute_ps3_func_by_index(PPUThread& CPU, u32 index) } else { - throw "Unimplemented function"; + LOG_ERROR(HLE, "Unimplemented function %s", SysCalls::GetHLEFuncName(func->id)); + CPU.GPR[3] = 0; } CPU.m_last_syscall = old_last_syscall; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index eb9d622c8d..0894a4e53b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -829,15 +829,6 @@ s32 cellSyncQueueClear(vm::ptr queue) // LFQueue functions -void syncLFQueueDump(vm::ptr queue) -{ - cellSync.Notice("CellSyncLFQueue dump: addr = 0x%x", queue.addr()); - for (u32 i = 0; i < sizeof(CellSyncLFQueue) / 16; i++) - { - cellSync.Notice("*** 0x%.16llx 0x%.16llx", vm::read64(queue.addr() + i * 16), vm::read64(queue.addr() + i * 16 + 8)); - } -} - void syncLFQueueInit(vm::ptr queue, vm::ptr buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr eaSignal) { queue->m_size = size; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.h b/rpcs3/Emu/SysCalls/Modules/cellSync.h index 998418615a..ba7ab97781 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.h @@ -135,16 +135,18 @@ struct CellSyncLFQueue be_t m_h6; }; - union + union // 0x0 { - atomic_t pop1; // 0x0 + atomic_t pop1; atomic_t pop3; }; - union + + union // 0x8 { - atomic_t push1; // 0x8 + atomic_t push1; atomic_t push3; }; + be_t m_size; // 0x10 be_t m_depth; // 0x14 vm::bptr m_buffer; // 0x18 @@ -159,6 +161,23 @@ struct CellSyncLFQueue vm::bptr m_eaSignal; // 0x70 be_t m_v2; // 0x78 be_t m_eq_id; // 0x7C + + std::string dump() + { + std::string res = "CellSyncLFQueue dump:"; + + auto data = (be_t*)this; + + for (u32 i = 0; i < sizeof(CellSyncLFQueue) / sizeof(u64); i += 2) + { + res += "\n*** 0x"; + res += fmt::to_hex(data[i + 0], 16); + res += " 0x"; + res += fmt::to_hex(data[i + 1], 16); + } + + return res; + } }; static_assert(sizeof(CellSyncLFQueue) == 128, "CellSyncLFQueue: wrong size"); diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index e3de0bb9fd..dfb12aee06 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -303,6 +303,7 @@ namespace loader std::vector start_funcs; std::vector stop_funcs; + std::vector exit_funcs; //load modules vfsDir lle_dir("/dev_flash/sys/external"); @@ -341,12 +342,48 @@ namespace loader { for (auto &e : m.second.exports) { + auto code = vm::ptr::make(vm::check_addr(e.second, 8) ? vm::read32(e.second) : 0); + + bool is_empty = !code || (code[0] == 0x38600000 && code[1] == BLR()); + + if (!code) + { + LOG_ERROR(LOADER, "bad OPD of special function 0x%08x in '%s' library (0x%x)", e.first, info.name.c_str(), code); + } + switch (e.first) { - case 0xbc9a0086: start_funcs.push_back(e.second); break; - case 0xab779874: stop_funcs.push_back(e.second); break; + case 0xbc9a0086: + { + if (!is_empty) + { + LOG_ERROR(LOADER, "start func found in '%s' library (0x%x)", info.name.c_str(), code); + start_funcs.push_back(e.second); + } + break; + } - default: LOG_ERROR(LOADER, "unknown special func 0x%08x in '%s' library", e.first, info.name.c_str()); break; + case 0xab779874: + { + if (!is_empty) + { + LOG_ERROR(LOADER, "stop func found in '%s' library (0x%x)", info.name.c_str(), code); + stop_funcs.push_back(e.second); + } + break; + } + + case 0x3ab9a95e: + { + if (!is_empty) + { + LOG_ERROR(LOADER, "exit func found in '%s' library (0x%x)", info.name.c_str(), code); + exit_funcs.push_back(e.second); + } + break; + } + + default: LOG_ERROR(LOADER, "unknown special func 0x%08x in '%s' library (0x%x)", e.first, info.name.c_str(), code); break; } } @@ -385,8 +422,15 @@ namespace loader LOG_NOTICE(LOADER, "Imported function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr); } - vm::write32(addr + 0, HACK(index)); - vm::write32(addr + 4, BLR()); + if (!vm::check_addr(addr, 8)) + { + LOG_ERROR(LOADER, "Failed to inject code for function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr); + } + else + { + vm::write32(addr + 0, HACK(index)); + vm::write32(addr + 4, BLR()); + } } } }