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");