2 * Author: Humberto Naves (hsnaves@gmail.com)
12 int check_module_info (struct prx
*p
)
14 struct prx_modinfo
*info
= p
->modinfo
;
18 error (__FILE__
": module name is not null terminated\n");
23 if (info
->expvaddr
> info
->expvaddrbtm
) {
24 error (__FILE__
": exports bottom is above top (0x%08X - 0x%08X)", info
->expvaddr
, info
->expvaddrbtm
);
27 if (!prx_inside_progfile (p
->programs
, info
->expvaddr
, info
->expvaddrbtm
- info
->expvaddr
)) {
28 error (__FILE__
": exports not inside the first program (0x%08X - 0x%08X)", info
->expvaddr
, info
->expvaddrbtm
);
32 offset
= prx_translate (p
, info
->expvaddr
);
33 for (vaddr
= info
->expvaddr
; vaddr
< info
->expvaddrbtm
; info
->numexports
++) {
35 size
= p
->data
[offset
+8];
37 error (__FILE__
": export size less than 4 words: %d", size
);
43 if (vaddr
!= info
->expvaddrbtm
) {
44 error (__FILE__
": invalid exports boundary");
50 if (info
->impvaddr
> info
->impvaddrbtm
) {
51 error (__FILE__
": imports bottom is above top (0x%08X - 0x%08X)", info
->impvaddr
, info
->impvaddrbtm
);
54 if (!prx_inside_progfile (p
->programs
, info
->impvaddr
, info
->impvaddrbtm
- info
->impvaddr
)) {
55 error (__FILE__
": imports not inside the first program (0x%08X - 0x%08X)", info
->impvaddr
, info
->impvaddrbtm
);
59 offset
= prx_translate (p
, info
->impvaddr
);
60 for (vaddr
= info
->impvaddr
; vaddr
< info
->impvaddrbtm
; info
->numimports
++) {
63 size
= p
->data
[offset
+8];
64 nvars
= p
->data
[offset
+9];
66 error (__FILE__
": import size less than 5 words: %d", size
);
69 if (nvars
&& size
< 6) {
70 error (__FILE__
": import size less than 6 words: %d", size
);
76 if (vaddr
!= info
->impvaddrbtm
) {
77 error (__FILE__
": invalid imports boundary");
85 int check_module_import (struct prx
*p
, uint32 index
)
87 struct prx_import
*imp
= &p
->modinfo
->imports
[index
];
89 if (!prx_inside_strprogfile (p
->programs
, imp
->namevaddr
)) {
90 error (__FILE__
": import name not inside first program");
94 if (!imp
->nfuncs
&& !imp
->nvars
) {
95 error (__FILE__
": no functions or variables imported");
99 if (!prx_inside_progfile (p
->programs
, imp
->funcsvaddr
, 8 * imp
->nfuncs
)) {
100 error (__FILE__
": functions not inside the first program");
104 if (!prx_inside_progfile (p
->programs
, imp
->nidsvaddr
, 4 * imp
->nfuncs
)) {
105 error (__FILE__
": nids not inside the first program");
110 if (!prx_inside_progfile (p
->programs
, imp
->varsvaddr
, 8 * imp
->nvars
)) {
111 error (__FILE__
": variables not inside first program");
121 int check_module_export (struct prx
*p
, uint32 index
)
123 struct prx_export
*exp
= &p
->modinfo
->exports
[index
];
125 if (!prx_inside_strprogfile (p
->programs
, exp
->namevaddr
)) {
126 error (__FILE__
": export name not inside first program");
130 if (!exp
->nfuncs
&& !exp
->nvars
) {
131 error (__FILE__
": no functions or variables exported");
135 if (!prx_inside_progfile (p
->programs
, exp
->expvaddr
, 8 * (exp
->nfuncs
+ exp
->nvars
))) {
136 error (__FILE__
": functions and variables not inside the first program");
146 int load_module_import (struct prx
*p
, struct prx_import
*imp
)
150 imp
->funcs
= (struct prx_function
*) xmalloc (imp
->nfuncs
* sizeof (struct prx_function
));
151 offset
= prx_translate (p
, imp
->nidsvaddr
);
152 for (i
= 0; i
< imp
->nfuncs
; i
++) {
153 struct prx_function
*f
= &imp
->funcs
[i
];
154 f
->nid
= read_uint32_le (&p
->data
[offset
+ 4 * i
]);
155 f
->vaddr
= imp
->funcsvaddr
+ 8 * i
;
156 f
->libname
= imp
->name
;
164 imp
->vars
= (struct prx_variable
*) xmalloc (imp
->nvars
* sizeof (struct prx_variable
));
165 offset
= prx_translate (p
, imp
->varsvaddr
);
166 for (i
= 0; i
< imp
->nvars
; i
++) {
167 struct prx_variable
*v
= &imp
->vars
[i
];
168 v
->nid
= read_uint32_le (&p
->data
[offset
+ 8 * i
+ 4]);
169 v
->vaddr
= read_uint32_le (&p
->data
[offset
+ 8 * i
]);
170 v
->libname
= imp
->name
;
178 int load_module_imports (struct prx
*p
)
180 uint32 i
= 0, offset
;
181 struct prx_modinfo
*info
= p
->modinfo
;
182 if (!info
->impvaddr
) return 1;
184 info
->imports
= (struct prx_import
*) xmalloc (info
->numimports
* sizeof (struct prx_import
));
185 memset (info
->imports
, 0, info
->numimports
* sizeof (struct prx_import
));
187 offset
= prx_translate (p
, info
->impvaddr
);
188 for (i
= 0; i
< info
->numimports
; i
++) {
189 struct prx_import
*imp
= &info
->imports
[i
];
190 imp
->namevaddr
= read_uint32_le (&p
->data
[offset
]);
191 imp
->flags
= read_uint32_le (&p
->data
[offset
+4]);
192 imp
->size
= p
->data
[offset
+8];
193 imp
->nvars
= p
->data
[offset
+9];
194 imp
->nfuncs
= read_uint16_le (&p
->data
[offset
+10]);
195 imp
->nidsvaddr
= read_uint32_le (&p
->data
[offset
+12]);
196 imp
->funcsvaddr
= read_uint32_le (&p
->data
[offset
+16]);
197 if (imp
->nvars
) imp
->varsvaddr
= read_uint32_le (&p
->data
[offset
+20]);
199 if (!check_module_import (p
, i
)) return 0;
202 imp
->name
= (const char *) &p
->data
[prx_translate (p
, imp
->namevaddr
)];
206 if (!load_module_import (p
, imp
)) return 0;
207 offset
+= imp
->size
<< 2;
213 const char *resolve_syslib_nid (uint32 nid
)
216 case 0xd3744be0: return "module_bootstart";
217 case 0x2f064fa6: return "module_reboot_before";
218 case 0xadf12745: return "module_reboot_phase";
219 case 0xd632acdb: return "module_start";
220 case 0xcee8593c: return "module_stop";
221 case 0xf01d73a7: return "module_info";
222 case 0x0f7c276c: return "module_start_thread_parameter";
223 case 0xcf0cc697: return "module_stop_thread_parameter";
229 int load_module_export (struct prx
*p
, struct prx_export
*exp
)
231 uint32 i
, offset
, disp
;
232 offset
= prx_translate (p
, exp
->expvaddr
);
233 disp
= 4 * (exp
->nfuncs
+ exp
->nvars
);
235 exp
->funcs
= (struct prx_function
*) xmalloc (exp
->nfuncs
* sizeof (struct prx_function
));
236 for (i
= 0; i
< exp
->nfuncs
; i
++) {
237 struct prx_function
*f
= &exp
->funcs
[i
];
238 f
->vaddr
= read_uint32_le (&p
->data
[offset
+ disp
]);
239 f
->nid
= read_uint32_le (&p
->data
[offset
]);
241 f
->libname
= exp
->name
;
245 if (exp
->namevaddr
== 0) {
246 f
->name
= resolve_syslib_nid (f
->nid
);
252 exp
->vars
= (struct prx_variable
*) xmalloc (exp
->nvars
* sizeof (struct prx_variable
));
253 for (i
= 0; i
< exp
->nvars
; i
++) {
254 struct prx_variable
*v
= &exp
->vars
[i
];
255 v
->vaddr
= read_uint32_le (&p
->data
[offset
+ disp
]);
256 v
->nid
= read_uint32_le (&p
->data
[offset
]);
258 v
->libname
= exp
->name
;
260 if (exp
->namevaddr
== 0) {
261 v
->name
= resolve_syslib_nid (v
->nid
);
269 int load_module_exports (struct prx
*p
)
271 uint32 i
= 0, offset
;
272 struct prx_modinfo
*info
= p
->modinfo
;
273 if (!info
->expvaddr
) return 1;
275 info
->exports
= (struct prx_export
*) xmalloc (info
->numexports
* sizeof (struct prx_export
));
276 memset (info
->exports
, 0, info
->numexports
* sizeof (struct prx_export
));
278 offset
= prx_translate (p
, info
->expvaddr
);
279 for (i
= 0; i
< info
->numexports
; i
++) {
280 struct prx_export
*exp
= &info
->exports
[i
];
281 exp
->namevaddr
= read_uint32_le (&p
->data
[offset
]);
282 exp
->flags
= read_uint32_le (&p
->data
[offset
+4]);
283 exp
->size
= p
->data
[offset
+8];
284 exp
->nvars
= p
->data
[offset
+9];
285 exp
->nfuncs
= read_uint16_le (&p
->data
[offset
+10]);
286 exp
->expvaddr
= read_uint32_le (&p
->data
[offset
+12]);
288 if (!check_module_export (p
, i
)) return 0;
291 exp
->name
= (const char *) &p
->data
[prx_translate (p
, exp
->namevaddr
)];
293 exp
->name
= "syslib";
295 if (!load_module_export (p
, exp
)) return 0;
296 offset
+= exp
->size
<< 2;
301 int load_module_info (struct prx
*p
)
303 struct prx_modinfo
*info
;
307 offset
= p
->programs
[0].paddr
& 0x7FFFFFFF;
309 error (__FILE__
": can't find module info for PRX");
313 info
= (struct prx_modinfo
*) xmalloc (sizeof (struct prx_modinfo
));
316 info
->attributes
= read_uint16_le (&p
->data
[offset
]);
317 info
->version
= read_uint16_le (&p
->data
[offset
+2]);
318 info
->name
= (const char *) &p
->data
[offset
+4];
319 info
->gp
= read_uint32_le (&p
->data
[offset
+32]);
320 info
->expvaddr
= read_uint32_le (&p
->data
[offset
+36]);
321 info
->expvaddrbtm
= read_uint32_le (&p
->data
[offset
+40]);
322 info
->impvaddr
= read_uint32_le (&p
->data
[offset
+44]);
323 info
->impvaddrbtm
= read_uint32_le (&p
->data
[offset
+48]);
325 info
->imports
= NULL
;
326 info
->exports
= NULL
;
328 if (!check_module_info (p
)) return 0;
330 if (!load_module_imports (p
)) return 0;
331 if (!load_module_exports (p
)) return 0;
338 void free_module_import (struct prx_import
*imp
)
340 if (imp
->funcs
) free (imp
->funcs
);
341 if (imp
->vars
) free (imp
->vars
);
347 void free_module_imports (struct prx
*p
)
349 if (!p
->modinfo
) return;
350 if (p
->modinfo
->imports
) {
352 for (i
= 0; i
< p
->modinfo
->numimports
; i
++)
353 free_module_import (&p
->modinfo
->imports
[i
]);
354 free (p
->modinfo
->imports
);
356 p
->modinfo
->imports
= NULL
;
360 void free_module_export (struct prx_export
*exp
)
362 if (exp
->funcs
) free (exp
->funcs
);
363 if (exp
->vars
) free (exp
->vars
);
369 void free_module_exports (struct prx
*p
)
371 if (!p
->modinfo
) return;
372 if (p
->modinfo
->exports
) {
374 for (i
= 0; i
< p
->modinfo
->numexports
; i
++)
375 free_module_export (&p
->modinfo
->exports
[i
]);
376 free (p
->modinfo
->exports
);
378 p
->modinfo
->imports
= NULL
;
381 void free_module_info (struct prx
*p
)
383 free_module_imports (p
);
384 free_module_exports (p
);
392 void print_module_imports (struct prx
*p
)
395 struct prx_modinfo
*info
= p
->modinfo
;
396 report ("\nImports:\n");
397 for (idx
= 0; idx
< info
->numimports
; idx
++) {
398 struct prx_import
*imp
= &info
->imports
[idx
];
399 report (" %s\n", imp
->name
);
401 report (" Flags: 0x%08X\n", imp
->flags
);
402 report (" Size: %6d\n", imp
->size
);
403 report (" Num Variables: %6d\n", imp
->nvars
);
404 report (" Num Functions: %6d\n", imp
->nfuncs
);
405 report (" Nids: 0x%08X\n", imp
->nidsvaddr
);
406 report (" Functions: 0x%08X\n", imp
->funcsvaddr
);
408 for (i
= 0; i
< imp
->nfuncs
; i
++) {
409 struct prx_function
*f
= &imp
->funcs
[i
];
410 report (" NID: 0x%08X VADDR: 0x%08X", f
->nid
, f
->vaddr
);
412 report (" NAME: %s", f
->name
);
416 report (" Variables: 0x%08X\n", imp
->varsvaddr
);
417 for (i
= 0; i
< imp
->nvars
; i
++) {
418 struct prx_variable
*v
= &imp
->vars
[i
];
419 report (" NID: 0x%08X VADDR: 0x%08X", v
->nid
, v
->vaddr
);
421 report (" NAME: %s", v
->name
);
431 void print_module_exports (struct prx
*p
)
434 struct prx_modinfo
*info
= p
->modinfo
;
435 report ("\nExports:\n");
436 for (idx
= 0; idx
< info
->numexports
; idx
++) {
437 struct prx_export
*exp
= &info
->exports
[idx
];
438 report (" %s\n", exp
->name
);
440 report (" Flags: 0x%08X\n", exp
->flags
);
441 report (" Size: %6d\n", exp
->size
);
442 report (" Num Variables: %6d\n", exp
->nvars
);
443 report (" Num Functions: %6d\n", exp
->nfuncs
);
444 report (" Exports: 0x%08X\n", exp
->expvaddr
);
446 report (" Functions:\n");
447 for (i
= 0; i
< exp
->nfuncs
; i
++) {
448 struct prx_function
*f
= &exp
->funcs
[i
];
449 report (" NID: 0x%08X VADDR: 0x%08X", f
->nid
, f
->vaddr
);
451 report (" NAME: %s", f
->name
);
456 report (" Variables:\n");
457 for (i
= 0; i
< exp
->nvars
; i
++) {
458 struct prx_variable
*v
= &exp
->vars
[i
];
459 report (" NID: 0x%08X VADDR: 0x%08X", v
->nid
, v
->vaddr
);
461 report (" NAME: %s", v
->name
);
469 void print_module_info (struct prx
*p
)
471 struct prx_modinfo
*info
= p
->modinfo
;
474 report ("\nModule info:\n");
475 report (" Name: %31s\n", info
->name
);
476 report (" Attributes: 0x%04X\n", info
->attributes
);
477 report (" Version: 0x%04X\n", info
->version
);
478 report (" GP: 0x%08X\n", info
->gp
);
479 report (" Library entry: 0x%08X\n", info
->expvaddr
);
480 report (" Library entry bottom: 0x%08X\n", info
->expvaddrbtm
);
481 report (" Library stubs: 0x%08X\n", info
->impvaddr
);
482 report (" Library stubs bottom: 0x%08X\n", info
->impvaddrbtm
);
484 print_module_imports (p
);
485 print_module_exports (p
);
489 void prx_resolve_nids (struct prx
*p
, struct nidstable
*nids
)
492 struct nidinfo
*ninfo
;
493 struct prx_modinfo
*info
= p
->modinfo
;
495 for (i
= 0; i
< info
->numimports
; i
++) {
496 struct prx_import
*imp
= &info
->imports
[i
];
497 for (j
= 0; j
< imp
->nfuncs
; j
++) {
498 struct prx_function
*f
= &imp
->funcs
[j
];
499 ninfo
= nids_find (nids
, imp
->name
, f
->nid
);
501 f
->name
= ninfo
->name
;
502 f
->numargs
= ninfo
->numargs
;
505 for (j
= 0; j
< imp
->nvars
; j
++) {
506 struct prx_variable
*v
= &imp
->vars
[j
];
507 ninfo
= nids_find (nids
, imp
->name
, v
->nid
);
509 v
->name
= ninfo
->name
;
514 for (i
= 0; i
< info
->numexports
; i
++) {
515 struct prx_export
*exp
= &info
->exports
[i
];
516 for (j
= 0; j
< exp
->nfuncs
; j
++) {
517 struct prx_function
*f
= &exp
->funcs
[j
];
518 ninfo
= nids_find (nids
, exp
->name
, f
->nid
);
520 f
->name
= ninfo
->name
;
521 f
->numargs
= ninfo
->numargs
;
524 for (j
= 0; j
< exp
->nvars
; j
++) {
525 struct prx_variable
*v
= &exp
->vars
[j
];
526 ninfo
= nids_find (nids
, exp
->name
, v
->nid
);
528 v
->name
= ninfo
->name
;