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