sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Loading...
Searching...
No Matches
loadfile.c
Go to the documentation of this file.
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# (C)2001, Gustavo Scotti (gustavo@scotti.com)
7# (c) 2003 Marcus R. Brown (mrbrown@0xd6.org)
8# Licenced under Academic Free License version 2.0
9# Review ps2sdk README & LICENSE files for further details.
10*/
11
17
18#include <tamtypes.h>
19#include <ps2lib_err.h>
20#include <kernel.h>
21#include <sifrpc.h>
22#include <string.h>
23#include <iopcontrol.h>
24#include "sifarg.h"
25
26#include <loadfile.h>
27#include <iopheap.h>
28#include <fcntl.h>
29#include <unistd.h>
30
31extern SifRpcClientData_t _lf_cd;
32
33int _SifLoadElfPart(const char *path, const char *secname, t_ExecData *data, int fno);
34int _SifLoadModuleBuffer(void *ptr, int arg_len, const char *args, int *modres);
35
36SifRpcClientData_t _lf_cd;
37
39{
40 int res;
41
42 if (HasIopRebootedSinceLastCall())
44
45 if (_lf_cd.server)
46 return 0;
47
48 sceSifInitRpc(0);
49
50 while ((res = sceSifBindRpc(&_lf_cd, 0x80000006, 0)) >= 0 && !_lf_cd.server)
51 nopdelay();
52
53 if (res < 0)
54 return -E_SIF_RPC_BIND;
55
56 return 0;
57}
58
60{
61 memset(&_lf_cd, 0, sizeof _lf_cd);
62}
63
64int _SifLoadModule(const char *path, int arg_len, const char *args, int *modres,
65 int fno, int dontwait)
66{
67 SIF_ARG(struct _lf_module_load_arg, arg);
68
69 if (SifLoadFileInit() < 0)
70 return -SCE_EBINDMISS;
71
72 memset(arg, 0, sizeof *arg);
73
74 strlcpy(arg->path, path, sizeof(arg->path));
75
76 if (args && arg_len) {
77 arg->p.arg_len = arg_len > LF_ARG_MAX ? LF_ARG_MAX : arg_len;
78 memcpy(arg->args, args, arg->p.arg_len);
79 } else {
80 arg->p.arg_len = 0;
81 }
82
83 if (sceSifCallRpc(&_lf_cd, fno, dontwait, arg, sizeof *arg, arg, 8, NULL, NULL) < 0)
84 return -SCE_ECALLMISS;
85
86 if (modres)
87 *modres = arg->modres;
88
89 return arg->p.result;
90}
91
92int SifLoadModule(const char *path, int arg_len, const char *args)
93{
94 return _SifLoadModule(path, arg_len, args, NULL, LF_F_MOD_LOAD, 0);
95}
96
97int SifLoadStartModule(const char *path, int arg_len, const char *args, int *mod_res)
98{
99 return _SifLoadModule(path, arg_len, args, mod_res, LF_F_MOD_LOAD, 0);
100}
101
102int SifLoadModuleEncrypted(const char *path, int arg_len, const char *args)
103{
104 return _SifLoadModule(path, arg_len, args, NULL, LF_F_MG_MOD_LOAD, 0);
105}
106
107int SifStopModule(int id, int arg_len, const char *args, int *mod_res)
108{
109 SIF_ARG(struct _lf_module_stop_arg, arg);
110
111 if (SifLoadFileInit() < 0)
112 return -SCE_EBINDMISS;
113
114 arg->p.id = id;
115
116 if (args && arg_len) {
117 arg->q.arg_len = arg_len > LF_ARG_MAX ? LF_ARG_MAX : arg_len;
118 memcpy(arg->args, args, arg->q.arg_len);
119 } else {
120 arg->q.arg_len = 0;
121 }
122
123 if (sceSifCallRpc(&_lf_cd, LF_F_MOD_STOP, 0, arg, sizeof *arg, arg, 8, NULL, NULL) < 0)
124 return -SCE_ECALLMISS;
125
126 if (mod_res)
127 *mod_res = arg->q.modres;
128
129 return arg->p.result;
130}
131
132int SifUnloadModule(int id)
133{
134 SIF_ARG(union _lf_module_unload_arg, arg);
135
136 if (SifLoadFileInit() < 0)
137 return -SCE_EBINDMISS;
138
139 arg->id = id;
140
141 if (sceSifCallRpc(&_lf_cd, LF_F_MOD_UNLOAD, 0, arg, sizeof *arg, arg, 4, NULL, NULL) < 0)
142 return -SCE_ECALLMISS;
143
144 return arg->result;
145}
146
147int SifSearchModuleByName(const char *name)
148{
149 SIF_ARG(struct _lf_search_module_by_name_arg, arg);
150 if (SifLoadFileInit() < 0)
151 return -SCE_EBINDMISS;
152
153 strlcpy(arg->name, name, sizeof(arg->name));
154
155 if (sceSifCallRpc(&_lf_cd, LF_F_SEARCH_MOD_BY_NAME, 0, arg, sizeof *arg, arg, 4, NULL, NULL) < 0)
156 return -SCE_ECALLMISS;
157
158 return arg->id;
159}
160
161int SifSearchModuleByAddress(const void *ptr)
162{
163 SIF_ARG(struct _lf_search_module_by_address_arg, arg);
164 if (SifLoadFileInit() < 0)
165 return -SCE_EBINDMISS;
166
167 arg->p.ptr = ptr;
168
169 if (sceSifCallRpc(&_lf_cd, LF_F_SEARCH_MOD_BY_ADDRESS, 0, arg, sizeof *arg, arg, 4, NULL, NULL) < 0)
170 return -SCE_ECALLMISS;
171
172 return arg->p.id;
173}
174
175int _SifLoadElfPart(const char *path, const char *secname, t_ExecData *data, int fno)
176{
177 SIF_ARG(struct _lf_elf_load_arg, arg);
178
179 if (SifLoadFileInit() < 0)
180 return -SCE_EBINDMISS;
181
182 strlcpy(arg->path, path, sizeof(arg->path));
183 strlcpy(arg->secname, secname, sizeof(arg->secname));
184
185 if (sceSifCallRpc(&_lf_cd, fno, 0, arg, sizeof *arg, arg,
186 sizeof(t_ExecData), NULL, NULL) < 0)
187 return -SCE_ECALLMISS;
188
189 if (arg->epc != 0) {
190 data->epc = arg->epc;
191 data->gp = arg->gp;
192
193 return 0;
194 } else
195 return -SCE_ELOADMISS;
196}
197
198int SifLoadElfPart(const char *path, const char *secname, t_ExecData *data)
199{
200 return _SifLoadElfPart(path, secname, data, LF_F_ELF_LOAD);
201}
202
203int SifLoadElf(const char *path, t_ExecData *data)
204{
205 u32 secname = 0x6c6c61; /* "all" */
206 return _SifLoadElfPart(path, (char *)&secname, data, LF_F_ELF_LOAD);
207}
208
209int SifLoadElfEncrypted(const char *path, t_ExecData *data)
210{
211 u32 secname = 0x6c6c61; /* "all" */
212 return _SifLoadElfPart(path, (char *)&secname, data, LF_F_MG_ELF_LOAD);
213}
214
215int SifIopSetVal(u32 iop_addr, int val, int type)
216{
217 SIF_ARG(struct _lf_iop_val_arg, arg);
218
219 if (SifLoadFileInit() < 0)
220 return -SCE_EBINDMISS;
221
222 switch (type) {
223 case LF_VAL_BYTE:
224 arg->val.b = (u8)(val & 0xff);
225 break;
226 case LF_VAL_SHORT:
227 arg->val.s = (u16)(val & 0xffff);
228 break;
229 case LF_VAL_LONG:
230 arg->val.l = val;
231 break;
232 default:
233 return -E_LIB_INVALID_ARG;
234 }
235
236 arg->p.iop_addr = iop_addr;
237 arg->type = type;
238
239 if (sceSifCallRpc(&_lf_cd, LF_F_SET_ADDR, 0, arg, sizeof *arg, arg, 4,
240 NULL, NULL) < 0)
241 return -SCE_ECALLMISS;
242
243 return arg->p.result;
244}
245
246int SifIopGetVal(u32 iop_addr, void *val, int type)
247{
248 SIF_ARG(struct _lf_iop_val_arg, arg);
249
250 if (SifLoadFileInit() < 0)
251 return -SCE_EBINDMISS;
252
253 arg->p.iop_addr = iop_addr;
254 arg->type = type;
255
256 if (sceSifCallRpc(&_lf_cd, LF_F_GET_ADDR, 0, arg, sizeof *arg, arg, 4,
257 NULL, NULL) < 0)
258 return -SCE_ECALLMISS;
259
260 if (val) {
261 switch (type) {
262 case LF_VAL_BYTE:
263 *(u8 *)val = (u8)arg->p.result & 0xff;
264 break;
265 case LF_VAL_SHORT:
266 *(u16 *)val = (u16)arg->p.result & 0xffff;
267 break;
268 case LF_VAL_LONG:
269 *(u32 *)val = arg->p.result;
270 break;
271 }
272 }
273
274 return 0;
275}
276
277int _SifLoadModuleBuffer(void *ptr, int arg_len, const char *args, int *modres)
278{
279 SIF_ARG(struct _lf_module_buffer_load_arg, arg);
280
281 if (SifLoadFileInit() < 0)
282 return -SCE_EBINDMISS;
283
284 memset(arg, 0, sizeof *arg);
285
286 arg->p.ptr = ptr;
287 if (args && arg_len) {
288 arg->q.arg_len = arg_len > LF_ARG_MAX ? LF_ARG_MAX : arg_len;
289 memcpy(arg->args, args, arg->q.arg_len);
290 } else {
291 arg->q.arg_len = 0;
292 }
293
294 if (sceSifCallRpc(&_lf_cd, LF_F_MOD_BUF_LOAD, 0, arg, sizeof *arg, arg, 8,
295 NULL, NULL) < 0)
296 return -SCE_ECALLMISS;
297
298 if (modres)
299 *modres = arg->q.modres;
300
301 return arg->p.result;
302}
303
304int SifLoadModuleBuffer(void *ptr, int arg_len, const char *args)
305{
306 return _SifLoadModuleBuffer(ptr, arg_len, args, NULL);
307}
308
309int SifLoadStartModuleBuffer(void *ptr, int arg_len, const char *args, int *mod_res)
310{
311 return _SifLoadModuleBuffer(ptr, arg_len, args, mod_res);
312}
313
314int SifExecModuleBuffer(void *ptr, u32 size, u32 arg_len, const char *args, int *mod_res)
315{
316 SifDmaTransfer_t dmat;
317 void *iop_addr;
318 int res;
319 unsigned int qid;
320
321 /* Round the size up to the nearest 16 bytes. */
322 size = (size + 15) & -16;
323
324 if (!(iop_addr = SifAllocIopHeap(size)))
325 return -E_IOP_NO_MEMORY;
326
327 dmat.src = ptr;
328 dmat.dest = iop_addr;
329 dmat.size = size;
330 dmat.attr = 0;
331 sceSifWriteBackDCache(ptr, size);
332 qid = sceSifSetDma(&dmat, 1);
333
334 if (!qid)
335 return -1; // should have a better error here...
336
337 while (sceSifDmaStat(qid) >= 0)
338 ;
339
340 res = _SifLoadModuleBuffer(iop_addr, arg_len, args, mod_res);
341 SifFreeIopHeap(iop_addr);
342
343 return res;
344}
345
346int SifExecModuleFile(const char *path, u32 arg_len, const char *args, int *mod_res)
347{
348 void *iop_addr;
349 int res, size, fd;
350
351 if ((fd = open(path, O_RDONLY)) < 0)
352 return fd;
353
354 if ((size = lseek(fd, 0, SEEK_END)) < 0)
355 return size;
356
357 close(fd);
358
359 if (!(iop_addr = SifAllocIopHeap(size)))
360 return -E_IOP_NO_MEMORY;
361
362 if ((res = SifLoadIopHeap(path, iop_addr)) < 0) {
363 SifFreeIopHeap(iop_addr);
364 return res;
365 }
366
367 res = _SifLoadModuleBuffer(iop_addr, arg_len, args, mod_res);
368 SifFreeIopHeap(iop_addr);
369
370 return res;
371}
int SifLoadModuleEncrypted(const char *path, int arg_len, const char *args)
Definition loadfile.c:102
int SifLoadModule(const char *path, int arg_len, const char *args)
Definition loadfile.c:92
int SifLoadStartModuleBuffer(void *ptr, int arg_len, const char *args, int *mod_res)
Definition loadfile.c:309
void SifLoadFileExit(void)
Definition loadfile.c:59
int SifLoadElf(const char *path, t_ExecData *data)
Definition loadfile.c:203
int SifLoadElfPart(const char *path, const char *secname, t_ExecData *data)
Definition loadfile.c:198
int SifLoadElfEncrypted(const char *path, t_ExecData *data)
Definition loadfile.c:209
int SifExecModuleBuffer(void *ptr, u32 size, u32 arg_len, const char *args, int *mod_res)
Definition loadfile.c:314
int SifLoadFileInit(void)
Definition loadfile.c:38
int SifIopSetVal(u32 iop_addr, int val, int type)
Definition loadfile.c:215
int SifExecModuleFile(const char *path, u32 arg_len, const char *args, int *mod_res)
Definition loadfile.c:346
int _SifLoadModule(const char *path, int arg_len, const char *args, int *modres, int fno, int dontwait)
Definition loadfile.c:64
int SifIopGetVal(u32 iop_addr, void *val, int type)
Definition loadfile.c:246
int SifLoadModuleBuffer(void *ptr, int arg_len, const char *args)
Definition loadfile.c:304
int SifLoadStartModule(const char *path, int arg_len, const char *args, int *mod_res)
Definition loadfile.c:97
#define SCE_ELOADMISS
Definition loadfile.h:29
#define SCE_ECALLMISS
Definition loadfile.h:27
#define SCE_EBINDMISS
Definition loadfile.h:25
@ E_LIB_INVALID_ARG
Definition ps2lib_err.h:79
@ E_IOP_NO_MEMORY
Definition ps2lib_err.h:65
@ E_SIF_RPC_BIND
Definition ps2lib_err.h:87