mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 19:45:20 +00:00
Merge pull request #734 from Nekotekina/master
Logging last syscall code for memory error
This commit is contained in:
commit
6bd45f9697
11 changed files with 224 additions and 32 deletions
|
@ -28,6 +28,7 @@ CPUThread::CPUThread(CPUThreadType type)
|
|||
, m_is_step(false)
|
||||
, m_is_branch(false)
|
||||
, 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
|
||||
//GetCurrentPPUThread().Stop();
|
||||
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
|
||||
{
|
||||
|
|
|
@ -133,6 +133,7 @@ public:
|
|||
bool m_is_interrupt;
|
||||
bool m_has_interrupt;
|
||||
u64 m_interrupt_arg;
|
||||
u64 m_last_syscall;
|
||||
|
||||
protected:
|
||||
CPUThread(CPUThreadType type);
|
||||
|
|
|
@ -66,6 +66,7 @@ private:
|
|||
|
||||
void SysCall()
|
||||
{
|
||||
CPU.m_last_syscall = CPU.GPR[11];
|
||||
SysCalls::DoSyscall(CPU.GPR[11]);
|
||||
|
||||
if(Ini.HLELogging.GetValue())
|
||||
|
@ -81,6 +82,8 @@ private:
|
|||
#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);
|
||||
#endif
|
||||
|
||||
CPU.m_last_syscall = 0;
|
||||
}
|
||||
|
||||
void NULL_OP()
|
||||
|
|
|
@ -1025,113 +1025,219 @@ s32 cellSyncQueueClear(mem_ptr_t<CellSyncQueue> queue)
|
|||
|
||||
int cellSyncLFQueueGetEntrySize()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("cellSyncLFQueueGetEntrySize()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSyncLFQueueSize()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("cellSyncLFQueueSize()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSyncLFQueueClear()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("cellSyncLFQueueClear()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int _cellSyncLFQueueCompletePushPointer2()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("_cellSyncLFQueueCompletePushPointer2()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int _cellSyncLFQueueGetPopPointer2()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("_cellSyncLFQueueGetPopPointer2()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int _cellSyncLFQueueCompletePushPointer()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("_cellSyncLFQueueCompletePushPointer()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int _cellSyncLFQueueAttachLv2EventQueue()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("_cellSyncLFQueueAttachLv2EventQueue()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int _cellSyncLFQueueGetPushPointer2()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("_cellSyncLFQueueGetPushPointer2()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int _cellSyncLFQueueGetPopPointer()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("_cellSyncLFQueueGetPopPointer()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int _cellSyncLFQueueCompletePopPointer2()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("_cellSyncLFQueueCompletePopPointer2()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int _cellSyncLFQueueDetachLv2EventQueue()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("_cellSyncLFQueueDetachLv2EventQueue()");
|
||||
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;
|
||||
}
|
||||
|
||||
int _cellSyncLFQueueGetSignalAddress()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("_cellSyncLFQueueGetSignalAddress()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int _cellSyncLFQueuePushBody()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("_cellSyncLFQueuePushBody()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSyncLFQueueGetDirection()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("cellSyncLFQueueGetDirection()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellSyncLFQueueDepth()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("cellSyncLFQueueDepth()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int _cellSyncLFQueuePopBody()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("_cellSyncLFQueuePopBody()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int _cellSyncLFQueueGetPushPointer()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("_cellSyncLFQueueGetPushPointer()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int _cellSyncLFQueueCompletePopPointer()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSync);
|
||||
cellSync->Todo("_cellSyncLFQueueCompletePopPointer()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
|
@ -10,10 +10,16 @@ SysCallBase sc_p("Process");
|
|||
|
||||
sysProcessObjects_t procObjects;
|
||||
|
||||
s32 process_getpid()
|
||||
{
|
||||
// TODO: get current process id
|
||||
return 1;
|
||||
}
|
||||
|
||||
s32 sys_process_getpid()
|
||||
{
|
||||
sc_p.Log("sys_process_getpid() -> 1");
|
||||
return 1;
|
||||
return process_getpid();
|
||||
}
|
||||
|
||||
s32 sys_process_getppid()
|
||||
|
@ -228,12 +234,29 @@ s32 sys_process_get_paramsfo(mem8_ptr_t buffer)
|
|||
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)
|
||||
{
|
||||
sc_p.Warning("sys_process_get_sdk_version(pid=%d, version_addr=0x%x)", pid, version.GetAddr());
|
||||
|
||||
version = 0x360001; // TODO
|
||||
return CELL_OK;
|
||||
s32 sdk_ver;
|
||||
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)
|
||||
|
|
|
@ -51,6 +51,10 @@ struct sysProcessObjects_t
|
|||
// Extern
|
||||
extern sysProcessObjects_t procObjects;
|
||||
|
||||
// Auxiliary functions
|
||||
s32 process_getpid();
|
||||
s32 process_get_sdk_version(u32 pid, s32& ver);
|
||||
|
||||
// SysCalls
|
||||
s32 sys_process_getpid();
|
||||
s32 sys_process_getppid();
|
||||
|
|
|
@ -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());
|
||||
|
||||
if (!rw_lock_id.GetAddr() || !attr.GetAddr())
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
switch (attr->attr_protocol.ToBE())
|
||||
{
|
||||
case se(attr->attr_protocol, SYS_SYNC_PRIORITY): sys_rwlock.Todo("SYS_SYNC_PRIORITY"); break;
|
||||
|
|
|
@ -298,7 +298,7 @@ s32 sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status)
|
|||
}
|
||||
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;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "Emu/CPU/CPUThreadManager.h" //gui dependency
|
||||
|
||||
#include "../Loader/PSF.h"
|
||||
#include "Loader/PSF.h"
|
||||
|
||||
#include "../Crypto/unself.h"
|
||||
#include <cstdlib>
|
||||
|
@ -270,6 +270,26 @@ void Emulator::Load()
|
|||
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);
|
||||
|
||||
CPUThread& thread = GetCPU().AddThread(thread_type);
|
||||
|
|
|
@ -106,6 +106,7 @@ public:
|
|||
std::string m_path;
|
||||
std::string m_elf_path;
|
||||
std::string m_title_id;
|
||||
s32 m_sdk_version;
|
||||
|
||||
Emulator();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue