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
;
160 imp
->vars
= (struct prx_variable
*) xmalloc (imp
->nvars
* sizeof (struct prx_variable
));
161 offset
= prx_translate (p
, imp
->varsvaddr
);
162 for (i
= 0; i
< imp
->nvars
; i
++) {
163 struct prx_variable
*v
= &imp
->vars
[i
];
164 v
->nid
= read_uint32_le (&p
->data
[offset
+ 8 * i
+ 4]);
165 v
->vaddr
= read_uint32_le (&p
->data
[offset
+ 8 * i
]);
166 v
->libname
= imp
->name
;
174 int load_module_imports (struct prx
*p
)
176 uint32 i
= 0, offset
;
177 struct prx_modinfo
*info
= p
->modinfo
;
178 if (!info
->impvaddr
) return 1;
180 info
->imports
= (struct prx_import
*) xmalloc (info
->numimports
* sizeof (struct prx_import
));
181 memset (info
->imports
, 0, info
->numimports
* sizeof (struct prx_import
));
183 offset
= prx_translate (p
, info
->impvaddr
);
184 for (i
= 0; i
< info
->numimports
; i
++) {
185 struct prx_import
*imp
= &info
->imports
[i
];
186 imp
->namevaddr
= read_uint32_le (&p
->data
[offset
]);
187 imp
->flags
= read_uint32_le (&p
->data
[offset
+4]);
188 imp
->size
= p
->data
[offset
+8];
189 imp
->nvars
= p
->data
[offset
+9];
190 imp
->nfuncs
= read_uint16_le (&p
->data
[offset
+10]);
191 imp
->nidsvaddr
= read_uint32_le (&p
->data
[offset
+12]);
192 imp
->funcsvaddr
= read_uint32_le (&p
->data
[offset
+16]);
193 if (imp
->nvars
) imp
->varsvaddr
= read_uint32_le (&p
->data
[offset
+20]);
195 if (!check_module_import (p
, i
)) return 0;
198 imp
->name
= (const char *) &p
->data
[prx_translate (p
, imp
->namevaddr
)];
202 if (!load_module_import (p
, imp
)) return 0;
203 offset
+= imp
->size
<< 2;
209 const char *resolve_syslib_nid (uint32 nid
)
212 case 0xd3744be0: return "module_bootstart";
213 case 0x2f064fa6: return "module_reboot_before";
214 case 0xadf12745: return "module_reboot_phase";
215 case 0xd632acdb: return "module_start";
216 case 0xcee8593c: return "module_stop";
217 case 0xf01d73a7: return "module_info";
218 case 0x0f7c276c: return "module_start_thread_parameter";
219 case 0xcf0cc697: return "module_stop_thread_parameter";
225 int load_module_export (struct prx
*p
, struct prx_export
*exp
)
227 uint32 i
, offset
, disp
;
228 offset
= prx_translate (p
, exp
->expvaddr
);
229 disp
= 4 * (exp
->nfuncs
+ exp
->nvars
);
231 exp
->funcs
= (struct prx_function
*) xmalloc (exp
->nfuncs
* sizeof (struct prx_function
));
232 for (i
= 0; i
< exp
->nfuncs
; i
++) {
233 struct prx_function
*f
= &exp
->funcs
[i
];
234 f
->vaddr
= read_uint32_le (&p
->data
[offset
+ disp
]);
235 f
->nid
= read_uint32_le (&p
->data
[offset
]);
237 f
->libname
= exp
->name
;
240 if (exp
->namevaddr
== 0) {
241 f
->name
= resolve_syslib_nid (f
->nid
);
247 exp
->vars
= (struct prx_variable
*) xmalloc (exp
->nvars
* sizeof (struct prx_variable
));
248 for (i
= 0; i
< exp
->nvars
; i
++) {
249 struct prx_variable
*v
= &exp
->vars
[i
];
250 v
->vaddr
= read_uint32_le (&p
->data
[offset
+ disp
]);
251 v
->nid
= read_uint32_le (&p
->data
[offset
]);
253 v
->libname
= exp
->name
;
255 if (exp
->namevaddr
== 0) {
256 v
->name
= resolve_syslib_nid (v
->nid
);
264 int load_module_exports (struct prx
*p
)
266 uint32 i
= 0, offset
;
267 struct prx_modinfo
*info
= p
->modinfo
;
268 if (!info
->expvaddr
) return 1;
270 info
->exports
= (struct prx_export
*) xmalloc (info
->numexports
* sizeof (struct prx_export
));
271 memset (info
->exports
, 0, info
->numexports
* sizeof (struct prx_export
));
273 offset
= prx_translate (p
, info
->expvaddr
);
274 for (i
= 0; i
< info
->numexports
; i
++) {
275 struct prx_export
*exp
= &info
->exports
[i
];
276 exp
->namevaddr
= read_uint32_le (&p
->data
[offset
]);
277 exp
->flags
= read_uint32_le (&p
->data
[offset
+4]);
278 exp
->size
= p
->data
[offset
+8];
279 exp
->nvars
= p
->data
[offset
+9];
280 exp
->nfuncs
= read_uint16_le (&p
->data
[offset
+10]);
281 exp
->expvaddr
= read_uint32_le (&p
->data
[offset
+12]);
283 if (!check_module_export (p
, i
)) return 0;
286 exp
->name
= (const char *) &p
->data
[prx_translate (p
, exp
->namevaddr
)];
288 exp
->name
= "syslib";
290 if (!load_module_export (p
, exp
)) return 0;
291 offset
+= exp
->size
<< 2;
296 int load_module_info (struct prx
*p
)
298 struct prx_modinfo
*info
;
302 offset
= p
->programs
[0].paddr
& 0x7FFFFFFF;
304 error (__FILE__
": can't find module info for PRX");
308 info
= (struct prx_modinfo
*) xmalloc (sizeof (struct prx_modinfo
));
311 info
->attributes
= read_uint16_le (&p
->data
[offset
]);
312 info
->version
= read_uint16_le (&p
->data
[offset
+2]);
313 info
->name
= (const char *) &p
->data
[offset
+4];
314 info
->gp
= read_uint32_le (&p
->data
[offset
+32]);
315 info
->expvaddr
= read_uint32_le (&p
->data
[offset
+36]);
316 info
->expvaddrbtm
= read_uint32_le (&p
->data
[offset
+40]);
317 info
->impvaddr
= read_uint32_le (&p
->data
[offset
+44]);
318 info
->impvaddrbtm
= read_uint32_le (&p
->data
[offset
+48]);
320 info
->imports
= NULL
;
321 info
->exports
= NULL
;
323 if (!check_module_info (p
)) return 0;
325 if (!load_module_imports (p
)) return 0;
326 if (!load_module_exports (p
)) return 0;
333 void free_module_import (struct prx_import
*imp
)
335 if (imp
->funcs
) free (imp
->funcs
);
336 if (imp
->vars
) free (imp
->vars
);
342 void free_module_imports (struct prx
*p
)
344 if (!p
->modinfo
) return;
345 if (p
->modinfo
->imports
) {
347 for (i
= 0; i
< p
->modinfo
->numimports
; i
++)
348 free_module_import (&p
->modinfo
->imports
[i
]);
349 free (p
->modinfo
->imports
);
351 p
->modinfo
->imports
= NULL
;
355 void free_module_export (struct prx_export
*exp
)
357 if (exp
->funcs
) free (exp
->funcs
);
358 if (exp
->vars
) free (exp
->vars
);
364 void free_module_exports (struct prx
*p
)
366 if (!p
->modinfo
) return;
367 if (p
->modinfo
->exports
) {
369 for (i
= 0; i
< p
->modinfo
->numexports
; i
++)
370 free_module_export (&p
->modinfo
->exports
[i
]);
371 free (p
->modinfo
->exports
);
373 p
->modinfo
->imports
= NULL
;
376 void free_module_info (struct prx
*p
)
378 free_module_imports (p
);
379 free_module_exports (p
);
387 void print_module_imports (struct prx
*p
)
390 struct prx_modinfo
*info
= p
->modinfo
;
391 report ("\nImports:\n");
392 for (idx
= 0; idx
< info
->numimports
; idx
++) {
393 struct prx_import
*imp
= &info
->imports
[idx
];
394 report (" %s\n", imp
->name
);
396 report (" Flags: 0x%08X\n", imp
->flags
);
397 report (" Size: %6d\n", imp
->size
);
398 report (" Num Variables: %6d\n", imp
->nvars
);
399 report (" Num Functions: %6d\n", imp
->nfuncs
);
400 report (" Nids: 0x%08X\n", imp
->nidsvaddr
);
401 report (" Functions: 0x%08X\n", imp
->funcsvaddr
);
403 for (i
= 0; i
< imp
->nfuncs
; i
++) {
404 struct prx_function
*f
= &imp
->funcs
[i
];
405 report (" NID: 0x%08X VADDR: 0x%08X", f
->nid
, f
->vaddr
);
407 report (" NAME: %s", f
->name
);
411 report (" Variables: 0x%08X\n", imp
->varsvaddr
);
412 for (i
= 0; i
< imp
->nvars
; i
++) {
413 struct prx_variable
*v
= &imp
->vars
[i
];
414 report (" NID: 0x%08X VADDR: 0x%08X", v
->nid
, v
->vaddr
);
416 report (" NAME: %s", v
->name
);
426 void print_module_exports (struct prx
*p
)
429 struct prx_modinfo
*info
= p
->modinfo
;
430 report ("\nExports:\n");
431 for (idx
= 0; idx
< info
->numexports
; idx
++) {
432 struct prx_export
*exp
= &info
->exports
[idx
];
433 report (" %s\n", exp
->name
);
435 report (" Flags: 0x%08X\n", exp
->flags
);
436 report (" Size: %6d\n", exp
->size
);
437 report (" Num Variables: %6d\n", exp
->nvars
);
438 report (" Num Functions: %6d\n", exp
->nfuncs
);
439 report (" Exports: 0x%08X\n", exp
->expvaddr
);
441 report (" Functions:\n");
442 for (i
= 0; i
< exp
->nfuncs
; i
++) {
443 struct prx_function
*f
= &exp
->funcs
[i
];
444 report (" NID: 0x%08X VADDR: 0x%08X", f
->nid
, f
->vaddr
);
446 report (" NAME: %s", f
->name
);
451 report (" Variables:\n");
452 for (i
= 0; i
< exp
->nvars
; i
++) {
453 struct prx_variable
*v
= &exp
->vars
[i
];
454 report (" NID: 0x%08X VADDR: 0x%08X", v
->nid
, v
->vaddr
);
456 report (" NAME: %s", v
->name
);
464 void print_module_info (struct prx
*p
)
466 struct prx_modinfo
*info
= p
->modinfo
;
469 report ("\nModule info:\n");
470 report (" Name: %31s\n", info
->name
);
471 report (" Attributes: 0x%04X\n", info
->attributes
);
472 report (" Version: 0x%04X\n", info
->version
);
473 report (" GP: 0x%08X\n", info
->gp
);
474 report (" Library entry: 0x%08X\n", info
->expvaddr
);
475 report (" Library entry bottom: 0x%08X\n", info
->expvaddrbtm
);
476 report (" Library stubs: 0x%08X\n", info
->impvaddr
);
477 report (" Library stubs bottom: 0x%08X\n", info
->impvaddrbtm
);
479 print_module_imports (p
);
480 print_module_exports (p
);
484 void prx_resolve_nids (struct prx
*p
, struct nidstable
*nids
)
487 struct nidinfo
*ninfo
;
488 struct prx_modinfo
*info
= p
->modinfo
;
490 for (i
= 0; i
< info
->numimports
; i
++) {
491 struct prx_import
*imp
= &info
->imports
[i
];
492 for (j
= 0; j
< imp
->nfuncs
; j
++) {
493 struct prx_function
*f
= &imp
->funcs
[j
];
494 ninfo
= nids_find (nids
, imp
->name
, f
->nid
);
496 f
->name
= ninfo
->name
;
497 f
->numargs
= ninfo
->numargs
;
500 for (j
= 0; j
< imp
->nvars
; j
++) {
501 struct prx_variable
*v
= &imp
->vars
[j
];
502 ninfo
= nids_find (nids
, imp
->name
, v
->nid
);
504 v
->name
= ninfo
->name
;
509 for (i
= 0; i
< info
->numexports
; i
++) {
510 struct prx_export
*exp
= &info
->exports
[i
];
511 for (j
= 0; j
< exp
->nfuncs
; j
++) {
512 struct prx_function
*f
= &exp
->funcs
[j
];
513 ninfo
= nids_find (nids
, exp
->name
, f
->nid
);
515 f
->name
= ninfo
->name
;
516 f
->numargs
= ninfo
->numargs
;
519 for (j
= 0; j
< exp
->nvars
; j
++) {
520 struct prx_variable
*v
= &exp
->vars
[j
];
521 ninfo
= nids_find (nids
, exp
->name
, v
->nid
);
523 v
->name
= ninfo
->name
;