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]);