From 42b748a881630f2405570f56c9a6448ebadff0a1 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 14 Jan 2015 22:45:36 +0300 Subject: [PATCH] Syscall name resolving improved --- rpcs3/Emu/ARMv7/Modules/sceLibc.cpp | 2 +- rpcs3/Emu/ARMv7/PSVFuncList.cpp | 32 +++++++-------- rpcs3/Emu/CPU/CPUThread.cpp | 63 +++++++++++++++++++++++++++-- rpcs3/Emu/Cell/PPUThread.h | 26 +++++++----- rpcs3/Emu/SysCalls/CB_FUNC.h | 4 +- rpcs3/Emu/SysCalls/SC_FUNC.h | 4 +- rpcs3/Loader/ELF32.cpp | 5 +-- 7 files changed, 97 insertions(+), 39 deletions(-) diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp index 95a1339e2d..9abcf593e4 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp @@ -26,7 +26,7 @@ namespace sce_libc_func }); } - void printf(vm::psv::ptr fmt) + void printf(vm::psv::ptr fmt) // va_args... { sceLibc.Error("printf(fmt=0x%x)", fmt); diff --git a/rpcs3/Emu/ARMv7/PSVFuncList.cpp b/rpcs3/Emu/ARMv7/PSVFuncList.cpp index d1d3d2b1a6..84262b3b0f 100644 --- a/rpcs3/Emu/ARMv7/PSVFuncList.cpp +++ b/rpcs3/Emu/ARMv7/PSVFuncList.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include #include "Utilities/Log.h" #include "Emu/System.h" #include "PSVFuncList.h" @@ -7,29 +8,19 @@ std::vector g_psv_func_list; void add_psv_func(psv_func& data) { + // setup special functions (without NIDs) if (!g_psv_func_list.size()) { psv_func unimplemented; - unimplemented.nid = 0x00000000; // must not be a valid id - unimplemented.name = "INVALID FUNCTION (0x0)"; - unimplemented.func.reset(new psv_func_detail::func_binder([]() -> u32 - { - LOG_ERROR(HLE, "Unimplemented function executed"); - Emu.Pause(); - - return 0xffffffffu; - })); + unimplemented.nid = 0; + unimplemented.name = "Special function (unimplemented stub)"; + unimplemented.func.reset(new psv_func_detail::func_binder([](ARMv7Thread& CPU){ CPU.m_last_syscall = vm::psv::read32(CPU.PC + 4); throw "Unimplemented function executed"; })); g_psv_func_list.push_back(unimplemented); psv_func hle_return; - hle_return.nid = 0x00000001; // must not be a valid id - hle_return.name = "INVALID FUNCTION (0x1)"; - hle_return.func.reset(new psv_func_detail::func_binder([](ARMv7Thread& CPU) - { - CPU.FastStop(); - - return; - })); + hle_return.nid = 1; + hle_return.name = "Special function (return from HLE)"; + hle_return.func.reset(new psv_func_detail::func_binder([](ARMv7Thread& CPU){ CPU.FastStop(); })); g_psv_func_list.push_back(hle_return); } @@ -40,7 +31,7 @@ psv_func* get_psv_func_by_nid(u32 nid) { for (auto& f : g_psv_func_list) { - if (f.nid == nid) + if (f.nid == nid && &f - g_psv_func_list.data() >= 2 /* special functions count */) { return &f; } @@ -61,8 +52,13 @@ u32 get_psv_func_index(psv_func* func) void execute_psv_func_by_index(ARMv7Thread& CPU, u32 index) { assert(index < g_psv_func_list.size()); + + auto old_last_syscall = CPU.m_last_syscall; + CPU.m_last_syscall = g_psv_func_list[index].nid; (*g_psv_func_list[index].func)(CPU); + + CPU.m_last_syscall = old_last_syscall; } extern psv_log_base sceLibc; diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index 826a593806..b990e0097b 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -1,10 +1,11 @@ #include "stdafx.h" #include "rpcs3/Ini.h" -#include "Emu/SysCalls/SysCalls.h" #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/DbgCommand.h" +#include "Emu/SysCalls/SysCalls.h" +#include "Emu/ARMv7/PSVFuncList.h" #include "CPUDecoder.h" #include "CPUThread.h" @@ -256,6 +257,62 @@ void CPUThread::ExecOnce() void CPUThread::Task() { + auto get_syscall_name = [this](u64 syscall) -> std::string + { + switch (GetType()) + { + case CPU_THREAD_ARMv7: + { + if ((u32)syscall == syscall) + { + if (syscall) + { + if (auto func = get_psv_func_by_nid((u32)syscall)) + { + return func->name; + } + } + else + { + return{}; + } + } + + return "unknown function"; + } + case CPU_THREAD_PPU: + { + if ((u32)syscall == syscall) + { + if (syscall) + { + if (syscall < 1024) + { + // TODO: + //return SysCalls::GetSyscallName((u32)syscall); + } + else + { + return SysCalls::GetHLEFuncName((u32)syscall); + } + } + else + { + return{}; + } + } + + // fallthrough + } + case CPU_THREAD_SPU: + case CPU_THREAD_RAW_SPU: + default: + { + return "unknown syscall"; + } + } + }; + if (Ini.HLELogging.GetValue()) LOG_NOTICE(GENERAL, "%s enter", CPUThread::GetFName().c_str()); const std::vector& bp = Emu.GetBreakPoints(); @@ -310,13 +367,13 @@ void CPUThread::Task() } catch (const std::string& e) { - LOG_ERROR(GENERAL, "Exception: %s (is_alive=%d, m_last_syscall=0x%llx (%s))", e, IsAlive(), m_last_syscall, SysCalls::GetHLEFuncName((u32)m_last_syscall)); + LOG_ERROR(GENERAL, "Exception: %s (is_alive=%d, m_last_syscall=0x%llx (%s))", e, IsAlive(), m_last_syscall, get_syscall_name(m_last_syscall)); LOG_NOTICE(GENERAL, RegsToString()); Emu.Pause(); } catch (const char* e) { - LOG_ERROR(GENERAL, "Exception: %s (is_alive=%d, m_last_syscall=0x%llx (%s))", e, IsAlive(), m_last_syscall, SysCalls::GetHLEFuncName((u32)m_last_syscall)); + LOG_ERROR(GENERAL, "Exception: %s (is_alive=%d, m_last_syscall=0x%llx (%s))", e, IsAlive(), m_last_syscall, get_syscall_name(m_last_syscall)); LOG_NOTICE(GENERAL, RegsToString()); Emu.Pause(); } diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index c0d5eda43c..4f023597ba 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -816,9 +816,9 @@ public: template struct cast_ppu_gpr { - static_assert(sizeof(T) <= 8, "Type for cast_ppu_gpr is invalid (too big)"); + static_assert(sizeof(T) <= 8, "Invalid type for cast_ppu_gpr"); - static u64 func(const T& value) + __forceinline static u64 to_gpr(const T& value) { u64 result = 0; (T&)result = value; @@ -829,7 +829,7 @@ struct cast_ppu_gpr template struct cast_ppu_gpr { - static u64 func(const T& value) + __forceinline static u64 to_gpr(const T& value) { return (u8&)value; } @@ -838,7 +838,7 @@ struct cast_ppu_gpr template struct cast_ppu_gpr { - static u64 func(const T& value) + __forceinline static u64 to_gpr(const T& value) { return (u16&)value; } @@ -847,7 +847,7 @@ struct cast_ppu_gpr template struct cast_ppu_gpr { - static u64 func(const T& value) + __forceinline static u64 to_gpr(const T& value) { return (u32&)value; } @@ -856,7 +856,7 @@ struct cast_ppu_gpr template struct cast_ppu_gpr { - static u64 func(const T& value) + __forceinline static u64 to_gpr(const T& value) { return (u64&)value; } @@ -865,7 +865,7 @@ struct cast_ppu_gpr template<> struct cast_ppu_gpr { - static u64 func(const s8& value) + __forceinline static u64 to_gpr(const s8& value) { return value; } @@ -874,7 +874,7 @@ struct cast_ppu_gpr template<> struct cast_ppu_gpr { - static u64 func(const s16& value) + __forceinline static u64 to_gpr(const s16& value) { return value; } @@ -883,7 +883,7 @@ struct cast_ppu_gpr template<> struct cast_ppu_gpr { - static u64 func(const s32& value) + __forceinline static u64 to_gpr(const s32& value) { return value; } @@ -892,8 +892,14 @@ struct cast_ppu_gpr template<> struct cast_ppu_gpr { - static u64 func(const s64& value) + __forceinline static u64 to_gpr(const s64& value) { return value; } }; + +template +__forceinline static u64 cast_to_ppu_gpr(const T& value) +{ + return cast_ppu_gpr::to_gpr(value); +} diff --git a/rpcs3/Emu/SysCalls/CB_FUNC.h b/rpcs3/Emu/SysCalls/CB_FUNC.h index 129fd5c109..ac49cb90b5 100644 --- a/rpcs3/Emu/SysCalls/CB_FUNC.h +++ b/rpcs3/Emu/SysCalls/CB_FUNC.h @@ -26,7 +26,7 @@ namespace cb_detail __forceinline static void set_value(PPUThread& CPU, const T& arg) { - CPU.GPR[g_count + 2] = cast_ppu_gpr::func(arg); + CPU.GPR[g_count + 2] = cast_to_ppu_gpr(arg); } }; @@ -63,7 +63,7 @@ namespace cb_detail { const int stack_pos = 0x70 + (g_count - 9) * 8 - FIXED_STACK_FRAME_SIZE; static_assert(stack_pos < 0, "TODO: Increase fixed stack frame size (arg count limit broken)"); - vm::write64(CPU.GPR[1] + stack_pos, cast_ppu_gpr::func(arg)); + vm::write64(CPU.GPR[1] + stack_pos, cast_to_ppu_gpr(arg)); } }; diff --git a/rpcs3/Emu/SysCalls/SC_FUNC.h b/rpcs3/Emu/SysCalls/SC_FUNC.h index d1d5f38dd1..d3ad6739b5 100644 --- a/rpcs3/Emu/SysCalls/SC_FUNC.h +++ b/rpcs3/Emu/SysCalls/SC_FUNC.h @@ -77,7 +77,7 @@ namespace detail static __forceinline void func(PPUThread& CPU, const T& result) { - CPU.GPR[3] = cast_ppu_gpr::func(result); + CPU.GPR[3] = cast_to_ppu_gpr(result); } }; @@ -88,7 +88,7 @@ namespace detail static __forceinline void func(PPUThread& CPU, const T& result) { - CPU.FPR[1] = (double)result; + CPU.FPR[1] = result; } }; diff --git a/rpcs3/Loader/ELF32.cpp b/rpcs3/Loader/ELF32.cpp index 31925d4b57..cb9be62759 100644 --- a/rpcs3/Loader/ELF32.cpp +++ b/rpcs3/Loader/ELF32.cpp @@ -187,9 +187,8 @@ namespace loader LOG_ERROR(LOADER, "Unimplemented function 0x%08x (addr=0x%x)", nid, addr); vm::psv::write16(addr + 0, 0xf870); // HACK instruction (Thumb) - vm::psv::write16(addr + 2, 0x0000); // index 0 - vm::psv::write16(addr + 4, 0x4770); // BX LR - vm::psv::write16(addr + 6, 0); // null + vm::psv::write16(addr + 2, 0); // index 0 (unimplemented stub) + vm::psv::write32(addr + 4, nid); // nid } } }