notaz.gp2x.de
/
pcsx_rearmed.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
psxbios: Add checks for strcpy & strncpy.
[pcsx_rearmed.git]
/
libpcsxcore
/
psxbios.c
diff --git
a/libpcsxcore/psxbios.c
b/libpcsxcore/psxbios.c
index
044a19a
..
13cfe73
100644
(file)
--- a/
libpcsxcore/psxbios.c
+++ b/
libpcsxcore/psxbios.c
@@
-254,6
+254,7
@@
static EvCB *RcEV; // 0xf2
static EvCB *UeEV; // 0xf3
static EvCB *SwEV; // 0xf4
static EvCB *ThEV; // 0xff
static EvCB *UeEV; // 0xf3
static EvCB *SwEV; // 0xf4
static EvCB *ThEV; // 0xff
+static u32 heap_size = 0;
static u32 *heap_addr = NULL;
static u32 *heap_end = NULL;
static u32 SysIntRP[8];
static u32 *heap_addr = NULL;
static u32 *heap_end = NULL;
static u32 SysIntRP[8];
@@
-540,13
+541,35
@@
void psxBios_strncat() { // 0x16
void psxBios_strcmp() { // 0x17
char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
void psxBios_strcmp() { // 0x17
char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
-
+ s32 n=0;
+ if (a0 == 0 && a1 == 0)
+ {
+ v0 = 0;
+ pc0 = ra;
+ return;
+ }
+ else if (a0 == 0 && a1 != 0)
+ {
+ v0 = -1;
+ pc0 = ra;
+ return;
+ }
+ else if (a0 != 0 && a1 == 0)
+ {
+ v0 = 1;
+ pc0 = ra;
+ return;
+ }
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s: %s (%x), %s (%x)\n", biosA0n[0x17], Ra0, a0, Ra1, a1);
#endif
while (*p1 == *p2++) {
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s: %s (%x), %s (%x)\n", biosA0n[0x17], Ra0, a0, Ra1, a1);
#endif
while (*p1 == *p2++) {
+ n++;
if (*p1++ == '\0') {
if (*p1++ == '\0') {
+ v1=n-1;
+ a0+=n;
+ a1+=n;
v0 = 0;
pc0 = ra;
return;
v0 = 0;
pc0 = ra;
return;
@@
-554,13
+577,33
@@
void psxBios_strcmp() { // 0x17
}
v0 = (*p1 - *--p2);
}
v0 = (*p1 - *--p2);
+ v1 = n;
+ a0+=n;
+ a1+=n;
pc0 = ra;
}
void psxBios_strncmp() { // 0x18
char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
s32 n = a2;
pc0 = ra;
}
void psxBios_strncmp() { // 0x18
char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
s32 n = a2;
-
+ if (a0 == 0 && a1 == 0)
+ {
+ v0 = 0;
+ pc0 = ra;
+ return;
+ }
+ else if (a0 == 0 && a1 != 0)
+ {
+ v0 = -1;
+ pc0 = ra;
+ return;
+ }
+ else if (a0 != 0 && a1 == 0)
+ {
+ v0 = 1;
+ pc0 = ra;
+ return;
+ }
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s: %s (%x), %s (%x), %d\n", biosA0n[0x18], Ra0, a0, Ra1, a1, a2);
#endif
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s: %s (%x), %s (%x), %d\n", biosA0n[0x18], Ra0, a0, Ra1, a1, a2);
#endif
@@
-569,16
+612,30
@@
void psxBios_strncmp() { // 0x18
if (*p1++ == '\0') {
v0 = 0;
pc0 = ra;
if (*p1++ == '\0') {
v0 = 0;
pc0 = ra;
+ v1 = a2 - ((a2-n) - 1);
+ a0 += (a2-n) - 1;
+ a1 += (a2-n) - 1;
+ a2 = n;
return;
}
}
v0 = (n < 0 ? 0 : *p1 - *--p2);
pc0 = ra;
return;
}
}
v0 = (n < 0 ? 0 : *p1 - *--p2);
pc0 = ra;
+ v1 = a2 - ((a2-n) - 1);
+ a0 += (a2-n) - 1;
+ a1 += (a2-n) - 1;
+ a2 = n;
}
void psxBios_strcpy() { // 0x19
char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
}
void psxBios_strcpy() { // 0x19
char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
+ if (a0 == 0 || a1 == 0)
+ {
+ v0 = 0;
+ pc0 = ra;
+ return;
+ }
while ((*p1++ = *p2++) != '\0');
v0 = a0; pc0 = ra;
while ((*p1++ = *p2++) != '\0');
v0 = a0; pc0 = ra;
@@
-587,7
+644,12
@@
void psxBios_strcpy() { // 0x19
void psxBios_strncpy() { // 0x1a
char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
s32 n = a2, i;
void psxBios_strncpy() { // 0x1a
char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
s32 n = a2, i;
-
+ if (a0 == 0 || a1 == 0)
+ {
+ v0 = 0;
+ pc0 = ra;
+ return;
+ }
for (i = 0; i < n; i++) {
if ((*p1++ = *p2++) == '\0') {
while (++i < n) {
for (i = 0; i < n; i++) {
if ((*p1++ = *p2++) == '\0') {
while (++i < n) {
@@
-610,7
+672,13
@@
void psxBios_strlen() { // 0x1b
void psxBios_index() { // 0x1c
char *p = (char *)Ra0;
void psxBios_index() { // 0x1c
char *p = (char *)Ra0;
-
+ if (a0 == 0)
+ {
+ v0 = 0;
+ pc0 = ra;
+ return;
+ }
+
do {
if (*p == a1) {
v0 = a0 + (p - (char *)Ra0);
do {
if (*p == a1) {
v0 = a0 + (p - (char *)Ra0);
@@
-626,7
+694,11
@@
void psxBios_rindex() { // 0x1d
char *p = (char *)Ra0;
v0 = 0;
char *p = (char *)Ra0;
v0 = 0;
-
+ if (a0 == 0)
+ {
+ pc0 = ra;
+ return;
+ }
do {
if (*p == a1)
v0 = a0 + (p - (char *)Ra0);
do {
if (*p == a1)
v0 = a0 + (p - (char *)Ra0);
@@
-729,15
+801,34
@@
void psxBios_tolower() { // 0x26
void psxBios_bcopy() { // 0x27
char *p1 = (char *)Ra1, *p2 = (char *)Ra0;
void psxBios_bcopy() { // 0x27
char *p1 = (char *)Ra1, *p2 = (char *)Ra0;
+ v0 = a0;
+ if (a0 == 0 || a2 > 0x7FFFFFFF)
+ {
+ pc0 = ra;
+ return;
+ }
while ((s32)a2-- > 0) *p1++ = *p2++;
while ((s32)a2-- > 0) *p1++ = *p2++;
-
+ a2 = 0;
pc0 = ra;
}
void psxBios_bzero() { // 0x28
char *p = (char *)Ra0;
pc0 = ra;
}
void psxBios_bzero() { // 0x28
char *p = (char *)Ra0;
+ v0 = a0;
+ /* Same as memset here (See memset below) */
+ if (a1 > 0x7FFFFFFF || a1 == 0)
+ {
+ v0 = 0;
+ pc0 = ra;
+ return;
+ }
+ else if (a0 == 0)
+ {
+ pc0 = ra;
+ return;
+ }
while ((s32)a1-- > 0) *p++ = '\0';
while ((s32)a1-- > 0) *p++ = '\0';
-
+ a1 = 0;
pc0 = ra;
}
pc0 = ra;
}
@@
-759,22
+850,48
@@
void psxBios_bcmp() { // 0x29
void psxBios_memcpy() { // 0x2a
char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
void psxBios_memcpy() { // 0x2a
char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
- while ((s32)a2-- > 0) *p1++ = *p2++;
-
- v0 = a0; pc0 = ra;
+ s32 n=0;
+ v0 = a0;
+ if (a0 == 0 || a2 > 0x7FFFFFFF)
+ {
+ pc0 = ra;
+ return;
+ }
+ while ((s32)a2-- > 0) {
+ n++;
+ *p1++ = *p2++;
+ }
+ a2 = 0;
+ pc0 = ra;
}
void psxBios_memset() { // 0x2b
char *p = (char *)Ra0;
}
void psxBios_memset() { // 0x2b
char *p = (char *)Ra0;
+ v0 = a0;
+ if (a2 > 0x7FFFFFFF || a2 == 0)
+ {
+ v0 = 0;
+ pc0 = ra;
+ return;
+ }
+ if (a0 == 0)
+ {
+ pc0 = ra;
+ return;
+ }
while ((s32)a2-- > 0) *p++ = (char)a1;
while ((s32)a2-- > 0) *p++ = (char)a1;
-
a2 = 0;
v0 = a0; pc0 = ra;
}
void psxBios_memmove() { // 0x2c
char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
a2 = 0;
v0 = a0; pc0 = ra;
}
void psxBios_memmove() { // 0x2c
char *p1 = (char *)Ra0, *p2 = (char *)Ra1;
-
+ v0 = a0;
+ if (a0 == 0 || a2 > 0x7FFFFFFF)
+ {
+ pc0 = ra;
+ return;
+ }
if (p2 <= p1 && p2 + a2 > p1) {
a2++; // BUG: copy one more byte here
p1 += a2;
if (p2 <= p1 && p2 + a2 > p1) {
a2++; // BUG: copy one more byte here
p1 += a2;
@@
-783,8
+900,7
@@
void psxBios_memmove() { // 0x2c
} else {
while ((s32)a2-- > 0) *p1++ = *p2++;
}
} else {
while ((s32)a2-- > 0) *p1++ = *p2++;
}
-
- v0 = a0; pc0 = ra;
+ pc0 = ra;
}
void psxBios_memcmp() { // 0x2d
}
void psxBios_memcmp() { // 0x2d
@@
-929,6
+1045,11
@@
void psxBios_malloc() { // 0x33
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x33]);
#endif
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x33]);
#endif
+ if (!a0 || (!heap_size || !heap_addr)) {
+ v0 = 0;
+ pc0 = ra;
+ return;
+ }
// scan through heap and combine free chunks of space
chunk = heap_addr;
// scan through heap and combine free chunks of space
chunk = heap_addr;
@@
-938,6
+1059,15
@@
void psxBios_malloc() { // 0x33
csize = ((u32)*chunk) & 0xfffffffc;
cstat = ((u32)*chunk) & 1;
csize = ((u32)*chunk) & 0xfffffffc;
cstat = ((u32)*chunk) & 1;
+ // most probably broken heap descriptor
+ // this fixes Burning Road
+ if (*chunk == 0) {
+ newchunk = chunk;
+ dsize = ((uptr)heap_end - (uptr)chunk) - 4;
+ colflag = 1;
+ break;
+ }
+
// it's a free chunk
if(cstat == 1) {
if(colflag == 0) {
// it's a free chunk
if(cstat == 1) {
if(colflag == 0) {
@@
-969,28
+1099,36
@@
void psxBios_malloc() { // 0x33
// exit on uninitialized heap
if (chunk == NULL) {
// exit on uninitialized heap
if (chunk == NULL) {
-
SysP
rintf("malloc %x,%x: Uninitialized Heap!\n", v0, a0);
+
p
rintf("malloc %x,%x: Uninitialized Heap!\n", v0, a0);
v0 = 0;
pc0 = ra;
return;
}
// search an unused chunk that is big enough until the end of the heap
v0 = 0;
pc0 = ra;
return;
}
// search an unused chunk that is big enough until the end of the heap
- while ((dsize > csize || cstat
==
0) && chunk < heap_end ) {
+ while ((dsize > csize || cstat
==
0) && chunk < heap_end ) {
chunk = (u32*)((uptr)chunk + csize + 4);
chunk = (u32*)((uptr)chunk + csize + 4);
+
+ // catch out of memory
+ if(chunk >= heap_end) {
+ printf("malloc %x,%x: Out of memory error!\n",
+ v0, a0);
+ v0 = 0; pc0 = ra;
+ return;
+ }
+
csize = ((u32)*chunk) & 0xfffffffc;
cstat = ((u32)*chunk) & 1;
}
csize = ((u32)*chunk) & 0xfffffffc;
cstat = ((u32)*chunk) & 1;
}
- // catch out of memory
- if(chunk >= heap_end) { SysPrintf("malloc %x,%x: Out of memory error!\n", v0, a0); v0 = 0; pc0 = ra; return; }
-
// allocate memory
if(dsize == csize) {
// chunk has same size
*chunk &= 0xfffffffc;
// allocate memory
if(dsize == csize) {
// chunk has same size
*chunk &= 0xfffffffc;
- }
- else {
+ } else if (dsize > csize) {
+ v0 = 0; pc0 = ra;
+ return;
+ } else {
// split free chunk
*chunk = SWAP32(dsize);
newchunk = (u32*)((uptr)chunk + dsize + 4);
// split free chunk
*chunk = SWAP32(dsize);
newchunk = (u32*)((uptr)chunk + dsize + 4);
@@
-998,9
+1136,9
@@
void psxBios_malloc() { // 0x33
}
// return pointer to allocated memory
}
// return pointer to allocated memory
- v0 = ((u
nsigned long)chunk - (unsigned long
)psxM) + 4;
+ v0 = ((u
ptr)chunk - (uptr
)psxM) + 4;
v0|= 0x80000000;
v0|= 0x80000000;
-
SysP
rintf ("malloc %x,%x\n", v0, a0);
+
//p
rintf ("malloc %x,%x\n", v0, a0);
pc0 = ra;
}
pc0 = ra;
}
@@
-1012,7
+1150,8
@@
void psxBios_free() { // 0x34
SysPrintf("free %x: %x bytes\n", a0, *(u32*)(Ra0-4));
SysPrintf("free %x: %x bytes\n", a0, *(u32*)(Ra0-4));
- *(u32*)(Ra0-4) |= 1; // set chunk to free
+ if (a0)
+ *(u32*)(Ra0-4) |= 1; // set chunk to free
pc0 = ra;
}
pc0 = ra;
}
@@
-1610,7
+1749,6
@@
void psxBios_WaitEvent() { // 0a
v0 = 0;
pc0 = ra;
v0 = 0;
pc0 = ra;
- ResetIoCycle();
}
void psxBios_TestEvent() { // 0b
}
void psxBios_TestEvent() { // 0b
@@
-1668,8
+1806,20
@@
void psxBios_OpenTh() { // 0e
int th;
for (th=1; th<8; th++)
int th;
for (th=1; th<8; th++)
+ {
if (Thread[th].status == 0) break;
if (Thread[th].status == 0) break;
+ }
+ if (th == 8) {
+ // Feb 2019 - Added out-of-bounds fix caught by cppcheck:
+ // When no free TCB is found, return 0xffffffff according to Nocash doc.
+#ifdef PSXBIOS_LOG
+ PSXBIOS_LOG("\t%s() WARNING! No Free TCBs found!\n", __func__);
+#endif
+ v0 = 0xffffffff;
+ pc0 = ra;
+ return;
+ }
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x0e], th);
#endif
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x0e], th);
#endif
@@
-1761,9
+1911,10
@@
void psxBios_StopPAD() { // 14
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x14]);
#endif
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x14]);
#endif
-
+ if (pad_buf == 0){
pad_buf1 = NULL;
pad_buf2 = NULL;
pad_buf1 = NULL;
pad_buf2 = NULL;
+ }
pc0 = ra;
}
pc0 = ra;
}
@@
-2098,15
+2249,16
@@
void psxBios_firstfile() { // 42
pfile = ffile+5;
nfile = 1;
if (!strncmp(pa0, "bu00", 4)) {
pfile = ffile+5;
nfile = 1;
if (!strncmp(pa0, "bu00", 4)) {
+ // firstfile() calls _card_read() internally, so deliver it's event
+ DeliverEvent(0x11, 0x2);
bufile(1);
} else if (!strncmp(pa0, "bu10", 4)) {
bufile(1);
} else if (!strncmp(pa0, "bu10", 4)) {
+ // firstfile() calls _card_read() internally, so deliver it's event
+ DeliverEvent(0x11, 0x2);
bufile(2);
}
}
bufile(2);
}
}
- // firstfile() calls _card_read() internally, so deliver it's event
- DeliverEvent(0x11, 0x2);
-
pc0 = ra;
}
pc0 = ra;
}
@@
-2327,6
+2479,13
@@
void psxBios__new_card() { // 0x50
pc0 = ra;
}
pc0 = ra;
}
+/* According to a user, this allows Final Fantasy Tactics to save/load properly */
+void psxBios__get_error(void) // 55
+{
+ v0 = 0;
+ pc0 = ra;
+}
+
void psxBios_Krom2RawAdd() { // 0x51
int i = 0;
void psxBios_Krom2RawAdd() { // 0x51
int i = 0;
@@
-2749,7
+2908,7
@@
void psxBiosInit() {
//biosB0[0x52] = psxBios_sys_b0_52;
//biosB0[0x53] = psxBios_sys_b0_53;
//biosB0[0x54] = psxBios__get_errno;
//biosB0[0x52] = psxBios_sys_b0_52;
//biosB0[0x53] = psxBios_sys_b0_53;
//biosB0[0x54] = psxBios__get_errno;
-
//
biosB0[0x55] = psxBios__get_error;
+ biosB0[0x55] = psxBios__get_error;
biosB0[0x56] = psxBios_GetC0Table;
biosB0[0x57] = psxBios_GetB0Table;
biosB0[0x58] = psxBios__card_chan;
biosB0[0x56] = psxBios_GetC0Table;
biosB0[0x57] = psxBios_GetB0Table;
biosB0[0x58] = psxBios__card_chan;
@@
-2818,6
+2977,7
@@
void psxBiosInit() {
pad_buf1len = pad_buf2len = 0;
heap_addr = NULL;
heap_end = NULL;
pad_buf1len = pad_buf2len = 0;
heap_addr = NULL;
heap_end = NULL;
+ heap_size = 0;
CardState = -1;
CurThread = 0;
memset(FDesc, 0, sizeof(FDesc));
CardState = -1;
CurThread = 0;
memset(FDesc, 0, sizeof(FDesc));