9 int check_module_info (struct prx
*p
)
11 struct prx_modinfo
*info
= p
->modinfo
;
15 error (__FILE__
": module name is not null terminated\n");
20 if (info
->expvaddr
> info
->expvaddrbtm
) {
21 error (__FILE__
": exports bottom is above top (0x%08X - 0x%08X)", info
->expvaddr
, info
->expvaddrbtm
);
24 if (!prx_inside_progfile (p
->programs
, info
->expvaddr
, info
->expvaddrbtm
- info
->expvaddr
)) {
25 error (__FILE__
": exports not inside the first program (0x%08X - 0x%08X)", info
->expvaddr
, info
->expvaddrbtm
);
29 offset
= prx_translate (p
, info
->expvaddr
);
30 for (vaddr
= info
->expvaddr
; vaddr
< info
->expvaddrbtm
; info
->numexports
++) {
32 size
= p
->data
[offset
+8];
34 error (__FILE__
": export size less than 4 words: %d", size
);
40 if (vaddr
!= info
->expvaddrbtm
) {
41 error (__FILE__
": invalid exports boundary");
47 if (info
->impvaddr
> info
->impvaddrbtm
) {
48 error (__FILE__
": imports bottom is above top (0x%08X - 0x%08X)", info
->impvaddr
, info
->impvaddrbtm
);
51 if (!prx_inside_progfile (p
->programs
, info
->impvaddr
, info
->impvaddrbtm
- info
->impvaddr
)) {
52 error (__FILE__
": imports not inside the first program (0x%08X - 0x%08X)", info
->impvaddr
, info
->impvaddrbtm
);
56 offset
= prx_translate (p
, info
->impvaddr
);
57 for (vaddr
= info
->impvaddr
; vaddr
< info
->impvaddrbtm
; info
->numimports
++) {
60 size
= p
->data
[offset
+8];
61 nvars
= p
->data
[offset
+9];
63 error (__FILE__
": import size less than 5 words: %d", size
);
66 if (nvars
&& size
< 6) {
67 error (__FILE__
": import size less than 6 words: %d", size
);
73 if (vaddr
!= info
->impvaddrbtm
) {
74 error (__FILE__
": invalid imports boundary");
82 int check_module_import (struct prx
*p
, uint32 index
)
84 struct prx_import
*imp
= &p
->modinfo
->imports
[index
];
86 if (!prx_inside_strprogfile (p
->programs
, imp
->namevaddr
)) {
87 error (__FILE__
": import name not inside first program");
91 if (!imp
->nfuncs
&& !imp
->nvars
) {
92 error (__FILE__
": no functions or variables imported");
96 if (!prx_inside_progfile (p
->programs
, imp
->funcsvaddr
, 8 * imp
->nfuncs
)) {
97 error (__FILE__
": functions not inside the first program");
101 if (!prx_inside_progfile (p
->programs
, imp
->nidsvaddr
, 4 * imp
->nfuncs
)) {
102 error (__FILE__
": nids not inside the first program");
107 if (!prx_inside_progfile (p
->programs
, imp
->varsvaddr
, 8 * imp
->nvars
)) {
108 error (__FILE__
": variables not inside first program");
118 int check_module_export (struct prx
*p
, uint32 index
)
120 struct prx_export
*exp
= &p
->modinfo
->exports
[index
];
122 if (!prx_inside_strprogfile (p
->programs
, exp
->namevaddr
)) {
123 error (__FILE__
": export name not inside first program");
127 if (!exp
->nfuncs
&& !exp
->nvars
) {
128 error (__FILE__
": no functions or variables exported");
132 if (!prx_inside_progfile (p
->programs
, exp
->expvaddr
, 8 * (exp
->nfuncs
+ exp
->nvars
))) {
133 error (__FILE__
": functions and variables not inside the first program");
143 int load_module_import (struct prx
*p
, struct prx_import
*imp
)
147 imp
->funcs
= (struct prx_function
*) xmalloc (imp
->nfuncs
* sizeof (struct prx_function
));
148 offset
= prx_translate (p
, imp
->nidsvaddr
);
149 for (i
= 0; i
< imp
->nfuncs
; i
++) {
150 struct prx_function
*f
= &imp
->funcs
[i
];
151 f
->nid
= read_uint32_le (&p
->data
[offset
+ 4 * i
]);
152 f
->vaddr
= imp
->funcsvaddr
+ 8 * i
;
153 f
->libname
= imp
->name
;
161 imp
->vars
= (struct prx_variable
*) xmalloc (imp
->nvars
* sizeof (struct prx_variable
));
162 offset
= prx_translate (p
, imp
->varsvaddr
);
163 for (i
= 0; i
< imp
->nvars
; i
++) {
164 struct prx_variable
*v
= &imp
->vars
[i
];
165 v
->nid
= read_uint32_le (&p
->data
[offset
+ 8 * i
+ 4]);
166 v
->vaddr
= read_uint32_le (&p
->data
[offset
+ 8 * i
]);
167 v
->libname
= imp
->name
;
175 int load_module_imports (struct prx
*p
)
177 uint32 i
= 0, offset
;
178 struct prx_modinfo
*info
= p
->modinfo
;
179 if (!info
->impvaddr
) return 1;
181 info
->imports
= (struct prx_import
*) xmalloc (info
->numimports
* sizeof (struct prx_import
));
182 memset (info
->imports
, 0, info
->numimports
* sizeof (struct prx_import
));
184 offset
= prx_translate (p
, info
->impvaddr
);
185 for (i
= 0; i
< info
->numimports
; i
++) {
186 struct prx_import
*imp
= &info
->imports
[i
];
187 imp
->namevaddr
= read_uint32_le (&p
->data
[offset
]);
188 imp
->flags
= read_uint32_le (&p
->data
[offset
+4]);
189 imp
->size
= p
->data
[offset
+8];
190 imp
->nvars
= p
->data
[offset
+9];
191 imp
->nfuncs
= read_uint16_le (&p
->data
[offset
+10]);
192 imp
->nidsvaddr
= read_uint32_le (&p
->data
[offset
+12]);
193 imp
->funcsvaddr
= read_uint32_le (&p
->data
[offset
+16]);
194 if (imp
->nvars
) imp
->varsvaddr
= read_uint32_le (&p
->data
[offset
+20]);
196 if (!check_module_import (p
, i
)) return 0;
199 imp
->name
= (const char *) &p
->data
[prx_translate (p
, imp
->namevaddr
)];
203 if (!load_module_import (p
, imp
)) return 0;
204 offset
+= imp
->size
<< 2;
210 const char *resolve_syslib_nid (uint32 nid
)
213 case 0xd3744be0: return "module_bootstart";
214 case 0x2f064fa6: return "module_reboot_before";
215 case 0xadf12745: return "module_reboot_phase";
216 case 0xd632acdb: return "module_start";
217 case 0xcee8593c: return "module_stop";
218 case 0xf01d73a7: return "module_info";
219 case 0x0f7c276c: return "module_start_thread_parameter";
220 case 0xcf0cc697: return "module_stop_thread_parameter";
226 int load_module_export (struct prx
*p
, struct prx_export
*exp
)
228 uint32 i
, offset
, disp
;
229 offset
= prx_translate (p
, exp
->expvaddr
);
230 disp
= 4 * (exp
->nfuncs
+ exp
->nvars
);
232 exp
->funcs
= (struct prx_function
*) xmalloc (exp
->nfuncs
* sizeof (struct prx_function
));
233 for (i
= 0; i
< exp
->nfuncs
; i
++) {
234 struct prx_function
*f
= &exp
->funcs
[i
];
235 f
->vaddr
= read_uint32_le (&p
->data
[offset
+ disp
]);
236 f
->nid
= read_uint32_le (&p
->data
[offset
]);
238 f
->libname
= exp
->name
;
242 if (exp
->namevaddr
== 0) {
243 f
->name
= resolve_syslib_nid (f
->nid
);
249 exp
->vars
= (struct prx_variable
*) xmalloc (exp
->nvars
* sizeof (struct prx_variable
));
250 for (i
= 0; i
< exp
->nvars
; i
++) {
251 struct prx_variable
*v
= &exp
->vars
[i
];
252 v
->vaddr
= read_uint32_le (&p
->data
[offset
+ disp
]);
253 v
->nid
= read_uint32_le (&p
->data
[offset
]);
255 v
->libname
= exp
->name
;
257 if (exp
->namevaddr
== 0) {
258 v
->name
= resolve_syslib_nid (v
->nid
);
266 int load_module_exports (struct prx
*p
)
268 uint32 i
= 0, offset
;
269 struct prx_modinfo
*info
= p
->modinfo
;
270 if (!info
->expvaddr
) return 1;
272 info
->exports
= (struct prx_export
*) xmalloc (info
->numexports
* sizeof (struct prx_export
));
273 memset (info
->exports
, 0, info
->numexports
* sizeof (struct prx_export
));
275 offset
= prx_translate (p
, info
->expvaddr
);
276 for (i
= 0; i
< info
->numexports
; i
++) {
277 struct prx_export
*exp
= &info
->exports
[i
];
278 exp
->namevaddr
= read_uint32_le (&p
->data
[offset
]);
279 exp
->flags
= read_uint32_le (&p
->data
[offset
+4]);
280 exp
->size
= p
->data
[offset
+8];
281 exp
->nvars
= p
->data
[offset
+9];
282 exp
->nfuncs
= read_uint16_le (&p
->data
[offset
+10]);
283 exp
->expvaddr
= read_uint32_le (&p
->data
[offset
+12]);
285 if (!check_module_export (p
, i
)) return 0;
288 exp
->name
= (const char *) &p
->data
[prx_translate (p
, exp
->namevaddr
)];
290 exp
->name
= "syslib";
292 if (!load_module_export (p
, exp
)) return 0;
293 offset
+= exp
->size
<< 2;
298 int load_module_info (struct prx
*p
)
300 struct prx_modinfo
*info
;
304 offset
= p
->programs
[0].paddr
& 0x7FFFFFFF;
306 error (__FILE__
": can't find module info for PRX");
310 info
= (struct prx_modinfo
*) xmalloc (sizeof (struct prx_modinfo
));
313 info
->attributes
= read_uint16_le (&p
->data
[offset
]);
314 info
->version
= read_uint16_le (&p
->data
[offset
+2]);
315 info
->name
= (const char *) &p
->data
[offset
+4];
316 info
->gp
= read_uint32_le (&p
->data
[offset
+32]);
317 info
->expvaddr
= read_uint32_le (&p
->data
[offset
+36]);
318 info
->expvaddrbtm
= read_uint32_le (&p
->data
[offset
+40]);
319 info
->impvaddr
= read_uint32_le (&p
->data
[offset
+44]);
320 info
->impvaddrbtm
= read_uint32_le (&p
->data
[offset
+48]);
322 info
->imports
= NULL
;
323 info
->exports
= NULL
;
325 if (!check_module_info (p
)) return 0;
327 if (!load_module_imports (p
)) return 0;
328 if (!load_module_exports (p
)) return 0;
335 void free_module_import (struct prx_import
*imp
)
337 if (imp
->funcs
) free (imp
->funcs
);
338 if (imp
->vars
) free (imp
->vars
);
344 void free_module_imports (struct prx
*p
)
346 if (!p
->modinfo
) return;
347 if (p
->modinfo
->imports
) {
349 for (i
= 0; i
< p
->modinfo
->numimports
; i
++)
350 free_module_import (&p
->modinfo
->imports
[i
]);
351 free (p
->modinfo
->imports
);
353 p
->modinfo
->imports
= NULL
;
357 void free_module_export (struct prx_export
*exp
)
359 if (exp
->funcs
) free (exp
->funcs
);
360 if (exp
->vars
) free (exp
->vars
);
366 void free_module_exports (struct prx
*p
)
368 if (!p
->modinfo
) return;
369 if (p
->modinfo
->exports
) {
371 for (i
= 0; i
< p
->modinfo
->numexports
; i
++)
372 free_module_export (&p
->modinfo
->exports
[i
]);
373 free (p
->modinfo
->exports
);
375 p
->modinfo
->imports
= NULL
;
378 void free_module_info (struct prx
*p
)
380 free_module_imports (p
);
381 free_module_exports (p
);
389 void print_module_imports (struct prx
*p
)
392 struct prx_modinfo
*info
= p
->modinfo
;
393 report ("\nImports:\n");
394 for (idx
= 0; idx
< info
->numimports
; idx
++) {
395 struct prx_import
*imp
= &info
->imports
[idx
];
396 report (" %s\n", imp
->name
);
398 report (" Flags: 0x%08X\n", imp
->flags
);
399 report (" Size: %6d\n", imp
->size
);
400 report (" Num Variables: %6d\n", imp
->nvars
);
401 report (" Num Functions: %6d\n", imp
->nfuncs
);
402 report (" Nids: 0x%08X\n", imp
->nidsvaddr
);
403 report (" Functions: 0x%08X\n", imp
->funcsvaddr
);
405 for (i
= 0; i
< imp
->nfuncs
; i
++) {
406 struct prx_function
*f
= &imp
->funcs
[i
];
407 report (" NID: 0x%08X VADDR: 0x%08X", f
->nid
, f
->vaddr
);
409 report (" NAME: %s", f
->name
);
413 report (" Variables: 0x%08X\n", imp
->varsvaddr
);
414 for (i
= 0; i
< imp
->nvars
; i
++) {
415 struct prx_variable
*v
= &imp
->vars
[i
];
416 report (" NID: 0x%08X VADDR: 0x%08X", v
->nid
, v
->vaddr
);
418 report (" NAME: %s", v
->name
);
428 void print_module_exports (struct prx
*p
)
431 struct prx_modinfo
*info
= p
->modinfo
;
432 report ("\nExports:\n");
433 for (idx
= 0; idx
< info
->numexports
; idx
++) {
434 struct prx_export
*exp
= &info
->exports
[idx
];
435 report (" %s\n", exp
->name
);
437 report (" Flags: 0x%08X\n", exp
->flags
);
438 report (" Size: %6d\n", exp
->size
);
439 report (" Num Variables: %6d\n", exp
->nvars
);
440 report (" Num Functions: %6d\n", exp
->nfuncs
);
441 report (" Exports: 0x%08X\n", exp
->expvaddr
);
443 report (" Functions:\n");
444 for (i
= 0; i
< exp
->nfuncs
; i
++) {
445 struct prx_function
*f
= &exp
->funcs
[i
];
446 report (" NID: 0x%08X VADDR: 0x%08X", f
->nid
, f
->vaddr
);
448 report (" NAME: %s", f
->name
);
453 report (" Variables:\n");
454 for (i
= 0; i
< exp
->nvars
; i
++) {
455 struct prx_variable
*v
= &exp
->vars
[i
];
456 report (" NID: 0x%08X VADDR: 0x%08X", v
->nid
, v
->vaddr
);
458 report (" NAME: %s", v
->name
);
466 void print_module_info (struct prx
*p
)
468 struct prx_modinfo
*info
= p
->modinfo
;
471 report ("\nModule info:\n");
472 report (" Name: %31s\n", info
->name
);
473 report (" Attributes: 0x%04X\n", info
->attributes
);
474 report (" Version: 0x%04X\n", info
->version
);
475 report (" GP: 0x%08X\n", info
->gp
);
476 report (" Library entry: 0x%08X\n", info
->expvaddr
);
477 report (" Library entry bottom: 0x%08X\n", info
->expvaddrbtm
);
478 report (" Library stubs: 0x%08X\n", info
->impvaddr
);
479 report (" Library stubs bottom: 0x%08X\n", info
->impvaddrbtm
);
481 print_module_imports (p
);
482 print_module_exports (p
);
486 void prx_resolve_nids (struct prx
*p
, struct nidstable
*nids
)
489 struct nidinfo
*ninfo
;
490 struct prx_modinfo
*info
= p
->modinfo
;
492 for (i
= 0; i
< info
->numimports
; i
++) {
493 struct prx_import
*imp
= &info
->imports
[i
];
494 for (j
= 0; j
< imp
->nfuncs
; j
++) {
495 struct prx_function
*f
= &imp
->funcs
[j
];
496 ninfo
= nids_find (nids
, imp
->name
, f
->nid
);
498 f
->name
= ninfo
->name
;
499 f
->numargs
= ninfo
->numargs
;
502 for (j
= 0; j
< imp
->nvars
; j
++) {
503 struct prx_variable
*v
= &imp
->vars
[j
];
504 ninfo
= nids_find (nids
, imp
->name
, v
->nid
);
506 v
->name
= ninfo
->name
;
511 for (i
= 0; i
< info
->numexports
; i
++) {
512 struct prx_export
*exp
= &info
->exports
[i
];
513 for (j
= 0; j
< exp
->nfuncs
; j
++) {
514 struct prx_function
*f
= &exp
->funcs
[j
];
515 ninfo
= nids_find (nids
, exp
->name
, f
->nid
);
517 f
->name
= ninfo
->name
;
518 f
->numargs
= ninfo
->numargs
;
521 for (j
= 0; j
< exp
->nvars
; j
++) {
522 struct prx_variable
*v
= &exp
->vars
[j
];
523 ninfo
= nids_find (nids
, exp
->name
, v
->nid
);
525 v
->name
= ninfo
->name
;