PS2SDK
PS2 Homebrew Libraries
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
18#include <tamtypes.h>
19#include <ps2lib_err.h>
20#include <kernel.h>
21#include <sifrpc.h>
22#include <string.h>
23
24#include <loadfile.h>
25#include <iopheap.h>
26#include <fcntl.h>
27#include <unistd.h>
28
29extern int _iop_reboot_count;
30extern SifRpcClientData_t _lf_cd;
31extern int _lf_init;
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
36#if defined(F_SifLoadFileInit)
38int _lf_init = 0;
39
41{
42 int res;
43 static int _rb_count = 0;
44 if (_rb_count != _iop_reboot_count) {
45 _rb_count = _iop_reboot_count;
46 memset(&_lf_cd, 0, sizeof _lf_cd);
47 _lf_init = 0;
48 }
49
50 if (_lf_init)
51 return 0;
52
53 SifInitRpc(0);
54
55 while ((res = SifBindRpc(&_lf_cd, 0x80000006, 0)) >= 0 && !_lf_cd.server)
56 nopdelay();
57
58 if (res < 0)
59 return -E_SIF_RPC_BIND;
60
61 _lf_init = 1;
62 return 0;
63}
64#endif
65
66#if defined(F_SifLoadFileExit)
67void SifLoadFileExit()
68{
69 _lf_init = 0;
70 memset(&_lf_cd, 0, sizeof _lf_cd);
71}
72#endif
73
74#ifdef F__SifLoadModule
75int _SifLoadModule(const char *path, int arg_len, const char *args, int *modres,
76 int fno, int dontwait)
77{
78 struct _lf_module_load_arg arg;
79
80 if (SifLoadFileInit() < 0)
81 return -SCE_EBINDMISS;
82
83 memset(&arg, 0, sizeof arg);
84
85 strncpy(arg.path, path, LF_PATH_MAX - 1);
86 arg.path[LF_PATH_MAX - 1] = 0;
87
88 if (args && arg_len) {
89 arg.p.arg_len = arg_len > LF_ARG_MAX ? LF_ARG_MAX : arg_len;
90 memcpy(arg.args, args, arg.p.arg_len);
91 } else {
92 arg.p.arg_len = 0;
93 }
94
95 if (SifCallRpc(&_lf_cd, fno, dontwait, &arg, sizeof arg, &arg, 8, NULL, NULL) < 0)
96 return -SCE_ECALLMISS;
97
98 if (modres)
99 *modres = arg.modres;
100
101 return arg.p.result;
102}
103#endif
104
105#if defined(F_SifLoadModule)
106int SifLoadModule(const char *path, int arg_len, const char *args)
107{
108 return _SifLoadModule(path, arg_len, args, NULL, LF_F_MOD_LOAD, 0);
109}
110#endif
111
112#if defined(F_SifLoadStartModule)
113int SifLoadStartModule(const char *path, int arg_len, const char *args, int *mod_res)
114{
115 return _SifLoadModule(path, arg_len, args, mod_res, LF_F_MOD_LOAD, 0);
116}
117#endif
118
119#if defined(F_SifLoadModuleEncrypted)
120int SifLoadModuleEncrypted(const char *path, int arg_len, const char *args)
121{
122 return _SifLoadModule(path, arg_len, args, NULL, LF_F_MG_MOD_LOAD, 0);
123}
124#endif
125
126#ifdef F_SifStopModule
127int SifStopModule(int id, int arg_len, const char *args, int *mod_res)
128{
129 struct _lf_module_stop_arg arg;
130
131 if (SifLoadFileInit() < 0)
132 return -SCE_EBINDMISS;
133
134 arg.p.id = id;
135
136 if (args && arg_len) {
137 arg.q.arg_len = arg_len > LF_ARG_MAX ? LF_ARG_MAX : arg_len;
138 memcpy(arg.args, args, arg.q.arg_len);
139 } else {
140 arg.q.arg_len = 0;
141 }
142
143 if (SifCallRpc(&_lf_cd, LF_F_MOD_STOP, 0, &arg, sizeof arg, &arg, 8, NULL, NULL) < 0)
144 return -SCE_ECALLMISS;
145
146 if (mod_res)
147 *mod_res = arg.q.modres;
148
149 return arg.p.result;
150}
151#endif
152
153#ifdef F_SifUnloadModule
154int SifUnloadModule(int id)
155{
156 union _lf_module_unload_arg arg;
157
158 if (SifLoadFileInit() < 0)
159 return -SCE_EBINDMISS;
160
161 arg.id = id;
162
163 if (SifCallRpc(&_lf_cd, LF_F_MOD_UNLOAD, 0, &arg, sizeof arg, &arg, 4, NULL, NULL) < 0)
164 return -SCE_ECALLMISS;
165
166 return arg.result;
167}
168#endif
169
170#ifdef F_SifSearchModuleByName
171int SifSearchModuleByName(const char *name)
172{
174 if (SifLoadFileInit() < 0)
175 return -SCE_EBINDMISS;
176
177 strncpy(arg.name, name, LF_PATH_MAX - 1);
178 arg.name[LF_PATH_MAX - 1] = 0;
179
180 if (SifCallRpc(&_lf_cd, LF_F_SEARCH_MOD_BY_NAME, 0, &arg, sizeof arg, &arg, 4, NULL, NULL) < 0)
181 return -SCE_ECALLMISS;
182
183 return arg.id;
184}
185#endif
186
187#ifdef F_SifSearchModuleByAddress
188int SifSearchModuleByAddress(const void *ptr)
189{
191 if (SifLoadFileInit() < 0)
192 return -SCE_EBINDMISS;
193
194 arg.p.ptr = ptr;
195
196 if (SifCallRpc(&_lf_cd, LF_F_SEARCH_MOD_BY_ADDRESS, 0, &arg, sizeof arg, &arg, 4, NULL, NULL) < 0)
197 return -SCE_ECALLMISS;
198
199 return arg.p.id;
200}
201#endif
202
203#ifdef F__SifLoadElfPart
204int _SifLoadElfPart(const char *path, const char *secname, t_ExecData *data, int fno)
205{
206 struct _lf_elf_load_arg arg;
207
208 if (SifLoadFileInit() < 0)
209 return -SCE_EBINDMISS;
210
211 strncpy(arg.path, path, LF_PATH_MAX - 1);
212 strncpy(arg.secname, secname, LF_ARG_MAX - 1);
213 arg.path[LF_PATH_MAX - 1] = 0;
214 arg.secname[LF_ARG_MAX - 1] = 0;
215
216 if (SifCallRpc(&_lf_cd, fno, 0, &arg, sizeof arg, &arg,
217 sizeof(t_ExecData), NULL, NULL) < 0)
218 return -SCE_ECALLMISS;
219
220 if (arg.epc != 0) {
221 data->epc = arg.epc;
222 data->gp = arg.gp;
223
224 return 0;
225 } else
226 return -SCE_ELOADMISS;
227}
228#endif
229
230#if defined(F_SifLoadElfPart)
231int SifLoadElfPart(const char *path, const char *secname, t_ExecData *data)
232{
233 return _SifLoadElfPart(path, secname, data, LF_F_ELF_LOAD);
234}
235#endif
236
237#if defined(F_SifLoadElf)
238int SifLoadElf(const char *path, t_ExecData *data)
239{
240 u32 secname = 0x6c6c61; /* "all" */
241 return _SifLoadElfPart(path, (char *)&secname, data, LF_F_ELF_LOAD);
242}
243#endif
244
245#if defined(F_SifLoadElfEncrypted)
246int SifLoadElfEncrypted(const char *path, t_ExecData *data)
247{
248 u32 secname = 0x6c6c61; /* "all" */
249 return _SifLoadElfPart(path, (char *)&secname, data, LF_F_MG_ELF_LOAD);
250}
251#endif
252
253#if defined(F_SifIopSetVal)
254int SifIopSetVal(u32 iop_addr, int val, int type)
255{
256 struct _lf_iop_val_arg arg;
257
258 if (SifLoadFileInit() < 0)
259 return -SCE_EBINDMISS;
260
261 switch (type) {
262 case LF_VAL_BYTE:
263 arg.val.b = (u8)(val & 0xff);
264 break;
265 case LF_VAL_SHORT:
266 arg.val.s = (u16)(val & 0xffff);
267 break;
268 case LF_VAL_LONG:
269 arg.val.l = val;
270 break;
271 default:
272 return -E_LIB_INVALID_ARG;
273 }
274
275 arg.p.iop_addr = iop_addr;
276 arg.type = type;
277
278 if (SifCallRpc(&_lf_cd, LF_F_SET_ADDR, 0, &arg, sizeof arg, &arg, 4,
279 NULL, NULL) < 0)
280 return -SCE_ECALLMISS;
281
282 return arg.p.result;
283}
284#endif
285
286#if defined(F_SifIopGetVal)
287int SifIopGetVal(u32 iop_addr, void *val, int type)
288{
289 struct _lf_iop_val_arg arg;
290
291 if (SifLoadFileInit() < 0)
292 return -SCE_EBINDMISS;
293
294 arg.p.iop_addr = iop_addr;
295 arg.type = type;
296
297 if (SifCallRpc(&_lf_cd, LF_F_GET_ADDR, 0, &arg, sizeof arg, &arg, 4,
298 NULL, NULL) < 0)
299 return -SCE_ECALLMISS;
300
301 if (val) {
302 switch (type) {
303 case LF_VAL_BYTE:
304 *(u8 *)val = (u8)arg.p.result & 0xff;
305 break;
306 case LF_VAL_SHORT:
307 *(u16 *)val = (u16)arg.p.result & 0xffff;
308 break;
309 case LF_VAL_LONG:
310 *(u32 *)val = arg.p.result;
311 break;
312 }
313 }
314
315 return 0;
316}
317#endif
318
319#ifdef F__SifLoadModuleBuffer
320int _SifLoadModuleBuffer(void *ptr, int arg_len, const char *args, int *modres)
321{
323
324 if (SifLoadFileInit() < 0)
325 return -SCE_EBINDMISS;
326
327 memset(&arg, 0, sizeof arg);
328
329 arg.p.ptr = ptr;
330 if (args && arg_len) {
331 arg.q.arg_len = arg_len > LF_ARG_MAX ? LF_ARG_MAX : arg_len;
332 memcpy(arg.args, args, arg.q.arg_len);
333 } else {
334 arg.q.arg_len = 0;
335 }
336
337 if (SifCallRpc(&_lf_cd, LF_F_MOD_BUF_LOAD, 0, &arg, sizeof arg, &arg, 8,
338 NULL, NULL) < 0)
339 return -SCE_ECALLMISS;
340
341 if (modres)
342 *modres = arg.q.modres;
343
344 return arg.p.result;
345}
346#endif
347
348#if defined(F_SifLoadModuleBuffer)
349int SifLoadModuleBuffer(void *ptr, int arg_len, const char *args)
350{
351 return _SifLoadModuleBuffer(ptr, arg_len, args, NULL);
352}
353#endif
354
355#if defined(F_SifLoadStartModuleBuffer)
356int SifLoadStartModuleBuffer(void *ptr, int arg_len, const char *args, int *mod_res)
357{
358 return _SifLoadModuleBuffer(ptr, arg_len, args, mod_res);
359}
360#endif
361
362#if defined(F_SifExecModuleBuffer)
363int SifExecModuleBuffer(void *ptr, u32 size, u32 arg_len, const char *args, int *mod_res)
364{
365 SifDmaTransfer_t dmat;
366 void *iop_addr;
367 int res;
368 unsigned int qid;
369
370 /* Round the size up to the nearest 16 bytes. */
371 size = (size + 15) & -16;
372
373 if (!(iop_addr = SifAllocIopHeap(size)))
374 return -E_IOP_NO_MEMORY;
375
376 dmat.src = ptr;
377 dmat.dest = iop_addr;
378 dmat.size = size;
379 dmat.attr = 0;
380 SifWriteBackDCache(ptr, size);
381 qid = SifSetDma(&dmat, 1);
382
383 if (!qid)
384 return -1; // should have a better error here...
385
386 while (SifDmaStat(qid) >= 0)
387 ;
388
389 res = _SifLoadModuleBuffer(iop_addr, arg_len, args, mod_res);
390 SifFreeIopHeap(iop_addr);
391
392 return res;
393}
394#endif
395
396#if defined(F_SifExecModuleFile)
397int SifExecModuleFile(const char *path, u32 arg_len, const char *args, int *mod_res)
398{
399 void *iop_addr;
400 int res, size, fd;
401
402 if ((fd = open(path, O_RDONLY)) < 0)
403 return fd;
404
405 if ((size = lseek(fd, 0, SEEK_END)) < 0)
406 return size;
407
408 close(fd);
409
410 if (!(iop_addr = SifAllocIopHeap(size)))
411 return -E_IOP_NO_MEMORY;
412
413 if ((res = SifLoadIopHeap(path, iop_addr)) < 0) {
414 SifFreeIopHeap(iop_addr);
415 return res;
416 }
417
418 res = _SifLoadModuleBuffer(iop_addr, arg_len, args, mod_res);
419 SifFreeIopHeap(iop_addr);
420
421 return res;
422}
423#endif
int SifLoadModuleEncrypted(const char *path, int arg_len, const char *args)
int SifLoadModule(const char *path, int arg_len, const char *args)
int SifLoadStartModuleBuffer(void *ptr, int arg_len, const char *args, int *mod_res)
void SifLoadFileExit(void)
int SifLoadElf(const char *path, t_ExecData *data)
int SifLoadElfPart(const char *path, const char *secname, t_ExecData *data)
int SifLoadElfEncrypted(const char *path, t_ExecData *data)
int SifExecModuleBuffer(void *ptr, u32 size, u32 arg_len, const char *args, int *mod_res)
int SifLoadFileInit(void)
int SifIopSetVal(u32 iop_addr, int val, int type)
int SifExecModuleFile(const char *path, u32 arg_len, const char *args, int *mod_res)
int _SifLoadModule(const char *path, int arg_len, const char *args, int *modres, int fno, int dontwait)
int SifIopGetVal(u32 iop_addr, void *val, int type)
int SifLoadModuleBuffer(void *ptr, int arg_len, const char *args)
int SifLoadStartModule(const char *path, int arg_len, const char *args, int *mod_res)
#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:78
@ E_IOP_NO_MEMORY
Definition ps2lib_err.h:64
@ E_SIF_RPC_BIND
Definition ps2lib_err.h:86