HLE: Add size checks to replace funcs.

This commit is contained in:
Unknown W. Brackets 2023-01-08 14:47:21 -08:00
parent c44d787df4
commit e9ce0d0b5e

View File

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