11#include "srxfixup_internal.h"
17static const char *conffile = NULL;
18static const char *ofile = NULL;
19static const char *rfile = NULL;
20static const char *ffile = NULL;
21static unsigned int startaddr;
22static const char *entrysym = NULL;
23static unsigned int verbose = 0;
24static unsigned int dumpflag = 0;
25static unsigned int dispmod_flag = 0;
26static int irx1_flag = 0;
27static int br_conv = 0;
28static int print_config = 0;
32 {
"-v", ARG_HAVEARG_NONE,
'f', &verbose },
33 {
"-d", ARG_HAVEARG_NONE,
'f', &dumpflag },
34 {
"-r", ARG_HAVEARG_REQUIRED,
's', &rfile },
35 {
"-o", ARG_HAVEARG_REQUIRED,
's', &ofile },
36 {
"-c", ARG_HAVEARG_REQUIRED,
's', &conffile },
37 {
"-f", ARG_HAVEARG_REQUIRED,
's', &ffile },
38 {
"-t", ARG_HAVEARG_REQUIRED,
'h', &startaddr },
39 {
"-e", ARG_HAVEARG_REQUIRED,
's', &entrysym },
40 {
"-m", ARG_HAVEARG_NONE,
'f', &dispmod_flag },
41 {
"--irx1", ARG_HAVEARG_NONE,
'f', &irx1_flag },
42 {
"--rb", ARG_HAVEARG_NONE,
'f', &br_conv },
43 {
"--relative-branch", ARG_HAVEARG_NONE,
'f', &br_conv },
44 {
"--print-internal-config", ARG_HAVEARG_NONE,
'f', &print_config },
45 { NULL, 0,
'\0', NULL },
47static const Opttable stripopttable[] =
49 {
"-v", ARG_HAVEARG_NONE,
'f', &verbose },
50 {
"-d", ARG_HAVEARG_NONE,
'f', &dumpflag },
51 {
"-o", ARG_HAVEARG_REQUIRED,
's', &ofile },
52 {
"-c", ARG_HAVEARG_REQUIRED,
's', &conffile },
53 {
"-e", ARG_HAVEARG_REQUIRED,
's', &entrysym },
54 {
"-m", ARG_HAVEARG_NONE,
'f', &dispmod_flag },
55 {
"--irx1", ARG_HAVEARG_NONE,
'f', &irx1_flag },
56 {
"--rb", ARG_HAVEARG_NONE,
'f', &br_conv },
57 {
"--relative-branch", ARG_HAVEARG_NONE,
'f', &br_conv },
58 {
"--print-internal-config", ARG_HAVEARG_NONE,
'f', &print_config },
59 { NULL, 0,
'\0', NULL },
63static void display_module_info(
elf_file *elf);
64static void convert_relative_branch_an_section(
elf_section *relsect);
65static void convert_relative_branch(
elf_file *elf);
67void usage(
const char *myname)
70 "IOP/EE relocatable object converter\n"
72 "usage: %s [options] <elf_input_file>\n",
79 " -o <elf_relocatable_nosymbol_output_file>\n"
80 " -r <elf_relocatable_output_file>\n"
81 " -e <entry_point_symbol>\n"
82 " --relative-branch or --rb\n");
85 printf(
" -t <.text start address>\n"
86 " -f <elf_fixedaddress_output_file>\n"
89 " bit0: dump section table\n"
90 " bit1: dump relocation record\n"
91 " bit2: dump symbol table\n"
92 " bit3: disassemble program code\n"
93 " bit4: dump .data/.rodata/.sdata... sections by byte\n"
94 " bit5: dump .data/.rodata/.sdata... sections by half word\n"
95 " bit6: dump .data/.rodata/.sdata... sections by word\n"
96 " bit7: dump .data/.rodata/.sdata... sections by word with relocation data\n"
97 " bit8: dump file layout\n"
98 " bit9: dump .mdebug section\n");
102 printf(
" bit12: dump srx genaration table\n"
103 " -c <config_file>\n"
104 " --print-internal-config\n");
108void stripusage(
const char *myname)
112 "usage: %s [options] <elf_file>\n",
118 " -o <elf_relocatable_nosymbol_output_file>\n"
119 " --relative-branch or --rb\n");
122int main(
int argc,
char **argv)
125 const char *defaultconf;
127 const char *myname_1;
128 const char *myname_2;
131 myname_1 = strrchr(*argv,
'/');
134 myname_1 = strrchr(*argv,
'\\');
138 myname_2 = myname_1 + 1;
144 if ( (strncmp(myname_2,
"ee", 2) != 0) && (strncmp(myname_2,
"EE", 2) != 0) )
146 defaultconf = iop_defaultconf;
150 defaultconf = ee_defaultconf;
152 if ( strlen(*argv) > 5 && !strcmp(&(*argv)[strlen(*argv) - 5],
"strip") )
156 argca = analize_arguments(stripopttable, argc, argv);
161 srxgen_2 = read_conf(defaultconf, conffile, print_config);
166 if ( (dumpflag & 0x1000) != 0 )
168 dump_srx_gen_table(srxgen_2);
179 fprintf(stderr,
"Too many input file\n");
192 argcb = analize_arguments(opttable, argc, argv);
197 srxgen_3 = read_conf(defaultconf, conffile, print_config);
202 if ( (dumpflag & 0x1000) != 0 )
204 dump_srx_gen_table(srxgen_3);
215 fprintf(stderr,
"Too many input file\n");
221 elf = read_elf(source);
227 ((elf->ehp->e_flags & EF_MIPS_MACH) == EF_MIPS_MACH_5900)
228 && ((elf->ehp->e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_3) )
230 srxgen_1 = read_conf(ee_defaultconf, conffile, print_config);
234 srxgen_1 = read_conf(iop_defaultconf, conffile, print_config);
240 if ( (dumpflag & 0x1000) != 0 )
242 dump_srx_gen_table(srxgen_1);
245 if ( (dumpflag & 0xFFF) != 0 )
247 print_elf(elf, dumpflag & 0xFFF);
250 elf->optdata = (
void *)srxgen_1;
251 switch ( elf->ehp->e_type )
254 if ( convert_rel2srx(elf, entrysym, (rfile || ofile || ffile) ? 1 : 0, irx1_flag) )
259 case ET_SCE_IOPRELEXEC:
260 case ET_SCE_IOPRELEXEC2:
261 case ET_SCE_EERELEXEC2:
265 fprintf(stderr,
"Error: '%s' is unsupport Type Elf file(type=%x)\n", source, elf->ehp->e_type);
271 display_module_info(elf);
273 switch ( elf->ehp->e_type )
275 case ET_SCE_IOPRELEXEC:
276 case ET_SCE_IOPRELEXEC2:
277 case ET_SCE_EERELEXEC2:
280 convert_relative_branch(elf);
284 if ( layout_srx_file(elf) )
288 write_elf(elf, rfile);
293 if ( layout_srx_file(elf) )
297 write_elf(elf, ofile);
301 if ( rfile || ofile )
303 fprintf(stderr,
"Error: Cannot generate IRX/ERX file. '%s' file type is ET_EXEC.\n", source);
308 if ( ffile || startaddr != (
unsigned int)(-1) )
310 switch ( elf->ehp->e_type )
312 case ET_SCE_IOPRELEXEC:
313 case ET_SCE_IOPRELEXEC2:
314 case ET_SCE_EERELEXEC2:
315 elf->ehp->e_type = ET_EXEC;
316 fixlocation_elf(elf, startaddr);
323 if ( layout_srx_file(elf) )
327 write_elf(elf, ffile);
333static void display_module_info(
elf_file *elf)
338 modsect_1 = search_section(elf, SHT_SCE_IOPMOD);
344 if ( iopmodinfo->moduleinfo != (Elf32_Word)(-1) )
347 "name:%s version:%d.%d\n",
348 iopmodinfo->modulename,
349 (uint8_t)(iopmodinfo->moduleversion >> 24),
350 (uint8_t)iopmodinfo->moduleversion);
353 modsect_2 = search_section(elf, SHT_SCE_EEMOD);
359 if ( eemodinfo->moduleinfo != (Elf32_Word)(-1) )
362 "name:%s version:%d.%d\n",
363 eemodinfo->modulename,
364 (uint8_t)(eemodinfo->moduleversion >> 24),
365 (uint8_t)eemodinfo->moduleversion);
370static void convert_relative_branch_an_section(
elf_section *relsect)
375 unsigned int entrise;
378 entrise = relsect->shr.sh_size / relsect->shr.sh_entsize;
382 for ( i = 0; i < entrise; i += 1 )
387 if ( rp->symptr && *symp != rp->symptr )
389 fprintf(stderr,
"Internal error: Illegal relocation entry\n");
393 relsect->info->shr.sh_addr > rp->rel.r_offset
394 || rp->rel.r_offset >= relsect->info->shr.sh_size + relsect->info->shr.sh_addr )
398 "Panic !! relocation #%u offset=0x%x range out (section limit addr=0x%x-0x%x)\n",
401 relsect->info->shr.sh_addr,
402 relsect->info->shr.sh_size + relsect->info->shr.sh_addr);
405 daddr = &relsect->info->data[rp->rel.r_offset - relsect->info->shr.sh_addr];
409 if ( type == R_MIPS_26 )
414 data = *(uint32_t *)daddr;
415 if ( rp->symptr && rp->symptr->bind != STB_LOCAL )
417 fprintf(stderr,
"R_MIPS_26 Unexcepted bind\n");
420 raddr = rp->rel.r_offset + relsect->info->shr.sh_addr;
422 !((((rp->rel.r_offset & 0xF0000000) | (4 * (data & 0x3FFFFFF))) - 4 - raddr) >> 18)
423 || (((rp->rel.r_offset & 0xF0000000) | (4 * (data & 0x3FFFFFF))) - 4 - raddr) >> 18 == 0x3FFF )
427 jaddr = (uint16_t)((((rp->rel.r_offset & 0xF0000000) | (4 * (data & 0x3FFFFFF))) - 4 - raddr) >> 2);
428 if ( data >> 26 == 2 )
430 *(uint32_t *)daddr = jaddr | 0x10000000;
431 rp->type = R_MIPS_NONE;
434 else if ( data >> 26 == 3 )
436 *(uint32_t *)daddr = jaddr | 0x4110000;
437 rp->type = R_MIPS_NONE;
449 if ( rmcount > 0 && (entrise - rmcount) > 0 )
459 for ( j = 0; j < entrise; j += 1 )
469 relsect->data = (uint8_t *)newtab;
470 relsect->shr.sh_size = relsect->shr.sh_entsize * (entrise - rmcount);
474static void convert_relative_branch(
elf_file *elf)
478 if ( elf->scp == NULL )
482 for ( i = 1; i < elf->ehp->e_shnum; i += 1 )
484 if ( elf->scp[i]->shr.sh_type == SHT_REL )
486 convert_relative_branch_an_section(elf->scp[i]);