From 867eb995055b532c05185c701c60be3980f883ae Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 3 Sep 2022 07:25:03 -0700 Subject: [PATCH 1/8] PPGe: Cleanup memory writes for clarity. Switch from WriteStruct to PSPPointer as well. --- Core/Util/PPGeDraw.cpp | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 425552a453..2b83bb4ccd 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -178,18 +178,16 @@ static void BeginVertexData() { static void Vertex(float x, float y, float u, float v, int tw, int th, u32 color = 0xFFFFFFFF) { if (g_RemasterMode) { - PPGeRemasterVertex vtx; - vtx.x = x; vtx.y = y; vtx.z = 0; - vtx.u = u * tw; vtx.v = v * th; - vtx.color = color; - Memory::WriteStruct(dataWritePtr, &vtx); + auto vtx = PSPPointer::Create(dataWritePtr); + vtx->x = x; vtx->y = y; vtx->z = 0; + vtx->u = u * tw; vtx->v = v * th; + vtx->color = color; dataWritePtr += sizeof(vtx); } else { - PPGeVertex vtx; - vtx.x = x; vtx.y = y; vtx.z = 0; - vtx.u = u * tw; vtx.v = v * th; - vtx.color = color; - Memory::WriteStruct(dataWritePtr, &vtx); + auto vtx = PSPPointer::Create(dataWritePtr); + vtx->x = x; vtx->y = y; vtx->z = 0; + vtx->u = u * tw; vtx->v = v * th; + vtx->color = color; dataWritePtr += sizeof(vtx); } _dbg_assert_(dataWritePtr <= dataPtr + dataSize); @@ -197,8 +195,11 @@ static void Vertex(float x, float y, float u, float v, int tw, int th, u32 color } static void EndVertexDataAndDraw(int prim) { + _assert_msg_(vertexStart != 0, "Missing matching call to BeginVertexData()"); + NotifyMemInfo(MemBlockFlags::WRITE, vertexStart, dataWritePtr - vertexStart, "PPGe Vertex"); WriteCmdAddrWithBase(GE_CMD_VADDR, vertexStart); WriteCmd(GE_CMD_PRIM, (prim << 16) | vertexCount); + vertexStart = 0; } bool PPGeIsFontTextureAddress(u32 addr) { @@ -272,6 +273,7 @@ void __PPGeInit() { int val = i; palette[i] = (val << 12) | 0xFFF; } + NotifyMemInfo(MemBlockFlags::WRITE, palette.ptr, 16 * sizeof(u16_le), "PPGe Palette"); const u32_le *imagePtr = (u32_le *)imageData[0]; u8 *ramPtr = atlasPtr == 0 ? nullptr : (u8 *)Memory::GetPointer(atlasPtr); @@ -286,7 +288,10 @@ void __PPGeInit() { u8 cval = (a2 << 4) | a1; ramPtr[i] = cval; } - atlasHash = XXH3_64bits(ramPtr, atlasWidth * atlasHeight / 2); + if (atlasPtr != 0) { + atlasHash = XXH3_64bits(ramPtr, atlasSize); + NotifyMemInfo(MemBlockFlags::WRITE, atlasPtr, atlasSize, "PPGe Atlas"); + } free(imageData[0]); @@ -457,6 +462,7 @@ void PPGeEnd() if (dataWritePtr > dataPtr) { // We actually drew something gpu->EnableInterrupts(false); + NotifyMemInfo(MemBlockFlags::WRITE, dlPtr, dlWritePtr - dlPtr, "PPGe ListCmds"); u32 list = sceGeListEnQueue(dlPtr, dlWritePtr, -1, listArgs.ptr); DEBUG_LOG(SCEGE, "PPGe enqueued display list %i", list); gpu->EnableInterrupts(true); From 3a372aa615b7dc27ae2a52396af6bfa875f39348 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 3 Sep 2022 07:48:52 -0700 Subject: [PATCH 2/8] HLE: Remove misc usage of WriteStruct(). Prefer PSPPointer and notifying. --- Core/HLE/sceChnnlsv.cpp | 82 ++++++++++++++++------------------------ Core/HLE/sceOpenPSID.cpp | 14 ++++--- Core/HLE/sceUsbCam.cpp | 33 ++++++++++------ Core/HLE/sceUsbGps.cpp | 16 +++++--- Core/MemMap.cpp | 9 +++++ Core/MemMap.h | 15 +++++++- 6 files changed, 94 insertions(+), 75 deletions(-) diff --git a/Core/HLE/sceChnnlsv.cpp b/Core/HLE/sceChnnlsv.cpp index 82e063b344..fc73837687 100644 --- a/Core/HLE/sceChnnlsv.cpp +++ b/Core/HLE/sceChnnlsv.cpp @@ -214,13 +214,12 @@ static int sub_17A8(u8* data) return -261; } -static int sceSdGetLastIndex(u32 addressCtx, u32 addressHash, u32 addressKey) -{ - pspChnnlsvContext1 ctx; - Memory::ReadStruct(addressCtx, &ctx); - int res = sceSdGetLastIndex_(ctx, Memory::GetPointerWrite(addressHash), Memory::GetPointerWrite(addressKey)); - Memory::WriteStruct(addressCtx, &ctx); - return res; +static int sceSdGetLastIndex(u32 addressCtx, u32 addressHash, u32 addressKey) { + auto ctx = PSPPointer::Create(addressCtx); + u8 *hash = Memory::GetPointerWrite(addressHash); + if (!ctx.IsValid() || !hash) + return hleLogError(SCEMISC, 0, "Invalid pointer"); + return hleLogSuccessI(SCEMISC, sceSdGetLastIndex_(*ctx, hash, Memory::GetPointerWrite(addressKey))); } int sceSdGetLastIndex_(pspChnnlsvContext1& ctx, u8* in_hash, u8* in_key) @@ -325,13 +324,11 @@ int sceSdGetLastIndex_(pspChnnlsvContext1& ctx, u8* in_hash, u8* in_key) return 0; } -static int sceSdSetIndex(u32 addressCtx, int value) -{ - pspChnnlsvContext1 ctx; - Memory::ReadStruct(addressCtx,&ctx); - int res = sceSdSetIndex_(ctx, value); - Memory::WriteStruct(addressCtx,&ctx); - return res; +static int sceSdSetIndex(u32 addressCtx, int value) { + auto ctx = PSPPointer::Create(addressCtx); + if (!ctx.IsValid()) + return hleLogError(SCEMISC, 0, "Invalid pointer"); + return hleLogSuccessI(SCEMISC, sceSdSetIndex_(*ctx, value)); } int sceSdSetIndex_(pspChnnlsvContext1& ctx, int value) @@ -344,14 +341,11 @@ int sceSdSetIndex_(pspChnnlsvContext1& ctx, int value) } -static int sceSdRemoveValue(u32 addressCtx, u32 addressData, int length) -{ - pspChnnlsvContext1 ctx; - Memory::ReadStruct(addressCtx, &ctx); - int res = sceSdRemoveValue_(ctx, Memory::GetPointerWrite(addressData), length); - Memory::WriteStruct(addressCtx, &ctx); - - return res; +static int sceSdRemoveValue(u32 addressCtx, u32 addressData, int length) { + auto ctx = PSPPointer::Create(addressCtx); + if (!ctx.IsValid() || !Memory::IsValidAddress(addressData)) + return hleLogError(SCEMISC, 0, "Invalid pointer"); + return hleLogSuccessI(SCEMISC, sceSdRemoveValue_(*ctx, Memory::GetPointerWrite(addressData), length)); } int sceSdRemoveValue_(pspChnnlsvContext1& ctx, u8* data, int length) @@ -396,18 +390,14 @@ int sceSdRemoveValue_(pspChnnlsvContext1& ctx, u8* data, int length) return 0; } -static int sceSdCreateList(u32 ctx2Addr, int mode, int unkwn, u32 dataAddr, u32 cryptkeyAddr) -{ - pspChnnlsvContext2 ctx2; - Memory::ReadStruct(ctx2Addr, &ctx2); +static int sceSdCreateList(u32 ctx2Addr, int mode, int unkwn, u32 dataAddr, u32 cryptkeyAddr) { + auto ctx2 = PSPPointer::Create(ctx2Addr); u8* data = Memory::GetPointerWrite(dataAddr); u8* cryptkey = Memory::GetPointerWrite(cryptkeyAddr); + if (!ctx2.IsValid() || !data) + return hleLogError(SCEMISC, 0, "Invalid pointer"); - int res = sceSdCreateList_(ctx2, mode, unkwn, data, cryptkey); - - Memory::WriteStruct(ctx2Addr, &ctx2); - - return res; + return hleLogSuccessI(SCEMISC, sceSdCreateList_(*ctx2, mode, unkwn, data, cryptkey)); } int sceSdCreateList_(pspChnnlsvContext2& ctx2, int mode, int uknw, u8* data, u8* cryptkey) @@ -464,17 +454,13 @@ int sceSdCreateList_(pspChnnlsvContext2& ctx2, int mode, int uknw, u8* data, u8* return 0; } -static int sceSdSetMember(u32 ctxAddr, u32 dataAddr, int alignedLen) -{ - pspChnnlsvContext2 ctx; - Memory::ReadStruct(ctxAddr, &ctx); - u8* data = Memory::GetPointerWrite(dataAddr); +static int sceSdSetMember(u32 ctxAddr, u32 dataAddr, int alignedLen) { + auto ctx = PSPPointer::Create(ctxAddr); + u8 *data = Memory::GetPointerWrite(dataAddr); + if (!ctx.IsValid() || !data) + return hleLogError(SCEMISC, 0, "Invalid pointer"); - int res = sceSdSetMember_(ctx, data, alignedLen); - - Memory::WriteStruct(ctxAddr, &ctx); - - return res; + return hleLogSuccessI(SCEMISC, sceSdSetMember_(*ctx, data, alignedLen)); } int sceSdSetMember_(pspChnnlsvContext2& ctx, u8* data, int alignedLen) @@ -511,15 +497,11 @@ int sceSdSetMember_(pspChnnlsvContext2& ctx, u8* data, int alignedLen) return res; } -static int sceChnnlsv_21BE78B4(u32 ctxAddr) -{ - pspChnnlsvContext2 ctx; - Memory::ReadStruct(ctxAddr, &ctx); - - int res = sceChnnlsv_21BE78B4_(ctx); - - Memory::WriteStruct(ctxAddr, &ctx); - return res; +static int sceChnnlsv_21BE78B4(u32 ctxAddr) { + auto ctx = PSPPointer::Create(ctxAddr); + if (!ctx.IsValid()) + return hleLogError(SCEMISC, 0, "Invalid pointer"); + return hleLogSuccessI(SCEMISC, sceChnnlsv_21BE78B4_(*ctx)); } int sceChnnlsv_21BE78B4_(pspChnnlsvContext2& ctx) diff --git a/Core/HLE/sceOpenPSID.cpp b/Core/HLE/sceOpenPSID.cpp index 43665f530f..9d47b48374 100644 --- a/Core/HLE/sceOpenPSID.cpp +++ b/Core/HLE/sceOpenPSID.cpp @@ -38,9 +38,10 @@ static int sceOpenPSIDGetOpenPSID(u32 OpenPSIDPtr) { WARN_LOG(HLE, "UNTESTED %s(%08x)", __FUNCTION__, OpenPSIDPtr); - if (Memory::IsValidAddress(OpenPSIDPtr)) - { - Memory::WriteStruct(OpenPSIDPtr, &dummyOpenPSID); + auto ptr = PSPPointer::Create(OpenPSIDPtr); + if (ptr.IsValid()) { + *ptr = dummyOpenPSID; + ptr.NotifyWrite("OpenPSIDGetOpenPSID"); } return 0; } @@ -49,9 +50,10 @@ static int sceOpenPSIDGetPSID(u32 OpenPSIDPtr,u32 unknown) { WARN_LOG(HLE, "UNTESTED %s(%08x, %08x)", __FUNCTION__, OpenPSIDPtr, unknown); - if (Memory::IsValidAddress(OpenPSIDPtr)) - { - Memory::WriteStruct(OpenPSIDPtr, &dummyOpenPSID); + auto ptr = PSPPointer::Create(OpenPSIDPtr); + if (ptr.IsValid()) { + *ptr = dummyOpenPSID; + ptr.NotifyWrite("OpenPSIDGetPSID"); } return 0; } diff --git a/Core/HLE/sceUsbCam.cpp b/Core/HLE/sceUsbCam.cpp index 18417bb9c2..c8d43a5027 100644 --- a/Core/HLE/sceUsbCam.cpp +++ b/Core/HLE/sceUsbCam.cpp @@ -113,11 +113,12 @@ static int getCameraResolution(Camera::ConfigType type, int *width, int *height) static int sceUsbCamSetupMic(u32 paramAddr, u32 workareaAddr, int wasize) { - INFO_LOG(HLE, "sceUsbCamSetupMic"); - if (Memory::IsValidRange(paramAddr, sizeof(PspUsbCamSetupMicParam))) { - Memory::ReadStruct(paramAddr, &config->micParam); + auto param = PSPPointer::Create(paramAddr); + if (param.IsValid()) { + config->micParam = *param; + param.NotifyRead("UsbCamSetupMic"); } - return 0; + return hleLogSuccessInfoI(SCEMISC, 0); } static int sceUsbCamStartMic() { @@ -155,16 +156,20 @@ static int sceUsbCamGetMicDataLength() { } static int sceUsbCamSetupVideo(u32 paramAddr, u32 workareaAddr, int wasize) { - if (Memory::IsValidRange(paramAddr, sizeof(PspUsbCamSetupVideoParam))) { - Memory::ReadStruct(paramAddr, &config->videoParam); + auto param = PSPPointer::Create(paramAddr); + if (param.IsValid()) { + config->videoParam = *param; + param.NotifyRead("UsbCamSetupVideo"); } config->type = Camera::ConfigType::CfVideo; return 0; } static int sceUsbCamSetupVideoEx(u32 paramAddr, u32 workareaAddr, int wasize) { - if (Memory::IsValidRange(paramAddr, sizeof(PspUsbCamSetupVideoExParam))) { - Memory::ReadStruct(paramAddr, &config->videoExParam); + auto param = PSPPointer::Create(paramAddr); + if (param.IsValid()) { + config->videoExParam = *param; + param.NotifyRead("UsbCamSetupVideoEx"); } config->type = Camera::ConfigType::CfVideoEx; return 0; @@ -222,8 +227,10 @@ static int sceUsbCamPollReadVideoFrameEnd() { static int sceUsbCamSetupStill(u32 paramAddr) { INFO_LOG(HLE, "UNIMPL sceUsbCamSetupStill"); - if (Memory::IsValidRange(paramAddr, sizeof(PspUsbCamSetupStillParam))) { - Memory::ReadStruct(paramAddr, &config->stillParam); + auto param = PSPPointer::Create(paramAddr); + if (param.IsValid()) { + config->stillParam = *param; + param.NotifyRead("UsbCamSetupStill"); } config->type = Camera::ConfigType::CfStill; return 0; @@ -231,8 +238,10 @@ static int sceUsbCamSetupStill(u32 paramAddr) { static int sceUsbCamSetupStillEx(u32 paramAddr) { INFO_LOG(HLE, "UNIMPL sceUsbCamSetupStillEx"); - if (Memory::IsValidRange(paramAddr, sizeof(PspUsbCamSetupStillExParam))) { - Memory::ReadStruct(paramAddr, &config->stillExParam); + auto param = PSPPointer::Create(paramAddr); + if (param.IsValid()) { + config->stillExParam = *param; + param.NotifyRead("UsbCamSetupStillEx"); } config->type = Camera::ConfigType::CfStillEx; return 0; diff --git a/Core/HLE/sceUsbGps.cpp b/Core/HLE/sceUsbGps.cpp index 2c9f320044..020339fe10 100644 --- a/Core/HLE/sceUsbGps.cpp +++ b/Core/HLE/sceUsbGps.cpp @@ -59,8 +59,8 @@ static int sceUsbGpsGetInitDataLocation(u32 addr) { } static int sceUsbGpsGetState(u32 stateAddr) { - if (Memory::IsValidAddress(stateAddr)) { - Memory::Write_U32(gpsStatus, stateAddr); + if (Memory::IsValidRange(stateAddr, 4)) { + Memory::WriteUnchecked_U32(gpsStatus, stateAddr); } return 0; } @@ -81,11 +81,15 @@ static int sceUsbGpsClose() { } static int sceUsbGpsGetData(u32 gpsDataAddr, u32 satDataAddr) { - if (Memory::IsValidRange(gpsDataAddr, sizeof(GpsData))) { - Memory::WriteStruct(gpsDataAddr, GPS::getGpsData()); + auto gpsData = PSPPointer::Create(gpsDataAddr); + if (gpsData.IsValid()) { + *gpsData = *GPS::getGpsData(); + gpsData.NotifyWrite("UsbGpsGetData"); } - if (Memory::IsValidRange(satDataAddr, sizeof(SatData))) { - Memory::WriteStruct(satDataAddr, GPS::getSatData()); + auto satData = PSPPointer::Create(satDataAddr); + if (satData.IsValid()) { + *satData = *GPS::getSatData(); + gpsData.NotifyWrite("UsbGpsGetData"); } return 0; } diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 1a0fd654f6..52ef9ff5f9 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -490,3 +490,12 @@ void Memset(const u32 _Address, const u8 _iValue, const u32 _iLength, const char } } // namespace + +void PSPPointerNotifyRW(int rw, uint32_t ptr, uint32_t bytes, const char * tag, size_t tagLen) { + if (MemBlockInfoDetailed(bytes)) { + if (rw & 1) + NotifyMemInfo(MemBlockFlags::WRITE, ptr, bytes, tag, tagLen); + if (rw & 2) + NotifyMemInfo(MemBlockFlags::READ, ptr, bytes, tag, tagLen); + } +} diff --git a/Core/MemMap.h b/Core/MemMap.h index 97b7fd76e7..306190f249 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -328,6 +328,9 @@ inline bool IsValidRange(const u32 address, const u32 size) { } // namespace Memory +// Avoiding a global include for NotifyMemInfo. +void PSPPointerNotifyRW(int rw, uint32_t ptr, uint32_t bytes, const char *tag, size_t tagLen); + template struct PSPPointer { @@ -440,7 +443,17 @@ struct PSPPointer bool IsValid() const { - return Memory::IsValidAddress(ptr); + return Memory::IsValidRange(ptr, (u32)sizeof(T)); + } + + template + void NotifyWrite(const char(&tag)[tagLen]) const { + PSPPointerNotifyRW(1, (uint32_t)ptr, (uint32_t)sizeof(T), tag, tagLen - 1); + } + + template + void NotifyRead(const char(&tag)[tagLen]) const { + PSPPointerNotifyRW(2, (uint32_t)ptr, (uint32_t)sizeof(T), tag, tagLen - 1); } static PSPPointer Create(u32 ptr) { From 8f96405ee51a412fb58fb21091cf9e4b1d7ef0b1 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 3 Sep 2022 08:38:34 -0700 Subject: [PATCH 3/8] Net: Remove usage of Memory::WriteStruct(). This also validates pointer write size better. --- Core/HLE/sceNet.cpp | 126 +++++++++++++++++++++++++++------------ Core/HLE/sceNetAdhoc.cpp | 52 +++++++--------- Core/HLE/sceNp.cpp | 82 +++++++++++++------------ Core/HLE/sceNp2.cpp | 6 +- 4 files changed, 159 insertions(+), 107 deletions(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index ff2cb8ed7e..c2a8987408 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -785,11 +785,12 @@ static void sceNetEtherStrton(u32 bufferPtr, u32 macPtr) { // Write static data since we don't actually manage any memory for sceNet* yet. static int sceNetGetMallocStat(u32 statPtr) { VERBOSE_LOG(SCENET, "UNTESTED sceNetGetMallocStat(%x) at %08x", statPtr, currentMIPS->pc); - if(Memory::IsValidAddress(statPtr)) - Memory::WriteStruct(statPtr, &netMallocStat); - else - ERROR_LOG(SCENET, "UNTESTED sceNetGetMallocStat(%x): tried to request invalid address!", statPtr); + auto stat = PSPPointer::Create(statPtr); + if (!stat.IsValid()) + return hleLogError(SCENET, 0, "invalid address"); + *stat = netMallocStat; + stat.NotifyWrite("sceNetGetMallocStat"); return 0; } @@ -893,77 +894,128 @@ static int sceNetApctlGetInfo(int code, u32 pInfoAddr) { if (!netApctlInited) return hleLogError(SCENET, ERROR_NET_APCTL_NOT_IN_BSS, "apctl not in bss"); // Only have valid info after joining an AP and got an IP, right? - if (!Memory::IsValidAddress(pInfoAddr)) - return hleLogError(SCENET, -1, "apctl invalid arg"); - - u8* info = Memory::GetPointerWrite(pInfoAddr); // FIXME: Points to a union instead of a struct thus each field have the same address - switch (code) { case PSP_NET_APCTL_INFO_PROFILE_NAME: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.name); + if (!Memory::IsValidRange(pInfoAddr, APCTL_PROFILENAME_MAXLEN)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.name, APCTL_PROFILENAME_MAXLEN); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, APCTL_PROFILENAME_MAXLEN, "NetApctlGetInfo"); DEBUG_LOG(SCENET, "ApctlInfo - ProfileName: %s", netApctlInfo.name); break; case PSP_NET_APCTL_INFO_BSSID: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.bssid); + if (!Memory::IsValidRange(pInfoAddr, ETHER_ADDR_LEN)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.bssid, ETHER_ADDR_LEN); DEBUG_LOG(SCENET, "ApctlInfo - BSSID: %s", mac2str((SceNetEtherAddr*)&netApctlInfo.bssid).c_str()); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, ETHER_ADDR_LEN, "NetApctlGetInfo"); break; case PSP_NET_APCTL_INFO_SSID: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.ssid); + if (!Memory::IsValidRange(pInfoAddr, APCTL_SSID_MAXLEN)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.ssid, APCTL_SSID_MAXLEN); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, APCTL_SSID_MAXLEN, "NetApctlGetInfo"); DEBUG_LOG(SCENET, "ApctlInfo - SSID: %s", netApctlInfo.ssid); break; case PSP_NET_APCTL_INFO_SSID_LENGTH: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.ssidLength); + if (!Memory::IsValidRange(pInfoAddr, 4)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::WriteUnchecked_U32(netApctlInfo.ssidLength, pInfoAddr); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 4, "NetApctlGetInfo"); break; case PSP_NET_APCTL_INFO_SECURITY_TYPE: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.securityType); + if (!Memory::IsValidRange(pInfoAddr, 4)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::WriteUnchecked_U32(netApctlInfo.securityType, pInfoAddr); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 4, "NetApctlGetInfo"); break; case PSP_NET_APCTL_INFO_STRENGTH: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.strength); + if (!Memory::IsValidRange(pInfoAddr, 1)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::WriteUnchecked_U8(netApctlInfo.strength, pInfoAddr); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 1, "NetApctlGetInfo"); break; case PSP_NET_APCTL_INFO_CHANNEL: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.channel); + if (!Memory::IsValidRange(pInfoAddr, 1)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::WriteUnchecked_U8(netApctlInfo.channel, pInfoAddr); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 1, "NetApctlGetInfo"); break; case PSP_NET_APCTL_INFO_POWER_SAVE: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.powerSave); + if (!Memory::IsValidRange(pInfoAddr, 1)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::WriteUnchecked_U8(netApctlInfo.powerSave, pInfoAddr); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 1, "NetApctlGetInfo"); break; case PSP_NET_APCTL_INFO_IP: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.ip); + if (!Memory::IsValidRange(pInfoAddr, APCTL_IPADDR_MAXLEN)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.ip, APCTL_IPADDR_MAXLEN); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, APCTL_IPADDR_MAXLEN, "NetApctlGetInfo"); DEBUG_LOG(SCENET, "ApctlInfo - IP: %s", netApctlInfo.ip); break; case PSP_NET_APCTL_INFO_SUBNETMASK: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.subNetMask); + if (!Memory::IsValidRange(pInfoAddr, APCTL_IPADDR_MAXLEN)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.subNetMask, APCTL_IPADDR_MAXLEN); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, APCTL_IPADDR_MAXLEN, "NetApctlGetInfo"); DEBUG_LOG(SCENET, "ApctlInfo - SubNet Mask: %s", netApctlInfo.subNetMask); break; case PSP_NET_APCTL_INFO_GATEWAY: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.gateway); + if (!Memory::IsValidRange(pInfoAddr, APCTL_IPADDR_MAXLEN)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.gateway, APCTL_IPADDR_MAXLEN); DEBUG_LOG(SCENET, "ApctlInfo - Gateway IP: %s", netApctlInfo.gateway); break; case PSP_NET_APCTL_INFO_PRIMDNS: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.primaryDns); + if (!Memory::IsValidRange(pInfoAddr, APCTL_IPADDR_MAXLEN)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.primaryDns, APCTL_IPADDR_MAXLEN); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, APCTL_IPADDR_MAXLEN, "NetApctlGetInfo"); DEBUG_LOG(SCENET, "ApctlInfo - Primary DNS: %s", netApctlInfo.primaryDns); break; case PSP_NET_APCTL_INFO_SECDNS: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.secondaryDns); + if (!Memory::IsValidRange(pInfoAddr, APCTL_IPADDR_MAXLEN)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.secondaryDns, APCTL_IPADDR_MAXLEN); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, APCTL_IPADDR_MAXLEN, "NetApctlGetInfo"); DEBUG_LOG(SCENET, "ApctlInfo - Secondary DNS: %s", netApctlInfo.secondaryDns); break; case PSP_NET_APCTL_INFO_USE_PROXY: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.useProxy); + if (!Memory::IsValidRange(pInfoAddr, 4)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::WriteUnchecked_U32(netApctlInfo.useProxy, pInfoAddr); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 4, "NetApctlGetInfo"); break; case PSP_NET_APCTL_INFO_PROXY_URL: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.proxyUrl); + if (!Memory::IsValidRange(pInfoAddr, APCTL_URL_MAXLEN)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::MemcpyUnchecked(pInfoAddr, netApctlInfo.proxyUrl, APCTL_URL_MAXLEN); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, APCTL_URL_MAXLEN, "NetApctlGetInfo"); DEBUG_LOG(SCENET, "ApctlInfo - Proxy URL: %s", netApctlInfo.proxyUrl); break; case PSP_NET_APCTL_INFO_PROXY_PORT: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.proxyPort); + if (!Memory::IsValidRange(pInfoAddr, 2)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::WriteUnchecked_U16(netApctlInfo.proxyPort, pInfoAddr); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 2, "NetApctlGetInfo"); break; case PSP_NET_APCTL_INFO_8021_EAP_TYPE: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.eapType); + if (!Memory::IsValidRange(pInfoAddr, 4)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::WriteUnchecked_U32(netApctlInfo.eapType, pInfoAddr); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 4, "NetApctlGetInfo"); break; case PSP_NET_APCTL_INFO_START_BROWSER: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.startBrowser); + if (!Memory::IsValidRange(pInfoAddr, 4)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::WriteUnchecked_U32(netApctlInfo.startBrowser, pInfoAddr); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 4, "NetApctlGetInfo"); break; case PSP_NET_APCTL_INFO_WIFISP: - Memory::WriteStruct(pInfoAddr, &netApctlInfo.wifisp); + if (!Memory::IsValidRange(pInfoAddr, 4)) + return hleLogError(SCENET, -1, "apctl invalid arg"); + Memory::WriteUnchecked_U32(netApctlInfo.wifisp, pInfoAddr); + NotifyMemInfo(MemBlockFlags::WRITE, pInfoAddr, 4, "NetApctlGetInfo"); break; default: return hleLogError(SCENET, ERROR_NET_APCTL_INVALID_CODE, "apctl invalid code"); @@ -1234,28 +1286,28 @@ int NetApctl_GetBSSDescEntryUser(int entryId, int infoId, u32 resultAddr) { switch (infoId) { case PSP_NET_APCTL_DESC_IBSS: // IBSS, 6 bytes if (entryId == 0) - Memory::WriteStruct(resultAddr, &netApctlInfo.bssid); + Memory::Memcpy(resultAddr, netApctlInfo.bssid, sizeof(netApctlInfo.bssid), "GetBSSDescEntryUser"); else { // Generate a BSSID/MAC address char dummyMAC[ETHER_ADDR_LEN]; memset(dummyMAC, entryId, sizeof(dummyMAC)); // Making sure the 1st 2-bits on the 1st byte of OUI are zero to prevent issue with some games (ie. Gran Turismo) dummyMAC[0] &= 0xfc; - Memory::WriteStruct(resultAddr, &dummyMAC); + Memory::Memcpy(resultAddr, dummyMAC, sizeof(dummyMAC), "GetBSSDescEntryUser"); } break; case PSP_NET_APCTL_DESC_SSID_NAME: // Return 32 bytes if (entryId == 0) - Memory::WriteStruct(resultAddr, &netApctlInfo.ssid); + Memory::Memcpy(resultAddr, netApctlInfo.ssid, sizeof(netApctlInfo.ssid), "GetBSSDescEntryUser"); else { - Memory::WriteStruct(resultAddr, &dummySSID); + Memory::Memcpy(resultAddr, dummySSID, sizeof(dummySSID), "GetBSSDescEntryUser"); } break; case PSP_NET_APCTL_DESC_SSID_NAME_LENGTH: // Return one 32-bit value if (entryId == 0) - Memory::WriteStruct(resultAddr, &netApctlInfo.ssidLength); + Memory::Write_U32(netApctlInfo.ssidLength, resultAddr); else { // Calculate the SSID length Memory::Write_U32((u32)strlen(dummySSID), resultAddr); @@ -1264,7 +1316,7 @@ int NetApctl_GetBSSDescEntryUser(int entryId, int infoId, u32 resultAddr) { case PSP_NET_APCTL_DESC_CHANNEL: // FIXME: Return one 1 byte value or may be 32-bit if this is not a channel? if (entryId == 0) - Memory::WriteStruct(resultAddr, &netApctlInfo.channel); + Memory::Write_U8(netApctlInfo.channel, resultAddr); else { // Generate channel for testing purposes, not even sure whether this is channel or not, MGS:PW seems to treat the data as u8 Memory::Write_U8(entryId, resultAddr); @@ -1273,7 +1325,7 @@ int NetApctl_GetBSSDescEntryUser(int entryId, int infoId, u32 resultAddr) { case PSP_NET_APCTL_DESC_SIGNAL_STRENGTH: // Return 1 byte if (entryId == 0) - Memory::WriteStruct(resultAddr, &netApctlInfo.strength); + Memory::Write_U8(netApctlInfo.strength, resultAddr); else { // Randomize signal strength between 1%~99% since games like MGS:PW are using signal strength to determine the strength of the recruit Memory::Write_U8((int)(((float)rand() / (float)RAND_MAX) * 99.0 + 1.0), resultAddr); @@ -1281,7 +1333,7 @@ int NetApctl_GetBSSDescEntryUser(int entryId, int infoId, u32 resultAddr) { break; case PSP_NET_APCTL_DESC_SECURITY: // Return one 32-bit value - Memory::WriteStruct(resultAddr, &netApctlInfo.securityType); + Memory::Write_U32(netApctlInfo.securityType, resultAddr); break; default: return hleLogError(SCENET, ERROR_NET_APCTL_INVALID_CODE, "unknown info id"); @@ -1432,7 +1484,7 @@ const HLEFunction sceNet[] = { {0XD27961C9, &WrapV_UU, "sceNetEtherStrton", 'v', "xx" }, {0X0BF0A3AE, &WrapU_U, "sceNetGetLocalEtherAddr", 'x', "x" }, {0X50647530, &WrapI_I, "sceNetFreeThreadinfo", 'i', "i" }, - {0XCC393E48, &WrapI_U, "sceNetGetMallocStat", 'i', "x" }, + {0XCC393E48, &WrapI_U, "sceNetGetMallocStat", 'i', "p" }, {0XAD6844C6, &WrapI_I, "sceNetThreadAbort", 'i', "i" }, }; diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index ec3cced95e..5e5da07fd1 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -1303,8 +1303,10 @@ static u32 sceNetAdhocctlInit(int stackSize, int prio, u32 productAddr) { if (netAdhocctlInited) return ERROR_NET_ADHOCCTL_ALREADY_INITIALIZED; - if (Memory::IsValidAddress(productAddr)) { - Memory::ReadStruct(productAddr, &product_code); + auto product = PSPPointer::Create(productAddr); + if (product.IsValid()) { + product_code = *product; + product.NotifyRead("NetAdhocctlInit"); } adhocctlEvents.clear(); @@ -1539,21 +1541,17 @@ static int sceNetAdhocctlGetParameter(u32 paramAddr) { } // Library initialized - if (netAdhocctlInited) { - // Valid Arguments - if (Memory::IsValidAddress(paramAddr)) { - // Copy Parameter - Memory::WriteStruct(paramAddr,¶meter); - // Return Success - return 0; - } - - // Invalid Arguments - return ERROR_NET_ADHOCCTL_INVALID_ARG; + if (!netAdhocctlInited) { + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_NOT_INITIALIZED); } - // Library uninitialized - return ERROR_NET_ADHOCCTL_NOT_INITIALIZED; + auto ptr = PSPPointer::Create(paramAddr); + if (!ptr.IsValid()) + return hleLogError(SCENET, ERROR_NET_ADHOCCTL_INVALID_ARG); + + *ptr = parameter; + ptr.NotifyWrite("NetAdhocctlGetParameter"); + return 0; } /** @@ -2258,25 +2256,17 @@ static int sceNetAdhocPdpDelete(int id, int unknown) { static int sceNetAdhocctlGetAdhocId(u32 productStructAddr) { INFO_LOG(SCENET, "sceNetAdhocctlGetAdhocId(%08x) at %08x", productStructAddr, currentMIPS->pc); - // Library initialized - if (netAdhocctlInited) - { - // Valid Arguments - if (Memory::IsValidAddress(productStructAddr)) - { - // Copy Product ID - Memory::WriteStruct(productStructAddr, &product_code); + if (!netAdhocctlInited) + return hleLogDebug(SCENET, ERROR_NET_ADHOCCTL_NOT_INITIALIZED, "not initialized"); - // Return Success - return hleLogDebug(SCENET, 0, "type = %d, code = %s", product_code.type, product_code.data); - } - - // Invalid Arguments + auto productStruct = PSPPointer::Create(productStructAddr); + if (!productStruct.IsValid()) return hleLogDebug(SCENET, ERROR_NET_ADHOCCTL_INVALID_ARG, "invalid arg"); - } - // Library uninitialized - return hleLogDebug(SCENET, ERROR_NET_ADHOCCTL_NOT_INITIALIZED, "not initialized"); + *productStruct = product_code; + productStruct.NotifyWrite("NetAdhocctlGetAdhocId"); + + return hleLogDebug(SCENET, 0, "type = %d, code = %s", product_code.type, product_code.data); } // FIXME: Scan probably not a blocking function since there is ADHOCCTL_STATE_SCANNING state that can be polled by the game, right? But apparently it need to be delayed for Naruto Shippuden Ultimate Ninja Heroes 3 diff --git a/Core/HLE/sceNp.cpp b/Core/HLE/sceNp.cpp index 50bb3f317b..c5ca4be4c6 100644 --- a/Core/HLE/sceNp.cpp +++ b/Core/HLE/sceNp.cpp @@ -154,15 +154,15 @@ static int sceNpGetOnlineId(u32 idPtr) { WARN_LOG(SCENET, "UNTESTED %s(%08x)", __FUNCTION__, idPtr); - if (!Memory::IsValidAddress(idPtr)) + auto id = PSPPointer::Create(idPtr); + if (!id.IsValid()) return hleLogError(SCENET, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg"); - SceNpOnlineId dummyOnlineId{}; - truncate_cpy(dummyOnlineId.data, sizeof(dummyOnlineId.data), npOnlineId.c_str()); + memset((SceNpOnlineId *)id, 0, sizeof(SceNpOnlineId)); + truncate_cpy(id->data, sizeof(id->data), npOnlineId.c_str()); + id.NotifyWrite("NpGetOnlineId"); - INFO_LOG(SCENET, "%s - Online ID: %s", __FUNCTION__, dummyOnlineId.data); - - Memory::WriteStruct(idPtr, &dummyOnlineId); + INFO_LOG(SCENET, "%s - Online ID: %s", __FUNCTION__, id->data); return 0; } @@ -177,20 +177,21 @@ static int sceNpGetNpId(u32 idPtr) { WARN_LOG(SCENET, "UNTESTED %s(%08x)", __FUNCTION__, idPtr); - if (!Memory::IsValidAddress(idPtr)) + auto id = PSPPointer::Create(idPtr); + if (!id.IsValid()) return hleLogError(SCENET, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg"); SceNpId dummyNpId{}; - int retval = NpGetNpId(&dummyNpId); + memset((SceNpId *)id, 0, sizeof(SceNpId)); + int retval = NpGetNpId(id); if (retval < 0) return hleLogError(SCENET, retval); - INFO_LOG(SCENET, "%s - Online ID: %s", __FUNCTION__, dummyNpId.handle.data); + INFO_LOG(SCENET, "%s - Online ID: %s", __FUNCTION__, id->handle.data); std::string datahex; - DataToHexString(dummyNpId.opt, sizeof(dummyNpId.opt), &datahex); + DataToHexString(id->opt, sizeof(id->opt), &datahex); INFO_LOG(SCENET, "%s - Options?: %s", __FUNCTION__, datahex.c_str()); - - Memory::WriteStruct(idPtr, &dummyNpId); + id.NotifyWrite("NpGetNpId"); return 0; } @@ -199,19 +200,21 @@ static int sceNpGetAccountRegion(u32 countryCodePtr, u32 regionCodePtr) { WARN_LOG(SCENET, "UNTESTED %s(%08x, %08x)", __FUNCTION__, countryCodePtr, regionCodePtr); - if (!Memory::IsValidAddress(countryCodePtr) || !Memory::IsValidAddress(regionCodePtr)) + auto countryCode = PSPPointer::Create(countryCodePtr); + auto regionCode = PSPPointer::Create(regionCodePtr); + if (!countryCode.IsValid() || !regionCode.IsValid()) return hleLogError(SCENET, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg"); - SceNpCountryCode dummyCountryCode{}; - memcpy(dummyCountryCode.data, npCountryCode, sizeof(dummyCountryCode.data)); - SceNpCountryCode dummyRegionCode{}; - memcpy(dummyRegionCode.data, npRegionCode, sizeof(dummyRegionCode.data)); + memset((SceNpCountryCode *)countryCode, 0, sizeof(SceNpCountryCode)); + memcpy(countryCode->data, npCountryCode, sizeof(countryCode->data)); + memset((SceNpCountryCode *)regionCode, 0, sizeof(SceNpCountryCode)); + memcpy(regionCode->data, npRegionCode, sizeof(regionCode->data)); - INFO_LOG(SCENET, "%s - Country Code: %s", __FUNCTION__, dummyCountryCode.data); - INFO_LOG(SCENET, "%s - Region? Code: %s", __FUNCTION__, dummyRegionCode.data); + INFO_LOG(SCENET, "%s - Country Code: %s", __FUNCTION__, countryCode->data); + INFO_LOG(SCENET, "%s - Region? Code: %s", __FUNCTION__, regionCode->data); - Memory::WriteStruct(countryCodePtr, &dummyCountryCode); - Memory::WriteStruct(regionCodePtr, &dummyRegionCode); + countryCode.NotifyWrite("NpGetAccountRegion"); + regionCode.NotifyWrite("NpGetAccountRegion"); return 0; } @@ -220,14 +223,16 @@ static int sceNpGetMyLanguages(u32 langListPtr) { WARN_LOG(SCENET, "UNTESTED %s(%08x)", __FUNCTION__, langListPtr); - if (!Memory::IsValidAddress(langListPtr)) + auto langList = PSPPointer::Create(langListPtr); + if (!langList.IsValid()) return hleLogError(SCENET, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg"); INFO_LOG(SCENET, "%s - Language1 Code: %d", __FUNCTION__, npMyLangList.language1); INFO_LOG(SCENET, "%s - Language2 Code: %d", __FUNCTION__, npMyLangList.language2); INFO_LOG(SCENET, "%s - Language3 Code: %d", __FUNCTION__, npMyLangList.language3); - Memory::WriteStruct(langListPtr, &npMyLangList); + *langList = npMyLangList; + langList.NotifyWrite("NpGetMyLanguages"); return 0; } @@ -236,20 +241,21 @@ static int sceNpGetUserProfile(u32 profilePtr) { WARN_LOG(SCENET, "UNTESTED %s(%08x)", __FUNCTION__, profilePtr); + auto profile = PSPPointer::Create(profilePtr); if (!Memory::IsValidAddress(profilePtr)) return hleLogError(SCENET, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg"); - SceNpUserInformation dummyProfile{}; - truncate_cpy(dummyProfile.userId.handle.data, sizeof(dummyProfile.userId.handle.data), npOnlineId.c_str()); - truncate_cpy(dummyProfile.icon.data, sizeof(dummyProfile.icon.data), npAvatarUrl.c_str()); + memset((SceNpUserInformation *)profile, 0, sizeof(SceNpUserInformation)); + truncate_cpy(profile->userId.handle.data, sizeof(profile->userId.handle.data), npOnlineId.c_str()); + truncate_cpy(profile->icon.data, sizeof(profile->icon.data), npAvatarUrl.c_str()); - INFO_LOG(SCENET, "%s - Online ID: %s", __FUNCTION__, dummyProfile.userId.handle.data); + INFO_LOG(SCENET, "%s - Online ID: %s", __FUNCTION__, profile->userId.handle.data); std::string datahex; - DataToHexString(dummyProfile.userId.opt, sizeof(dummyProfile.userId.opt), &datahex); + DataToHexString(profile->userId.opt, sizeof(profile->userId.opt), &datahex); INFO_LOG(SCENET, "%s - Options?: %s", __FUNCTION__, datahex.c_str()); - INFO_LOG(SCENET, "%s - Avatar URL: %s", __FUNCTION__, dummyProfile.icon.data); + INFO_LOG(SCENET, "%s - Avatar URL: %s", __FUNCTION__, profile->icon.data); - Memory::WriteStruct(profilePtr, &dummyProfile); + profile.NotifyWrite("NpGetUserProfile"); return 0; } @@ -295,10 +301,12 @@ int sceNpAuthGetMemoryStat(u32 memStatAddr) { ERROR_LOG(SCENET, "UNIMPL %s(%08x)", __FUNCTION__, memStatAddr); - if (!Memory::IsValidAddress(memStatAddr)) + auto memStat = PSPPointer::Create(memStatAddr); + if (!memStat.IsValid()) return hleLogError(SCENET, SCE_NP_AUTH_ERROR_INVALID_ARGUMENT, "invalid arg"); - Memory::WriteStruct(memStatAddr, &npAuthMemStat); + *memStat = npAuthMemStat; + memStat.NotifyWrite("NpAuthGetMemoryStat"); return 0; } @@ -386,7 +394,7 @@ int sceNpAuthGetTicket(u32 requestId, u32 bufferAddr, u32 length) return hleLogError(SCENET, SCE_NP_AUTH_ERROR_INVALID_ARGUMENT, "invalid arg"); int result = length; - Memory::Memset(bufferAddr, 0, length); + Memory::Memset(bufferAddr, 0, length, "NpAuthGetTicket"); SceNpTicket ticket = {}; // Dummy Login ticket returned as Login response. Dummy ticket contents were taken from https://www.psdevwiki.com/ps3/X-I-5-Ticket ticket.header.version = TICKET_VER_2_1; @@ -415,14 +423,14 @@ int sceNpAuthGetTicket(u32 requestId, u32 bufferAddr, u32 length) ofs += writeTicketParam(buf + ofs, PARAM_TYPE_NULL); ticket.section.type = SECTION_TYPE_BODY; ticket.section.size = ofs; - Memory::WriteStruct(bufferAddr, &ticket); + Memory::Memcpy(bufferAddr, &ticket, sizeof(SceNpTicket), "NpAuthGetTicket"); SceNpTicketSection footer = { SECTION_TYPE_FOOTER, 32 }; // footer section? ie. 32-bytes on version 2.1 containing 4-chars ASCII + 20-chars ASCII - Memory::WriteStruct(bufferAddr + sizeof(ticket) + ofs, &footer); + Memory::Memcpy(bufferAddr + sizeof(ticket) + ofs, &footer, sizeof(SceNpTicketSection), "NpAuthGetTicket"); ofs += sizeof(footer); ofs += writeTicketParam(buf + ofs, PARAM_TYPE_STRING_ASCII, "\x34\xcd\x3c\xa9", 4); ofs += writeTicketParam(buf + ofs, PARAM_TYPE_STRING_ASCII, "\x3a\x4b\x42\x66\x92\xda\x6b\x7c\xb7\x4c\xe8\xd9\x4f\x2b\x77\x15\x91\xb8\xa4\xa9", 20); // 20 random letters, token key or SceNpSignature? - u8 unknownBytes[36] = {}; // includes Language list? - Memory::WriteStruct(bufferAddr + sizeof(ticket) + ofs, unknownBytes); + // includes Language list? + Memory::Memset(bufferAddr + sizeof(ticket) + ofs, 0, 36); result = ticket.header.size + sizeof(ticket.header); // dummy ticket is 248 bytes diff --git a/Core/HLE/sceNp2.cpp b/Core/HLE/sceNp2.cpp index 51a1ada775..59f7b0cfdf 100644 --- a/Core/HLE/sceNp2.cpp +++ b/Core/HLE/sceNp2.cpp @@ -280,10 +280,12 @@ static int sceNpMatching2GetMemoryStat(u32 memStatPtr) if (!npMatching2Inited) return hleLogError(SCENET, SCE_NP_MATCHING2_ERROR_NOT_INITIALIZED); - if (!Memory::IsValidAddress(memStatPtr)) + auto memStat = PSPPointer::Create(memStatPtr); + if (!memStat.IsValid()) return hleLogError(SCENET, SCE_NP_MATCHING2_ERROR_INVALID_ARGUMENT); - Memory::WriteStruct(memStatPtr, &npMatching2MemStat); + *memStat = npMatching2MemStat; + memStat.NotifyWrite("NpMatching2GetMemoryStat"); return 0; } From 8b41178cb8b2f29d3c784f7dc1a7dcfcafae9d6e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 3 Sep 2022 08:47:13 -0700 Subject: [PATCH 4/8] Psmf: Use PSPPointer instead of WriteStruct. --- Core/HLE/sceMpeg.cpp | 14 ++++++------ Core/HLE/scePsmf.cpp | 53 ++++++++++++++++++++++---------------------- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 5a3cd77d35..8aa429ba1d 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -125,7 +125,7 @@ struct SceMpegLLI }; void SceMpegAu::read(u32 addr) { - Memory::ReadStruct(addr, this); + Memory::Memcpy(this, addr, sizeof(this), "SceMpegAu"); pts = (pts & 0xFFFFFFFFULL) << 32 | (((u64)pts) >> 32); dts = (dts & 0xFFFFFFFFULL) << 32 | (((u64)dts) >> 32); } @@ -133,7 +133,7 @@ void SceMpegAu::read(u32 addr) { void SceMpegAu::write(u32 addr) { pts = (pts & 0xFFFFFFFFULL) << 32 | (((u64)pts) >> 32); dts = (dts & 0xFFFFFFFFULL) << 32 | (((u64)dts) >> 32); - Memory::WriteStruct(addr, this); + Memory::Memcpy(addr, this, sizeof(this), "SceMpegAu"); } /* @@ -2410,15 +2410,15 @@ static u32 sceMpegBasePESpacketCopy(u32 p) { pmp_videoSource = p; pmp_nBlocks = 0; - SceMpegLLI lli; - while (1){ - Memory::ReadStruct(p, &lli); + + auto lli = PSPPointer::Create(p); + while (lli.IsValid()) { pmp_nBlocks++; // lli.Next ==0 for last block - if (lli.Next == 0){ + if (lli->Next == 0){ break; } - p = p + sizeof(SceMpegLLI); + ++lli; } DEBUG_LOG(ME, "sceMpegBasePESpacketCopy(%08x), received %d block(s)", pmp_videoSource, pmp_nBlocks); diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index 020ca8a808..b2aefa9a1a 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -766,20 +766,21 @@ static u32 scePsmfSetPsmf(u32 psmfStruct, u32 psmfData) { // Note: this structure changes between versions. // TODO: These values are not right, but games probably don't read them. - PsmfData data = {0}; - data.version = psmf->version; - data.headerSize = 0x800; - data.streamSize = psmf->streamSize; + auto data = PSPPointer::Create(psmfStruct); + memset((PsmfData *)data, 0, sizeof(PsmfData)); + data->version = psmf->version; + data->headerSize = 0x800; + data->streamSize = psmf->streamSize; // This should be and needs to be the current stream. - data.streamNum = psmf->currentStreamNum; - data.headerOffset = psmf->headerOffset; - Memory::WriteStruct(psmfStruct, &data); + data->streamNum = psmf->currentStreamNum; + data->headerOffset = psmf->headerOffset; + data.NotifyWrite("PsmfSetPsmf"); // Because the Psmf struct is sometimes copied, we use a value inside as an id. - auto iter = psmfMap.find(data.headerOffset); + auto iter = psmfMap.find(data->headerOffset); if (iter != psmfMap.end()) delete iter->second; - psmfMap[data.headerOffset] = psmf; + psmfMap[data->headerOffset] = psmf; return hleLogSuccessI(ME, 0); } @@ -1046,45 +1047,43 @@ static u32 scePsmfGetEPWithId(u32 psmfStruct, int epid, u32 entryAddr) { Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(ME, "scePsmfGetEPWithId(%08x, %i, %08x): invalid psmf", psmfStruct, epid, entryAddr); - return ERROR_PSMF_NOT_INITIALIZED; + return hleLogError(ME, ERROR_PSMF_NOT_INITIALIZED, "invalid psmf"); } - DEBUG_LOG(ME, "scePsmfGetEPWithId(%08x, %i, %08x)", psmfStruct, epid, entryAddr); if (epid < 0 || epid >= (int)psmf->EPMap.size()) { - ERROR_LOG(ME, "scePsmfGetEPWithId(%08x, %i): invalid id", psmfStruct, epid); - return ERROR_PSMF_NOT_FOUND; + return hleLogError(ME, ERROR_PSMF_NOT_FOUND, "invalid id"); } - if (Memory::IsValidAddress(entryAddr)) { - Memory::WriteStruct(entryAddr, &psmf->EPMap[epid]); + + auto entry = PSPPointer::Create(entryAddr); + if (entry.IsValid()) { + *entry = psmf->EPMap[epid]; + entry.NotifyWrite("PsmfGetEPWithId"); } - return 0; + return hleLogSuccessI(ME, 0); } static u32 scePsmfGetEPWithTimestamp(u32 psmfStruct, u32 ts, u32 entryAddr) { Psmf *psmf = getPsmf(psmfStruct); if (!psmf) { - ERROR_LOG(ME, "scePsmfGetEPWithTimestamp(%08x, %i, %08x): invalid psmf", psmfStruct, ts, entryAddr); - return ERROR_PSMF_NOT_INITIALIZED; + return hleLogError(ME, ERROR_PSMF_NOT_INITIALIZED, "invalid psmf"); } - DEBUG_LOG(ME, "scePsmfGetEPWithTimestamp(%08x, %i, %08x)", psmfStruct, ts, entryAddr); if (ts < psmf->presentationStartTime) { - ERROR_LOG(ME, "scePsmfGetEPWithTimestamp(%08x, %i): invalid timestamp", psmfStruct, ts); - return ERROR_PSMF_NOT_FOUND; + return hleLogError(ME, ERROR_PSMF_NOT_FOUND, "invalid timestamp"); } int epid = psmf->FindEPWithTimestamp(ts); if (epid < 0 || epid >= (int)psmf->EPMap.size()) { - ERROR_LOG(ME, "scePsmfGetEPWithTimestamp(%08x, %i): invalid id", psmfStruct, epid); - return ERROR_PSMF_NOT_FOUND; + return hleLogError(ME, ERROR_PSMF_NOT_FOUND, "invalid id"); } - if (Memory::IsValidAddress(entryAddr)) { - Memory::WriteStruct(entryAddr, &psmf->EPMap[epid]); + auto entry = PSPPointer::Create(entryAddr); + if (entry.IsValid()) { + *entry = psmf->EPMap[epid]; + entry.NotifyWrite("PsmfGetEPWithTimestamp"); } - return 0; + return hleLogSuccessI(ME, 0); } static u32 scePsmfGetEPidWithTimestamp(u32 psmfStruct, u32 ts) From a86b904cf2e0b155acff7254a6cab3389642dcd8 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 3 Sep 2022 09:01:23 -0700 Subject: [PATCH 5/8] Ge: Switch from ReadStruct to PSPPointer. --- Core/HLE/sceGe.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Core/HLE/sceGe.cpp b/Core/HLE/sceGe.cpp index e56f631c16..46230373d2 100644 --- a/Core/HLE/sceGe.cpp +++ b/Core/HLE/sceGe.cpp @@ -427,8 +427,6 @@ static int sceGeBreak(u32 mode, u32 unknownPtr) { } static u32 sceGeSetCallback(u32 structAddr) { - DEBUG_LOG(SCEGE, "sceGeSetCallback(struct=%08x)", structAddr); - int cbID = -1; for (size_t i = 0; i < ARRAY_SIZE(ge_used_callbacks); ++i) { if (!ge_used_callbacks[i]) { @@ -438,12 +436,13 @@ static u32 sceGeSetCallback(u32 structAddr) { } if (cbID == -1) { - WARN_LOG(SCEGE, "sceGeSetCallback(): out of callback ids"); - return SCE_KERNEL_ERROR_OUT_OF_MEMORY; + return hleLogWarning(SCEGE, SCE_KERNEL_ERROR_OUT_OF_MEMORY, "out of callback ids"); } ge_used_callbacks[cbID] = true; - Memory::ReadStruct(structAddr, &ge_callback_data[cbID]); + auto callbackData = PSPPointer::Create(structAddr); + ge_callback_data[cbID] = *callbackData; + callbackData.NotifyRead("GeSetCallback"); int subIntrBase = __GeSubIntrBase(cbID); @@ -458,7 +457,7 @@ static u32 sceGeSetCallback(u32 structAddr) { sceKernelEnableSubIntr(PSP_GE_INTR, subIntrBase | PSP_GE_SUBINTR_SIGNAL); } - return cbID; + return hleLogSuccessI(SCEGE, cbID); } static int sceGeUnsetCallback(u32 cbID) { @@ -603,7 +602,7 @@ const HLEFunction sceGe_user[] = { {0XB287BD61, &WrapU_U, "sceGeDrawSync", 'x', "x" }, {0XB448EC0D, &WrapI_UU, "sceGeBreak", 'i', "xx" }, {0X4C06E472, &WrapI_V, "sceGeContinue", 'i', "" }, - {0XA4FC06A4, &WrapU_U, "sceGeSetCallback", 'x', "x" }, + {0XA4FC06A4, &WrapU_U, "sceGeSetCallback", 'i', "p" }, {0X05DB22CE, &WrapI_U, "sceGeUnsetCallback", 'i', "x" }, {0X1F6752AD, &WrapU_V, "sceGeEdramGetSize", 'x', "" }, {0XB77905EA, &WrapU_I, "sceGeEdramSetAddrTranslation", 'x', "i" }, From 79c7a91d989e1845bdc9298851f1f30074e0acb0 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 3 Sep 2022 09:02:59 -0700 Subject: [PATCH 6/8] Font: Remove needless ReadStruct(). --- Core/HLE/sceFont.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index e91eeef88b..d55ce61514 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -486,8 +486,8 @@ public: // For save states only. } - FontLib(u32 paramPtr, u32 errorCodePtr) { - Memory::ReadStruct(paramPtr, ¶ms_); + FontLib(FontNewLibParams *params, u32 errorCodePtr) { + params_ = *params; if (params_.numFonts > 9) { params_.numFonts = 9; } @@ -998,7 +998,7 @@ static u32 sceFontNewLib(u32 paramPtr, u32 errorCodePtr) { INFO_LOG(SCEFONT, "sceFontNewLib(%08x, %08x)", paramPtr, errorCodePtr); *errorCode = 0; - FontLib *newLib = new FontLib(paramPtr, errorCodePtr); + FontLib *newLib = new FontLib(params, errorCodePtr); fontLibList.push_back(newLib); // The game should never see this value, the return value is replaced // by the action. Except if we disable the alloc, in this case we return From dd0de46ed96d8408174023a26d4a6c626996cb71 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 3 Sep 2022 09:13:07 -0700 Subject: [PATCH 7/8] Io: Use PSPPointer instead of struct temps. --- Core/Dialog/PSPGamedataInstallDialog.cpp | 11 ++--- Core/HLE/sceIo.cpp | 51 ++++++++++++++---------- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/Core/Dialog/PSPGamedataInstallDialog.cpp b/Core/Dialog/PSPGamedataInstallDialog.cpp index 0e550a9d2e..9fe30db3c8 100644 --- a/Core/Dialog/PSPGamedataInstallDialog.cpp +++ b/Core/Dialog/PSPGamedataInstallDialog.cpp @@ -116,9 +116,9 @@ int PSPGamedataInstallDialog::Update(int animSpeed) { WriteSfoFile(); // TODO: What is this? Should one of these update per file or anything? - request.unknownResult1 = readFiles; - request.unknownResult2 = readFiles; - Memory::WriteStruct(param.ptr, &request); + param->unknownResult1 = readFiles; + param->unknownResult2 = readFiles; + param.NotifyWrite("DialogResult"); ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0); } @@ -250,8 +250,9 @@ void PSPGamedataInstallDialog::UpdateProgress() { progressValue = (int)((allReadSize * 100) / allFilesSize); else progressValue = 100; - request.progress = progressValue; - Memory::WriteStruct(param.ptr, &request); + + param->progress = progressValue; + param.NotifyWrite("DialogResult"); } void PSPGamedataInstallDialog::DoState(PointerWrap &p) { diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 575f4be959..9e161828a8 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -931,12 +931,12 @@ static u32 sceIoGetstat(const char *filename, u32 addr) { // TODO: Improve timing (although this seems normally slow..) int usec = 1000; - SceIoStat stat; + auto stat = PSPPointer::Create(addr); PSPFileInfo info = pspFileSystem.GetFileInfo(filename); if (info.exists) { - __IoGetStat(&stat, info); - if (Memory::IsValidAddress(addr)) { - Memory::WriteStruct(addr, &stat); + if (stat.IsValid()) { + __IoGetStat(stat, info); + stat.NotifyWrite("IoGetstat"); DEBUG_LOG(SCEIO, "sceIoGetstat(%s, %08x) : sector = %08x", filename, addr, info.startSector); return hleDelayResult(0, "io getstat", usec); } else { @@ -1798,19 +1798,23 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o return SCE_KERNEL_ERROR_ERRNO_DEVICE_NOT_FOUND; } // TODO: Pretend we have a 2GB memory stick? Should we check MemoryStick_FreeSpace? - if (Memory::IsValidAddress(argAddr) && argLen >= 4) { // NOTE: not outPtr - u32 pointer = Memory::Read_U32(argAddr); + if (Memory::IsValidRange(argAddr, 4) && argLen >= 4) { // NOTE: not outPtr + u32 pointer = Memory::ReadUnchecked_U32(argAddr); u32 sectorSize = 0x200; u32 memStickSectorSize = 32 * 1024; u32 sectorCount = memStickSectorSize / sectorSize; u64 freeSize = 1 * 1024 * 1024 * 1024; - DeviceSize deviceSize; - deviceSize.maxClusters = (u32)((freeSize * 95 / 100) / (sectorSize * sectorCount)); - deviceSize.freeClusters = deviceSize.maxClusters; - deviceSize.maxSectors = deviceSize.maxClusters; - deviceSize.sectorSize = sectorSize; - deviceSize.sectorCount = sectorCount; - Memory::WriteStruct(pointer, &deviceSize); + + auto deviceSize = PSPPointer::Create(pointer); + if (deviceSize.IsValid()) { + deviceSize->maxClusters = (u32)((freeSize * 95 / 100) / (sectorSize * sectorCount)); + deviceSize->freeClusters = deviceSize->maxClusters; + deviceSize->maxSectors = deviceSize->maxClusters; + deviceSize->sectorSize = sectorSize; + deviceSize->sectorCount = sectorCount; + deviceSize.NotifyWrite("ms0:02425818"); + } + return 0; } else { return ERROR_MEMSTICK_DEVCTL_BAD_PARAMS; @@ -1821,8 +1825,8 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o if (MemoryStick_State() != PSP_MEMORYSTICK_STATE_INSERTED) { return SCE_KERNEL_ERROR_ERRNO_DEVICE_NOT_FOUND; } - if (Memory::IsValidAddress(outPtr) && outLen == 4) { - Memory::Write_U32(0, outPtr); + if (Memory::IsValidRange(outPtr, 4) && outLen == 4) { + Memory::WriteUnchecked_U32(0, outPtr); return 0; } else { ERROR_LOG(SCEIO, "Failed 0x02425824 fat"); @@ -1939,13 +1943,16 @@ static u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 o u32 memStickSectorSize = 32 * 1024; u32 sectorCount = memStickSectorSize / sectorSize; u64 freeSize = 1 * 1024 * 1024 * 1024; - DeviceSize deviceSize; - deviceSize.maxClusters = (u32)((freeSize * 95 / 100) / (sectorSize * sectorCount)); - deviceSize.freeClusters = deviceSize.maxClusters; - deviceSize.maxSectors = deviceSize.maxClusters; - deviceSize.sectorSize = sectorSize; - deviceSize.sectorCount = sectorCount; - Memory::WriteStruct(pointer, &deviceSize); + + auto deviceSize = PSPPointer::Create(pointer); + if (deviceSize.IsValid()) { + deviceSize->maxClusters = (u32)((freeSize * 95 / 100) / (sectorSize * sectorCount)); + deviceSize->freeClusters = deviceSize->maxClusters; + deviceSize->maxSectors = deviceSize->maxClusters; + deviceSize->sectorSize = sectorSize; + deviceSize->sectorCount = sectorCount; + deviceSize.NotifyWrite("fatms0:02425818"); + } return 0; } else { return ERROR_MEMSTICK_DEVCTL_BAD_PARAMS; From ccd4e921846a0174f1b2d4877ad7a3543af79343 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 3 Sep 2022 10:37:58 -0700 Subject: [PATCH 8/8] Kernel: Use PSPPointer for status objects. Code makes more sense when reading ->size rather than offset 0. --- Core/HLE/sceKernel.cpp | 38 ++++++++-------- Core/HLE/sceKernelEventFlag.cpp | 9 ++-- Core/HLE/sceKernelInterrupt.cpp | 2 +- Core/HLE/sceKernelMbx.cpp | 20 ++++----- Core/HLE/sceKernelMemory.cpp | 58 +++++++++++------------- Core/HLE/sceKernelModule.cpp | 74 +++++++++++++++--------------- Core/HLE/sceKernelMsgPipe.cpp | 30 +++++-------- Core/HLE/sceKernelMutex.cpp | 79 +++++++++++---------------------- Core/HLE/sceKernelSemaphore.cpp | 28 +++++------- Core/HLE/sceKernelThread.cpp | 15 ++++--- Core/MemMap.h | 15 ++++++- Core/MemMapHelpers.h | 27 ----------- 12 files changed, 172 insertions(+), 223 deletions(-) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 738ce25303..cb858c0e90 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -646,12 +646,12 @@ struct SystemStatus { static int sceKernelReferSystemStatus(u32 statusPtr) { DEBUG_LOG(SCEKERNEL, "sceKernelReferSystemStatus(%08x)", statusPtr); - if (Memory::IsValidAddress(statusPtr)) { - SystemStatus status; - memset(&status, 0, sizeof(SystemStatus)); - status.size = sizeof(SystemStatus); + auto status = PSPPointer::Create(statusPtr); + if (status.IsValid()) { + memset((SystemStatus *)status, 0, sizeof(SystemStatus)); + status->size = sizeof(SystemStatus); // TODO: Fill in the struct! - Memory::WriteStruct(statusPtr, &status); + status.NotifyWrite("SystemStatus"); } return 0; } @@ -684,11 +684,11 @@ static u32 sceKernelReferThreadProfiler(u32 statusPtr) { // Can we confirm that the struct above is the right struct? // If so, re-enable this code. - //DebugProfilerRegs regs; - //memset(®s, 0, sizeof(regs)); + //auto regs = PSPPointer::Create(statusPtr); // TODO: fill the struct. - //if (Memory::IsValidAddress(statusPtr)) { - // Memory::WriteStruct(statusPtr, ®s); + //if (regs.IsValid()) { + // memset((DebugProfilerRegs *)regs, 0, sizeof(DebugProfilerRegs)); + // regs.NotifyWrite("ThreadProfiler"); //} return 0; } @@ -715,14 +715,14 @@ const HLEFunction ThreadManForUser[] = {0XD6DA4BA1, &WrapI_CUIIU, "sceKernelCreateSema", 'i', "sxiix" }, {0X28B6489C, &WrapI_I, "sceKernelDeleteSema", 'i', "i" }, {0X58B1F937, &WrapI_II, "sceKernelPollSema", 'i', "ii" }, - {0XBC6FEBC5, &WrapI_IU, "sceKernelReferSemaStatus", 'i', "ix" }, + {0XBC6FEBC5, &WrapI_IU, "sceKernelReferSemaStatus", 'i', "ip" }, {0X3F53E640, &WrapI_II, "sceKernelSignalSema", 'i', "ii" }, {0X4E3A1105, &WrapI_IIU, "sceKernelWaitSema", 'i', "iix", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0X6D212BAC, &WrapI_IIU, "sceKernelWaitSemaCB", 'i', "iix", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0X60107536, &WrapI_U, "sceKernelDeleteLwMutex", 'i', "x" }, {0X19CFF145, &WrapI_UCUIU, "sceKernelCreateLwMutex", 'i', "xsxix" }, - {0X4C145944, &WrapI_IU, "sceKernelReferLwMutexStatusByID", 'i', "ix" }, + {0X4C145944, &WrapI_IU, "sceKernelReferLwMutexStatusByID", 'i', "xp" }, // NOTE: LockLwMutex, UnlockLwMutex, and ReferLwMutexStatus are in Kernel_Library, see sceKernelInterrupt.cpp. // The below should not be called directly. //{0x71040D5C, nullptr, "_sceKernelTryLockLwMutex", '?', "" }, @@ -736,7 +736,7 @@ const HLEFunction ThreadManForUser[] = {0X6B30100F, &WrapI_II, "sceKernelUnlockMutex", 'i', "ii" }, {0XB7D098C6, &WrapI_CUIU, "sceKernelCreateMutex", 'i', "sxix" }, {0X0DDCD2C9, &WrapI_II, "sceKernelTryLockMutex", 'i', "ii" }, - {0XA9C2CB9A, &WrapI_IU, "sceKernelReferMutexStatus", 'i', "ix" }, + {0XA9C2CB9A, &WrapI_IU, "sceKernelReferMutexStatus", 'i', "ip" }, {0X87D9223C, &WrapI_IIU, "sceKernelCancelMutex", 'i', "iix" }, {0XFCCFAD26, &WrapI_I, "sceKernelCancelWakeupThread", 'i', "i" }, @@ -818,7 +818,7 @@ const HLEFunction ThreadManForUser[] = {0XF3986382, &WrapI_IUU, "sceKernelReceiveMbxCB", 'i', "ixx", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0X0D81716A, &WrapI_IU, "sceKernelPollMbx", 'i', "ix" }, {0X87D4DD36, &WrapI_IU, "sceKernelCancelReceiveMbx", 'i', "ix" }, - {0XA8E8C846, &WrapI_IU, "sceKernelReferMbxStatus", 'i', "ix" }, + {0XA8E8C846, &WrapI_IU, "sceKernelReferMbxStatus", 'i', "ip" }, {0X7C0DC2A0, &WrapI_CIUUU, "sceKernelCreateMsgPipe", 'i', "sixxx" }, {0XF0B7DA1C, &WrapI_I, "sceKernelDeleteMsgPipe", 'i', "i" }, @@ -829,7 +829,7 @@ const HLEFunction ThreadManForUser[] = {0XFBFA697D, &WrapI_IUUUUU, "sceKernelReceiveMsgPipeCB", 'i', "ixxxxx" }, {0XDF52098F, &WrapI_IUUUU, "sceKernelTryReceiveMsgPipe", 'i', "ixxxx" }, {0X349B864D, &WrapI_IUU, "sceKernelCancelMsgPipe", 'i', "ixx" }, - {0X33BE4024, &WrapI_IU, "sceKernelReferMsgPipeStatus", 'i', "ix" }, + {0X33BE4024, &WrapI_IU, "sceKernelReferMsgPipeStatus", 'i', "ip" }, {0X56C039B5, &WrapI_CIUUU, "sceKernelCreateVpl", 'i', "sixxx" }, {0X89B3D48C, &WrapI_I, "sceKernelDeleteVpl", 'i', "i" }, @@ -838,7 +838,7 @@ const HLEFunction ThreadManForUser[] = {0XAF36D708, &WrapI_IUU, "sceKernelTryAllocateVpl", 'i', "ixx" }, {0XB736E9FF, &WrapI_IU, "sceKernelFreeVpl", 'i', "ix" }, {0X1D371B8A, &WrapI_IU, "sceKernelCancelVpl", 'i', "ix" }, - {0X39810265, &WrapI_IU, "sceKernelReferVplStatus", 'i', "ix" }, + {0X39810265, &WrapI_IU, "sceKernelReferVplStatus", 'i', "ip" }, {0XC07BB470, &WrapI_CUUUUU, "sceKernelCreateFpl", 'i', "sxxxxx" }, {0XED1410E0, &WrapI_I, "sceKernelDeleteFpl", 'i', "i" }, @@ -847,7 +847,7 @@ const HLEFunction ThreadManForUser[] = {0X623AE665, &WrapI_IU, "sceKernelTryAllocateFpl", 'i', "ix" }, {0XF6414A71, &WrapI_IU, "sceKernelFreeFpl", 'i', "ix" }, {0XA8AA591F, &WrapI_IU, "sceKernelCancelFpl", 'i', "ix" }, - {0XD8199E4C, &WrapI_IU, "sceKernelReferFplStatus", 'i', "ix" }, + {0XD8199E4C, &WrapI_IU, "sceKernelReferFplStatus", 'i', "ip" }, {0X20FFF560, &WrapU_CU, "sceKernelCreateVTimer", 'x', "sx", HLE_NOT_IN_INTERRUPT }, {0X328F9E52, &WrapU_I, "sceKernelDeleteVTimer", 'x', "i", HLE_NOT_IN_INTERRUPT }, @@ -866,7 +866,7 @@ const HLEFunction ThreadManForUser[] = {0X8DAFF657, &WrapI_CUUUUU, "sceKernelCreateTlspl", 'i', "sxxxxx" }, {0X32BF938E, &WrapI_I, "sceKernelDeleteTlspl", 'i', "i" }, - {0X721067F3, &WrapI_IU, "sceKernelReferTlsplStatus", 'i', "ix" }, + {0X721067F3, &WrapI_IU, "sceKernelReferTlsplStatus", 'i', "xp" }, // Not completely certain about args. {0X4A719FB2, &WrapI_I, "sceKernelFreeTlspl", 'i', "i" }, // Internal. Takes (uid, &addr) as parameters... probably. @@ -931,7 +931,7 @@ const HLEFunction ThreadManForKernel[] = {0xF3986382, &WrapI_IUU, "sceKernelReceiveMbxCB", 'i', "ixx", HLE_KERNEL_SYSCALL | HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0x0D81716A, &WrapI_IU, "sceKernelPollMbx", 'i', "ix", HLE_KERNEL_SYSCALL }, {0x87D4DD36, &WrapI_IU, "sceKernelCancelReceiveMbx", 'i', "ix", HLE_KERNEL_SYSCALL }, - {0xA8E8C846, &WrapI_IU, "sceKernelReferMbxStatus", 'i', "ix", HLE_KERNEL_SYSCALL }, + {0xA8E8C846, &WrapI_IU, "sceKernelReferMbxStatus", 'i', "ip", HLE_KERNEL_SYSCALL }, {0x56C039B5, &WrapI_CIUUU, "sceKernelCreateVpl", 'i', "sixxx", HLE_KERNEL_SYSCALL }, {0x89B3D48C, &WrapI_I, "sceKernelDeleteVpl", 'i', "i", HLE_KERNEL_SYSCALL }, {0xBED27435, &WrapI_IUUU, "sceKernelAllocateVpl", 'i', "ixxx", HLE_KERNEL_SYSCALL | HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, @@ -939,7 +939,7 @@ const HLEFunction ThreadManForKernel[] = {0xAF36D708, &WrapI_IUU, "sceKernelTryAllocateVpl", 'i', "ixx", HLE_KERNEL_SYSCALL }, {0xB736E9FF, &WrapI_IU, "sceKernelFreeVpl", 'i', "ix", HLE_KERNEL_SYSCALL }, {0x1D371B8A, &WrapI_IU, "sceKernelCancelVpl", 'i', "ix", HLE_KERNEL_SYSCALL }, - {0x39810265, &WrapI_IU, "sceKernelReferVplStatus", 'i', "ix", HLE_KERNEL_SYSCALL }, + {0x39810265, &WrapI_IU, "sceKernelReferVplStatus", 'i', "ip", HLE_KERNEL_SYSCALL }, }; void Register_ThreadManForUser() diff --git a/Core/HLE/sceKernelEventFlag.cpp b/Core/HLE/sceKernelEventFlag.cpp index 9ea935f06d..b903f950d3 100644 --- a/Core/HLE/sceKernelEventFlag.cpp +++ b/Core/HLE/sceKernelEventFlag.cpp @@ -522,14 +522,17 @@ u32 sceKernelReferEventFlagStatus(SceUID id, u32 statusPtr) { u32 error; EventFlag *e = kernelObjects.Get(id, error); if (e) { - if (!Memory::IsValidAddress(statusPtr)) + auto status = PSPPointer::Create(statusPtr); + if (!status.IsValid()) return hleLogWarning(SCEKERNEL, -1, "invalid ptr"); HLEKernel::CleanupWaitingThreads(WAITTYPE_EVENTFLAG, id, e->waitingThreads); e->nef.numWaitThreads = (int) e->waitingThreads.size(); - if (Memory::Read_U32(statusPtr) != 0) - Memory::WriteStruct(statusPtr, &e->nef); + if (status->size != 0) { + *status = e->nef; + status.NotifyWrite("EventFlagStatus"); + } return hleLogSuccessI(SCEKERNEL, 0); } else { return hleLogDebug(SCEKERNEL, error, "invalid event flag"); diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index cffedaeb46..4c91ffe529 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -677,7 +677,7 @@ const HLEFunction Kernel_Library[] = {0XBEA46419, &WrapI_UIU, "sceKernelLockLwMutex", 'i', "xix", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0X1FC64E09, &WrapI_UIU, "sceKernelLockLwMutexCB", 'i', "xix", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED }, {0X15B6446B, &WrapI_UI, "sceKernelUnlockLwMutex", 'i', "xi" }, - {0XC1734599, &WrapI_UU, "sceKernelReferLwMutexStatus", 'i', "xx" }, + {0XC1734599, &WrapI_UU, "sceKernelReferLwMutexStatus", 'i', "xp" }, {0X293B45B8, &WrapI_V, "sceKernelGetThreadId", 'i', "" }, {0XD13BDE95, &WrapI_V, "sceKernelCheckThreadStack", 'i', "" }, {0X1839852A, &WrapU_UUU, "sceKernelMemcpy", 'x', "xxx" }, diff --git a/Core/HLE/sceKernelMbx.cpp b/Core/HLE/sceKernelMbx.cpp index 412c70188d..0a5f132f01 100644 --- a/Core/HLE/sceKernelMbx.cpp +++ b/Core/HLE/sceKernelMbx.cpp @@ -552,19 +552,17 @@ int sceKernelCancelReceiveMbx(SceUID id, u32 numWaitingThreadsAddr) return 0; } -int sceKernelReferMbxStatus(SceUID id, u32 infoAddr) -{ +int sceKernelReferMbxStatus(SceUID id, u32 infoAddr) { u32 error; Mbx *m = kernelObjects.Get(id, error); - if (!m) - { - ERROR_LOG(SCEKERNEL, "sceKernelReferMbxStatus(%i, %08x): invalid mbx id", id, infoAddr); - return error; + if (!m) { + return hleLogError(SCEKERNEL, error, "invalid mbx id"); } // Should we crash the thread somehow? - if (!Memory::IsValidAddress(infoAddr)) - return -1; + auto info = PSPPointer::Create(infoAddr); + if (!info.IsValid()) + return hleLogError(SCEKERNEL, -1, "invalid pointer"); for (int i = 0, n = m->nmb.numMessages; i < n; ++i) m->nmb.packetListHead = Memory::Read_U32(m->nmb.packetListHead); @@ -572,10 +570,10 @@ int sceKernelReferMbxStatus(SceUID id, u32 infoAddr) HLEKernel::CleanupWaitingThreads(WAITTYPE_MBX, id, m->waitingThreads); // For whatever reason, it won't write if the size (first member) is 0. - if (Memory::Read_U32(infoAddr) != 0) - { + if (info->size != 0) { m->nmb.numWaitThreads = (int) m->waitingThreads.size(); - Memory::WriteStruct(infoAddr, &m->nmb); + *info = m->nmb; + info.NotifyWrite("MbxStatus"); } return 0; diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index 3c5cce3a9f..ac853d5bb3 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -881,30 +881,26 @@ int sceKernelCancelFpl(SceUID uid, u32 numWaitThreadsPtr) } } -int sceKernelReferFplStatus(SceUID uid, u32 statusPtr) -{ +int sceKernelReferFplStatus(SceUID uid, u32 statusPtr) { u32 error; FPL *fpl = kernelObjects.Get(uid, error); - if (fpl) - { - DEBUG_LOG(SCEKERNEL, "sceKernelReferFplStatus(%i, %08x)", uid, statusPtr); + if (fpl) { // Refresh waiting threads and free block count. __KernelSortFplThreads(fpl); fpl->nf.numWaitThreads = (int) fpl->waitingThreads.size(); fpl->nf.numFreeBlocks = 0; - for (int i = 0; i < (int)fpl->nf.numBlocks; ++i) - { + for (int i = 0; i < (int)fpl->nf.numBlocks; ++i) { if (!fpl->blocks[i]) ++fpl->nf.numFreeBlocks; } - if (Memory::Read_U32(statusPtr) != 0) - Memory::WriteStruct(statusPtr, &fpl->nf); - return 0; - } - else - { - DEBUG_LOG(SCEKERNEL, "sceKernelReferFplStatus(%i, %08x): invalid fpl", uid, statusPtr); - return error; + auto status = PSPPointer::Create(statusPtr); + if (status.IsValid() && status->size != 0) { + *status = fpl->nf; + status.NotifyWrite("FplStatus"); + } + return hleLogSuccessI(SCEKERNEL, 0); + } else { + return hleLogError(SCEKERNEL, error, "invalid fpl"); } } @@ -1782,8 +1778,6 @@ int sceKernelReferVplStatus(SceUID uid, u32 infoPtr) { u32 error; VPL *vpl = kernelObjects.Get(uid, error); if (vpl) { - DEBUG_LOG(SCEKERNEL, "sceKernelReferVplStatus(%i, %08x)", uid, infoPtr); - __KernelSortVplThreads(vpl); vpl->nv.numWaitThreads = (int) vpl->waitingThreads.size(); if (vpl->header.IsValid()) { @@ -1791,12 +1785,14 @@ int sceKernelReferVplStatus(SceUID uid, u32 infoPtr) { } else { vpl->nv.freeSize = vpl->alloc.GetTotalFreeBytes(); } - if (Memory::IsValidAddress(infoPtr) && Memory::Read_U32(infoPtr) != 0) { - Memory::WriteStruct(infoPtr, &vpl->nv); + auto info = PSPPointer::Create(infoPtr); + if (info.IsValid() && info->size != 0) { + *info = vpl->nv; + info.NotifyWrite("VplStatus"); } - return 0; + return hleLogSuccessI(SCEKERNEL, 0); } else { - return error; + return hleLogError(SCEKERNEL, error, "invalid vpl"); } } @@ -2270,23 +2266,23 @@ int sceKernelFreeTlspl(SceUID uid) return error; } -int sceKernelReferTlsplStatus(SceUID uid, u32 infoPtr) -{ - DEBUG_LOG(SCEKERNEL, "sceKernelReferTlsplStatus(%08x, %08x)", uid, infoPtr); +int sceKernelReferTlsplStatus(SceUID uid, u32 infoPtr) { u32 error; TLSPL *tls = kernelObjects.Get(uid, error); - if (tls) - { + if (tls) { // Update the waiting threads in case of deletions, etc. __KernelSortTlsplThreads(tls); tls->ntls.numWaitThreads = (int) tls->waitingThreads.size(); - if (Memory::Read_U32(infoPtr) != 0) - Memory::WriteStruct(infoPtr, &tls->ntls); - return 0; + auto info = PSPPointer::Create(infoPtr); + if (info.IsValid() && info->size != 0) { + *info = tls->ntls; + info.NotifyWrite("TlsplStatus"); + } + return hleLogSuccessI(SCEKERNEL, 0); + } else { + return hleLogError(SCEKERNEL, error, "invalid tlspl"); } - else - return error; } const HLEFunction SysMemUserForUser[] = { diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 502c48fc2e..a32604e928 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -247,6 +247,10 @@ enum NativeModuleStatus { class PSPModule : public KernelObject { public: + PSPModule() { + modulePtr.ptr = 0; + } + ~PSPModule() { if (memoryBlockAddr) { // If it's either below user memory, or using a high kernel bit, it's in kernel. @@ -258,9 +262,9 @@ public: g_symbolMap->UnloadModule(memoryBlockAddr, memoryBlockSize); } - if (modulePtr) { + if (modulePtr.ptr) { //Only alloc at kernel memory. - kernelMemory.Free(modulePtr); + kernelMemory.Free(modulePtr.ptr); } } const char *GetName() override { return nm.name; } @@ -320,7 +324,7 @@ public: } if (s >= 5) { - Do(p, modulePtr); + Do(p, modulePtr.ptr); } ModuleWaitingThread mwt = {0}; @@ -454,7 +458,7 @@ public: u32 memoryBlockAddr = 0; u32 memoryBlockSize = 0; - u32 modulePtr = 0; + PSPPointer modulePtr; bool isFake = false; }; @@ -1616,11 +1620,13 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load u32 moduleSize = sizeof(module->nm); char tag[32]; snprintf(tag, sizeof(tag), "SceModule-%d", module->nm.modid); - module->modulePtr = kernelMemory.Alloc(moduleSize, true, tag); + module->modulePtr.ptr = kernelMemory.Alloc(moduleSize, true, tag); // Fill the struct. - if (Memory::IsValidAddress(module->modulePtr)) - Memory::WriteStruct(module->modulePtr, &module->nm); + if (module->modulePtr.IsValid()) { + *module->modulePtr = module->nm; + module->modulePtr.NotifyWrite("KernelModule"); + } error = 0; return module; @@ -1763,17 +1769,18 @@ void __KernelLoadReset() { } bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_string) { - SceKernelLoadExecParam param; + SceKernelLoadExecParam param{}; PSP_SetLoading("Loading exec..."); - if (paramPtr) - Memory::ReadStruct(paramPtr, ¶m); - else - memset(¶m, 0, sizeof(SceKernelLoadExecParam)); + auto paramData = PSPPointer::Create(paramPtr); + if (paramData.IsValid()) { + param = *paramData; + paramData.NotifyRead("KernelLoadExec"); + } - u8 *param_argp = 0; - u8 *param_key = 0; + u8 *param_argp = nullptr; + u8 *param_key = nullptr; if (param.args > 0) { u32 argpAddr = param.argp; param_argp = new u8[param.args]; @@ -1792,10 +1799,8 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str if (!info.exists) { ERROR_LOG(LOADER, "Failed to load executable %s - file doesn't exist", filename); *error_string = StringFromFormat("Could not find executable %s", filename); - if (paramPtr) { - if (param_argp) delete[] param_argp; - if (param_key) delete[] param_key; - } + delete[] param_argp; + delete[] param_key; __KernelShutdown(); return false; } @@ -1817,10 +1822,8 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str ERROR_LOG(LOADER, "Failed to load module %s", filename); *error_string = "Failed to load executable: " + *error_string; delete [] temp; - if (paramPtr) { - if (param_argp) delete[] param_argp; - if (param_key) delete[] param_key; - } + delete[] param_argp; + delete[] param_key; return false; } @@ -1857,8 +1860,8 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str __KernelStartIdleThreads(module->GetUID()); - if (param_argp) delete[] param_argp; - if (param_key) delete[] param_key; + delete[] param_argp; + delete[] param_key; hleSkipDeadbeef(); return true; @@ -1989,11 +1992,13 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr) { u32 moduleSize = sizeof(module->nm); char tag[32]; snprintf(tag, sizeof(tag), "SceModule-%d", module->nm.modid); - module->modulePtr = kernelMemory.Alloc(moduleSize, true, tag); + module->modulePtr.ptr = kernelMemory.Alloc(moduleSize, true, tag); // Fill the struct. - if(Memory::IsValidAddress(module->modulePtr)) - Memory::WriteStruct(module->modulePtr, &module->nm); + if (module->modulePtr.IsValid()) { + *module->modulePtr = module->nm; + module->modulePtr.NotifyWrite("KernelModule"); + } // TODO: It would be more ideal to allocate memory for this module. @@ -2147,10 +2152,7 @@ int KernelStartModule(SceUID moduleId, u32 argsize, u32 argAddr, u32 returnValue static void sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 returnValueAddr, u32 optionAddr) { - SceKernelSMOption smoption = {0}; - if (optionAddr) { - Memory::ReadStruct(optionAddr, &smoption); - } + auto smoption = PSPPointer::Create(optionAddr); u32 error; PSPModule *module = kernelObjects.Get(moduleId, error); if (!module) { @@ -2176,7 +2178,7 @@ static void sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 ret moduleId,argsize,argAddr,returnValueAddr,optionAddr); bool needsWait; - int ret = KernelStartModule(moduleId, argsize, argAddr, returnValueAddr, optionAddr ? &smoption : nullptr, &needsWait); + int ret = KernelStartModule(moduleId, argsize, argAddr, returnValueAddr, smoption.PtrOrNull(), &needsWait); if (needsWait) { __KernelWaitCurThread(WAITTYPE_MODULE, moduleId, 1, 0, false, "started module"); @@ -2464,8 +2466,8 @@ u32 sceKernelFindModuleByUID(u32 uid) ERROR_LOG(SCEMODULE, "0 = sceKernelFindModuleByUID(%d): Module Not Found or Fake", uid); return 0; } - INFO_LOG(SCEMODULE, "%d = sceKernelFindModuleByUID(%d)", module->modulePtr, uid); - return module->modulePtr; + INFO_LOG(SCEMODULE, "%d = sceKernelFindModuleByUID(%d)", module->modulePtr.ptr, uid); + return module->modulePtr.ptr; } u32 sceKernelFindModuleByName(const char *name) @@ -2477,8 +2479,8 @@ u32 sceKernelFindModuleByName(const char *name) continue; if (strcmp(name, module->nm.name) == 0) { if (!module->isFake) { - INFO_LOG(SCEMODULE, "%d = sceKernelFindModuleByName(%s)", module->modulePtr, name); - return module->modulePtr; + INFO_LOG(SCEMODULE, "%d = sceKernelFindModuleByName(%s)", module->modulePtr.ptr, name); + return module->modulePtr.ptr; } else { WARN_LOG(SCEMODULE, "0 = sceKernelFindModuleByName(%s): Module Fake", name); diff --git a/Core/HLE/sceKernelMsgPipe.cpp b/Core/HLE/sceKernelMsgPipe.cpp index 253bf9ae65..b16e8060e2 100644 --- a/Core/HLE/sceKernelMsgPipe.cpp +++ b/Core/HLE/sceKernelMsgPipe.cpp @@ -1006,33 +1006,27 @@ int sceKernelCancelMsgPipe(SceUID uid, u32 numSendThreadsAddr, u32 numReceiveThr return 0; } -int sceKernelReferMsgPipeStatus(SceUID uid, u32 statusPtr) -{ +int sceKernelReferMsgPipeStatus(SceUID uid, u32 statusPtr) { u32 error; MsgPipe *m = kernelObjects.Get(uid, error); - if (m) - { - if (!Memory::IsValidAddress(statusPtr)) - { - ERROR_LOG(SCEKERNEL, "sceKernelReferMsgPipeStatus(%i, %08x): invalid address", uid, statusPtr); - return -1; + if (m) { + auto status = PSPPointer::Create(statusPtr); + if (!status.IsValid()) { + return hleLogError(SCEKERNEL, -1, "invalid address"); } - DEBUG_LOG(SCEKERNEL, "sceKernelReferMsgPipeStatus(%i, %08x)", uid, statusPtr); - // Clean up any that have timed out. m->SortReceiveThreads(); m->SortSendThreads(); m->nmp.numSendWaitThreads = (int) m->sendWaitingThreads.size(); m->nmp.numReceiveWaitThreads = (int) m->receiveWaitingThreads.size(); - if (Memory::Read_U32(statusPtr) != 0) - Memory::WriteStruct(statusPtr, &m->nmp); - return 0; - } - else - { - DEBUG_LOG(SCEKERNEL, "sceKernelReferMsgPipeStatus(%i, %08x): bad message pipe", uid, statusPtr); - return error; + if (status->size != 0) { + *status = m->nmp; + status.NotifyWrite("MsgPipeStatus"); + } + return hleLogSuccessI(SCEKERNEL, 0); + } else { + return hleLogError(SCEKERNEL, error, "bad message pipe"); } } diff --git a/Core/HLE/sceKernelMutex.cpp b/Core/HLE/sceKernelMutex.cpp index 899230142b..2cba7b5ca5 100644 --- a/Core/HLE/sceKernelMutex.cpp +++ b/Core/HLE/sceKernelMutex.cpp @@ -664,31 +664,27 @@ int sceKernelUnlockMutex(SceUID id, int count) return 0; } -int sceKernelReferMutexStatus(SceUID id, u32 infoAddr) -{ +int sceKernelReferMutexStatus(SceUID id, u32 infoAddr) { u32 error; PSPMutex *m = kernelObjects.Get(id, error); - if (!m) - { - ERROR_LOG(SCEKERNEL, "sceKernelReferMutexStatus(%i, %08x): invalid mutex id", id, infoAddr); - return error; + if (!m) { + return hleLogError(SCEKERNEL, error, "invalid mutex id"); } - DEBUG_LOG(SCEKERNEL, "sceKernelReferMutexStatus(%08x, %08x)", id, infoAddr); - // Should we crash the thread somehow? - if (!Memory::IsValidAddress(infoAddr)) - return -1; + auto info = PSPPointer::Create(infoAddr); + if (!info.IsValid()) + return hleLogError(SCEKERNEL, -1, "invalid pointer"); // Don't write if the size is 0. Anything else is A-OK, though, apparently. - if (Memory::Read_U32(infoAddr) != 0) - { + if (info->size != 0) { HLEKernel::CleanupWaitingThreads(WAITTYPE_MUTEX, id, m->waitingThreads); m->nm.numWaitThreads = (int) m->waitingThreads.size(); - Memory::WriteStruct(infoAddr, &m->nm); + *info = m->nm; + info.NotifyWrite("MutexStatus"); } - return 0; + return hleLogSuccessI(SCEKERNEL, 0); } int sceKernelCreateLwMutex(u32 workareaPtr, const char *name, u32 attr, int initialCount, u32 optionsPtr) @@ -1075,18 +1071,18 @@ int sceKernelUnlockLwMutex(u32 workareaPtr, int count) return 0; } -static int __KernelReferLwMutexStatus(SceUID uid, u32 infoPtr) -{ +static int __KernelReferLwMutexStatus(SceUID uid, u32 infoPtr) { u32 error; LwMutex *m = kernelObjects.Get(uid, error); if (!m) - return error; + return hleLogError(SCEKERNEL, error, "invalid id"); // Should we crash the thread somehow? - if (!Memory::IsValidAddress(infoPtr)) - return -1; + auto info = PSPPointer::Create(infoPtr); + if (!info.IsValid()) + return hleLogError(SCEKERNEL, -1, "invalid pointer"); - if (Memory::Read_U32(infoPtr) != 0) + if (info->size != 0) { auto workarea = m->nm.workarea; @@ -1096,44 +1092,21 @@ static int __KernelReferLwMutexStatus(SceUID uid, u32 infoPtr) m->nm.currentCount = workarea->lockLevel; m->nm.lockThread = workarea->lockThread == 0 ? SceUID_le(-1) : workarea->lockThread; m->nm.numWaitThreads = (int) m->waitingThreads.size(); - Memory::WriteStruct(infoPtr, &m->nm); + *info = m->nm; + info.NotifyWrite("LwMutexStatus"); } - return 0; + return hleLogSuccessI(SCEKERNEL, 0); } -int sceKernelReferLwMutexStatusByID(SceUID uid, u32 infoPtr) -{ - int error = __KernelReferLwMutexStatus(uid, infoPtr); - if (error >= 0) - { - DEBUG_LOG(SCEKERNEL, "sceKernelReferLwMutexStatusByID(%08x, %08x)", uid, infoPtr); - return error; - } - else - { - ERROR_LOG(SCEKERNEL, "%08x=sceKernelReferLwMutexStatusByID(%08x, %08x)", error, uid, infoPtr); - return error; - } +int sceKernelReferLwMutexStatusByID(SceUID uid, u32 infoPtr) { + return __KernelReferLwMutexStatus(uid, infoPtr); } -int sceKernelReferLwMutexStatus(u32 workareaPtr, u32 infoPtr) -{ - if (!Memory::IsValidAddress(workareaPtr)) { - ERROR_LOG(SCEKERNEL, "Bad workarea pointer for LwMutex"); - return SCE_KERNEL_ERROR_ACCESS_ERROR; - } - +int sceKernelReferLwMutexStatus(u32 workareaPtr, u32 infoPtr) { auto workarea = PSPPointer::Create(workareaPtr); + if (!workarea.IsValid()) { + return hleLogError(SCEKERNEL, SCE_KERNEL_ERROR_ACCESS_ERROR, "bad workarea pointer for LwMutex"); + } - int error = __KernelReferLwMutexStatus(workarea->uid, infoPtr); - if (error >= 0) - { - DEBUG_LOG(SCEKERNEL, "sceKernelReferLwMutexStatus(%08x, %08x)", workareaPtr, infoPtr); - return error; - } - else - { - ERROR_LOG(SCEKERNEL, "%08x=sceKernelReferLwMutexStatus(%08x, %08x)", error, workareaPtr, infoPtr); - return error; - } + return __KernelReferLwMutexStatus(workarea->uid, infoPtr); } diff --git a/Core/HLE/sceKernelSemaphore.cpp b/Core/HLE/sceKernelSemaphore.cpp index d6ebbaf2c1..fffb16c20f 100644 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -263,28 +263,24 @@ int sceKernelDeleteSema(SceUID id) } } -int sceKernelReferSemaStatus(SceUID id, u32 infoPtr) -{ +int sceKernelReferSemaStatus(SceUID id, u32 infoPtr) { u32 error; PSPSemaphore *s = kernelObjects.Get(id, error); - if (s) - { - DEBUG_LOG(SCEKERNEL, "sceKernelReferSemaStatus(%i, %08x)", id, infoPtr); - - if (!Memory::IsValidAddress(infoPtr)) - return -1; + if (s) { + auto info = PSPPointer::Create(infoPtr); + if (!info.IsValid()) + return hleLogWarning(SCEKERNEL, -1, "invalid pointer"); HLEKernel::CleanupWaitingThreads(WAITTYPE_SEMA, id, s->waitingThreads); s->ns.numWaitThreads = (int) s->waitingThreads.size(); - if (Memory::Read_U32(infoPtr) != 0) - Memory::WriteStruct(infoPtr, &s->ns); - return 0; - } - else - { - ERROR_LOG(SCEKERNEL, "sceKernelReferSemaStatus: error %08x", error); - return error; + if (info->size != 0) { + *info = s->ns; + info.NotifyWrite("SemaStatus"); + } + return hleLogSuccessI(SCEKERNEL, 0); + } else { + return hleLogError(SCEKERNEL, error); } } diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 86a234cd3b..ea9caaba1e 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2902,13 +2902,14 @@ int sceKernelGetCallbackCount(SceUID cbId) } } -int sceKernelReferCallbackStatus(SceUID cbId, u32 statusAddr) -{ +int sceKernelReferCallbackStatus(SceUID cbId, u32 statusAddr) { u32 error; PSPCallback *c = kernelObjects.Get(cbId, error); if (c) { - if (Memory::IsValidAddress(statusAddr) && Memory::Read_U32(statusAddr) != 0) { - Memory::WriteStruct(statusAddr, &c->nc); + auto status = PSPPointer::Create(statusAddr); + if (status.IsValid() && status->size != 0) { + *status = c->nc; + status.NotifyWrite("CallbackStatus"); return hleLogSuccessI(SCEKERNEL, 0); } else { return hleLogDebug(SCEKERNEL, 0, "struct size was 0"); @@ -3789,8 +3790,10 @@ int sceKernelReferThreadEventHandlerStatus(SceUID uid, u32 infoPtr) { return hleReportError(SCEKERNEL, error, "bad handler id"); } - if (Memory::IsValidAddress(infoPtr) && Memory::Read_U32(infoPtr) != 0) { - Memory::WriteStruct(infoPtr, &teh->nteh); + auto info = PSPPointer::Create(infoPtr); + if (info.IsValid() && info->size != 0) { + *info = teh->nteh; + info.NotifyWrite("ThreadEventHandlerStatus"); return hleLogSuccessI(SCEKERNEL, 0); } else { return hleLogDebug(SCEKERNEL, 0, "struct size was 0"); diff --git a/Core/MemMap.h b/Core/MemMap.h index 306190f249..0e8863b090 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -441,11 +441,22 @@ struct PSPPointer #endif } - bool IsValid() const - { + bool IsValid() const { return Memory::IsValidRange(ptr, (u32)sizeof(T)); } + T *PtrOrNull() { + if (IsValid()) + return (T *)*this; + return nullptr; + } + + const T *PtrOrNull() const { + if (IsValid()) + return (const T *)*this; + return nullptr; + } + template void NotifyWrite(const char(&tag)[tagLen]) const { PSPPointerNotifyRW(1, (uint32_t)ptr, (uint32_t)sizeof(T), tag, tagLen - 1); diff --git a/Core/MemMapHelpers.h b/Core/MemMapHelpers.h index e623d9e768..fdee215d03 100644 --- a/Core/MemMapHelpers.h +++ b/Core/MemMapHelpers.h @@ -109,31 +109,4 @@ inline void Memcpy(const u32 to_address, const u32 from_address, const u32 len) void Memset(const u32 _Address, const u8 _Data, const u32 _iLength, const char *tag = "Memset"); -template -void ReadStruct(u32 address, T *ptr) -{ - const u32 sz = (u32)sizeof(*ptr); - Memcpy(ptr, address, sz); -} - -template -void ReadStructUnchecked(u32 address, T *ptr) -{ - const u32 sz = (u32)sizeof(*ptr); - MemcpyUnchecked(ptr, address, sz); -} - -template -void WriteStruct(u32 address, T *ptr) -{ - const u32 sz = (u32)sizeof(*ptr); - Memcpy(address, ptr, sz); -} - -template -void WriteStructUnchecked(u32 address, T *ptr) -{ - const u32 sz = (u32)sizeof(*ptr); - MemcpyUnchecked(address, ptr, sz); -} }