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;
29static int allow_zero_text = 0;
33 {
"-v", ARG_HAVEARG_NONE,
'f', &verbose },
34 {
"-d", ARG_HAVEARG_NONE,
'f', &dumpflag },
35 {
"-r", ARG_HAVEARG_REQUIRED,
's', &rfile },
36 {
"-o", ARG_HAVEARG_REQUIRED,
's', &ofile },
37 {
"-c", ARG_HAVEARG_REQUIRED,
's', &conffile },
38 {
"-f", ARG_HAVEARG_REQUIRED,
's', &ffile },
39 {
"-t", ARG_HAVEARG_REQUIRED,
'h', &startaddr },
40 {
"-e", ARG_HAVEARG_REQUIRED,
's', &entrysym },
41 {
"-m", ARG_HAVEARG_NONE,
'f', &dispmod_flag },
42 {
"--irx1", ARG_HAVEARG_NONE,
'f', &irx1_flag },
43 {
"--rb", ARG_HAVEARG_NONE,
'f', &br_conv },
44 {
"--relative-branch", ARG_HAVEARG_NONE,
'f', &br_conv },
45 {
"--print-internal-config", ARG_HAVEARG_NONE,
'f', &print_config },
46 {
"--allow-zero-text", ARG_HAVEARG_NONE,
'f', &allow_zero_text },
47 { NULL, 0,
'\0', NULL },
49static const Opttable stripopttable[] =
51 {
"-v", ARG_HAVEARG_NONE,
'f', &verbose },
52 {
"-d", ARG_HAVEARG_NONE,
'f', &dumpflag },
53 {
"-o", ARG_HAVEARG_REQUIRED,
's', &ofile },
54 {
"-c", ARG_HAVEARG_REQUIRED,
's', &conffile },
55 {
"-e", ARG_HAVEARG_REQUIRED,
's', &entrysym },
56 {
"-m", ARG_HAVEARG_NONE,
'f', &dispmod_flag },
57 {
"--irx1", ARG_HAVEARG_NONE,
'f', &irx1_flag },
58 {
"--rb", ARG_HAVEARG_NONE,
'f', &br_conv },
59 {
"--relative-branch", ARG_HAVEARG_NONE,
'f', &br_conv },
60 {
"--print-internal-config", ARG_HAVEARG_NONE,
'f', &print_config },
61 { NULL, 0,
'\0', NULL },
65static void display_module_info(
elf_file *elf);
66static void convert_relative_branch_an_section(
elf_section *relsect);
67static void convert_relative_branch(
elf_file *elf);
68static int check_zero_text_symbols(
const char *source,
const elf_file *elf);
70void usage(
const char *myname)
73 "IOP/EE relocatable object converter\n"
75 "usage: %s [options] <elf_input_file>\n",
82 " -o <elf_relocatable_nosymbol_output_file>\n"
83 " -r <elf_relocatable_output_file>\n"
84 " -e <entry_point_symbol>\n"
85 " --relative-branch or --rb\n"
86 " --allow-zero-text (skip check for .text symbols with value 0)\n");
89 printf(
" -t <.text start address>\n"
90 " -f <elf_fixedaddress_output_file>\n"
93 " bit0: dump section table\n"
94 " bit1: dump relocation record\n"
95 " bit2: dump symbol table\n"
96 " bit3: disassemble program code\n"
97 " bit4: dump .data/.rodata/.sdata... sections by byte\n"
98 " bit5: dump .data/.rodata/.sdata... sections by half word\n"
99 " bit6: dump .data/.rodata/.sdata... sections by word\n"
100 " bit7: dump .data/.rodata/.sdata... sections by word with relocation data\n"
101 " bit8: dump file layout\n"
102 " bit9: dump .mdebug section\n");
106 printf(
" bit12: dump srx genaration table\n"
107 " -c <config_file>\n"
108 " --print-internal-config\n");
112void stripusage(
const char *myname)
116 "usage: %s [options] <elf_file>\n",
122 " -o <elf_relocatable_nosymbol_output_file>\n"
123 " --relative-branch or --rb\n");
126int main(
int argc,
char **argv)
129 const char *defaultconf;
131 const char *myname_1;
132 const char *myname_2;
135 myname_1 = strrchr(*argv,
'/');
138 myname_1 = strrchr(*argv,
'\\');
142 myname_2 = myname_1 + 1;
148 if ( (strncmp(myname_2,
"ee", 2) != 0) && (strncmp(myname_2,
"EE", 2) != 0) )
150 defaultconf = iop_defaultconf;
154 defaultconf = ee_defaultconf;
156 if ( strlen(*argv) > 5 && !strcmp(&(*argv)[strlen(*argv) - 5],
"strip") )
160 argca = analize_arguments(stripopttable, argc, argv);
165 srxgen_2 = read_conf(defaultconf, conffile, print_config);
170 if ( (dumpflag & 0x1000) != 0 )
172 dump_srx_gen_table(srxgen_2);
183 fprintf(stderr,
"Too many input file\n");
196 argcb = analize_arguments(opttable, argc, argv);
201 srxgen_3 = read_conf(defaultconf, conffile, print_config);
206 if ( (dumpflag & 0x1000) != 0 )
208 dump_srx_gen_table(srxgen_3);
219 fprintf(stderr,
"Too many input file\n");
225 elf = read_elf(source);
231 ((elf->ehp->e_flags & EF_MIPS_MACH) == EF_MIPS_MACH_5900)
232 && ((elf->ehp->e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_3) )
234 srxgen_1 = read_conf(ee_defaultconf, conffile, print_config);
238 srxgen_1 = read_conf(iop_defaultconf, conffile, print_config);
244 if ( (dumpflag & 0x1000) != 0 )
246 dump_srx_gen_table(srxgen_1);
249 if ( (dumpflag & 0xFFF) != 0 )
251 print_elf(elf, dumpflag & 0xFFF);
254 elf->optdata = (
void *)srxgen_1;
255 switch ( elf->ehp->e_type )
258 if ( !allow_zero_text && check_zero_text_symbols(source, elf) )
262 if ( convert_rel2srx(elf, entrysym, (rfile || ofile || ffile) ? 1 : 0, irx1_flag) )
267 case ET_SCE_IOPRELEXEC:
268 case ET_SCE_IOPRELEXEC2:
269 case ET_SCE_EERELEXEC2:
273 fprintf(stderr,
"Error: '%s' is unsupport Type Elf file(type=%x)\n", source, elf->ehp->e_type);
279 display_module_info(elf);
281 switch ( elf->ehp->e_type )
283 case ET_SCE_IOPRELEXEC:
284 case ET_SCE_IOPRELEXEC2:
285 case ET_SCE_EERELEXEC2:
288 convert_relative_branch(elf);
292 if ( layout_srx_file(elf) )
296 write_elf(elf, rfile);
301 if ( layout_srx_file(elf) )
305 write_elf(elf, ofile);
309 if ( rfile || ofile )
311 fprintf(stderr,
"Error: Cannot generate IRX/ERX file. '%s' file type is ET_EXEC.\n", source);
316 if ( ffile || startaddr != (
unsigned int)(-1) )
318 switch ( elf->ehp->e_type )
320 case ET_SCE_IOPRELEXEC:
321 case ET_SCE_IOPRELEXEC2:
322 case ET_SCE_EERELEXEC2:
323 elf->ehp->e_type = ET_EXEC;
324 fixlocation_elf(elf, startaddr);
331 if ( layout_srx_file(elf) )
335 write_elf(elf, ffile);
341static void display_module_info(
elf_file *elf)
346 modsect_1 = search_section(elf, SHT_SCE_IOPMOD);
352 if ( iopmodinfo->moduleinfo != (Elf32_Word)(-1) )
355 "name:%s version:%d.%d\n",
356 iopmodinfo->modulename,
357 (uint8_t)(iopmodinfo->moduleversion >> 24),
358 (uint8_t)iopmodinfo->moduleversion);
361 modsect_2 = search_section(elf, SHT_SCE_EEMOD);
367 if ( eemodinfo->moduleinfo != (Elf32_Word)(-1) )
370 "name:%s version:%d.%d\n",
371 eemodinfo->modulename,
372 (uint8_t)(eemodinfo->moduleversion >> 24),
373 (uint8_t)eemodinfo->moduleversion);
378static void convert_relative_branch_an_section(
elf_section *relsect)
383 unsigned int entrise;
386 entrise = relsect->shr.sh_size / relsect->shr.sh_entsize;
390 for ( i = 0; i < entrise; i += 1 )
395 if ( rp->symptr && *symp != rp->symptr )
397 fprintf(stderr,
"Internal error: Illegal relocation entry\n");
401 relsect->info->shr.sh_addr > rp->rel.r_offset
402 || rp->rel.r_offset >= relsect->info->shr.sh_size + relsect->info->shr.sh_addr )
406 "Panic !! relocation #%u offset=0x%x range out (section limit addr=0x%x-0x%x)\n",
409 relsect->info->shr.sh_addr,
410 relsect->info->shr.sh_size + relsect->info->shr.sh_addr);
413 daddr = &relsect->info->data[rp->rel.r_offset - relsect->info->shr.sh_addr];
417 if ( type == R_MIPS_26 )
422 data = *(uint32_t *)daddr;
423 if ( rp->symptr && rp->symptr->bind != STB_LOCAL )
425 fprintf(stderr,
"R_MIPS_26 Unexcepted bind\n");
428 raddr = rp->rel.r_offset + relsect->info->shr.sh_addr;
430 !((((rp->rel.r_offset & 0xF0000000) | (4 * (data & 0x3FFFFFF))) - 4 - raddr) >> 18)
431 || (((rp->rel.r_offset & 0xF0000000) | (4 * (data & 0x3FFFFFF))) - 4 - raddr) >> 18 == 0x3FFF )
435 jaddr = (uint16_t)((((rp->rel.r_offset & 0xF0000000) | (4 * (data & 0x3FFFFFF))) - 4 - raddr) >> 2);
436 if ( data >> 26 == 2 )
438 *(uint32_t *)daddr = jaddr | 0x10000000;
439 rp->type = R_MIPS_NONE;
442 else if ( data >> 26 == 3 )
444 *(uint32_t *)daddr = jaddr | 0x4110000;
445 rp->type = R_MIPS_NONE;
457 if ( rmcount > 0 && (entrise - rmcount) > 0 )
467 for ( j = 0; j < entrise; j += 1 )
477 relsect->data = (uint8_t *)newtab;
478 relsect->shr.sh_size = relsect->shr.sh_entsize * (entrise - rmcount);
482static void convert_relative_branch(
elf_file *elf)
486 if ( elf->scp == NULL )
490 for ( i = 1; i < elf->ehp->e_shnum; i += 1 )
492 if ( elf->scp[i]->shr.sh_type == SHT_REL )
494 convert_relative_branch_an_section(elf->scp[i]);
499static int check_zero_text_symbols(
const char *source,
const elf_file *elf)
505 if ( elf->scp == NULL )
512 for ( i = 1; i < elf->ehp->e_shnum; i += 1 )
514 if ( elf->scp[i]->name && strcmp(elf->scp[i]->name,
".text") == 0 )
526 for ( i = 1; i < elf->ehp->e_shnum; i += 1 )
534 if ( sect->shr.sh_type != SHT_SYMTAB || sect->data == NULL || sect->shr.sh_entsize == 0 )
538 nsyms = sect->shr.sh_size / sect->shr.sh_entsize;
540 for ( j = 1; j < nsyms; j += 1 )
550 && (strcmp(sym->name,
"_start") == 0 || strcmp(sym->name,
"_ftext") == 0) )
554 if ( (
unsigned int)sym->sym.st_shndx == (
unsigned int)text_idx
555 && (sym->type == STT_FUNC || sym->type == STT_NOTYPE)
556 && sym->sym.st_value == 0 )
560 "ERROR: %s: symbol '%s' (sym#%u) is in .text with value 0"
561 " -- if this module has an export table, put exports.o"
562 " first in IOP_OBJS and move _retonly after"
563 " DECLARE_EXPORT_TABLE in exports.tab;"
564 " otherwise use --allow-zero-text.\n",
566 (sym->name && sym->name[0]) ? sym->name :
"<unnamed>",