diff --git a/Common/Data/Collections/FastVec.h b/Common/Data/Collections/FastVec.h index 5bff743723..ee3799d775 100644 --- a/Common/Data/Collections/FastVec.h +++ b/Common/Data/Collections/FastVec.h @@ -47,7 +47,7 @@ public: other.capacity_ = 0; } - FastVec &operator=(FastVec &&other) { + FastVec &operator=(FastVec &&other) noexcept { if (this != &other) { free(data_); data_ = other.data_; diff --git a/Core/FileLoaders/ZipFileLoader.cpp b/Core/FileLoaders/ZipFileLoader.cpp index 63cce14406..d7b9871792 100644 --- a/Core/FileLoaders/ZipFileLoader.cpp +++ b/Core/FileLoaders/ZipFileLoader.cpp @@ -61,16 +61,16 @@ size_t ZipFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, Flags fl return 0; } - if (absolutePos + bytes > dataFileSize_) { + if (absolutePos + (s64)bytes > dataFileSize_) { // TODO: This could go negative.. bytes = dataFileSize_ - absolutePos; } // Decompress until the requested point, filling up data_ as we go. TODO: Do on thread. - while (dataReadPos_ < absolutePos + bytes) { + while (dataReadPos_ < absolutePos + (s64)bytes) { int remaining = BLOCK_SIZE; if (dataReadPos_ + remaining > dataFileSize_) { - remaining = dataFileSize_ - dataReadPos_; + remaining = (int)(dataFileSize_ - dataReadPos_); } zip_int64_t retval = zip_fread(dataFile_, data_ + dataReadPos_, remaining); _dbg_assert_(retval == remaining); diff --git a/Core/HLE/AtracCtx2.cpp b/Core/HLE/AtracCtx2.cpp index 2a7cd6e2c2..714f2345dd 100644 --- a/Core/HLE/AtracCtx2.cpp +++ b/Core/HLE/AtracCtx2.cpp @@ -1092,7 +1092,7 @@ void Atrac2::DecodeForSas(s16 *dstData, int *bytesWritten, int *finish) { u8 assembly[1000]; // Keep decoding from the current buffer until it runs out. - if (sas_.streamOffset + info.sampleSize <= sas_.bufSize[sas_.curBuffer]) { + if (sas_.streamOffset + (int)info.sampleSize <= (int)sas_.bufSize[sas_.curBuffer]) { // Just decode. const u8 *srcData = Memory::GetPointer(sas_.bufPtr[sas_.curBuffer] + sas_.streamOffset); int bytesConsumed = 0; diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 748d8c29bd..59efa7e63e 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -1331,7 +1331,7 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load // Seen in WWE: Smackdown vs Raw 2009. See #17435. continue; } - if (!Memory::IsValidRange(start, len)) { + if (!Memory::IsValid4AlignedRange(start, len)) { ERROR_LOG(Log::Loader, "Bad section %08x (len %08x) of section %d", start, len, id); continue; } @@ -1351,7 +1351,7 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load u32 scanStart = module->textStart; u32 scanEnd = module->textEnd; - if (Memory::IsValidRange(scanStart, scanEnd - scanStart)) { + if (Memory::IsValid4AlignedRange(scanStart, scanEnd - scanStart)) { // Skip the exports and imports sections, they're not code. if (scanEnd >= std::min(modinfo->libent, modinfo->libstub)) { insertSymbols = MIPSAnalyst::ScanForFunctions(scanStart, std::min(modinfo->libent, modinfo->libstub) - 4, insertSymbols); @@ -1473,6 +1473,11 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load u32 nid = residentPtr[ent->fcount + j]; u32 exportAddr = exportPtr[ent->fcount + j]; + if (exportAddr & 3) { + ERROR_LOG(Log::Loader, "Bad export address %08x", exportAddr); + continue; + } + int size; switch (nid) { case NID_MODULE_INFO: diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index a08089a2b7..19876bbb52 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -1023,6 +1023,8 @@ skip: } bool ScanForFunctions(u32 startAddr, u32 endAddr, bool insertSymbols) { + _assert_(((startAddr | endAddr) & 3) == 0); + std::lock_guard guard(functions_lock); FunctionsVector new_functions; @@ -1204,6 +1206,8 @@ skip: } void RegisterFunction(u32 startAddr, u32 size, const char *name) { + _assert_((startAddr & 3) == 0); + std::lock_guard guard(functions_lock); // Check if we have this already @@ -1237,6 +1241,8 @@ skip: } void ForgetFunctions(u32 startAddr, u32 endAddr) { + _assert_(((startAddr | endAddr) & 3) == 0); + std::lock_guard guard(functions_lock); // It makes sense to forget functions as modules are unloaded but it breaks diff --git a/Core/MIPS/MIPSCodeUtils.cpp b/Core/MIPS/MIPSCodeUtils.cpp index d32d4e5888..7bd2847a24 100644 --- a/Core/MIPS/MIPSCodeUtils.cpp +++ b/Core/MIPS/MIPSCodeUtils.cpp @@ -74,6 +74,7 @@ namespace MIPSCodeUtils } } + // As long as addr is aligned, this will only return aligned addresses. u32 GetSureBranchTarget(u32 addr) { MIPSOpcode op = Memory::Read_Instruction(addr, true); if (op != 0) { @@ -130,6 +131,4 @@ namespace MIPSCodeUtils bool IsBranch(MIPSOpcode op) { return (MIPSGetInfo(op) & IS_CONDBRANCH) == IS_CONDBRANCH; } - - } diff --git a/Core/MemMap.h b/Core/MemMap.h index 57481471c5..f327ab4c38 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -369,6 +369,15 @@ inline bool IsValidRange(const u32 address, const u32 size) { return ValidSize(address, size) == size; } +// NOTE: If size == 0, any address will be accepted. This may not be ideal for all cases. +// Also, length is not checked for alignment. +inline bool IsValid4AlignedRange(const u32 address, const u32 size) { + if (address & 3) { + return false; + } + return ValidSize(address, size) == size; +} + // Used for auto-converted char * parameters, which can sometimes legitimately be null - // so we don't want to get caught in GetPointer's crash reporting // TODO: This should use IsValidNullTerminatedString, but may be expensive since this is used so much - needs evaluation.