Merge pull request #734 from Nekotekina/master

Logging last syscall code for memory error
This commit is contained in:
B1ackDaemon 2014-08-09 20:19:23 +03:00
commit 6bd45f9697
11 changed files with 224 additions and 32 deletions

View File

@ -28,6 +28,7 @@ CPUThread::CPUThread(CPUThreadType type)
, m_is_step(false) , m_is_step(false)
, m_is_branch(false) , m_is_branch(false)
, m_status(Stopped) , m_status(Stopped)
, m_last_syscall(0)
{ {
} }
@ -284,7 +285,8 @@ void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp)
// TODO: allow recovering from a page fault // TODO: allow recovering from a page fault
//GetCurrentPPUThread().Stop(); //GetCurrentPPUThread().Stop();
Emu.Pause(); Emu.Pause();
throw fmt::Format("Access violation: addr = 0x%x", (u32)addr); throw fmt::Format("Access violation: addr = 0x%x (last_syscall=0x%llx)",
(u32)addr, (u64)GetCurrentCPUThread()->m_last_syscall);
} }
else else
{ {

View File

@ -133,6 +133,7 @@ public:
bool m_is_interrupt; bool m_is_interrupt;
bool m_has_interrupt; bool m_has_interrupt;
u64 m_interrupt_arg; u64 m_interrupt_arg;
u64 m_last_syscall;
protected: protected:
CPUThread(CPUThreadType type); CPUThread(CPUThreadType type);

View File

@ -66,6 +66,7 @@ private:
void SysCall() void SysCall()
{ {
CPU.m_last_syscall = CPU.GPR[11];
SysCalls::DoSyscall(CPU.GPR[11]); SysCalls::DoSyscall(CPU.GPR[11]);
if(Ini.HLELogging.GetValue()) if(Ini.HLELogging.GetValue())
@ -81,6 +82,8 @@ private:
#ifdef HLE_CALL_DEBUG #ifdef HLE_CALL_DEBUG
LOG_NOTICE(PPU, "SysCall[%lld] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC); LOG_NOTICE(PPU, "SysCall[%lld] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC);
#endif #endif
CPU.m_last_syscall = 0;
} }
void NULL_OP() void NULL_OP()

View File

@ -1025,113 +1025,219 @@ s32 cellSyncQueueClear(mem_ptr_t<CellSyncQueue> queue)
int cellSyncLFQueueGetEntrySize() int cellSyncLFQueueGetEntrySize()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("cellSyncLFQueueGetEntrySize()");
return CELL_OK; return CELL_OK;
} }
int cellSyncLFQueueSize() int cellSyncLFQueueSize()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("cellSyncLFQueueSize()");
return CELL_OK; return CELL_OK;
} }
int cellSyncLFQueueClear() int cellSyncLFQueueClear()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("cellSyncLFQueueClear()");
return CELL_OK; return CELL_OK;
} }
int _cellSyncLFQueueCompletePushPointer2() int _cellSyncLFQueueCompletePushPointer2()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("_cellSyncLFQueueCompletePushPointer2()");
return CELL_OK; return CELL_OK;
} }
int _cellSyncLFQueueGetPopPointer2() int _cellSyncLFQueueGetPopPointer2()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("_cellSyncLFQueueGetPopPointer2()");
return CELL_OK; return CELL_OK;
} }
int _cellSyncLFQueueCompletePushPointer() int _cellSyncLFQueueCompletePushPointer()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("_cellSyncLFQueueCompletePushPointer()");
return CELL_OK; return CELL_OK;
} }
int _cellSyncLFQueueAttachLv2EventQueue() int _cellSyncLFQueueAttachLv2EventQueue()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("_cellSyncLFQueueAttachLv2EventQueue()");
return CELL_OK; return CELL_OK;
} }
int _cellSyncLFQueueGetPushPointer2() int _cellSyncLFQueueGetPushPointer2()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("_cellSyncLFQueueGetPushPointer2()");
return CELL_OK; return CELL_OK;
} }
int _cellSyncLFQueueGetPopPointer() int _cellSyncLFQueueGetPopPointer()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("_cellSyncLFQueueGetPopPointer()");
return CELL_OK; return CELL_OK;
} }
int _cellSyncLFQueueCompletePopPointer2() int _cellSyncLFQueueCompletePopPointer2()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("_cellSyncLFQueueCompletePopPointer2()");
return CELL_OK; return CELL_OK;
} }
int _cellSyncLFQueueDetachLv2EventQueue() int _cellSyncLFQueueDetachLv2EventQueue()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("_cellSyncLFQueueDetachLv2EventQueue()");
return CELL_OK; return CELL_OK;
} }
int cellSyncLFQueueInitialize() void syncLFQueueInitialize(mem_ptr_t<CellSyncLFQueue> ea, u32 buffer_addr, u32 size, u32 depth, CellSyncQueueDirection direction, u32 eaSignal_addr)
{ {
UNIMPLEMENTED_FUNC(cellSync);
}
int cellSyncLFQueueInitialize(mem_ptr_t<CellSyncLFQueue> ea, u32 buffer_addr, u32 size, u32 depth, CellSyncQueueDirection direction, u32 eaSignal_addr)
{
cellSync->Todo("cellSyncLFQueueInitialize(ea_addr=0x%x, buffer_addr=0x%x, size=0x%x, depth=0x%x, direction=%d, eaSignal_addr=0x%x)",
ea.GetAddr(), buffer_addr, size, depth, direction, eaSignal_addr);
if (!ea)
{
return CELL_SYNC_ERROR_NULL_POINTER;
}
if (size)
{
if (!buffer_addr)
{
return CELL_SYNC_ERROR_NULL_POINTER;
}
if (size > 0x4000 || size % 16)
{
return CELL_SYNC_ERROR_INVAL;
}
}
if (!depth || (depth >> 15) || direction > 3)
{
return CELL_SYNC_ERROR_INVAL;
}
if (ea.GetAddr() % 128 || buffer_addr % 16)
{
return CELL_SYNC_ERROR_ALIGN;
}
// prx: get sdk version of current process, return non-zero result of sys_process_get_sdk_version
s32 sdk_ver;
s32 ret = process_get_sdk_version(process_getpid(), sdk_ver);
if (ret != CELL_OK)
{
return ret;
}
if (sdk_ver == -1)
{
sdk_ver = 0x460000;
}
// prx: reserve u32 at 0x2c offset
u32 old_value;
while (true)
{
const u32 old_data = ea->m_data1();
CellSyncLFQueue new_data;
new_data.m_data1() = old_data;
if (old_data)
{
if (sdk_ver > 0x17ffff && old_data != se32(2))
{
return CELL_SYNC_ERROR_STAT;
}
old_value = old_data;
}
else
{
if (sdk_ver > 0x17ffff)
{
for (u32 i = 0; i < sizeof(CellSyncLFQueue) / sizeof(u64); i++)
{
if ((u64&)Memory[ea.GetAddr() + i * sizeof(u64)])
{
return CELL_SYNC_ERROR_STAT;
}
}
}
new_data.m_data1() = se32(1);
old_value = se32(1);
}
if (InterlockedCompareExchange(&ea->m_data1(), new_data.m_data1(), old_data) == old_data) break;
}
if (old_value == se32(2))
{
if ((u32)ea->m_size != size || (u32)ea->m_depth != depth || (u64)ea->m_buffer != (u64)buffer_addr)
{
return CELL_SYNC_ERROR_INVAL;
}
if (sdk_ver > 0x17ffff)
{
if ((u64)ea->m_eaSignal != (u64)eaSignal_addr || (u32)ea->m_direction != direction)
{
return CELL_SYNC_ERROR_INVAL;
}
}
}
else
{
// prx: call internal function with same arguments
// prx: sync, zeroize u32 at 0x2c offset
InterlockedCompareExchange(&ea->m_data1(), 0, 0);
ea->m_data1() = 0;
}
// prx: sync
InterlockedCompareExchange(&ea->m_data1(), 0, 0);
return CELL_OK; return CELL_OK;
} }
int _cellSyncLFQueueGetSignalAddress() int _cellSyncLFQueueGetSignalAddress()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("_cellSyncLFQueueGetSignalAddress()");
return CELL_OK; return CELL_OK;
} }
int _cellSyncLFQueuePushBody() int _cellSyncLFQueuePushBody()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("_cellSyncLFQueuePushBody()");
return CELL_OK; return CELL_OK;
} }
int cellSyncLFQueueGetDirection() int cellSyncLFQueueGetDirection()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("cellSyncLFQueueGetDirection()");
return CELL_OK; return CELL_OK;
} }
int cellSyncLFQueueDepth() int cellSyncLFQueueDepth()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("cellSyncLFQueueDepth()");
return CELL_OK; return CELL_OK;
} }
int _cellSyncLFQueuePopBody() int _cellSyncLFQueuePopBody()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("_cellSyncLFQueuePopBody()");
return CELL_OK; return CELL_OK;
} }
int _cellSyncLFQueueGetPushPointer() int _cellSyncLFQueueGetPushPointer()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("_cellSyncLFQueueGetPushPointer()");
return CELL_OK; return CELL_OK;
} }
int _cellSyncLFQueueCompletePopPointer() int _cellSyncLFQueueCompletePopPointer()
{ {
UNIMPLEMENTED_FUNC(cellSync); cellSync->Todo("_cellSyncLFQueueCompletePopPointer()");
return CELL_OK; return CELL_OK;
} }

View File

@ -85,4 +85,41 @@ struct CellSyncQueue
}; };
}; };
static_assert(sizeof(CellSyncQueue) == 32, "CellSyncQueue: wrong size"); static_assert(sizeof(CellSyncQueue) == 32, "CellSyncQueue: wrong size");
enum CellSyncQueueDirection : u32
{
CELL_SYNC_QUEUE_SPU2SPU = 0, // SPU to SPU
CELL_SYNC_QUEUE_SPU2PPU = 1, // SPU to PPU
CELL_SYNC_QUEUE_PPU2SPU = 2, // PPU to SPU
CELL_SYNC_QUEUE_ANY2ANY = 3, // SPU/PPU to SPU/PPU
};
struct CellSyncLFQueue
{
be_t<u64> m_v1;
be_t<u64> m_v2;
be_t<u32> m_size;
be_t<u32> m_depth;
be_t<u64> m_buffer;
be_t<u32> m_v5;
be_t<CellSyncQueueDirection> m_direction;
be_t<u64> m_v6;
be_t<u64> m_v7;
be_t<u64> m_v8;
be_t<u64> m_v9;
be_t<u64> m_v10;
be_t<u64> m_v11;
be_t<u64> m_v12;
be_t<u64> m_v13;
be_t<u64> m_v14;
be_t<u64> m_eaSignal;
be_t<u64> reserved;
volatile u32& m_data1()
{
return *reinterpret_cast<u32*>((u8*)this + 0x2c);
}
};
static_assert(sizeof(CellSyncLFQueue) == 128, "CellSyncLFQueue: wrong size");

View File

@ -10,10 +10,16 @@ SysCallBase sc_p("Process");
sysProcessObjects_t procObjects; sysProcessObjects_t procObjects;
s32 process_getpid()
{
// TODO: get current process id
return 1;
}
s32 sys_process_getpid() s32 sys_process_getpid()
{ {
sc_p.Log("sys_process_getpid() -> 1"); sc_p.Log("sys_process_getpid() -> 1");
return 1; return process_getpid();
} }
s32 sys_process_getppid() s32 sys_process_getppid()
@ -228,12 +234,29 @@ s32 sys_process_get_paramsfo(mem8_ptr_t buffer)
return CELL_OK;*/ return CELL_OK;*/
} }
s32 process_get_sdk_version(u32 pid, s32& ver)
{
// TODO: get correct SDK version for selected pid
ver = Emu.m_sdk_version;
return CELL_OK;
}
s32 sys_process_get_sdk_version(u32 pid, mem32_t version) s32 sys_process_get_sdk_version(u32 pid, mem32_t version)
{ {
sc_p.Warning("sys_process_get_sdk_version(pid=%d, version_addr=0x%x)", pid, version.GetAddr()); sc_p.Warning("sys_process_get_sdk_version(pid=%d, version_addr=0x%x)", pid, version.GetAddr());
version = 0x360001; // TODO s32 sdk_ver;
return CELL_OK; s32 ret = process_get_sdk_version(pid, sdk_ver);
if (ret != CELL_OK)
{
return ret; // error code
}
else
{
version = sdk_ver;
return CELL_OK;
}
} }
s32 sys_process_kill(u32 pid) s32 sys_process_kill(u32 pid)

View File

@ -51,6 +51,10 @@ struct sysProcessObjects_t
// Extern // Extern
extern sysProcessObjects_t procObjects; extern sysProcessObjects_t procObjects;
// Auxiliary functions
s32 process_getpid();
s32 process_get_sdk_version(u32 pid, s32& ver);
// SysCalls // SysCalls
s32 sys_process_getpid(); s32 sys_process_getpid();
s32 sys_process_getppid(); s32 sys_process_getppid();

View File

@ -10,11 +10,6 @@ s32 sys_rwlock_create(mem32_t rw_lock_id, mem_ptr_t<sys_rwlock_attribute_t> attr
{ {
sys_rwlock.Warning("sys_rwlock_create(rw_lock_id_addr=0x%x, attr_addr=0x%x)", rw_lock_id.GetAddr(), attr.GetAddr()); sys_rwlock.Warning("sys_rwlock_create(rw_lock_id_addr=0x%x, attr_addr=0x%x)", rw_lock_id.GetAddr(), attr.GetAddr());
if (!rw_lock_id.GetAddr() || !attr.GetAddr())
{
return CELL_EFAULT;
}
switch (attr->attr_protocol.ToBE()) switch (attr->attr_protocol.ToBE())
{ {
case se(attr->attr_protocol, SYS_SYNC_PRIORITY): sys_rwlock.Todo("SYS_SYNC_PRIORITY"); break; case se(attr->attr_protocol, SYS_SYNC_PRIORITY): sys_rwlock.Todo("SYS_SYNC_PRIORITY"); break;

View File

@ -298,7 +298,7 @@ s32 sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status)
} }
if (Emu.IsStopped()) if (Emu.IsStopped())
{ {
LOG_WARNING(Log::SPU, "sys_spu_thread_group_join(id=%d, ...) aborted", id); LOG_WARNING(Log::SPU, "sys_spu_thread_group_join(id=%d) aborted", id);
return CELL_OK; return CELL_OK;
} }
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(1));

View File

@ -16,7 +16,7 @@
#include "Emu/CPU/CPUThreadManager.h" //gui dependency #include "Emu/CPU/CPUThreadManager.h" //gui dependency
#include "../Loader/PSF.h" #include "Loader/PSF.h"
#include "../Crypto/unself.h" #include "../Crypto/unself.h"
#include <cstdlib> #include <cstdlib>
@ -270,6 +270,26 @@ void Emulator::Load()
return; return;
} }
// setting default values
Emu.m_sdk_version = -1; // possibly "unknown" value
// trying to load some info from PARAM.SFO
vfsFile f2("/app_home/PARAM.SFO");
if (f2.IsOpened())
{
PSFLoader psf(f2);
if (psf.Load(false))
{
std::string version = psf.GetString("PS3_SYSTEM_VER");
const size_t dot = version.find('.');
if (dot != std::string::npos)
{
Emu.m_sdk_version = (std::stoi(version, nullptr, 16) << 20) | ((std::stoi(version.substr(dot + 1), nullptr, 16) & 0xffff) << 4) | 1;
}
}
}
LoadPoints(BreakPointsDBName); LoadPoints(BreakPointsDBName);
CPUThread& thread = GetCPU().AddThread(thread_type); CPUThread& thread = GetCPU().AddThread(thread_type);

View File

@ -106,6 +106,7 @@ public:
std::string m_path; std::string m_path;
std::string m_elf_path; std::string m_elf_path;
std::string m_title_id; std::string m_title_id;
s32 m_sdk_version;
Emulator(); Emulator();