From c44d787df45b6d0f7f8925dd89a124c7fbda3a76 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 7 Aug 2022 14:58:14 -0700 Subject: [PATCH 1/3] Mpeg: Check memory access range on GetPointer(). --- Core/HLE/sceMpeg.cpp | 17 ++++++--- Core/HW/MediaEngine.cpp | 77 +++++++++++++++++++------------------- Core/HW/SimpleAudioDec.cpp | 13 +++++-- 3 files changed, 59 insertions(+), 48 deletions(-) diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 5bfeb81dfb..02c66b6268 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -974,7 +974,9 @@ static bool decodePmpVideo(PSPPointer ringbuffer, u32 pmpctxA for (int i = 0; i < pmp_nBlocks; i++){ auto lli = PSPPointer::Create(pmp_videoSource); // add source block into pmpframes - pmpframes->add(Memory::GetPointerWrite(lli->pSrc), lli->iSize); + const uint8_t *ptr = Memory::GetPointerRange(lli->pSrc, lli->iSize); + if (ptr) + pmpframes->add(ptr, lli->iSize); // get next block pmp_videoSource += sizeof(SceMpegLLI); } @@ -1502,7 +1504,6 @@ void PostPutAction::run(MipsCall &call) { MpegContext *ctx = getMpegCtx(ringbuffer->mpeg); int writeOffset = ringbuffer->packetsWritePos % (s32)ringbuffer->packets; - const u8 *data = Memory::GetPointer(ringbuffer->data + writeOffset * 2048); int packetsAddedThisRound = currentMIPS->r[MIPS_REG_V0]; if (packetsAddedThisRound > 0) { @@ -1514,9 +1515,10 @@ void PostPutAction::run(MipsCall &call) { // TODO: Faster / less wasteful validation. std::unique_ptr demuxer(new MpegDemux(packetsAddedThisRound * 2048, 0)); int readOffset = ringbuffer->packetsRead % (s32)ringbuffer->packets; + uint32_t bufSize = Memory::ValidSize(ringbuffer->data + readOffset * 2048, packetsAddedThisRound * 2048); const u8 *buf = Memory::GetPointer(ringbuffer->data + readOffset * 2048); bool invalid = false; - for (int i = 0; i < packetsAddedThisRound; ++i) { + for (uint32_t i = 0; i < bufSize / 2048; ++i) { demuxer->addStreamData(buf, 2048); buf += 2048; @@ -1548,7 +1550,9 @@ void PostPutAction::run(MipsCall &call) { WARN_LOG(ME, "sceMpegRingbufferPut clamping packetsAdded old=%i new=%i", packetsAddedThisRound, ringbuffer->packets - ringbuffer->packetsAvail); packetsAddedThisRound = ringbuffer->packets - ringbuffer->packetsAvail; } - int actuallyAdded = ctx->mediaengine == NULL ? 8 : ctx->mediaengine->addStreamData(data, packetsAddedThisRound * 2048) / 2048; + const u8 *data = Memory::GetPointer(ringbuffer->data + writeOffset * 2048); + uint32_t dataSize = Memory::ValidSize(ringbuffer->data + writeOffset * 2048, packetsAddedThisRound * 2048); + int actuallyAdded = ctx->mediaengine == NULL ? 8 : ctx->mediaengine->addStreamData(data, dataSize) / 2048; if (actuallyAdded != packetsAddedThisRound) { WARN_LOG_REPORT(ME, "sceMpegRingbufferPut(): unable to enqueue all added packets, going to overwrite some frames."); } @@ -2175,10 +2179,13 @@ static int __MpegAvcConvertToYuv420(const void *data, u32 bufferOutputAddr, int u32 *imageBuffer = (u32*)data; int sizeY = width * height; int sizeCb = sizeY >> 2; - u8 *Y = (u8*)Memory::GetPointer(bufferOutputAddr); + u8 *Y = Memory::GetPointerWriteRange(bufferOutputAddr, sizeY + sizeCb + sizeCb); u8 *Cb = Y + sizeY; u8 *Cr = Cb + sizeCb; + if (!Y) + return hleLogError(ME, 0, "Bad output buffer pointer for yuv conv: %08x", bufferOutputAddr); + for (int y = 0; y < height; y += 2) { for (int x = 0; x < width; x += 2) { u32 abgr0 = imageBuffer[width * (y + 0) + x + 0]; diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index 53277b7ded..fa4b8191c4 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -777,24 +777,6 @@ inline void writeVideoLineABGR4444(void *destp, const void *srcp, int width) { } int MediaEngine::writeVideoImage(u32 bufferPtr, int frameWidth, int videoPixelMode) { - if (!Memory::IsValidAddress(bufferPtr) || frameWidth > 2048) { - // Clearly invalid values. Let's just not. - ERROR_LOG_REPORT(ME, "Ignoring invalid video decode address %08x/%x", bufferPtr, frameWidth); - return 0; - } - - u8 *buffer = Memory::GetPointerWrite(bufferPtr); - -#ifdef USE_FFMPEG - if (!m_pFrame || !m_pFrameRGB) - return 0; - - // lock the image size - int height = m_desHeight; - int width = m_desWidth; - u8 *imgbuf = buffer; - const u8 *data = m_pFrameRGB->data[0]; - int videoLineSize = 0; switch (videoPixelMode) { case GE_CMODE_32BIT_ABGR8888: @@ -807,7 +789,25 @@ int MediaEngine::writeVideoImage(u32 bufferPtr, int frameWidth, int videoPixelMo break; } - int videoImageSize = videoLineSize * height; + int videoImageSize = videoLineSize * m_desHeight; + + if (!Memory::IsValidRange(bufferPtr, videoImageSize) || frameWidth > 2048) { + // Clearly invalid values. Let's just not. + ERROR_LOG_REPORT(ME, "Ignoring invalid video decode address %08x/%x", bufferPtr, frameWidth); + return 0; + } + + u8 *buffer = Memory::GetPointerWriteUnchecked(bufferPtr); + +#ifdef USE_FFMPEG + if (!m_pFrame || !m_pFrameRGB) + return 0; + + // lock the image size + int height = m_desHeight; + int width = m_desWidth; + u8 *imgbuf = buffer; + const u8 *data = m_pFrameRGB->data[0]; bool swizzle = Memory::IsVRAMAddress(bufferPtr) && (bufferPtr & 0x00200000) == 0x00200000; if (swizzle) { @@ -867,22 +867,6 @@ int MediaEngine::writeVideoImage(u32 bufferPtr, int frameWidth, int videoPixelMo int MediaEngine::writeVideoImageWithRange(u32 bufferPtr, int frameWidth, int videoPixelMode, int xpos, int ypos, int width, int height) { - if (!Memory::IsValidAddress(bufferPtr) || frameWidth > 2048) { - // Clearly invalid values. Let's just not. - ERROR_LOG_REPORT(ME, "Ignoring invalid video decode address %08x/%x", bufferPtr, frameWidth); - return 0; - } - - u8 *buffer = Memory::GetPointerWrite(bufferPtr); - -#ifdef USE_FFMPEG - if (!m_pFrame || !m_pFrameRGB) - return 0; - - // lock the image size - u8 *imgbuf = buffer; - const u8 *data = m_pFrameRGB->data[0]; - int videoLineSize = 0; switch (videoPixelMode) { case GE_CMODE_32BIT_ABGR8888: @@ -894,8 +878,24 @@ int MediaEngine::writeVideoImageWithRange(u32 bufferPtr, int frameWidth, int vid videoLineSize = frameWidth * sizeof(u16); break; } - int videoImageSize = videoLineSize * height; + + if (!Memory::IsValidRange(bufferPtr, videoImageSize) || frameWidth > 2048) { + // Clearly invalid values. Let's just not. + ERROR_LOG_REPORT(ME, "Ignoring invalid video decode address %08x/%x", bufferPtr, frameWidth); + return 0; + } + + u8 *buffer = Memory::GetPointerWriteUnchecked(bufferPtr); + +#ifdef USE_FFMPEG + if (!m_pFrame || !m_pFrameRGB) + return 0; + + // lock the image size + u8 *imgbuf = buffer; + const u8 *data = m_pFrameRGB->data[0]; + bool swizzle = Memory::IsVRAMAddress(bufferPtr) && (bufferPtr & 0x00200000) == 0x00200000; if (swizzle) { imgbuf = new u8[videoImageSize]; @@ -1006,11 +1006,10 @@ int MediaEngine::getNextAudioFrame(u8 **buf, int *headerCode1, int *headerCode2) } int MediaEngine::getAudioSamples(u32 bufferPtr) { - if (!Memory::IsValidAddress(bufferPtr)) { + u8 *buffer = Memory::GetPointerWriteRange(bufferPtr, 8192); + if (buffer == nullptr) { ERROR_LOG_REPORT(ME, "Ignoring bad audio decode address %08x during video playback", bufferPtr); } - - u8 *buffer = Memory::GetPointerWrite(bufferPtr); if (!m_demux) { return 0; } diff --git a/Core/HW/SimpleAudioDec.cpp b/Core/HW/SimpleAudioDec.cpp index 0a19d92f85..8f250abdd8 100644 --- a/Core/HW/SimpleAudioDec.cpp +++ b/Core/HW/SimpleAudioDec.cpp @@ -252,7 +252,10 @@ bool SimpleAudio::Decode(const uint8_t *inbuf, int inbytes, uint8_t *outbuf, int } // convert audio to AV_SAMPLE_FMT_S16 - int swrRet = swr_convert(swrCtx_, &outbuf, frame_->nb_samples, (const u8 **)frame_->extended_data, frame_->nb_samples); + int swrRet = 0; + if (outbuf != nullptr) { + swrRet = swr_convert(swrCtx_, &outbuf, frame_->nb_samples, (const u8 **)frame_->extended_data, frame_->nb_samples); + } if (swrRet < 0) { ERROR_LOG(ME, "swr_convert: Error while converting: %d", swrRet); return false; @@ -338,7 +341,7 @@ size_t AuCtx::FindNextMp3Sync() { // return output pcm size, <0 error u32 AuCtx::AuDecode(u32 pcmAddr) { u32 outptr = PCMBuf + nextOutputHalf * PCMBufSize / 2; - auto outbuf = Memory::GetPointerWrite(outptr); + auto outbuf = Memory::GetPointerWriteRange(outptr, PCMBufSize / 2); int outpcmbufsize = 0; if (pcmAddr) @@ -380,10 +383,12 @@ u32 AuCtx::AuDecode(u32 pcmAddr) { if (outpcmbufsize == 0 && !end) { // If we didn't decode anything, we fill this half of the buffer with zeros. outpcmbufsize = PCMBufSize / 2; - memset(outbuf, 0, outpcmbufsize); + if (outbuf != nullptr) + memset(outbuf, 0, outpcmbufsize); } else if ((u32)outpcmbufsize < PCMBufSize) { // TODO: Not sure it actually zeros this out. - memset(outbuf + outpcmbufsize, 0, PCMBufSize / 2 - outpcmbufsize); + if (outbuf != nullptr) + memset(outbuf + outpcmbufsize, 0, PCMBufSize / 2 - outpcmbufsize); } if (outpcmbufsize != 0) From e9ce0d0b5ea489bf5cd80a84446498b23de5b14c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 8 Jan 2023 14:47:21 -0800 Subject: [PATCH 2/3] HLE: Add size checks to replace funcs. --- Core/HLE/ReplaceTables.cpp | 76 +++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index f09e59006c..446df7826c 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -268,8 +268,8 @@ static int Replace_memcpy_swizzled() { gpu->PerformReadbackToMemory(srcPtr, pitch * h); } } - u8 *dstp = Memory::GetPointerWrite(destPtr); - const u8 *srcp = Memory::GetPointer(srcPtr); + u8 *dstp = Memory::GetPointerWriteRange(destPtr, pitch * h); + const u8 *srcp = Memory::GetPointerRange(srcPtr, pitch * h); if (dstp && srcp) { const u8 *ysrcp = srcp; @@ -382,19 +382,31 @@ static int Replace_memset_jak() { return 5 + bytes * 6 + 2; // approximation (hm, inspecting the disasm this should be 5 + 6 * bytes + 2, but this is what works..) } +static uint32_t SafeStringLen(const uint32_t ptr, uint32_t maxLen = 0x07FFFFFF) { + maxLen = Memory::ValidSize(ptr, 0x07FFFFFF); + const uint8_t *p = Memory::GetPointerRange(ptr, maxLen); + if (!p) + return 0; + const uint8_t *end = (const uint8_t *)memchr(p, '\0', maxLen); + if (!end) + return 0; + return (uint32_t)(end - p); +} + static int Replace_strlen() { u32 srcPtr = PARAM(0); - const char *src = (const char *)Memory::GetPointer(srcPtr); - u32 len = src ? (u32)strlen(src) : 0UL; + u32 len = SafeStringLen(srcPtr); RETURN(len); return 7 + len * 4; // approximation } static int Replace_strcpy() { u32 destPtr = PARAM(0); - char *dst = (char *)Memory::GetPointer(destPtr); - const char *src = (const char *)Memory::GetPointer(PARAM(1)); - if (dst && src) { + u32 srcPtr = PARAM(1); + u32 len = SafeStringLen(srcPtr); + char *dst = (char *)Memory::GetPointerWriteRange(destPtr, len); + const char *src = (const char *)Memory::GetPointerRange(srcPtr, len); + if (dst && src && len != 0) { strcpy(dst, src); } RETURN(destPtr); @@ -403,9 +415,11 @@ static int Replace_strcpy() { static int Replace_strncpy() { u32 destPtr = PARAM(0); - char *dst = (char *)Memory::GetPointer(destPtr); - const char *src = (const char *)Memory::GetPointer(PARAM(1)); + u32 srcPtr = PARAM(1); u32 bytes = PARAM(2); + char *dst = (char *)Memory::GetPointerRange(destPtr, bytes); + u32 srcLen = SafeStringLen(srcPtr, bytes); + const char *src = (const char *)Memory::GetPointerRange(srcPtr, srcLen == 0 ? bytes : srcLen); if (dst && src && bytes != 0) { strncpy(dst, src, bytes); } @@ -414,9 +428,11 @@ static int Replace_strncpy() { } static int Replace_strcmp() { - const char *a = (const char *)Memory::GetPointer(PARAM(0)); - const char *b = (const char *)Memory::GetPointer(PARAM(1)); - if (a && b) { + u32 aLen = SafeStringLen(PARAM(0)); + const char *a = (const char *)Memory::GetPointerRange(PARAM(0), aLen); + u32 bLen = SafeStringLen(PARAM(1)); + const char *b = (const char *)Memory::GetPointerRange(PARAM(1), bLen); + if (a && b && aLen != 0 && bLen != 0) { RETURN(strcmp(a, b)); } else { RETURN(0); @@ -425,9 +441,11 @@ static int Replace_strcmp() { } static int Replace_strncmp() { - const char *a = (const char *)Memory::GetPointer(PARAM(0)); - const char *b = (const char *)Memory::GetPointer(PARAM(1)); u32 bytes = PARAM(2); + u32 aLen = SafeStringLen(PARAM(0), bytes); + const char *a = (const char *)Memory::GetPointerRange(PARAM(0), aLen == 0 ? bytes : aLen); + u32 bLen = SafeStringLen(PARAM(1), bytes); + const char *b = (const char *)Memory::GetPointerRange(PARAM(1), bLen == 0 ? bytes : bLen); if (a && b && bytes != 0) { RETURN(strncmp(a, b, bytes)); } else { @@ -442,9 +460,9 @@ static int Replace_fabsf() { } static int Replace_vmmul_q_transp() { - float_le *out = (float_le *)Memory::GetPointer(PARAM(0)); - const float_le *a = (const float_le *)Memory::GetPointer(PARAM(1)); - const float_le *b = (const float_le *)Memory::GetPointer(PARAM(2)); + float_le *out = (float_le *)Memory::GetPointerRange(PARAM(0), 16 * 4); + const float_le *a = (const float_le *)Memory::GetPointerRange(PARAM(1), 16 * 4); + const float_le *b = (const float_le *)Memory::GetPointerRange(PARAM(2), 16 * 4); // TODO: Actually use an optimized matrix multiply here... if (out && b && a) { @@ -469,8 +487,8 @@ static int Replace_vmmul_q_transp() { // a1 = matrix // a2 = source address static int Replace_gta_dl_write_matrix() { - u32_le *ptr = (u32_le *)Memory::GetPointer(PARAM(0)); - u32_le *src = (u32_le *)Memory::GetPointer(PARAM(2)); + u32_le *ptr = (u32_le *)Memory::GetPointerWriteRange(PARAM(0), 4); + const u32_le *src = (const u32_le *)Memory::GetPointerRange(PARAM(2), 16); u32 matrix = PARAM(1) << 24; if (!ptr || !src) { @@ -478,7 +496,7 @@ static int Replace_gta_dl_write_matrix() { return 38; } - u32_le *dest = (u32_le *)Memory::GetPointer(ptr[0]); + u32_le *dest = (u32_le *)Memory::GetPointerWriteRange(ptr[0], 12 * 4); if (!dest) { RETURN(0); return 38; @@ -528,20 +546,14 @@ static int Replace_gta_dl_write_matrix() { // TODO: Inline into a few NEON or SSE instructions - especially if a1 is a known immediate! // Anyway, not sure if worth it. There's not that many matrices written per frame normally. static int Replace_dl_write_matrix() { - u32_le *dlStruct = (u32_le *)Memory::GetPointer(PARAM(0)); - u32_le *src = (u32_le *)Memory::GetPointer(PARAM(2)); + u32_le *dlStruct = (u32_le *)Memory::GetPointerWriteRange(PARAM(0), 3 * 4); + const u32_le *src = (const u32_le *)Memory::GetPointerRange(PARAM(2), 16 * 4); if (!dlStruct || !src) { RETURN(0); return 60; } - u32_le *dest = (u32_le *)Memory::GetPointer(dlStruct[2]); - if (!dest) { - RETURN(0); - return 60; - } - u32 matrix = 0; int count = 12; switch (PARAM(1)) { @@ -559,6 +571,12 @@ static int Replace_dl_write_matrix() { count = 16; break; } + + u32_le *dest = (u32_le *)Memory::GetPointerWriteRange(dlStruct[2], 4 + count * 4); + if (!dest) { + RETURN(0); + return 60; + } *dest++ = matrix; matrix += 0x01000000; @@ -637,7 +655,7 @@ static int Replace_dl_write_matrix() { #endif } - NotifyMemInfo(MemBlockFlags::READ, PARAM(2), count * sizeof(float), "ReplaceDLWriteMatrix"); + NotifyMemInfo(MemBlockFlags::READ, PARAM(2), 16 * sizeof(float), "ReplaceDLWriteMatrix"); NotifyMemInfo(MemBlockFlags::WRITE, PARAM(0) + 2 * sizeof(u32), sizeof(u32), "ReplaceDLWriteMatrix"); NotifyMemInfo(MemBlockFlags::WRITE, dlStruct[2], (count + 1) * sizeof(u32), "ReplaceDLWriteMatrix"); From dea9cac16ce8fa6aca922869c5250ccb74009b94 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 8 Jan 2023 14:10:16 -0800 Subject: [PATCH 3/3] Core: Add range checks to some helpers and similar. --- Core/Dialog/PSPSaveDialog.cpp | 6 ++++-- Core/ELF/ElfReader.cpp | 2 +- Core/FileSystems/ISOFileSystem.cpp | 6 +++--- Core/HLE/proAdhoc.cpp | 2 +- Core/HW/SasAudio.cpp | 14 ++++++++------ Core/MIPS/JitCommon/JitBlockCache.cpp | 2 +- Core/MIPS/MIPSAnalyst.cpp | 2 +- Core/MIPS/MIPSIntVFPU.cpp | 9 +++++---- Core/MemMapHelpers.h | 8 ++++---- Core/Util/PPGeDraw.cpp | 8 ++++---- 10 files changed, 32 insertions(+), 27 deletions(-) diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index a1ef203606..9b21f5d770 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -22,6 +22,7 @@ #endif #endif +#include #include #include @@ -639,8 +640,9 @@ 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 = Memory::Read_U32(requestAddr); - if (memcmp(Memory::GetPointer(requestAddr), &originalRequest, size) != 0) { + int size = std::min((u32)sizeof(originalRequest), Memory::Read_U32(requestAddr)); + const u8 *updatedRequest = Memory::GetPointerRange(requestAddr, size); + if (updatedRequest && memcmp(updatedRequest, &originalRequest, size) != 0) { memset(&request, 0, sizeof(request)); Memory::Memcpy(&request, requestAddr, size); Memory::Memcpy(&originalRequest, requestAddr, size); diff --git a/Core/ELF/ElfReader.cpp b/Core/ELF/ElfReader.cpp index 2baf2690d6..3008b17f61 100644 --- a/Core/ELF/ElfReader.cpp +++ b/Core/ELF/ElfReader.cpp @@ -511,9 +511,9 @@ int ElfReader::LoadInto(u32 loadAddress, bool fromTop) ERROR_LOG(LOADER, "Segment %d pointer invalid - truncated?", i); continue; } - u8 *dst = Memory::GetPointerWrite(writeAddr); u32 srcSize = p->p_filesz; u32 dstSize = p->p_memsz; + u8 *dst = Memory::GetPointerWriteRange(writeAddr, dstSize); if (srcSize < dstSize) { diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index f52bc947c2..6d8d830cee 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -401,8 +401,8 @@ int ISOFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outd return SCE_KERNEL_ERROR_ERRNO_FUNCTION_NOT_SUPPORTED; } - if (!Memory::IsValidAddress(outdataPtr) || outlen < 0x800) { - WARN_LOG_REPORT(FILESYS, "sceIoIoctl: Invalid out pointer while reading ISO9660 volume descriptor"); + if (!Memory::IsValidRange(outdataPtr, 0x800) || outlen < 0x800) { + WARN_LOG_REPORT(FILESYS, "sceIoIoctl: Invalid out pointer %08x while reading ISO9660 volume descriptor", outdataPtr); return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT; } @@ -424,7 +424,7 @@ int ISOFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outd } else { int block = (u16)desc.firstLETableSector; u32 size = Memory::ValidSize(outdataPtr, (u32)desc.pathTableLength); - u8 *out = Memory::GetPointerWrite(outdataPtr); + u8 *out = Memory::GetPointerWriteRange(outdataPtr, size); int blocks = size / blockDevice->GetBlockSize(); blockDevice->ReadBlocks(block, blocks, out); diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index 2a18f05534..d0fe0028b5 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1263,7 +1263,7 @@ void notifyMatchingHandler(SceNetAdhocMatchingContext * context, ThreadMessage * MatchingArgs argsNew = { 0 }; u32_le dataBufLen = msg->optlen + 8; //max(bufLen, msg->optlen + 8); u32_le dataBufAddr = userMemory.Alloc(dataBufLen); // We will free this memory after returning from mipscall. FIXME: Are these buffers supposed to be taken/pre-allocated from the memory pool during sceNetAdhocMatchingInit? - uint8_t * dataPtr = Memory::GetPointerWrite(dataBufAddr); + uint8_t *dataPtr = Memory::GetPointerWriteRange(dataBufAddr, dataBufLen); if (dataPtr) { memcpy(dataPtr, &msg->mac, sizeof(msg->mac)); if (msg->optlen > 0) diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index 4a76553d4a..4d85d0fd7c 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -120,8 +120,8 @@ void VagDecoder::GetSamples(s16 *outSamples, int numSamples) { memset(outSamples, 0, numSamples * sizeof(s16)); return; } - if (!Memory::IsValidAddress(read_)) { - WARN_LOG(SASMIX, "Bad VAG samples address?"); + if (!Memory::IsValidRange(read_, numBlocks_ * 16)) { + WARN_LOG_REPORT(SASMIX, "Bad VAG samples address? %08x / %d", read_, numBlocks_); return; } const u8 *readp = Memory::GetPointerUnchecked(read_); @@ -577,9 +577,11 @@ void SasInstance::Mix(u32 outAddr, u32 inAddr, int leftVol, int rightVol) { // Then mix the send buffer in with the rest. // Alright, all voices mixed. Let's convert and clip, and at the same time, wipe mixBuffer for next time. Could also dither. - s16 *outp = (s16 *)Memory::GetPointer(outAddr); - const s16 *inp = inAddr ? (s16*)Memory::GetPointer(inAddr) : 0; - if (outputMode == PSP_SAS_OUTPUTMODE_MIXED) { + s16 *outp = (s16 *)Memory::GetPointerWriteRange(outAddr, 4 * grainSize); + const s16 *inp = inAddr ? (const s16 *)Memory::GetPointerRange(inAddr, 4 * grainSize) : 0; + if (!outp) { + WARN_LOG_REPORT(SCESAS, "Bad SAS Mix output address: %08x, grain=%d", outAddr, grainSize); + } else if (outputMode == PSP_SAS_OUTPUTMODE_MIXED) { // Okay, apply effects processing to the Send buffer. WriteMixedOutput(outp, inp, leftVol, rightVol); if (MemBlockInfoDetailed()) { @@ -605,7 +607,7 @@ void SasInstance::Mix(u32 outAddr, u32 inAddr, int leftVol, int rightVol) { memset(sendBuffer, 0, grainSize * sizeof(int) * 2); #ifdef AUDIO_TO_FILE - fwrite(Memory::GetPointer(outAddr), 1, grainSize * 2 * 2, audioDump); + fwrite(Memory::GetPointer(outAddr, grainSize * 2 * 2), 1, grainSize * 2 * 2, audioDump); #endif } diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp index 16e82f809c..5dfb580bb7 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.cpp +++ b/Core/MIPS/JitCommon/JitBlockCache.cpp @@ -65,7 +65,7 @@ static uint64_t HashJitBlock(const JitBlock &b) { PROFILE_THIS_SCOPE("jithash"); if (JIT_USE_COMPILEDHASH) { // Includes the emuhack (or emuhacks) in memory. - return XXH3_64bits(Memory::GetPointer(b.originalAddress), b.originalSize * 4); + return XXH3_64bits(Memory::GetPointerRange(b.originalAddress, b.originalSize * 4), b.originalSize * 4); } return 0; } diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index cdeaa6a169..f4fb504a89 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -673,7 +673,7 @@ namespace MIPSAnalyst { int vt = (((op >> 16) & 0x1f)) | ((op & 1) << 5); float rd[4]; ReadVector(rd, V_Quad, vt); - return memcmp(rd, Memory::GetPointer(addr), sizeof(float) * 4) != 0; + return memcmp(rd, Memory::GetPointerRange(addr, 16), sizeof(float) * 4) != 0; } // TODO: Technically, the break might be for 1 byte in the middle of a sw. diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index 1b2c8d60ec..b8bbe25caf 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -207,6 +207,7 @@ namespace MIPSInt u32 addr = R(rs) + imm; float *f; + const float *cf; switch (op >> 26) { @@ -245,9 +246,9 @@ namespace MIPSInt _dbg_assert_msg_( 0, "Misaligned lv.q at %08x (pc = %08x)", addr, PC); } #ifndef COMMON_BIG_ENDIAN - f = reinterpret_cast(Memory::GetPointerWrite(addr)); - if (f) - WriteVector(f, V_Quad, vt); + cf = reinterpret_cast(Memory::GetPointerRange(addr, 16)); + if (cf) + WriteVector(cf, V_Quad, vt); #else float lvqd[4]; @@ -294,7 +295,7 @@ namespace MIPSInt _dbg_assert_msg_( 0, "Misaligned sv.q at %08x (pc = %08x)", addr, PC); } #ifndef COMMON_BIG_ENDIAN - f = reinterpret_cast(Memory::GetPointerWrite(addr)); + f = reinterpret_cast(Memory::GetPointerWriteRange(addr, 16)); if (f) ReadVector(f, V_Quad, vt); #else diff --git a/Core/MemMapHelpers.h b/Core/MemMapHelpers.h index 56a950728c..6f2ceaca63 100644 --- a/Core/MemMapHelpers.h +++ b/Core/MemMapHelpers.h @@ -32,7 +32,7 @@ namespace Memory { inline void Memcpy(const u32 to_address, const void *from_data, const u32 len, const char *tag, size_t tagLen) { - u8 *to = GetPointerWrite(to_address); + u8 *to = GetPointerWriteRange(to_address, len); if (to) { memcpy(to, from_data, len); if (!tag) { @@ -45,7 +45,7 @@ inline void Memcpy(const u32 to_address, const void *from_data, const u32 len, c } inline void Memcpy(void *to_data, const u32 from_address, const u32 len, const char *tag, size_t tagLen) { - const u8 *from = GetPointer(from_address); + const u8 *from = GetPointerRange(from_address, len); if (from) { memcpy(to_data, from, len); if (!tag) { @@ -58,11 +58,11 @@ inline void Memcpy(void *to_data, const u32 from_address, const u32 len, const c } inline void Memcpy(const u32 to_address, const u32 from_address, const u32 len, const char *tag, size_t tagLen) { - u8 *to = GetPointerWrite(to_address); + u8 *to = GetPointerWriteRange(to_address, len); // If not, GetPointer will log. if (!to) return; - const u8 *from = GetPointer(from_address); + const u8 *from = GetPointerRange(from_address, len); if (!from) return; diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index 9d0c6f832c..495e4d1249 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -276,7 +276,7 @@ void __PPGeInit() { 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); + u8 *ramPtr = atlasPtr == 0 ? nullptr : (u8 *)Memory::GetPointerRange(atlasPtr, atlasSize); // Palettize to 4-bit, the easy way. for (int i = 0; i < width[0] * height[0] / 2; i++) { @@ -325,7 +325,7 @@ void __PPGeDoState(PointerWrap &p) } else { // Memory was already updated by this point, so check directly. if (atlasPtr != 0) { - savedHash = XXH3_64bits(Memory::GetPointer(atlasPtr), atlasWidth * atlasHeight / 2); + savedHash = XXH3_64bits(Memory::GetPointerRange(atlasPtr, atlasWidth * atlasHeight / 2), atlasWidth * atlasHeight / 2); } else { savedHash ^= 1; } @@ -886,7 +886,7 @@ static PPGeTextDrawerImage PPGeGetTextImage(const char *text, const PPGeStyle &s if (im.ptr) { int wBytes = (im.entry.bmWidth + 1) / 2; - u8 *ramPtr = (u8 *)Memory::GetPointer(im.ptr); + u8 *ramPtr = Memory::GetPointerWriteRange(im.ptr, sz); for (int y = 0; y < im.entry.bmHeight; ++y) { for (int x = 0; x < wBytes; ++x) { uint8_t c1 = bitmapData[y * im.entry.bmWidth + x * 2]; @@ -1327,7 +1327,7 @@ bool PPGeImage::Load() { unsigned char *textureData; int success; if (filename_.empty()) { - success = pngLoadPtr(Memory::GetPointer(png_), size_, &width_, &height_, &textureData); + success = pngLoadPtr(Memory::GetPointerRange(png_, size_), size_, &width_, &height_, &textureData); } else { std::vector pngData; if (pspFileSystem.ReadEntireFile(filename_, pngData) < 0) {