mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
More manual Read_U32 cleanup
Buildfix
This commit is contained in:
1 parent
af9891cd7d
commit
3c81d6b121
20 files changed
+141
-86
No files matched your search
@@ -385,6 +385,7 @@ add_library(Core STATIC
|
||||
HLE/FunctionWrappers.h
|
||||
HLE/HLE.cpp
|
||||
HLE/HLE.h
|
||||
HLE/HLEUtil.h
|
||||
HLE/ReplaceTables.cpp
|
||||
HLE/ReplaceTables.h
|
||||
HLE/HLEHelperThread.cpp
|
||||
|
||||
@@ -1009,6 +1009,7 @@
|
||||
<ClInclude Include="HLE\AtracCtx.h" />
|
||||
<ClInclude Include="HLE\AtracCtx2.h" />
|
||||
<ClInclude Include="HLE\ErrorCodes.h" />
|
||||
<ClInclude Include="HLE\HLEUtil.h" />
|
||||
<ClInclude Include="HLE\KernelThreadDebugInterface.h" />
|
||||
<ClInclude Include="HLE\KUBridge.h" />
|
||||
<ClInclude Include="HLE\NetInetConstants.h" />
|
||||
|
||||
@@ -2262,6 +2262,9 @@
|
||||
<ClInclude Include="EmuThread.h">
|
||||
<Filter>Core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HLE\HLEUtil.h">
|
||||
<Filter>HLE</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\LICENSE.TXT" />
|
||||
|
||||
@@ -660,7 +660,11 @@ bool BreakpointManager::EvaluateLogFormat(MIPSDebugInterface *cpu, const std::st
|
||||
snprintf(resultString, sizeof(resultString), "%f", expResult.f);
|
||||
break;
|
||||
case 'p':
|
||||
snprintf(resultString, sizeof(resultString), "%08x[%08x]", expResult.u, Memory::IsValidAddress(expResult.u) ? Memory::Read_U32(expResult.u) : 0);
|
||||
if (Memory::IsValidAddress(expResult.u)) {
|
||||
snprintf(resultString, sizeof(resultString), "%08x[%08x]", expResult.u, Memory::ReadUnchecked_U32(expResult.u));
|
||||
} else {
|
||||
snprintf(resultString, sizeof(resultString), "%08x[invalid]", expResult.u);
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
snprintf(resultString, sizeof(resultString) - 1, "%s", Memory::IsValidAddress(expResult.u) ? Memory::GetCharPointer(expResult.u) : "(invalid)");
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "Core/MemMapHelpers.h"
|
||||
#include "Core/Util/PPGeDraw.h"
|
||||
#include "Core/HLE/HLE.h"
|
||||
#include "Core/HLE/HLEUtil.h"
|
||||
#include "Core/HLE/ErrorCodes.h"
|
||||
#include "Core/HLE/sceKernelMemory.h"
|
||||
#include "Core/HLE/sceCtrl.h"
|
||||
@@ -59,21 +60,15 @@ int PSPNetconfDialog::Init(u32 paramAddr) {
|
||||
if (ReadStatus() != SCE_UTILITY_STATUS_NONE)
|
||||
return SCE_ERROR_UTILITY_INVALID_STATUS;
|
||||
|
||||
if (!Memory::IsValid4AlignedRange(paramAddr, sizeof(request))) {
|
||||
// What to do?
|
||||
return SCE_KERNEL_ERROR_BAD_ARGUMENT;
|
||||
}
|
||||
|
||||
NOTICE_LOG(Log::sceUtility, "PSPNetConfDialog Init");
|
||||
jsonReady_ = false;
|
||||
// Kick off a request to the infra-dns.json since we'll need it later.
|
||||
StartInfraJsonDownload();
|
||||
|
||||
requestAddr = paramAddr;
|
||||
const u32 size = Memory::ReadUnchecked_U32(paramAddr);
|
||||
memset(&request, 0, sizeof(request));
|
||||
// Only copy the right size (bounded by the struct) to support different request format
|
||||
Memory::Memcpy(&request, paramAddr, std::min(size, (u32)sizeof(request)));
|
||||
if (!ReadVariableSizedStruct(paramAddr, &request.common)) {
|
||||
return SCE_KERNEL_ERROR_BAD_ARGUMENT; // untested
|
||||
}
|
||||
|
||||
ChangeStatusInit(NET_INIT_DELAY_US);
|
||||
|
||||
@@ -250,22 +245,27 @@ int PSPNetconfDialog::Update(int animSpeed) {
|
||||
if (Memory::IsValidAddress(scanInfosAddr))
|
||||
userMemory.Free(scanInfosAddr);
|
||||
scanInfosAddr = userMemory.Alloc(structsz, false, "NetconfScanInfo");
|
||||
Memory::Write_U32(sizeof(SceNetAdhocctlScanInfoEmu), scanInfosAddr);
|
||||
// TOOD: What if scanInfosAddr is not valid?
|
||||
if (Memory::IsValid4AlignedAddress(scanInfosAddr)) {
|
||||
Memory::WriteUnchecked_U32(sizeof(SceNetAdhocctlScanInfoEmu), scanInfosAddr);
|
||||
}
|
||||
scanStep = 1;
|
||||
}
|
||||
}
|
||||
else if (scanStep == 1) {
|
||||
s32 sz = Memory::Read_U32(scanInfosAddr);
|
||||
s32 sz = Memory::ReadUnchecked_U32(scanInfosAddr);
|
||||
// Get required buffer size
|
||||
if (hleCall(sceNetAdhocctl, int, sceNetAdhocctlGetScanInfo, scanInfosAddr, 0) >= 0) {
|
||||
s32 reqsz = Memory::Read_U32(scanInfosAddr);
|
||||
s32 reqsz = Memory::ReadUnchecked_U32(scanInfosAddr);
|
||||
if (reqsz > sz) {
|
||||
sz = reqsz;
|
||||
if (Memory::IsValidAddress(scanInfosAddr))
|
||||
userMemory.Free(scanInfosAddr);
|
||||
userMemory.Free(scanInfosAddr);
|
||||
u32 structsz = sz + sizeof(s32);
|
||||
scanInfosAddr = userMemory.Alloc(structsz, false, "NetconfScanInfo");
|
||||
Memory::Write_U32(sz, scanInfosAddr);
|
||||
// TOOD: What if scanInfosAddr is not valid?
|
||||
if (Memory::IsValid4AlignedAddress(scanInfosAddr)) {
|
||||
Memory::WriteUnchecked_U32(sz, scanInfosAddr);
|
||||
}
|
||||
}
|
||||
if (reqsz > 0) {
|
||||
if (hleCall(sceNetAdhocctl, int, sceNetAdhocctlGetScanInfo, scanInfosAddr, scanInfosAddr + (u32)sizeof(s32)) >= 0) {
|
||||
@@ -299,7 +299,7 @@ int PSPNetconfDialog::Update(int animSpeed) {
|
||||
connResult = hleCall(sceNetAdhocctl, int, sceNetAdhocctlJoin, scanInfosAddr + (u32)sizeof(s32));
|
||||
if (connResult >= 0) {
|
||||
// We are done!
|
||||
if (Memory::IsValidAddress(scanInfosAddr))
|
||||
if (Memory::IsValid4AlignedAddress(scanInfosAddr))
|
||||
userMemory.Free(scanInfosAddr);
|
||||
scanInfosAddr = 0;
|
||||
}
|
||||
@@ -325,7 +325,7 @@ int PSPNetconfDialog::Update(int animSpeed) {
|
||||
}
|
||||
|
||||
// Let's not leaks any memory
|
||||
if (Memory::IsValidAddress(scanInfosAddr))
|
||||
if (Memory::IsValid4AlignedAddress(scanInfosAddr))
|
||||
userMemory.Free(scanInfosAddr);
|
||||
scanInfosAddr = 0;
|
||||
}
|
||||
@@ -335,7 +335,7 @@ int PSPNetconfDialog::Update(int animSpeed) {
|
||||
ChangeStatus(SCE_UTILITY_STATUS_FINISHED, NET_SHUTDOWN_DELAY_US);
|
||||
request.common.result = SCE_UTILITY_DIALOG_RESULT_ABORT;
|
||||
// Let's not leaks any memory
|
||||
if (Memory::IsValidAddress(scanInfosAddr))
|
||||
if (Memory::IsValid4AlignedAddress(scanInfosAddr))
|
||||
userMemory.Free(scanInfosAddr);
|
||||
scanInfosAddr = 0;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "Core/HLE/sceCtrl.h"
|
||||
#include "Core/HLE/sceUtility.h"
|
||||
#include "Core/HLE/sceNp.h"
|
||||
#include "Core/HLE/HLEUtil.h"
|
||||
#include "Core/HLE/HLE.h"
|
||||
#include "Core/HLE/ErrorCodes.h"
|
||||
#include "Core/Dialog/PSPNpSigninDialog.h"
|
||||
#include "Common/Data/Encoding/Utf8.h"
|
||||
@@ -42,11 +44,10 @@ int PSPNpSigninDialog::Init(u32 paramAddr) {
|
||||
return SCE_ERROR_UTILITY_INVALID_STATUS;
|
||||
|
||||
requestAddr = paramAddr;
|
||||
int size = Memory::Read_U32(paramAddr);
|
||||
memset(&request, 0, sizeof(request));
|
||||
// Only copy the right size to support different request format
|
||||
Memory::Memcpy(&request, paramAddr, size);
|
||||
|
||||
if (!ReadVariableSizedStruct(paramAddr, &request)) {
|
||||
return SCE_KERNEL_ERROR_BAD_ARGUMENT; // untested
|
||||
}
|
||||
|
||||
WARN_LOG_REPORT_ONCE(PSPNpSigninDialogInit, Log::sceNet, "NpSignin Init Params: %08x, %08x, %08x, %08x", request.npSigninStatus, request.unknown1, request.unknown2, request.unknown3);
|
||||
|
||||
ChangeStatusInit(NP_INIT_DELAY_US);
|
||||
|
||||
@@ -126,8 +126,13 @@ int PSPSaveDialog::Init(int paramAddr) {
|
||||
|
||||
ioThreadStatus = SAVEIO_NONE;
|
||||
|
||||
requestAddr = 0;
|
||||
if (!Memory::IsValid4AlignedAddress(paramAddr)) {
|
||||
return SCE_KERNEL_ERROR_BAD_ARGUMENT; // untested
|
||||
}
|
||||
requestAddr = paramAddr;
|
||||
int size = Memory::Read_U32(requestAddr);
|
||||
|
||||
int size = Memory::ReadUnchecked_U32(requestAddr);
|
||||
memset(&request, 0, sizeof(request));
|
||||
// Only copy the right size to support different save request format
|
||||
if (size != SAVEDATA_DIALOG_SIZE_V1 && size != SAVEDATA_DIALOG_SIZE_V2 && size != SAVEDATA_DIALOG_SIZE_V3) {
|
||||
@@ -655,8 +660,7 @@ void PSPSaveDialog::DisplayMessage(std::string_view text, bool hasYesNo)
|
||||
PPGeDrawRect(202.0f, ey, 466.0f, ey + 1.0f, CalcFadedColor(0xFFFFFFFF));
|
||||
}
|
||||
|
||||
int PSPSaveDialog::Update(int animSpeed)
|
||||
{
|
||||
int PSPSaveDialog::Update(int animSpeed) {
|
||||
if (GetStatus() != SCE_UTILITY_STATUS_RUNNING)
|
||||
return SCE_ERROR_UTILITY_INVALID_STATUS;
|
||||
|
||||
@@ -673,7 +677,7 @@ int PSPSaveDialog::Update(int animSpeed)
|
||||
// The struct may have been updated by the game. This happens in "Where Is My Heart?"
|
||||
// Check if it has changed, reload it.
|
||||
// TODO: Cut down on preloading? This rebuilds the list from scratch.
|
||||
int size = std::min((u32)sizeof(originalRequest), Memory::Read_U32(requestAddr));
|
||||
int size = std::min((u32)sizeof(originalRequest), Memory::ReadUnchecked_U32(requestAddr));
|
||||
const u8 *updatedRequest = Memory::GetPointerRange(requestAddr, size);
|
||||
if (updatedRequest && memcmp(updatedRequest, &originalRequest, size) != 0) {
|
||||
memset(&request, 0, sizeof(request));
|
||||
|
||||
+6
-1
@@ -1032,7 +1032,12 @@ size_t HLEFormatLogArgs(const MIPSState *mips, char *message, size_t sz, const c
|
||||
u32 sp = mips->r[MIPS_REG_SP];
|
||||
// Goes upward on stack.
|
||||
// NOTE: Currently we only support > 8 for 32-bit integer args.
|
||||
regval = Memory::Read_U32(sp + (reg - 8) * 4);
|
||||
if (Memory::IsValid4AlignedAddress(sp)) {
|
||||
regval = Memory::ReadUnchecked_U32(sp + (reg - 8) * 4);
|
||||
} else {
|
||||
// This should basically never happen.
|
||||
ERROR_LOG(Log::HLE, "Couldn't read sp=%08x for arg %zu", sp, i);
|
||||
}
|
||||
}
|
||||
|
||||
switch (argmask[i]) {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include <cstring>
|
||||
#include "Core/MemMap.h"
|
||||
|
||||
// Used in various places in the PSP OS.
|
||||
template<typename T> bool ReadVariableSizedStruct(u32 addr, T *out) {
|
||||
int size = Memory::ReadUnchecked_U32(addr);
|
||||
if (!Memory::IsValid4AlignedRange(addr, size)) {
|
||||
return false;
|
||||
}
|
||||
memset(out, 0, sizeof(*out));
|
||||
// Only copy the right size to support different struct versions.
|
||||
// Let's add a debug assert in case we have a struct that is too small for the data.
|
||||
_dbg_assert_(sizeof(*out) >= size);
|
||||
Memory::Memcpy(out, addr, std::min(size, (int)sizeof(*out)));
|
||||
return true;
|
||||
}
|
||||
@@ -1110,9 +1110,10 @@ void AtracSasDecodeData(int atracID, u8* outbuf, int *SamplesNum, int *finish) {
|
||||
atrac->DecodeForSas((s16 *)outbuf, SamplesNum, finish);
|
||||
}
|
||||
|
||||
// The context pointer is assumed to be valid.
|
||||
int AtracSasBindContextAndGetID(u32 contextAddr) {
|
||||
// Ugly hack, but needed to support both old and new contexts.
|
||||
int atracID = (int)Memory::Read_U32(contextAddr + 0xfc);
|
||||
int atracID = (int)Memory::ReadUnchecked_U32(contextAddr + 0xfc);
|
||||
if (atracID < PSP_MAX_ATRAC_IDS && atracContexts[atracID] && atracContexts[atracID]->GetContextVersion() == 1) {
|
||||
// We can assume the old atracID hack was used, and atracID is valid.
|
||||
} else {
|
||||
|
||||
@@ -315,14 +315,13 @@ static void __KernelMsgPipeTimeout(u64 userdata, int cyclesLate)
|
||||
HLEKernel::WaitExecTimeout<MsgPipe, WAITTYPE_MSGPIPE>(threadID);
|
||||
}
|
||||
|
||||
static bool __KernelSetMsgPipeTimeout(u32 timeoutPtr)
|
||||
{
|
||||
// Assumes timeout is valid or 0.
|
||||
static bool __KernelSetMsgPipeTimeout(u32 timeoutPtr) {
|
||||
if (timeoutPtr == 0 || waitTimer == -1)
|
||||
return true;
|
||||
|
||||
int micro = (int) Memory::Read_U32(timeoutPtr);
|
||||
if (micro <= 2)
|
||||
{
|
||||
int micro = (int)Memory::ReadUnchecked_U32(timeoutPtr);
|
||||
if (micro <= 2) {
|
||||
// Don't wait or reschedule, just timeout immediately.
|
||||
return false;
|
||||
}
|
||||
@@ -779,8 +778,8 @@ static int __KernelValidateSendMsgPipe(SceUID uid, u32 sendBufAddr, u32 sendSize
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __KernelSendMsgPipe(MsgPipe *m, u32 sendBufAddr, u32 sendSize, int waitMode, u32 resultAddr, u32 timeoutPtr, bool cbEnabled, bool poll)
|
||||
{
|
||||
// Assumes timeoutPtr is valid or 0.
|
||||
static int __KernelSendMsgPipe(MsgPipe *m, u32 sendBufAddr, u32 sendSize, int waitMode, u32 resultAddr, u32 timeoutPtr, bool cbEnabled, bool poll) {
|
||||
hleEatCycles(2400);
|
||||
|
||||
bool needsResched = false;
|
||||
@@ -791,8 +790,7 @@ static int __KernelSendMsgPipe(MsgPipe *m, u32 sendBufAddr, u32 sendSize, int wa
|
||||
if (needsResched)
|
||||
hleReSchedule(cbEnabled, "msgpipe data sent");
|
||||
|
||||
if (needsWait)
|
||||
{
|
||||
if (needsWait) {
|
||||
if (__KernelSetMsgPipeTimeout(timeoutPtr))
|
||||
__KernelWaitCurThread(WAITTYPE_MSGPIPE, m->GetUID(), MSGPIPE_WAIT_VALUE_SEND, timeoutPtr, cbEnabled, "msgpipe send waited");
|
||||
else
|
||||
@@ -801,8 +799,7 @@ static int __KernelSendMsgPipe(MsgPipe *m, u32 sendBufAddr, u32 sendSize, int wa
|
||||
return result;
|
||||
}
|
||||
|
||||
int sceKernelSendMsgPipe(SceUID uid, u32 sendBufAddr, u32 sendSize, u32 waitMode, u32 resultAddr, u32 timeoutPtr)
|
||||
{
|
||||
int sceKernelSendMsgPipe(SceUID uid, u32 sendBufAddr, u32 sendSize, u32 waitMode, u32 resultAddr, u32 timeoutPtr) {
|
||||
u32 error = __KernelValidateSendMsgPipe(uid, sendBufAddr, sendSize, waitMode, resultAddr);
|
||||
if (error != 0) {
|
||||
return hleLogError(Log::sceKernel, error);
|
||||
@@ -811,13 +808,15 @@ int sceKernelSendMsgPipe(SceUID uid, u32 sendBufAddr, u32 sendSize, u32 waitMode
|
||||
if (!m) {
|
||||
return hleLogError(Log::sceKernel, error, "bad msgpipe id");
|
||||
}
|
||||
if (timeoutPtr && !Memory::IsValid4AlignedAddress(timeoutPtr)) {
|
||||
return hleLogError(Log::sceKernel, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "bad timeout address");
|
||||
}
|
||||
|
||||
int result = __KernelSendMsgPipe(m, sendBufAddr, sendSize, waitMode, resultAddr, timeoutPtr, false, false);
|
||||
return hleLogDebug(Log::sceKernel, result);
|
||||
}
|
||||
|
||||
int sceKernelSendMsgPipeCB(SceUID uid, u32 sendBufAddr, u32 sendSize, u32 waitMode, u32 resultAddr, u32 timeoutPtr)
|
||||
{
|
||||
int sceKernelSendMsgPipeCB(SceUID uid, u32 sendBufAddr, u32 sendSize, u32 waitMode, u32 resultAddr, u32 timeoutPtr) {
|
||||
u32 error = __KernelValidateSendMsgPipe(uid, sendBufAddr, sendSize, waitMode, resultAddr);
|
||||
if (error != 0) {
|
||||
return hleLogError(Log::sceKernel, error);
|
||||
@@ -826,6 +825,9 @@ int sceKernelSendMsgPipeCB(SceUID uid, u32 sendBufAddr, u32 sendSize, u32 waitMo
|
||||
if (!m) {
|
||||
return hleLogError(Log::sceKernel, error, "bad msgpipe id");
|
||||
}
|
||||
if (timeoutPtr && !Memory::IsValid4AlignedAddress(timeoutPtr)) {
|
||||
return hleLogError(Log::sceKernel, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "bad timeout address");
|
||||
}
|
||||
|
||||
// TODO: Verify callback behavior.
|
||||
hleCheckCurrentCallbacks();
|
||||
@@ -833,8 +835,7 @@ int sceKernelSendMsgPipeCB(SceUID uid, u32 sendBufAddr, u32 sendSize, u32 waitMo
|
||||
return hleLogDebug(Log::sceKernel, result);
|
||||
}
|
||||
|
||||
int sceKernelTrySendMsgPipe(SceUID uid, u32 sendBufAddr, u32 sendSize, u32 waitMode, u32 resultAddr)
|
||||
{
|
||||
int sceKernelTrySendMsgPipe(SceUID uid, u32 sendBufAddr, u32 sendSize, u32 waitMode, u32 resultAddr) {
|
||||
u32 error = __KernelValidateSendMsgPipe(uid, sendBufAddr, sendSize, waitMode, resultAddr, true);
|
||||
if (error != 0) {
|
||||
return hleLogError(Log::sceKernel, error);
|
||||
@@ -848,7 +849,7 @@ int sceKernelTrySendMsgPipe(SceUID uid, u32 sendBufAddr, u32 sendSize, u32 waitM
|
||||
return hleLogDebug(Log::sceKernel, result);
|
||||
}
|
||||
|
||||
static int __KernelValidateReceiveMsgPipe(SceUID uid, u32 receiveBufAddr, u32 receiveSize, int waitMode, u32 resultAddr, bool tryMode = false)
|
||||
static int __KernelValidateReceiveMsgPipe(SceUID uid, u32 receiveBufAddr, u32 receiveSize, int waitMode, bool tryMode = false)
|
||||
{
|
||||
if (receiveSize & 0x80000000)
|
||||
{
|
||||
@@ -907,7 +908,7 @@ static int __KernelReceiveMsgPipe(MsgPipe *m, u32 receiveBufAddr, u32 receiveSiz
|
||||
|
||||
int sceKernelReceiveMsgPipe(SceUID uid, u32 receiveBufAddr, u32 receiveSize, u32 waitMode, u32 resultAddr, u32 timeoutPtr)
|
||||
{
|
||||
u32 error = __KernelValidateReceiveMsgPipe(uid, receiveBufAddr, receiveSize, waitMode, resultAddr);
|
||||
u32 error = __KernelValidateReceiveMsgPipe(uid, receiveBufAddr, receiveSize, waitMode);
|
||||
if (error != 0) {
|
||||
return hleLogError(Log::sceKernel, error);
|
||||
}
|
||||
@@ -922,7 +923,7 @@ int sceKernelReceiveMsgPipe(SceUID uid, u32 receiveBufAddr, u32 receiveSize, u32
|
||||
|
||||
int sceKernelReceiveMsgPipeCB(SceUID uid, u32 receiveBufAddr, u32 receiveSize, u32 waitMode, u32 resultAddr, u32 timeoutPtr)
|
||||
{
|
||||
u32 error = __KernelValidateReceiveMsgPipe(uid, receiveBufAddr, receiveSize, waitMode, resultAddr);
|
||||
u32 error = __KernelValidateReceiveMsgPipe(uid, receiveBufAddr, receiveSize, waitMode);
|
||||
if (error != 0) {
|
||||
return hleLogError(Log::sceKernel, error);
|
||||
}
|
||||
@@ -939,7 +940,7 @@ int sceKernelReceiveMsgPipeCB(SceUID uid, u32 receiveBufAddr, u32 receiveSize, u
|
||||
|
||||
int sceKernelTryReceiveMsgPipe(SceUID uid, u32 receiveBufAddr, u32 receiveSize, u32 waitMode, u32 resultAddr)
|
||||
{
|
||||
u32 error = __KernelValidateReceiveMsgPipe(uid, receiveBufAddr, receiveSize, waitMode, resultAddr, true);
|
||||
u32 error = __KernelValidateReceiveMsgPipe(uid, receiveBufAddr, receiveSize, waitMode, true);
|
||||
if (error != 0) {
|
||||
return hleLogError(Log::sceKernel, error);
|
||||
}
|
||||
@@ -966,10 +967,10 @@ int sceKernelCancelMsgPipe(SceUID uid, u32 numSendThreadsAddr, u32 numReceiveThr
|
||||
if (!m->sendWaitingThreads.empty() || !m->receiveWaitingThreads.empty())
|
||||
hleEatCycles(4000);
|
||||
|
||||
if (Memory::IsValidAddress(numSendThreadsAddr))
|
||||
Memory::Write_U32((u32) m->sendWaitingThreads.size(), numSendThreadsAddr);
|
||||
if (Memory::IsValidAddress(numReceiveThreadsAddr))
|
||||
Memory::Write_U32((u32) m->receiveWaitingThreads.size(), numReceiveThreadsAddr);
|
||||
if (Memory::IsValid4AlignedAddress(numSendThreadsAddr))
|
||||
Memory::WriteUnchecked_U32((u32) m->sendWaitingThreads.size(), numSendThreadsAddr);
|
||||
if (Memory::IsValid4AlignedAddress(numReceiveThreadsAddr))
|
||||
Memory::WriteUnchecked_U32((u32) m->receiveWaitingThreads.size(), numReceiveThreadsAddr);
|
||||
|
||||
for (size_t i = 0; i < m->sendWaitingThreads.size(); i++)
|
||||
m->sendWaitingThreads[i].Cancel(uid, SCE_KERNEL_ERROR_WAIT_CANCEL);
|
||||
|
||||
@@ -224,10 +224,11 @@ int sceKernelCreateSema(const char* name, u32 attr, int initVal, int maxVal, u32
|
||||
}
|
||||
|
||||
// Many games pass garbage into optionPtr, it doesn't have any options.
|
||||
// TODO: Presumably that means that this function simply doesn't have an option parameter?
|
||||
if (optionPtr != 0) {
|
||||
if (!Memory::IsValidRange(optionPtr, 4))
|
||||
return hleLogWarning(Log::sceKernel, id, "invalid options parameter");
|
||||
else if (Memory::Read_U32(optionPtr) > 4)
|
||||
else if (Memory::ReadUnchecked_U32(optionPtr) > 4)
|
||||
return hleLogDebug(Log::sceKernel, id, "invalid options parameter size");
|
||||
}
|
||||
return hleLogDebug(Log::sceKernel, id);
|
||||
@@ -328,11 +329,12 @@ void __KernelSemaTimeout(u64 userdata, int cycleslate) {
|
||||
}
|
||||
}
|
||||
|
||||
// Assumes timeoutPtr is zero or valid.
|
||||
static void __KernelSetSemaTimeout(PSPSemaphore *s, u32 timeoutPtr) {
|
||||
if (timeoutPtr == 0 || semaWaitTimer == -1)
|
||||
return;
|
||||
|
||||
int micro = (int) Memory::Read_U32(timeoutPtr);
|
||||
int micro = (int) Memory::ReadUnchecked_U32(timeoutPtr);
|
||||
|
||||
// This happens to be how the hardware seems to time things.
|
||||
if (micro <= 3)
|
||||
@@ -344,6 +346,7 @@ static void __KernelSetSemaTimeout(PSPSemaphore *s, u32 timeoutPtr) {
|
||||
CoreTiming::ScheduleEvent(usToCycles(micro), semaWaitTimer, __KernelGetCurThread());
|
||||
}
|
||||
|
||||
// Assumes timeoutPtr is zero or valid.
|
||||
static int __KernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr, bool processCallbacks) {
|
||||
hleEatCycles(900);
|
||||
|
||||
@@ -378,6 +381,10 @@ static int __KernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr, bool pro
|
||||
}
|
||||
|
||||
int sceKernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr) {
|
||||
if (timeoutPtr && !Memory::IsValid4AlignedAddress(timeoutPtr)) {
|
||||
return hleLogError(Log::sceKernel, SCE_KERNEL_ERROR_BAD_ARGUMENT, "invalid timeout pointer"); // untested
|
||||
}
|
||||
|
||||
int result = __KernelWaitSema(id, wantedCount, timeoutPtr, false);
|
||||
|
||||
if (id == 0 && result == SCE_KERNEL_ERROR_UNKNOWN_SEMID) {
|
||||
@@ -389,6 +396,10 @@ int sceKernelWaitSema(SceUID id, int wantedCount, u32 timeoutPtr) {
|
||||
}
|
||||
|
||||
int sceKernelWaitSemaCB(SceUID id, int wantedCount, u32 timeoutPtr) {
|
||||
if (timeoutPtr && !Memory::IsValid4AlignedAddress(timeoutPtr)) {
|
||||
return hleLogError(Log::sceKernel, SCE_KERNEL_ERROR_BAD_ARGUMENT, "invalid timeout pointer"); // untested
|
||||
}
|
||||
|
||||
int result = __KernelWaitSema(id, wantedCount, timeoutPtr, true);
|
||||
|
||||
if (id == 0 && result == SCE_KERNEL_ERROR_UNKNOWN_SEMID) {
|
||||
|
||||
@@ -228,8 +228,8 @@ u32 sceKernelCreateVTimer(const char *name, u32 optParamAddr) {
|
||||
strncpy(vtimer->nvt.name, name, KERNELOBJECT_MAX_NAME_LENGTH);
|
||||
vtimer->nvt.name[KERNELOBJECT_MAX_NAME_LENGTH] = '\0';
|
||||
|
||||
if (optParamAddr != 0) {
|
||||
u32 size = Memory::Read_U32(optParamAddr);
|
||||
if (optParamAddr != 0 && Memory::IsValid4AlignedAddress(optParamAddr)) {
|
||||
u32 size = Memory::ReadUnchecked_U32(optParamAddr);
|
||||
if (size > 4)
|
||||
WARN_LOG_REPORT_ONCE(vtimeropt, Log::sceKernel, "sceKernelCreateVTimer(%s) unsupported options parameter, size = %d", name, size);
|
||||
}
|
||||
@@ -470,9 +470,9 @@ u32 sceKernelReferVTimerStatus(SceUID uid, u32 statusAddr) {
|
||||
return hleLogError(Log::sceKernel, error, "bad timer ID");
|
||||
}
|
||||
|
||||
if (Memory::IsValidAddress(statusAddr)) {
|
||||
if (Memory::IsValid4AlignedAddress(statusAddr)) {
|
||||
NativeVTimer status = vt->nvt;
|
||||
u32 size = Memory::Read_U32(statusAddr);
|
||||
u32 size = Memory::ReadUnchecked_U32(statusAddr);
|
||||
status.current = __getVTimerCurrentTime(vt);
|
||||
Memory::Memcpy(statusAddr, &status, std::min(size, (u32)sizeof(status)), "VTimerStatus");
|
||||
}
|
||||
|
||||
+1
-1
@@ -412,7 +412,7 @@ static int FindMp3Header(AuCtx *ctx, int &header, int end) {
|
||||
for (int offset = 0; offset < end; ++offset) {
|
||||
// If we hit valid sync bits, then we've found a header.
|
||||
if (ptr[offset] == 0xFF && (ptr[offset + 1] & 0xC0) == 0xC0) {
|
||||
header = bswap32(Memory::Read_U32(addr + offset));
|
||||
header = bswap32(Memory::ReadUnchecked_U32(addr + offset));
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3200,9 +3200,13 @@ int sceNetAdhocctlScan() {
|
||||
|
||||
int sceNetAdhocctlGetScanInfo(u32 sizeAddr, u32 bufAddr) {
|
||||
s32_le *buflen = NULL;
|
||||
if (Memory::IsValidAddress(sizeAddr)) buflen = (s32_le *)Memory::GetPointer(sizeAddr);
|
||||
if (Memory::IsValidAddress(sizeAddr)) {
|
||||
buflen = (s32_le *)Memory::GetPointer(sizeAddr);
|
||||
}
|
||||
SceNetAdhocctlScanInfoEmu *buf = NULL;
|
||||
if (Memory::IsValidAddress(bufAddr)) buf = (SceNetAdhocctlScanInfoEmu *)Memory::GetPointer(bufAddr);
|
||||
if (Memory::IsValidAddress(bufAddr)) {
|
||||
buf = (SceNetAdhocctlScanInfoEmu *)Memory::GetPointer(bufAddr);
|
||||
}
|
||||
|
||||
INFO_LOG(Log::sceNet, "sceNetAdhocctlGetScanInfo([%08x]=%i, %08x) at %08x", sizeAddr, Memory::Read_U32(sizeAddr), bufAddr, currentMIPS->pc);
|
||||
if (!g_Config.bEnableWlan) {
|
||||
|
||||
@@ -485,7 +485,7 @@ static int sceNetInetSetsockopt(int socket, int level, int optname, u32 optvalPt
|
||||
return hleLogError(Log::sceNet, ERROR_INET_EBADF, "Bad socket #%d", socket);
|
||||
}
|
||||
|
||||
u32 optval = optvalPtr ? Memory::Read_U32(optvalPtr) : 0;
|
||||
const u32 optval = Memory::IsValid4AlignedAddress(optvalPtr) ? Memory::ReadUnchecked_U32(optvalPtr) : 0;
|
||||
INFO_LOG(Log::sceNet, "sceNetInetSetsockopt(%i, %i, %i, %08x, %i) at %08x: Level = %s, OptName = %s, OptValue = %d",
|
||||
socket, level, optname, optvalPtr, optlen, currentMIPS->pc,
|
||||
inetSockoptLevel2str(level).c_str(), inetSockoptName2str(optname, level).c_str(), optval);
|
||||
|
||||
+6
-8
@@ -28,10 +28,10 @@
|
||||
#include "Core/CoreTiming.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/HLE/HLE.h"
|
||||
#include "Core/HLE/HLEUtil.h"
|
||||
#include "Core/HLE/FunctionWrappers.h"
|
||||
#include "Core/HLE/sceNp.h"
|
||||
|
||||
|
||||
bool npAuthInited = false;
|
||||
int npSigninState = NP_SIGNIN_STATUS_NONE;
|
||||
SceNpAuthMemoryStat npAuthMemStat = {};
|
||||
@@ -354,14 +354,12 @@ param seems to be a struct where offset:
|
||||
+20: 32-bit a pointer to a random data (4 to 8-bytes data max? both 2x 32-bit seems to be a valid pointer). optional handler args?
|
||||
return value >= 0 and <0 seems to be stored at a different location by the game (valid result vs error code?)
|
||||
*/
|
||||
int sceNpAuthCreateStartRequest(u32 paramAddr)
|
||||
{
|
||||
if (!Memory::IsValidAddress(paramAddr))
|
||||
return hleLogError(Log::sceNet, SCE_NP_AUTH_ERROR_INVALID_ARGUMENT, "invalid arg");
|
||||
|
||||
int sceNpAuthCreateStartRequest(u32 paramAddr) {
|
||||
SceNpAuthRequestParameter params = {};
|
||||
int size = Memory::Read_U32(paramAddr);
|
||||
Memory::Memcpy(¶ms, paramAddr, size);
|
||||
if (!ReadVariableSizedStruct(paramAddr, ¶ms)) {
|
||||
return hleLogError(Log::sceNet, SCE_NP_AUTH_ERROR_INVALID_ARGUMENT, "invalid arg");
|
||||
}
|
||||
|
||||
npServiceId = Memory::GetCharPointer(params.serviceIdAddr);
|
||||
|
||||
INFO_LOG(Log::sceNet, "%s - Max Version: %u.%u", __FUNCTION__, params.version.major, params.version.minor);
|
||||
|
||||
+11
-14
@@ -21,18 +21,17 @@
|
||||
#include "Core/MemMap.h"
|
||||
#include "Core/Reporting.h"
|
||||
|
||||
static u32 sceP3daBridgeInit(u32 channelsNum, u32 samplesNum)
|
||||
{
|
||||
ERROR_LOG_REPORT(Log::sceAudio, "UNIMPL sceP3daBridgeInit(%08x, %08x)", channelsNum, samplesNum);
|
||||
static u32 sceP3daBridgeInit(u32 channelsNum, u32 samplesNum) {
|
||||
WARN_LOG(Log::sceAudio, "UNIMPL sceP3daBridgeInit(%08x, %08x)", channelsNum, samplesNum);
|
||||
return hleNoLog(0);
|
||||
}
|
||||
|
||||
static u32 sceP3daBridgeExit()
|
||||
{
|
||||
ERROR_LOG_REPORT(Log::sceAudio, "UNIMPL sceP3daBridgeExit()");
|
||||
static u32 sceP3daBridgeExit() {
|
||||
WARN_LOG(Log::sceAudio, "UNIMPL sceP3daBridgeExit()");
|
||||
return hleNoLog(0);
|
||||
}
|
||||
|
||||
// Isn't this just a log2?
|
||||
static inline int getScaleValue(u32 channelsNum) {
|
||||
int val = 0;
|
||||
while (channelsNum > 1) {
|
||||
@@ -42,14 +41,14 @@ static inline int getScaleValue(u32 channelsNum) {
|
||||
return val;
|
||||
}
|
||||
|
||||
static u32 sceP3daBridgeCore(u32 p3daCoreAddr, u32 channelsNum, u32 samplesNum, u32 inputAddr, u32 outputAddr)
|
||||
{
|
||||
if (Memory::IsValidAddress(inputAddr) && Memory::IsValidAddress(outputAddr)) {
|
||||
// What is this??
|
||||
static u32 sceP3daBridgeCore(u32 p3daCoreAddr, u32 channelsNum, u32 samplesNum, u32 inputAddr, u32 outputAddr) {
|
||||
if (Memory::IsValidRange(inputAddr, channelsNum * 4) && Memory::IsValidRange(outputAddr, samplesNum * sizeof(s16) * 2)) {
|
||||
int scaleval = getScaleValue(channelsNum);
|
||||
s16_le *outbuf = (s16_le *)Memory::GetPointerWriteUnchecked(outputAddr);
|
||||
memset(outbuf, 0, samplesNum * sizeof(s16) * 2);
|
||||
for (u32 k = 0; k < channelsNum; k++) {
|
||||
u32 inaddr = Memory::Read_U32(inputAddr + k * 4);
|
||||
u32 inaddr = Memory::ReadUnchecked_U32(inputAddr + k * 4);
|
||||
const s16 *inbuf = (const s16 *)Memory::GetPointerUnchecked(inaddr);
|
||||
if (!inbuf)
|
||||
continue;
|
||||
@@ -64,14 +63,12 @@ static u32 sceP3daBridgeCore(u32 p3daCoreAddr, u32 channelsNum, u32 samplesNum,
|
||||
return hleDelayResult(hleLogDebug(Log::sceAudio, 0), "p3da core", 240);
|
||||
}
|
||||
|
||||
const HLEFunction sceP3da[] =
|
||||
{
|
||||
const HLEFunction sceP3da[] = {
|
||||
{0X374500A5, &WrapU_UU<sceP3daBridgeInit>, "sceP3daBridgeInit", 'x', "xx" },
|
||||
{0X43F756A2, &WrapU_V<sceP3daBridgeExit>, "sceP3daBridgeExit", 'x', "" },
|
||||
{0X013016F3, &WrapU_UUUUU<sceP3daBridgeCore>, "sceP3daBridgeCore", 'x', "xxxxx"},
|
||||
};
|
||||
|
||||
void Register_sceP3da()
|
||||
{
|
||||
void Register_sceP3da() {
|
||||
RegisterHLEModule("sceP3da", ARRAY_SIZE(sceP3da), sceP3da);
|
||||
}
|
||||
+7
-1
@@ -686,6 +686,12 @@ static u32 __sceSasSetVoiceATRAC3(u32 core, int voiceNum, u32 atrac3Context) {
|
||||
return hleLogWarning(Log::sceSas, SCE_SAS_ERROR_INVALID_VOICE, "invalid voicenum");
|
||||
}
|
||||
|
||||
// Not sure what an appropriate range length check is. It's at least 256 though.
|
||||
if (!Memory::IsValid4AlignedRange(atrac3Context, 256)) {
|
||||
// Untested
|
||||
return hleLogError(Log::sceSas, SCE_SAS_ERROR_INVALID_PARAMETER, "invalid ATRAC3 context address");
|
||||
}
|
||||
|
||||
__SasDrain();
|
||||
SasVoice &v = sas->voices[voiceNum];
|
||||
if (v.type == VOICETYPE_ATRAC3) {
|
||||
@@ -695,7 +701,7 @@ static u32 __sceSasSetVoiceATRAC3(u32 core, int voiceNum, u32 atrac3Context) {
|
||||
v.loop = false;
|
||||
v.playing = true;
|
||||
v.atrac3.SetContext(atrac3Context);
|
||||
Memory::Write_U32(atrac3Context, core + 56 * voiceNum + 20);
|
||||
Memory::WriteUnchecked_U32(atrac3Context, core + 56 * voiceNum + 20);
|
||||
return hleLogDebug(Log::sceSas, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -188,6 +188,7 @@ void VagDecoder::DoState(PointerWrap &p) {
|
||||
Do(p, end_);
|
||||
}
|
||||
|
||||
// The context pointer is assumed to be valid.
|
||||
int SasAtrac3::SetContext(u32 contextAddr) {
|
||||
contextAddr_ = contextAddr;
|
||||
// Note: On hardware, atracID_ is also stored in the loopNum member of the context.
|
||||
|
||||
Reference in new issue
Block a user