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