PS2SDK
PS2 Homebrew Libraries
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 
29 extern int _iop_reboot_count;
30 extern SifRpcClientData_t _lf_cd;
31 extern int _lf_init;
32 
33 int _SifLoadElfPart(const char *path, const char *secname, t_ExecData *data, int fno);
34 int _SifLoadModuleBuffer(void *ptr, int arg_len, const char *args, int *modres);
35 
36 #if defined(F_SifLoadFileInit)
37 SifRpcClientData_t _lf_cd;
38 int _lf_init = 0;
39 
40 int SifLoadFileInit()
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  sceSifInitRpc(0);
54 
55  while ((res = sceSifBindRpc(&_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)
67 void SifLoadFileExit()
68 {
69  _lf_init = 0;
70  memset(&_lf_cd, 0, sizeof _lf_cd);
71 }
72 #endif
73 
74 #ifdef F__SifLoadModule
75 int _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 (sceSifCallRpc(&_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)
106 int 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)
113 int 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)
120 int 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
127 int 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 (sceSifCallRpc(&_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
154 int 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 (sceSifCallRpc(&_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
171 int 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 (sceSifCallRpc(&_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
188 int SifSearchModuleByAddress(const void *ptr)
189 {
191  if (SifLoadFileInit() < 0)
192  return -SCE_EBINDMISS;
193 
194  arg.p.ptr = ptr;
195 
196  if (sceSifCallRpc(&_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
204 int _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 (sceSifCallRpc(&_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)
231 int 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)
238 int 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)
246 int 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)
254 int 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 (sceSifCallRpc(&_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)
287 int 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 (sceSifCallRpc(&_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
320 int _SifLoadModuleBuffer(void *ptr, int arg_len, const char *args, int *modres)
321 {
322  struct _lf_module_buffer_load_arg arg;
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 (sceSifCallRpc(&_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)
349 int 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)
356 int 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)
363 int 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  sceSifWriteBackDCache(ptr, size);
381  qid = sceSifSetDma(&dmat, 1);
382 
383  if (!qid)
384  return -1; // should have a better error here...
385 
386  while (sceSifDmaStat(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)
397 int 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
kernel.h
ps2lib_err.h
SifExecModuleBuffer
int SifExecModuleBuffer(void *ptr, u32 size, u32 arg_len, const char *args, int *mod_res)
SifLoadElfPart
int SifLoadElfPart(const char *path, const char *secname, t_ExecData *data)
SCE_ECALLMISS
#define SCE_ECALLMISS
Definition: loadfile.h:27
SCE_ELOADMISS
#define SCE_ELOADMISS
Definition: loadfile.h:29
_lf_search_module_by_name_arg
Definition: loadfile-common.h:111
SifLoadFileInit
int SifLoadFileInit(void)
_lf_module_stop_arg
Definition: loadfile-common.h:89
loadfile.h
E_LIB_INVALID_ARG
@ E_LIB_INVALID_ARG
Definition: ps2lib_err.h:78
SifLoadModuleEncrypted
int SifLoadModuleEncrypted(const char *path, int arg_len, const char *args)
_lf_module_load_arg
Definition: loadfile-common.h:77
iopheap.h
_lf_module_buffer_load_arg
Definition: loadfile-common.h:136
_lf_elf_load_arg
Definition: loadfile-common.h:128
SifLoadModule
int SifLoadModule(const char *path, int arg_len, const char *args)
_iop_reboot_count
int _iop_reboot_count
E_SIF_RPC_BIND
@ E_SIF_RPC_BIND
Definition: ps2lib_err.h:86
tamtypes.h
SifLoadStartModule
int SifLoadStartModule(const char *path, int arg_len, const char *args, int *mod_res)
t_ExecData
Definition: loadfile-common.h:53
t_SifDmaTransfer
Definition: sifdma.h:52
_lf_search_module_by_address_arg
Definition: loadfile-common.h:119
SifLoadElfEncrypted
int SifLoadElfEncrypted(const char *path, t_ExecData *data)
SifLoadFileExit
void SifLoadFileExit(void)
SifExecModuleFile
int SifExecModuleFile(const char *path, u32 arg_len, const char *args, int *mod_res)
_SifLoadModule
int _SifLoadModule(const char *path, int arg_len, const char *args, int *modres, int fno, int dontwait)
_lf_module_unload_arg
Definition: loadfile-common.h:105
SifLoadStartModuleBuffer
int SifLoadStartModuleBuffer(void *ptr, int arg_len, const char *args, int *mod_res)
t_SifRpcClientData
Definition: sifrpc-common.h:134
SifIopGetVal
int SifIopGetVal(u32 iop_addr, void *val, int type)
SCE_EBINDMISS
#define SCE_EBINDMISS
Definition: loadfile.h:25
SifLoadModuleBuffer
int SifLoadModuleBuffer(void *ptr, int arg_len, const char *args)
_lf_iop_val_arg
Definition: loadfile-common.h:61
E_IOP_NO_MEMORY
@ E_IOP_NO_MEMORY
Definition: ps2lib_err.h:64
SifLoadElf
int SifLoadElf(const char *path, t_ExecData *data)
SifIopSetVal
int SifIopSetVal(u32 iop_addr, int val, int type)