Syscall name resolving improved

This commit is contained in:
Nekotekina 2015-01-14 22:45:36 +03:00
parent a43e03b549
commit 42b748a881
7 changed files with 97 additions and 39 deletions

View File

@ -26,7 +26,7 @@ namespace sce_libc_func
});
}
void printf(vm::psv::ptr<const char> fmt)
void printf(vm::psv::ptr<const char> fmt) // va_args...
{
sceLibc.Error("printf(fmt=0x%x)", fmt);

View File

@ -1,4 +1,5 @@
#include "stdafx.h"
#include <unordered_map>
#include "Utilities/Log.h"
#include "Emu/System.h"
#include "PSVFuncList.h"
@ -7,29 +8,19 @@ std::vector<psv_func> 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>([]() -> 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<void, ARMv7Thread&>([](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<void, ARMv7Thread&>([](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<void, ARMv7Thread&>([](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;

View File

@ -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<u64>& 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();
}

View File

@ -816,9 +816,9 @@ public:
template<typename T, size_t size = sizeof(T)>
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<typename T>
struct cast_ppu_gpr<T, 1>
{
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<T, 1>
template<typename T>
struct cast_ppu_gpr<T, 2>
{
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<T, 2>
template<typename T>
struct cast_ppu_gpr<T, 4>
{
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<T, 4>
template<typename T>
struct cast_ppu_gpr<T, 8>
{
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<T, 8>
template<>
struct cast_ppu_gpr<s8, 1>
{
static u64 func(const s8& value)
__forceinline static u64 to_gpr(const s8& value)
{
return value;
}
@ -874,7 +874,7 @@ struct cast_ppu_gpr<s8, 1>
template<>
struct cast_ppu_gpr<s16, 2>
{
static u64 func(const s16& value)
__forceinline static u64 to_gpr(const s16& value)
{
return value;
}
@ -883,7 +883,7 @@ struct cast_ppu_gpr<s16, 2>
template<>
struct cast_ppu_gpr<s32, 4>
{
static u64 func(const s32& value)
__forceinline static u64 to_gpr(const s32& value)
{
return value;
}
@ -892,8 +892,14 @@ struct cast_ppu_gpr<s32, 4>
template<>
struct cast_ppu_gpr<s64, 8>
{
static u64 func(const s64& value)
__forceinline static u64 to_gpr(const s64& value)
{
return value;
}
};
template<typename T>
__forceinline static u64 cast_to_ppu_gpr(const T& value)
{
return cast_ppu_gpr<T>::to_gpr(value);
}

View File

@ -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<T>::func(arg);
CPU.GPR[g_count + 2] = cast_to_ppu_gpr<T>(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<T>::func(arg));
vm::write64(CPU.GPR[1] + stack_pos, cast_to_ppu_gpr<T>(arg));
}
};

View File

@ -77,7 +77,7 @@ namespace detail
static __forceinline void func(PPUThread& CPU, const T& result)
{
CPU.GPR[3] = cast_ppu_gpr<T>::func(result);
CPU.GPR[3] = cast_to_ppu_gpr<T>(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;
}
};

View File

@ -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
}
}
}