IsGoodAddr() bug fixed

This commit is contained in:
Nekotekina 2014-07-14 23:15:30 +04:00
parent a71053ae15
commit 01aa74e4a8
6 changed files with 181 additions and 220 deletions

View file

@ -6,6 +6,12 @@
#define thread_local __thread
#endif
#ifdef _WIN32
#define noinline __declspec(noinline)
#else
#define noinline __attribute__((noinline))
#endif
template<size_t size>
void strcpy_trunc(char (&dst)[size], const std::string& src)
{

View file

@ -364,193 +364,7 @@ bool MemoryBlockLE::Write128(const u64 addr, const u128 value)
return true;
}
//MemoryBase
void MemoryBase::Write8(u64 addr, const u8 data)
{
if ((u32)addr == addr)
{
*(u8*)((u8*)GetBaseAddr() + addr) = data;
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
}
}
void MemoryBase::Write16(u64 addr, const u16 data)
{
if ((u32)addr == addr)
{
*(u16*)((u8*)GetBaseAddr() + addr) = re16(data);
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
}
}
void MemoryBase::Write32(u64 addr, const u32 data)
{
if ((u32)addr == addr)
{
if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET])
{
*(u32*)((u8*)GetBaseAddr() + addr) = re32(data);
}
else
{
RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Write32(addr, data);
}
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
}
}
void MemoryBase::Write64(u64 addr, const u64 data)
{
if ((u32)addr == addr)
{
*(u64*)((u8*)GetBaseAddr() + addr) = re64(data);
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
}
}
void MemoryBase::Write128(u64 addr, const u128 data)
{
if ((u32)addr == addr)
{
*(u128*)((u8*)GetBaseAddr() + addr) = re128(data);
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
}
}
bool MemoryBase::Write8NN(u64 addr, const u8 data)
{
if(!IsGoodAddr(addr)) return false;
Write8(addr, data);
return true;
}
bool MemoryBase::Write16NN(u64 addr, const u16 data)
{
if(!IsGoodAddr(addr, 2)) return false;
Write16(addr, data);
return true;
}
bool MemoryBase::Write32NN(u64 addr, const u32 data)
{
if(!IsGoodAddr(addr, 4)) return false;
Write32(addr, data);
return true;
}
bool MemoryBase::Write64NN(u64 addr, const u64 data)
{
if(!IsGoodAddr(addr, 8)) return false;
Write64(addr, data);
return true;
}
bool MemoryBase::Write128NN(u64 addr, const u128 data)
{
if(!IsGoodAddr(addr, 16)) return false;
Write128(addr, data);
return true;
}
u8 MemoryBase::Read8(u64 addr)
{
if ((u32)addr == addr)
{
return *(u8*)((u8*)GetBaseAddr() + addr);
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
return 0;
}
}
u16 MemoryBase::Read16(u64 addr)
{
if ((u32)addr == addr)
{
return re16(*(u16*)((u8*)GetBaseAddr() + addr));
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
return 0;
}
}
u32 MemoryBase::Read32(u64 addr)
{
if ((u32)addr == addr)
{
if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET])
{
return re32(*(u32*)((u8*)GetBaseAddr() + addr));
}
else
{
u32 res;
RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Read32(addr, &res);
return res;
}
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
return 0;
}
}
u64 MemoryBase::Read64(u64 addr)
{
if ((u32)addr == addr)
{
return re64(*(u64*)((u8*)GetBaseAddr() + addr));
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
return 0;
}
}
u128 MemoryBase::Read128(u64 addr)
{
if ((u32)addr == addr)
{
return re128(*(u128*)((u8*)GetBaseAddr() + addr));
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
Emu.Pause();
return u128::From128(0, 0);
}
}
// MemoryBase
template<> __forceinline u64 MemoryBase::ReverseData<1>(u64 val) { return val; }
template<> __forceinline u64 MemoryBase::ReverseData<2>(u64 val) { return Reverse16(val); }
template<> __forceinline u64 MemoryBase::ReverseData<4>(u64 val) { return Reverse32(val); }

View file

@ -111,17 +111,26 @@ public:
return m_base_addr;
}
noinline void InvalidAddress(const char* func, const u64 addr)
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", func, addr);
}
void RegisterPages(u64 addr, u32 size)
{
std::lock_guard<std::recursive_mutex> lock(m_mutex);
//LOG_NOTICE(MEMORY, "RegisterPages(addr=0x%llx, size=0x%x)", addr, size);
for (u32 i = addr / 4096; i < (addr + size) / 4096; i++)
for (u64 i = addr / 4096; i < (addr + size) / 4096; i++)
{
if (i >= sizeof(m_pages) / sizeof(m_pages[0])) break;
if (i >= sizeof(m_pages) / sizeof(m_pages[0]))
{
InvalidAddress(__FUNCTION__, i * 4096);
break;
}
if (m_pages[i])
{
LOG_ERROR(MEMORY, "Page already registered (page=0x%x)", i * 4096);
LOG_ERROR(MEMORY, "Page already registered (addr=0x%llx)", i * 4096);
}
m_pages[i] = 1; // TODO: define page parameters
}
@ -132,12 +141,16 @@ public:
std::lock_guard<std::recursive_mutex> lock(m_mutex);
//LOG_NOTICE(MEMORY, "UnregisterPages(addr=0x%llx, size=0x%x)", addr, size);
for (u32 i = addr / 4096; i < (addr + size) / 4096; i++)
for (u64 i = addr / 4096; i < (addr + size) / 4096; i++)
{
if (i >= sizeof(m_pages) / sizeof(m_pages[0])) break;
if (i >= sizeof(m_pages) / sizeof(m_pages[0]))
{
InvalidAddress(__FUNCTION__, i * 4096);
break;
}
if (!m_pages[i])
{
LOG_ERROR(MEMORY, "Page not registered (page=0x%x)", i * 4096);
LOG_ERROR(MEMORY, "Page not registered (addr=0x%llx)", i * 4096);
}
m_pages[i] = 0; // TODO: define page parameters
}
@ -181,8 +194,7 @@ public:
}
else
{
LOG_ERROR(MEMORY, "%s(): invalid address (0x%llx)", __FUNCTION__, addr);
assert(0);
InvalidAddress(__FUNCTION__, addr);
return (u8*)GetBaseAddr();
}
}
@ -287,9 +299,9 @@ public:
LOG_NOTICE(MEMORY, "Memory initialized.");
}
bool IsGoodAddr(const u64 addr)
template<typename T> bool IsGoodAddr(const T addr)
{
if (addr >= 0x100000000 || !m_pages[addr / 4096]) // TODO: define page parameters
if ((u32)addr != addr || !m_pages[addr / 4096]) // TODO: define page parameters
{
return false;
}
@ -299,9 +311,9 @@ public:
}
}
bool IsGoodAddr(const u64 addr, const u32 size)
template<typename T> bool IsGoodAddr(const T addr, const u32 size)
{
if (addr + size > 0x100000000)
if ((u32)addr != addr || (u64)addr + (u64)size > 0x100000000ull)
{
return false;
}
@ -346,23 +358,152 @@ public:
#endif
}
void Write8(const u64 addr, const u8 data);
void Write16(const u64 addr, const u16 data);
void Write32(const u64 addr, const u32 data);
void Write64(const u64 addr, const u64 data);
void Write128(const u64 addr, const u128 data);
//MemoryBase
template<typename T> void Write8(T addr, const u8 data)
{
if ((u32)addr == addr)
{
*(u8*)((u8*)GetBaseAddr() + addr) = data;
}
else
{
InvalidAddress(__FUNCTION__, addr);
*(u8*)GetBaseAddr() = data;
}
}
bool Write8NN(const u64 addr, const u8 data);
bool Write16NN(const u64 addr, const u16 data);
bool Write32NN(const u64 addr, const u32 data);
bool Write64NN(const u64 addr, const u64 data);
bool Write128NN(const u64 addr, const u128 data);
template<typename T> void Write16(T addr, const u16 data)
{
if ((u32)addr == addr)
{
*(u16*)((u8*)GetBaseAddr() + addr) = re16(data);
}
else
{
InvalidAddress(__FUNCTION__, addr);
*(u16*)GetBaseAddr() = data;
}
}
u8 Read8(const u64 addr);
u16 Read16(const u64 addr);
u32 Read32(const u64 addr);
u64 Read64(const u64 addr);
u128 Read128(const u64 addr);
template<typename T> void Write32(T addr, const u32 data)
{
if ((u32)addr == addr)
{
if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET])
{
*(u32*)((u8*)GetBaseAddr() + addr) = re32(data);
}
else
{
RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Write32(addr, data);
}
}
else
{
InvalidAddress(__FUNCTION__, addr);
*(u32*)GetBaseAddr() = data;
}
}
template<typename T> void Write64(T addr, const u64 data)
{
if ((u32)addr == addr)
{
*(u64*)((u8*)GetBaseAddr() + addr) = re64(data);
}
else
{
InvalidAddress(__FUNCTION__, addr);
*(u64*)GetBaseAddr() = data;
}
}
template<typename T> void Write128(T addr, const u128 data)
{
if ((u32)addr == addr)
{
*(u128*)((u8*)GetBaseAddr() + addr) = re128(data);
}
else
{
InvalidAddress(__FUNCTION__, addr);
*(u128*)GetBaseAddr() = data;
}
}
template<typename T> u8 Read8(T addr)
{
if ((u32)addr == addr)
{
return *(u8*)((u8*)GetBaseAddr() + addr);
}
else
{
InvalidAddress(__FUNCTION__, addr);
return *(u8*)GetBaseAddr();
}
}
template<typename T> u16 Read16(T addr)
{
if ((u32)addr == addr)
{
return re16(*(u16*)((u8*)GetBaseAddr() + addr));
}
else
{
InvalidAddress(__FUNCTION__, addr);
return *(u16*)GetBaseAddr();
}
}
template<typename T> u32 Read32(T addr)
{
if ((u32)addr == addr)
{
if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET])
{
return re32(*(u32*)((u8*)GetBaseAddr() + addr));
}
else
{
u32 res;
RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Read32(addr, &res);
return res;
}
}
else
{
InvalidAddress(__FUNCTION__, addr);
return *(u32*)GetBaseAddr();
}
}
template<typename T> u64 Read64(T addr)
{
if ((u32)addr == addr)
{
return re64(*(u64*)((u8*)GetBaseAddr() + addr));
}
else
{
InvalidAddress(__FUNCTION__, addr);
return *(u64*)GetBaseAddr();
}
}
template<typename T> u128 Read128(T addr)
{
if ((u32)addr == addr)
{
return re128(*(u128*)((u8*)GetBaseAddr() + addr));
}
else
{
InvalidAddress(__FUNCTION__, addr);
return *(u128*)GetBaseAddr();
}
}
bool CopyToReal(void* real, u64 from, u32 count)
{

View file

@ -531,7 +531,8 @@ int cellSurMixerStart()
int cellSurMixerSetParameter(u32 param, float value)
{
libmixer->Error("cellSurMixerSetParameter(param=0x%x, value=%f)", param, value);
declCPU();
libmixer->Error("cellSurMixerSetParameter(param=0x%x, value=%f, FPR[1]=%f, FPR[2]=%f)", param, value, (float&)CPU.FPR[1], (float&)CPU.FPR[2]);
return CELL_OK;
}
@ -559,8 +560,7 @@ int cellSurMixerSurBusAddData(u32 busNo, u32 offset, u32 addr, u32 samples)
}
else
{
libmixer->Error("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, samples);
Emu.Pause();
libmixer->Error("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d): unknown parameters", busNo, offset, addr, samples);
return CELL_OK;
}

View file

@ -109,7 +109,7 @@ s32 sys_timer_sleep(u32 sleep_time)
std::this_thread::sleep_for(std::chrono::seconds(1));
if (Emu.IsStopped())
{
sys_timer.Warning("sys_timer_sleep(sleep_time=%d)", sleep_time);
sys_timer.Warning("sys_timer_sleep(sleep_time=%d) aborted", sleep_time);
return CELL_OK;
}
}
@ -125,7 +125,7 @@ s32 sys_timer_usleep(u64 sleep_time)
std::this_thread::sleep_for(std::chrono::seconds(1));
if (Emu.IsStopped())
{
sys_timer.Warning("sys_timer_usleep(sleep_time=%lld)", sleep_time);
sys_timer.Warning("sys_timer_usleep(sleep_time=%lld) aborted", sleep_time);
return CELL_OK;
}
}

View file

@ -9,7 +9,7 @@ s32 sys_tty_read(u32 ch, u64 buf_addr, u32 len, u64 preadlen_addr)
{
// We currently do not support reading from the Console
LOG_WARNING(HLE, "sys_tty_read: ch: %d, buf addr: %llx, len: %d", ch, buf_addr, len);
Memory.Write32NN(preadlen_addr, len);
Memory.Write32(preadlen_addr, len);
Emu.Pause();
return CELL_OK;