sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Loading...
Searching...
No Matches
patch_fileio.c
1#include <tamtypes.h>
2#include <kernel.h>
3#include <sifrpc.h>
4#include <iopheap.h>
5#include <string.h>
6
7#include "slib.h"
8#include "smod.h"
9
10#include "common.h"
11
12#define JMP(addr) (0x08000000|(0x3ffffff&((addr)>>2)))
13#define JAL(addr) (0x0c000000 | (0x3ffffff & ((addr) >> 2)))
14
15static const u32 g_new_fileio[20] = {
16 //sceFioRemove fix
17 0x0c0001ce, // jal +0x738 <- jal fio_remove
18 0x00000000, // nop
19 0x0800033a, // j +0xce8 <- j rpc_handler_exit
20 0x00000000, // nop
21 //sceFioGetstat()/sceFioDread() fix
22 0x27bdfff0, // addiu sp,sp,-16
23 0xafbf0000, // sw ra,0(sp)
24 0xafa40004, // sw a0,4(sp)
25 0xafa50008, // sw a1,8(sp)
26 0x0c000423, // jal +0x108c <- jal CpuSuspendIntr
27 0x27a4000c, // addiu a0,sp,12
28 0x8fa40004, // lw a0,4(sp)
29 0x0c000430, // jal +0x10c0 <- jal sceSifSetDma
30 0x8fa50008, // lw a1,8(sp)
31 0x8fa4000c, // lw a0,12(sp)
32 0x0c000425, // jal +0x1094 <- jal CpuResumeIntr
33 0xafa20004, // sw v0,4(sp)
34 0x8fbf0000, // lw ra,0(sp)
35 0x8fa20004, // lw v0,4(sp)
36 0x03e00008, // jr ra
37 0x27bd0010, // addiu sp,sp,16
38};
39
41{
42 /* This patch is a fix for FILEIO on the IOP:
43 The handler of rpc_fioremove doesn't exit right after file is
44 removed due to the break being missing, which ends up
45 calling the mkdir RPC handler in succession.
46 A folder with the same name as the deleted file will be created.
47 We'll search for FILEIO text section start and patch the rpc
48 handler to jump to a subroutine to correct this.
49
50 The RPC handlers for getstat() and dread() do not suspend interrupts
51 before invoking sceSifSetDma(), which may result in a race condition
52 that destroys the internal SIF data structure within SIFMAN. */
53
54 smod_mod_info_t mod_info;
55 SifDmaTransfer_t dmat;
56 static u32 new_fileio[sizeof(g_new_fileio)/sizeof(g_new_fileio[0])] ALIGNED(16);
57 u32 *p_new_fileio;
58 u32 new_jump_op;
59 void *patch_addr;
60
61 memcpy(UNCACHED_SEG(new_fileio), g_new_fileio, sizeof(g_new_fileio));
62 memset(&mod_info, 0, sizeof(mod_info));
63 int ret = smod_get_mod_by_name("FILEIO_service", &mod_info);
64 if ((!ret) || (mod_info.version != 0x101))
65 return -1;
66
67 SifInitIopHeap();
68 if((patch_addr = SifAllocIopHeap(sizeof(new_fileio))) == NULL)
69 return -1;
70
71 /* setup our jump opcodes */
72 p_new_fileio = UNCACHED_SEG(new_fileio);
73
74 //For the sceFioRemove() patch
75 p_new_fileio[0] += ((u32)mod_info.text_start >> 2);
76 p_new_fileio[2] += ((u32)mod_info.text_start >> 2);
77
78 //For the sceFioGetstat() and sceFioDread() patch
79 p_new_fileio[8] += ((u32)mod_info.text_start >> 2);
80 p_new_fileio[11] += ((u32)mod_info.text_start >> 2);
81 p_new_fileio[14] += ((u32)mod_info.text_start >> 2);
82
83 /* apply it */
84 dmat.src=new_fileio;
85 dmat.dest=patch_addr;
86 dmat.size=sizeof(new_fileio);
87 dmat.attr=0;
88 sceSifSetDma(&dmat, 1);
89
90 //For the dump to sceRemove()
91 new_jump_op = JMP((u32)patch_addr);
92 smem_write_word((void *)((u8 *)mod_info.text_start + 0x0bb8), new_jump_op);
93 new_jump_op = JAL((u32)patch_addr + 16);
94 //For the jumps to sceSifSetDma within sceGetstat() and sceDread():
95 smem_write_word((void *)((u8 *)mod_info.text_start + 0x09cc), new_jump_op);
96 smem_write_word((void *)((u8 *)mod_info.text_start + 0x0a58), new_jump_op);
97
98 return 0;
99}
ModuleInfo_t * smod_get_mod_by_name(const char *name)
Definition smod.c:63
int sbv_patch_fileio(void)
struct _smod_mod_info smod_mod_info_t