More manual Read_U32 cleanup

Buildfix
This commit is contained in:
Henrik Rydgård committed 2026-08-11 10:28:36 +02:00
1 parent af9891cd7d
commit 3c81d6b121
20 files changed
+141 -86

No files matched your search

+1
View File
@@ -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
+1
View File
@@ -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" />
+3
View File
@@ -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" />
+5 -1
View File
@@ -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)");
+18 -18
View File
@@ -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;
}
+6 -5
View File
@@ -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);
+8 -4
View File
@@ -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
View File
@@ -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]) {
+17
View File
@@ -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;
}
+2 -1
View File
@@ -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 {
+24 -23
View File
@@ -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);
+13 -2
View File
@@ -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) {
+4 -4
View File
@@ -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
View File
@@ -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;
}
}
+6 -2
View File
@@ -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) {
+1 -1
View File
@@ -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
View File
@@ -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(&params, paramAddr, size);
if (!ReadVariableSizedStruct(paramAddr, &params)) {
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
View File
@@ -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
View File
@@ -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);
}
+1
View File
@@ -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.