11#include "srxfixup_internal.h"
19 unsigned int org_addr;
20 unsigned int org_gp_value;
23static int setup_start_entry(
elf_file *elf,
const char *entrysym,
elf_section *modinfo,
int needoutput);
25static void fixlocation_an_rel(
elf_section *relsect,
unsigned int startaddr);
26static void save_org_addrs(
elf_file *elf);
30static void add_reserved_symbol_table(
39static void define_special_section_symbols(
elf_file *elf);
40static void create_need_section(
elf_file *elf);
41static int sect_name_match(
const char *pattern,
const char *name);
42static int reorder_section_table(
elf_file *elf);
43static void create_phdr(
elf_file *elf);
44static void check_change_bit(
unsigned int oldbit,
unsigned int newbit,
unsigned int *up,
unsigned int *down);
45static void segment_start_setup(
SegConf *seglist,
unsigned int bitid,
const unsigned int *moffset);
46static void add_section_to_segment(
SegConf *seglist,
elf_section *scp,
unsigned int bitid);
47static void segment_end_setup(
SegConf *seglist,
unsigned int bitid,
unsigned int *moffset,
int ee);
48static void update_modinfo(
elf_file *elf);
49static void update_mdebug(
elf_file *elf);
50static void update_programheader(
elf_file *elf);
51static void remove_unuse_section(
elf_file *elf);
52static int layout_srx_memory(
elf_file *elf);
54static int check_undef_symboles_an_reloc(
elf_section *relsect);
55static int check_undef_symboles(
elf_file *elf);
56static int create_reserved_symbols(
elf_file *elf);
57static void symbol_value_update(
elf_file *elf);
58static void rebuild_relocation(
elf_file *elf,
unsigned int gpvalue);
59static int check_irx12(
elf_file *elf,
int cause_irx1);
60static void setup_module_info(
elf_file *elf,
elf_section *modsect,
const char *modulesymbol);
61static void rebuild_an_relocation(
elf_section *relsect,
unsigned int gpvalue,
int target);
63static size_t eemod_size(
const Elf32_EeMod *modinfo);
65int convert_rel2srx(
elf_file *elf,
const char *entrysym,
int needoutput,
int cause_irx1)
75 modinfo = add_iopmod(elf);
78 modinfo = add_eemod(elf);
81 fprintf(stderr,
"Internal error: target unknown\n");
84 remove_unuse_section(elf);
85 define_special_section_symbols(elf);
86 create_need_section(elf);
87 reorder_section_table(elf);
89 if ( layout_srx_memory(elf) )
93 modify_eemod(elf, modinfo);
94 if ( create_reserved_symbols(elf) )
98 if ( check_undef_symboles(elf) )
102 symbol_value_update(elf);
103 rebuild_relocation(elf, lookup_segment(tp,
"GLOBALDATA", 1)->addr + 0x7FF0);
104 if ( check_irx12(elf, cause_irx1) )
108 if ( setup_start_entry(elf, entrysym, modinfo, needoutput) )
113 const char *module_info_symbol;
116 module_info_symbol =
"Module";
117 syp = search_global_symbol(
"_irx_id", elf);
118 if ( is_defined_symbol(syp) != 0 )
120 module_info_symbol =
"_irx_id";
122 setup_module_info(elf, modinfo, module_info_symbol);
124 return layout_srx_file(elf);
127static int setup_start_entry(
elf_file *elf,
const char *entrysym,
elf_section *modinfo,
int needoutput)
133 syp = search_global_symbol(entrysym, elf);
134 if ( !is_defined_symbol(syp) )
136 fprintf(stderr,
"Error: Cannot find entry symbol %s\n", entrysym);
139 elf->ehp->e_entry = get_symbol_value(syp, elf);
143 syp = search_global_symbol(
"start", elf);
146 syp = search_global_symbol(
"_start", elf);
148 if ( !is_defined_symbol(syp) )
150 if ( modinfo->shr.sh_type == SHT_SCE_EEMOD )
152 elf->ehp->e_entry = -1;
154 else if ( needoutput )
156 fprintf(stderr,
"warning: Cannot find entry symbol `start' and `_start'\n");
161 elf->ehp->e_entry = get_symbol_value(syp, elf);
164 switch ( modinfo->shr.sh_type )
168 *((uint32_t *)modinfo->data + 1) = elf->ehp->e_entry;
180 if ( !strcmp(ordstr,
"@Section_header_table") )
182 for ( ; order->type != EFS_TYPE_END; order += 1 )
184 if ( order->type == EFS_TYPE_SECTION_HEADER_TABLE )
191 if ( !strncmp(ordstr,
"@Program_header_data ", 0x15) )
195 n = strtol(ordstr + 21, NULL, 10);
196 for ( ; order->type != EFS_TYPE_END; order += 1 )
198 if ( order->type == EFS_TYPE_PROGRAM_HEADER_ENTRY && order->d.php == &elf->php[n] )
205 for ( ; order->type != EFS_TYPE_END; order += 1 )
207 switch ( order->type )
209 case EFS_TYPE_PROGRAM_HEADER_ENTRY:
210 for ( scp = order->d.php->scp; *scp; scp += 1 )
212 if ( !sect_name_match(ordstr, (*scp)->name) )
218 case EFS_TYPE_SECTION_DATA:
219 if ( !sect_name_match(ordstr, order->d.scp->name) )
241 unsigned int max_seg_align;
247 switch ( tp->target )
253 max_seg_align = 0x10000;
256 fprintf(stderr,
"Internal error: target unknown\n");
260 rebuild_section_name_strings(elf);
261 rebuild_symbol_name_strings(elf);
262 order = build_file_order_list(elf);
263 for ( maxslot = 0; order[maxslot].type != EFS_TYPE_END; maxslot += 1 )
269 nslotp = neworder + 1;
270 order->type = EFS_TYPE_NONE;
271 if ( elf->ehp->e_phnum )
274 nslotp = neworder + 2;
275 order[1].type = EFS_TYPE_NONE;
277 for ( ordstr = tp->file_layout_order; *ordstr; ordstr += 1 )
281 slotp_1 = search_order_slots(*ordstr, elf, order);
288 slotp_1->type = EFS_TYPE_NONE;
291 nslotp->type = EFS_TYPE_END;
292 shrink_file_order_list(neworder);
293 writeback_file_order_list(elf, neworder);
294 for ( slotp_2 = neworder; slotp_2->type != EFS_TYPE_END; slotp_2 += 1 )
297 slotp_2->type == EFS_TYPE_PROGRAM_HEADER_ENTRY && slotp_2->d.php->phdr.p_type == PT_LOAD
298 && max_seg_align < slotp_2->align )
300 fprintf(stderr,
"Program Header Entry: unsupported align %u\n", slotp_2->align);
302 for ( scp = slotp_2->d.php->scp; *scp; scp += 1 )
304 if ( max_seg_align < (*scp)->shr.sh_addralign )
307 stderr,
"Section '%s' : unsupported section align %d\n", (*scp)->name, (
int)((*scp)->shr.sh_addralign));
314 if (error && tp->target == SRX_TARGET_IOP)
316 fprintf(stderr,
"LOADCORE limits possible alignment to 16 bytes\n");
328 unsigned int entrise;
332 remove_section(elf, SHT_MIPS_DEBUG);
333 scp = search_section(elf, SHT_SYMTAB);
338 entrise = scp->shr.sh_size / scp->shr.sh_entsize;
341 for ( s = 1; s < entrise; s += 1 )
343 if ( syp[s]->refcount <= 0 )
353 scp->shr.sh_size = d * scp->shr.sh_entsize;
360 for ( i = conf->segment_list; i->name; i += 1 )
362 if ( !strcmp(segname, i->name) )
369 fprintf(stderr,
"segment '%s' not found \n", segname);
374static void fixlocation_an_rel(
elf_section *relsect,
unsigned int startaddr)
384 unsigned int entrise;
387 entrise = relsect->shr.sh_size / relsect->shr.sh_entsize;
390 for ( i = 0; i < entrise; i += 1 )
394 if ( rp->symptr && *symp != rp->symptr )
396 fprintf(stderr,
"Internal error: Illegal relocation entry\n");
400 relsect->info->shr.sh_addr > rp->rel.r_offset
401 || rp->rel.r_offset >= relsect->info->shr.sh_size + relsect->info->shr.sh_addr )
405 "Panic !! relocation #%u offset=0x%x range out (section limit addr=0x%x-0x%x)\n",
408 relsect->info->shr.sh_addr,
409 relsect->info->shr.sh_size + relsect->info->shr.sh_addr);
412 datal = &relsect->info->data[rp->rel.r_offset - relsect->info->shr.sh_addr];
416 data_1 = startaddr + (int16_t)*(uint32_t *)datal;
417 if ( (uint16_t)(data_1 >> 16) )
419 if ( (uint16_t)(data_1 >> 16) != 0xFFFF )
421 fprintf(stderr,
"REFHALF data overflow\n");
425 *(uint32_t *)datal &= 0xFFFF0000;
426 *(uint32_t *)datal |= (uint16_t)data_1;
429 *(uint32_t *)datal += startaddr;
432 if ( rp->symptr && rp->symptr->bind != STB_LOCAL )
434 fprintf(stderr,
"R_MIPS_26 Unexcepted bind\n");
437 data_2 = startaddr + ((rp->rel.r_offset & 0xF0000000) | (4 * (*(uint32_t *)datal & 0x3FFFFFF)));
438 *(uint32_t *)datal &= 0xFC000000;
439 *(uint32_t *)datal |= (16 * data_2) >> 6;
442 if ( i == entrise + 1 || rp[1].type != R_MIPS_LO16 || (rp->symptr && rp[1].symptr != rp->symptr) )
444 fprintf(stderr,
"R_MIPS_HI16 without R_MIPS_LO16\n");
447 data_4 = startaddr + (int16_t)*(uint32_t *)&relsect->info->data[rp[1].rel.r_offset - relsect->info->shr.sh_addr]
448 + (*(uint32_t *)datal << 16);
449 *(uint32_t *)datal &= 0xFFFF0000;
450 *(uint32_t *)datal |= (uint16_t)(((data_4 >> 15) + 1) >> 1);
453 data_5 = startaddr + *(uint32_t *)datal;
454 *(uint32_t *)datal &= 0xFFFF0000;
455 *(uint32_t *)datal |= data_5;
458 fprintf(stderr,
"Unexcepted R_MIPS_GPREL16\n");
462 fprintf(stderr,
"Unexcepted R_MIPS_LITERAL\n");
465 case R_MIPSSCE_MHI16:
466 if ( i == entrise + 1 || rp[1].type != R_MIPSSCE_ADDEND )
468 fprintf(stderr,
"R_MIPSSCE_MHI16 without R_MIPSSCE_ADDEND\n");
471 data_3 = (uint16_t)((((startaddr + rp[1].rel.r_offset) >> 15) + 1) >> 1);
472 for ( daddr1 = 1; daddr1; datal += daddr1 )
474 daddr1 = *(uint16_t *)datal << 16 >> 14;
475 *(uint32_t *)datal &= 0xFFFF0000;
476 *(uint32_t *)datal |= data_3;
488 case R_MIPS_CALLHI16:
489 case R_MIPS_CALLLO16:
490 fprintf(stderr,
"unacceptable relocation type: 0x%x\n", rp->type);
494 fprintf(stderr,
"unknown relocation type: 0x%x\n", rp->type);
502void fixlocation_elf(
elf_file *elf,
unsigned int startaddr)
504 unsigned int entrise;
515 if ( elf->scp == NULL )
520 for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
522 if ( elf->scp[s]->shr.sh_type == SHT_REL )
524 fixlocation_an_rel(elf->scp[s], startaddr);
528 elf->scp[d] = elf->scp[s];
532 elf->ehp->e_shnum = d;
533 elf->ehp->e_entry += startaddr;
534 modsect_1 = search_section(elf, SHT_SCE_IOPMOD);
540 if ( iopmodinfo->moduleinfo != (Elf32_Word)(-1) )
542 iopmodinfo->moduleinfo += startaddr;
544 iopmodinfo->entry += startaddr;
545 iopmodinfo->gp_value += startaddr;
547 modsect_2 = search_section(elf, SHT_SCE_EEMOD);
553 if ( eemodinfo->moduleinfo != (Elf32_Word)(-1) )
555 eemodinfo->moduleinfo += startaddr;
557 eemodinfo->entry += startaddr;
558 eemodinfo->gp_value += startaddr;
560 for ( i = 0; i < elf->ehp->e_phnum; i += 1 )
562 if ( elf->php[i].phdr.p_type == PT_LOAD )
564 elf->php[i].phdr.p_vaddr = startaddr;
565 elf->php[i].phdr.p_paddr = startaddr;
569 for ( j = 1; j < elf->ehp->e_shnum; j += 1 )
571 switch ( elf->scp[j]->shr.sh_type )
575 elf->scp[j]->shr.sh_addr += startaddr;
581 scp = search_section(elf, SHT_SYMTAB);
586 entrise = scp->shr.sh_size / scp->shr.sh_entsize;
588 for ( k = 1; k < entrise; k += 1 )
590 if ( syp[k]->sym.st_shndx == SHN_RADDR || (syp[k]->sym.st_shndx && syp[k]->sym.st_shndx <= 0xFEFF) )
592 syp[k]->sym.st_value += startaddr;
594 if ( syp[k]->sym.st_shndx == SHN_RADDR )
596 syp[k]->sym.st_shndx = -15;
601static void save_org_addrs(
elf_file *elf)
608 reginfosec = search_section(elf, SHT_MIPS_REGINFO);
618 for ( i = 1; i < elf->ehp->e_shnum; i += 1 )
623 org->org_addr = elf->scp[i]->shr.sh_addr;
626 org->org_gp_value = reginfop->ri_gp_value;
628 elf->scp[i]->optdata = (
void *)org;
641 iopmodp->moduleinfo = -1;
642 modsect->name = strdup(
".iopmod");
643 modsect->data = (uint8_t *)iopmodp;
644 modsect->shr.sh_type = SHT_SCE_IOPMOD;
645 modsect->shr.sh_size = iopmod_size(iopmodp);
646 modsect->shr.sh_addralign = 4;
647 modsect->shr.sh_entsize = 0;
648 add_section(elf, modsect);
661 eemodp->moduleinfo = -1;
662 modsect->name = strdup(
".eemod");
663 modsect->data = (uint8_t *)eemodp;
664 modsect->shr.sh_type = SHT_SCE_EEMOD;
665 modsect->shr.sh_size = eemod_size(eemodp);
666 modsect->shr.sh_addralign = 4;
667 modsect->shr.sh_entsize = 0;
668 add_section(elf, modsect);
678 if ( eemod->shr.sh_type != SHT_SCE_EEMOD )
683 scp_1 = search_section_by_name(elf,
".erx.lib");
686 moddata->erx_lib_addr = scp_1->shr.sh_addr;
687 moddata->erx_lib_size = scp_1->shr.sh_size;
691 moddata->erx_lib_addr = -1;
692 moddata->erx_lib_size = 0;
694 scp_2 = search_section_by_name(elf,
".erx.stub");
697 moddata->erx_stub_addr = scp_2->shr.sh_addr;
698 moddata->erx_stub_size = scp_2->shr.sh_size;
702 moddata->erx_stub_addr = -1;
703 moddata->erx_stub_size = 0;
707static void add_reserved_symbol_table(
713 const char *sectname,
722 for ( newent_1 = tp->create_symbols; newent_1->name; newent_1 += 1 )
727 memset(&tp->create_symbols[entries], 0,
sizeof(tp->create_symbols[entries]));
728 newent_2 = &tp->create_symbols[entries - 1];
729 newent_2->name = strdup(name);
730 newent_2->bind = bind;
731 newent_2->type = type;
732 newent_2->segment = segment;
733 newent_2->sectname = strdup(sectname);
734 newent_2->shindex = shindex;
735 newent_2->seflag = base;
738const char *bos_str =
"_begin_of_section_";
739const char *eos_str =
"_end_of_section_";
740static void define_special_section_symbols(
elf_file *elf)
746 unsigned int entrise;
751 scp = search_section(elf, SHT_SYMTAB);
756 sectname = (
char *)__builtin_alloca(((elf->shstrptr->shr.sh_size + 22) >> 2) << 2);
757 entrise = scp->shr.sh_size / scp->shr.sh_entsize;
759 for ( i = 1; i < entrise; i += 1 )
762 if ( sym->bind == STB_GLOBAL && !sym->sym.st_shndx )
764 if ( !strncmp(bos_str, sym->name, strlen(bos_str)) )
766 strcpy(sectname,
".");
767 strcat(sectname, &sym->name[strlen(bos_str)]);
768 add_reserved_symbol_table(tp, sym->name, 2, 1, 0, sectname, 0, 0);
770 if ( !strncmp(eos_str, sym->name, strlen(eos_str)) )
772 strcpy(sectname,
".");
773 strcat(sectname, &sym->name[strlen(eos_str)]);
774 add_reserved_symbol_table(tp, sym->name, 2, 1, 0, sectname, 65311, 1);
780static void create_need_section(
elf_file *elf)
788 scp = search_section(elf, SHT_SYMTAB);
793 for ( i = 1; i < (scp->shr.sh_size / scp->shr.sh_entsize); i += 1 )
797 syment = *(
elf_syment **)&scp->data[i *
sizeof(
void *)];
798 if ( !syment->sym.st_shndx )
800 csym = is_reserve_symbol(tp, syment->name);
807 addscp_1 = csym->segment->empty_section;
810 if ( !search_section_by_name(elf, addscp_1->name) )
812 add_section(elf, addscp_1);
816 else if ( csym->sectname && !search_section_by_name(elf, csym->sectname) )
820 for ( odr = tp->section_list; odr->sect_name_pattern; odr += 1 )
822 if ( !sect_name_match(odr->sect_name_pattern, csym->sectname) && odr->secttype && odr->sectflag )
827 addscp_2->name = strdup(csym->sectname);
828 addscp_2->shr.sh_type = odr->secttype;
829 addscp_2->shr.sh_flags = odr->sectflag;
830 addscp_2->shr.sh_size = 0;
831 addscp_2->shr.sh_addralign = 4;
832 addscp_2->shr.sh_entsize = 0;
833 add_section(elf, addscp_2);
843static int sect_name_match(
const char *pattern,
const char *name)
845 for ( ; *pattern && *name && *pattern !=
'*'; pattern += 1, name += 1 )
847 if ( *name > *pattern )
851 if ( *name < *pattern )
856 if ( !*pattern && !*name )
860 if ( *pattern ==
'*' && !pattern[1] )
864 if ( *pattern !=
'*' )
866 return strcmp(pattern, name);
869 if ( strlen(name) < strlen(pattern) )
871 return strcmp(pattern, name);
873 return strcmp(pattern, &name[strlen(name) - strlen(pattern)]);
876static int reorder_section_table(
elf_file *elf)
878 const char **secorder;
884 sections = elf->ehp->e_shnum;
885 secorder = ((
Srx_gen_table *)elf->optdata)->section_table_order;
887 memcpy(scp, elf->scp, sections *
sizeof(
elf_section *));
890 for ( ; *secorder; secorder += 1 )
892 for ( s = 1; s < sections; s += 1 )
896 if ( !sect_name_match(*secorder, scp[s]->name) )
898 elf->scp[d] = scp[s];
910static void create_phdr(
elf_file *elf)
915 phip = ((
Srx_gen_table *)(elf->optdata))->program_header_order;
916 for ( i = 0; phip[i].sw; i += 1 )
921 if ( elf->php != NULL )
926 elf->ehp->e_phnum = i;
927 if ( elf->php != NULL )
931 for ( j = 0; phip[j].sw; j += 1 )
933 switch ( phip[j].sw )
935 case SRX_PH_TYPE_MOD:
936 elf->php[j].phdr.p_flags = PF_R;
937 elf->php[j].phdr.p_align = 4;
938 if ( !strcmp(
".iopmod", phip[j].d.section_name) )
940 elf->php[j].phdr.p_type = PT_SCE_IOPMOD;
943 *elf->php[j].scp = search_section(elf, SHT_SCE_IOPMOD);
945 else if ( !strcmp(
".eemod", phip[j].d.section_name) )
947 elf->php[j].phdr.p_type = PT_SCE_EEMOD;
950 *elf->php[j].scp = search_section(elf, SHT_SCE_EEMOD);
954 fprintf(stderr,
"Unsuport section '%s' for program header\n", phip[j].d.section_name);
957 case SRX_PH_TYPE_TEXT:
958 elf->php[j].phdr.p_type = PT_LOAD;
959 elf->php[j].phdr.p_flags = PF_X | PF_W | PF_R;
960 elf->php[j].phdr.p_align = 16;
969static void check_change_bit(
unsigned int oldbit,
unsigned int newbit,
unsigned int *up,
unsigned int *down)
971 *up = ~oldbit & newbit & (newbit ^ oldbit);
972 *down = ~newbit & oldbit & (newbit ^ oldbit);
975static void segment_start_setup(
SegConf *seglist,
unsigned int bitid,
const unsigned int *moffset)
977 for ( ; seglist->name; seglist += 1 )
979 if ( (seglist->bitid & bitid) != 0 )
981 seglist->addr = *moffset;
987static void add_section_to_segment(
SegConf *seglist,
elf_section *scp,
unsigned int bitid)
989 for ( ; seglist->name; seglist += 1 )
991 if ( (seglist->bitid & bitid) != 0 )
993 if ( !seglist->nsect )
995 seglist->addr = scp->shr.sh_addr;
999 seglist->scp[seglist->nsect - 1] = scp;
1000 seglist->scp[seglist->nsect] = 0;
1005static void segment_end_setup(
SegConf *seglist,
unsigned int bitid,
unsigned int *moffset,
int ee)
1007 for ( ; seglist->name; seglist += 1 )
1009 if ( (seglist->bitid & bitid) != 0 )
1013 if ( !strcmp(seglist->name,
"TEXT") )
1018 seglist->size = *moffset - seglist->addr;
1023static void update_modinfo(
elf_file *elf)
1034 seginfo = lookup_segment(tp,
"TEXT", 1);
1035 seginfo_4 = lookup_segment(tp,
"DATA", 1);
1036 seginfo_8 = lookup_segment(tp,
"BSS", 1);
1037 seginfo_12 = lookup_segment(tp,
"GLOBALDATA", 1);
1038 if ( !seginfo || !seginfo_4 || !seginfo_8 || !seginfo_12 )
1040 fprintf(stderr,
"TEXT,DATA,BSS,GLOBALDATA segment missing abort");
1043 scp_1 = search_section(elf, SHT_SCE_IOPMOD);
1048 scp_1->shr.sh_addr = 0;
1050 imp->text_size = seginfo_4->addr - seginfo->addr;
1051 imp->data_size = seginfo_8->addr - seginfo_4->addr;
1052 imp->bss_size = seginfo_8->size;
1053 imp->gp_value = seginfo_12->addr + 0x7FF0;
1055 scp_2 = search_section(elf, SHT_SCE_EEMOD);
1060 scp_2->shr.sh_addr = 0;
1062 emp->text_size = seginfo_4->addr - seginfo->addr;
1063 emp->data_size = seginfo_8->addr - seginfo_4->addr;
1064 emp->bss_size = seginfo_8->size;
1065 emp->gp_value = seginfo_12->addr + 0x7FF0;
1069static void update_mdebug(
elf_file *elf)
1073 scp = search_section(elf, SHT_MIPS_DEBUG);
1076 scp->shr.sh_addr = 0;
1080static void update_programheader(
elf_file *elf)
1086 unsigned int minsegalign;
1096 phip = tp->program_header_order;
1097 switch ( tp->target )
1099 case SRX_TARGET_IOP:
1106 fprintf(stderr,
"Internal error: target unknown\n");
1110 for ( n = 0; phip[n].sw; n += 1 )
1112 if ( phip[n].sw == SRX_PH_TYPE_TEXT )
1114 segp = phip[n].d.segment_list;
1117 elf->php[n].phdr.p_vaddr = (*segp)->addr;
1118 align = minsegalign;
1119 for ( nsect_1 = 0, nseg_1 = 0; segp[nseg_1]; nsect_1 += segp[nseg_1]->nsect, nseg_1 += 1 )
1124 elf->php[n].scp = scp;
1125 for ( nsect_2 = 0, nseg_2 = 0; segp[nseg_2]; nsect_2 += segp[nseg_2]->nsect, nseg_2 += 1 )
1127 memcpy(&scp[nsect_2], segp[nseg_2]->scp, segp[nseg_2]->nsect *
sizeof(
elf_section *));
1129 for ( s = 0; s < nsect_2 && scp[s]->shr.sh_type == SHT_PROGBITS; s += 1 )
1131 if ( scp[s]->shr.sh_addralign > align )
1133 align = scp[s]->shr.sh_addralign;
1136 elf->php[n].phdr.p_filesz = scp[s - 1]->shr.sh_size + scp[s - 1]->shr.sh_addr - (*scp)->shr.sh_addr;
1137 elf->php[n].phdr.p_memsz = scp[nsect_2 - 1]->shr.sh_size + scp[nsect_2 - 1]->shr.sh_addr - (*scp)->shr.sh_addr;
1138 for ( ; s < nsect_2; s += 1 )
1140 if ( scp[s]->shr.sh_addralign > align )
1142 align = scp[s]->shr.sh_addralign;
1145 elf->php[n].phdr.p_align = align;
1151static void remove_unuse_section(
elf_file *elf)
1153 const char **sectnames;
1160 sections = elf->ehp->e_shnum;
1161 sectnames = ((
Srx_gen_table *)(elf->optdata))->removesection_list;
1163 memset(dscp, 0, sections *
sizeof(
elf_section *));
1165 for ( ; *sectnames; sectnames += 1 )
1167 for ( i = 1; i < sections; i += 1 )
1171 if ( !sect_name_match(*sectnames, elf->scp[i]->name) )
1173 dscp[d] = elf->scp[i];
1179 for ( j = 0; j < sections; j += 1 )
1183 remove_section_by_name(elf, dscp[j]->name);
1189static int layout_srx_memory(
elf_file *elf)
1200 unsigned int downdelta;
1201 unsigned int updelta;
1202 unsigned int oldbitid;
1203 unsigned int moffset;
1209 is_ee = tp->target == SRX_TARGET_EE;
1214 sections = elf->ehp->e_shnum;
1216 memcpy(scp, elf->scp, sections *
sizeof(
elf_section *));
1217 for ( odr = tp->section_list; odr->sect_name_pattern; odr += 1 )
1219 check_change_bit(oldbitid, odr->flag, &updelta, &downdelta);
1222 segment_start_setup(tp->segment_list, updelta, &moffset);
1224 for ( s_1 = 1; s_1 < sections; s_1 += 1 )
1227 scp[s_1] && !sect_name_match(odr->sect_name_pattern, scp[s_1]->name)
1228 && (scp[s_1]->shr.sh_flags & SHF_ALLOC) != 0 )
1230 moffset = adjust_align(moffset, scp[s_1]->shr.sh_addralign);
1231 scp[s_1]->shr.sh_addr = moffset;
1232 moffset += scp[s_1]->shr.sh_size;
1233 add_section_to_segment(tp->segment_list, scp[s_1], odr->flag);
1237 oldbitid = odr->flag;
1238 check_change_bit(oldbitid, odr[1].flag, &updelta, &downdelta);
1241 segment_end_setup(tp->segment_list, downdelta, &moffset, is_ee);
1244 for ( s_2 = 1; s_2 < sections; s_2 += 1 )
1246 if ( scp[s_2] && (scp[s_2]->shr.sh_flags & SHF_ALLOC) != 0 )
1251 && (!scp[s_3] || (scp[s_3]->shr.sh_type != SHT_RELA && scp[s_3]->shr.sh_type != SHT_REL) || scp[s_2] != scp[s_3]->info);
1256 if ( sections > s_3 )
1260 "Error: section '%s' needs allocation and has relocation data but not in program segment\n",
1267 fprintf(stderr,
"Warning: section '%s' needs allocation but not in program segment\n", scp[s_2]->name);
1275 update_modinfo(elf);
1277 update_programheader(elf);
1290 for ( csyms = tp->create_symbols; csyms->name; csyms += 1 )
1292 if ( !strcmp(csyms->name, name) )
1300static int check_undef_symboles_an_reloc(
elf_section *relsect)
1305 unsigned int entrise;
1308 entrise = relsect->shr.sh_size / relsect->shr.sh_entsize;
1309 rp = (
elf_rel *)relsect->data;
1312 for ( i = 0; i < entrise; i += 1 )
1314 if ( rp->symptr && *symp != rp->symptr )
1316 if ( rp->symptr->sym.st_shndx )
1319 rp->symptr->sym.st_shndx > 0xFEFF && rp->symptr->sym.st_shndx != SHN_ABS
1320 && rp->symptr->sym.st_shndx != SHN_RADDR )
1322 if ( rp->symptr->sym.st_shndx == SHN_COMMON )
1324 fprintf(stderr,
" unallocated variable `%s'\n", rp->symptr->name);
1328 fprintf(stderr,
" `%s' unknown symbol type %x\n", rp->symptr->name, rp->symptr->sym.st_shndx);
1333 else if ( rp->symptr->bind != STB_WEAK )
1335 fprintf(stderr,
" undefined reference to `%s'\n", rp->symptr->name);
1344static int check_undef_symboles(
elf_file *elf)
1354 for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
1356 if ( elf->scp[s]->shr.sh_type == SHT_REL )
1358 err += check_undef_symboles_an_reloc(elf->scp[s]);
1366static const char *
const SymbolType[] =
1369 XEACH_SymbolType_enum()
1374static int create_reserved_symbols(
elf_file *elf)
1377 unsigned int sh_size;
1378 unsigned int sh_addr;
1385 if ( !search_section(elf, SHT_SYMTAB) )
1389 for ( csyms = tp->create_symbols; csyms->name; csyms += 1 )
1393 sym = search_global_symbol(csyms->name, elf);
1395 && (csyms->shindex > 0xFEFF
1396 || (csyms->segment && csyms->segment->scp)
1397 || (!csyms->segment && csyms->sectname && search_section_by_name(elf, csyms->sectname))) )
1399 sym = add_symbol(elf, csyms->name, csyms->bind, 0, 0, 0, 0);
1406 if ( csyms->segment )
1408 sh_addr = csyms->segment->addr;
1409 sh_size = csyms->segment->size;
1410 if ( csyms->shindex <= 0xFEFF )
1412 scp = *csyms->segment->scp;
1415 else if ( csyms->sectname != NULL )
1417 scp = search_section_by_name(elf, csyms->sectname);
1420 sh_addr = scp->shr.sh_addr;
1421 sh_size = scp->shr.sh_size;
1424 if ( csyms->segment || scp )
1428 if ( sym->sym.st_shndx )
1430 fprintf(stderr,
"Unexcepted Symbol \"%s\":%s \n", sym->name, SymbolType[sym->type]);
1436 sym->bind = csyms->bind;
1439 sym->type = csyms->type;
1441 sym->sym.st_info = ((csyms->bind & 0xFF) << 4) + (csyms->type & 0xF);
1442 if ( csyms->shindex > 0xFEFF )
1444 sym->sym.st_shndx = csyms->shindex;
1446 switch ( csyms->seflag )
1449 sym->sym.st_value = sh_addr;
1452 sym->sym.st_value = sh_size + sh_addr;
1455 sym->sym.st_value = sh_addr + 0x7FF0;
1463 sym->sym.st_shndx = 1;
1465 switch ( csyms->seflag )
1468 sym->sym.st_value = 0;
1471 sym->sym.st_value = sh_size;
1480 if ( csyms->bind == STB_WEAK && (sym->bind == STB_GLOBAL || sym->bind == STB_WEAK) && !sym->sym.st_shndx )
1484 sym->type = csyms->type;
1486 sym->bind = csyms->bind;
1487 sym->sym.st_info = ((csyms->bind & 0xFF) << 4) + (csyms->type & 0xF);
1494static void symbol_value_update(
elf_file *elf)
1496 unsigned int entrise;
1503 if ( elf->ehp->e_type != ET_REL )
1509 case SRX_TARGET_IOP:
1510 elf->ehp->e_type = ET_SCE_IOPRELEXEC;
1513 elf->ehp->e_type = ET_SCE_EERELEXEC2;
1518 scp = search_section(elf, SHT_SYMTAB);
1523 entrise = scp->shr.sh_size / scp->shr.sh_entsize;
1525 for ( i = 1; i < entrise; i += 1 )
1527 if ( syp[i]->sym.st_shndx )
1529 if ( syp[i]->sym.st_shndx <= 0xFEFF )
1531 syp[i]->sym.st_value += syp[i]->shptr->shr.sh_addr;
1537static void rebuild_relocation(
elf_file *elf,
unsigned int gpvalue)
1541 if ( elf->scp == NULL )
1545 for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
1547 if ( elf->scp[s]->shr.sh_type == SHT_REL )
1549 rebuild_an_relocation(elf->scp[s], gpvalue, ((
Srx_gen_table *)(elf->optdata))->target);
1554static int check_irx12(
elf_file *elf,
int cause_irx1)
1558 if ( elf->ehp->e_type != ET_SCE_IOPRELEXEC )
1562 for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
1564 if ( elf->scp[s]->shr.sh_type == SHT_REL && relocation_is_version2(elf->scp[s]) )
1568 fprintf(stderr,
"R_MIPS_LO16 without R_MIPS_HI16\n");
1571 elf->ehp->e_type = ET_SCE_IOPRELEXEC2;
1577static void setup_module_info(
elf_file *elf,
elf_section *modsect,
const char *modulesymbol)
1579 unsigned int *section_data;
1585 const unsigned int *modnamep;
1586 unsigned int *modidatap;
1587 unsigned int modiaddr;
1590 syp = search_global_symbol(modulesymbol, elf);
1591 if ( is_defined_symbol(syp) == 0 )
1595 modiaddr = get_symbol_value(syp, elf);
1596 modidatap = get_section_data(elf, modiaddr);
1597 section_data = get_section_data(elf, *modidatap);
1598 woff = (uintptr_t)section_data & 3;
1599 modnamep = (
unsigned int *)((
char *)section_data - woff);
1600 buflen = (strlen((
const char *)section_data - woff + 4) + 15) & 0xFFFFFFFC;
1601 buf = (
char *)malloc(buflen);
1602 memcpy(buf, modnamep, buflen);
1603 swapmemory(buf,
"l", buflen >> 2);
1605 switch ( modsect->shr.sh_type )
1607 case SHT_SCE_IOPMOD:
1613 iopmodp_1->moduleinfo = modiaddr;
1614 iopmodp_1->moduleversion = *((uint16_t *)modidatap + 2);
1618 strcpy(iopmodp_2->modulename, name);
1619 modsect->data = (uint8_t *)iopmodp_2;
1620 modsect->shr.sh_size = iopmod_size(iopmodp_2);
1628 eemodp_1->moduleinfo = modiaddr;
1629 eemodp_1->moduleversion = *((uint16_t *)modidatap + 2);
1631 strcpy(eemodp_2->modulename, name);
1632 modsect->data = (uint8_t *)eemodp_2;
1633 modsect->shr.sh_size = eemod_size(eemodp_2);
1640 if ( elf->php == NULL )
1644 for ( i = 0; i < elf->ehp->e_phnum; i += 1 )
1646 if ( elf->php[i].scp && (modsect == *elf->php[i].scp) )
1648 elf->php[i].phdr.p_filesz = modsect->shr.sh_size;
1653static void rebuild_an_relocation(
elf_section *relsect,
unsigned int gpvalue,
int target)
1665 unsigned int data_5;
1666 unsigned int data_6;
1672 unsigned int entrise;
1678 entrise = relsect->shr.sh_size / relsect->shr.sh_entsize;
1679 rp = (
elf_rel *)relsect->data;
1682 for ( i_1 = 0; i_1 < entrise; )
1689 if ( relsect->info->shr.sh_size <= rp->rel.r_offset )
1693 "Panic !! relocation #%u offset=0x%x overflow (section size=0x%x)\n",
1696 relsect->info->shr.sh_size);
1700 daddr_1 = (
void *)&relsect->info->data[rp->rel.r_offset];
1704 if ( rp->symptr->sym.st_shndx )
1706 symvalue = rp->symptr->sym.st_value;
1711 !rp->symptr || (rp->symptr->sym.st_shndx && rp->symptr->sym.st_shndx <= 0xFEFF)
1712 || rp->symptr->sym.st_shndx == SHN_RADDR )
1722 data_1 = symvalue + (int16_t)*(uint32_t *)daddr_1;
1723 if ( (uint16_t)(data_1 >> 16) && (uint16_t)(data_1 >> 16) != 0xFFFF )
1725 fprintf(stderr,
"REFHALF data overflow\n");
1728 *(uint32_t *)daddr_1 &= 0xFFFF0000;
1729 *(uint32_t *)daddr_1 |= (uint16_t)data_1;
1732 rp->type = R_MIPS_NONE;
1737 *(uint32_t *)daddr_1 += symvalue;
1740 rp->type = R_MIPS_NONE;
1745 data_2 = *(uint32_t *)daddr_1;
1746 if ( rp->symptr && rp->symptr->bind != STB_LOCAL )
1748 data_33 = data_2 << 6 >> 4;
1752 data_33 = ((relsect->info->shr.sh_addr + rp->rel.r_offset) & 0xF0000000) | (4 * (data_2 & 0x3FFFFFF));
1754 *(uint32_t *)daddr_1 &= 0xFC000000;
1755 *(uint32_t *)daddr_1 |= (16 * (symvalue + data_33)) >> 6;
1758 rp->type = R_MIPS_NONE;
1763 datah = *(uint32_t *)daddr_1 << 16;
1764 for ( j_1 = i_1 + 1; j_1 < entrise && rp[next].type == R_MIPS_HI16; j_1 += 1 )
1766 if ( rp->symptr && rp[next].symptr != rp->symptr )
1768 fprintf(stderr,
"R_MIPS_HI16 without R_MIPS_LO16\n");
1771 if ( relsect->info->shr.sh_size <= rp[next].rel.r_offset )
1775 "Panic !! relocation #%u offset=0x%x overflow (section size=0x%x)\n",
1777 rp[next].rel.r_offset,
1778 relsect->info->shr.sh_size);
1781 daddr_1 = (
void *)&relsect->info->data[rp[next].rel.r_offset];
1782 if ( datah != *(uint32_t *)daddr_1 << 16 )
1784 fprintf(stderr,
"R_MIPS_HI16s not same offsets\n");
1789 if ( j_1 == entrise + 1 || rp[next].type != R_MIPS_LO16 || (rp->symptr && rp[next].symptr != rp->symptr) )
1791 fprintf(stderr,
"R_MIPS_HI16 without R_MIPS_LO16\n");
1794 data32_1 = symvalue + (int16_t)*(uint32_t *)&relsect->info->data[rp[next].rel.r_offset] + datah;
1797 *(uint32_t *)daddr_1 &= 0xFFFF0000;
1798 *(uint32_t *)daddr_1 |= (uint16_t)(((data32_1 >> 15) + 1) >> 1);
1801 rp->type = R_MIPS_NONE;
1807 for ( j_2 = 0; j_2 < next; j_2 += 1 )
1809 daddr_2 = (
void *)&relsect->info->data[rp[j_2].rel.r_offset];
1810 *(uint32_t *)daddr_2 &= 0xFFFF0000;
1811 if ( j_2 < next - 1 )
1813 step = rp[j_2 + 1].rel.r_offset - rp[j_2].rel.r_offset;
1814 if ( step >> 18 && step >> 18 != 0x3FFF )
1816 fprintf(stderr,
"R_MIPS_HI16s too long distance\n");
1819 *(uint32_t *)daddr_2 |= (uint16_t)(step >> 2);
1821 rp[j_2].type = R_MIPS_NONE;
1822 if ( rp[j_2].symptr )
1824 rp[j_2].symptr->refcount -= 1;
1825 rp[j_2].symptr = *symp;
1828 rp->type = R_MIPSSCE_MHI16;
1829 rp->rel.r_offset += relsect->info->shr.sh_addr;
1830 rp[1].type = R_MIPSSCE_ADDEND;
1831 rp[1].rel.r_offset = data32_1;
1839 data32_2 = (uint16_t)(((data32_1 >> 15) + 1) >> 1);
1840 for ( j_3 = 0; j_3 < next; j_3 += 1 )
1842 daddr_3 = (
void *)&relsect->info->data[rp[j_3].rel.r_offset];
1843 *(uint32_t *)daddr_3 &= 0xFFFF0000;
1844 *(uint32_t *)daddr_3 |= data32_2;
1845 rp[j_3].type = R_MIPS_NONE;
1851 data_4 = symvalue + *(uint32_t *)daddr_1;
1852 *(uint32_t *)daddr_1 &= 0xFFFF0000;
1853 *(uint32_t *)daddr_1 |= data_4;
1856 rp->type = R_MIPS_NONE;
1860 case R_MIPS_GPREL16:
1861 data_5 = (int16_t)*(uint32_t *)daddr_1;
1864 if ( rp->symptr->type == STT_SECTION )
1866 data_5 += ((
Sect_org_data *)(rp->symptr->shptr->optdata))->org_gp_value + symvalue
1867 - ((
Sect_org_data *)(rp->symptr->shptr->optdata))->org_addr - gpvalue;
1869 else if ( rp->symptr->bind == STB_GLOBAL || (rp->symptr->bind == STB_WEAK && rp->symptr->sym.st_shndx) )
1871 data_5 += symvalue - gpvalue;
1873 else if ( rp->symptr->bind != STB_WEAK || rp->symptr->sym.st_shndx )
1875 fprintf(stderr,
"R_MIPS_GPREL16 unknown case abort\n");
1881 fprintf(stderr,
"R_MIPS_GPREL16 no symtab\n");
1884 if ( (uint16_t)(data_5 >> 16) && (uint16_t)(data_5 >> 16) != 0xFFFF )
1886 fprintf(stderr,
"R_MIPS_GPREL16 data overflow\n");
1889 *(uint32_t *)daddr_1 &= 0xFFFF0000;
1890 *(uint32_t *)daddr_1 |= (uint16_t)data_5;
1891 rp->type = R_MIPS_NONE;
1894 case R_MIPS_LITERAL:
1895 if ( !rp->symptr || rp->symptr->type != STT_SECTION )
1897 fprintf(stderr,
"R_MIPS_LITERAL unknown case abort\n");
1900 data_6 = ((
Sect_org_data *)(rp->symptr->shptr->optdata))->org_gp_value + symvalue
1901 - ((
Sect_org_data *)(rp->symptr->shptr->optdata))->org_addr - gpvalue + (int16_t)*(uint32_t *)daddr_1;
1902 if ( (uint16_t)(data_6 >> 16) && (uint16_t)(data_6 >> 16) != 0xFFFF )
1904 fprintf(stderr,
"R_MIPS_LITERAL data overflow\n");
1907 *(uint32_t *)daddr_1 &= 0xFFFF0000;
1908 *(uint32_t *)daddr_1 |= (uint16_t)data_6;
1909 rp->type = R_MIPS_NONE;
1912 case R_MIPS_DVP_27_S4:
1913 if ( target != SRX_TARGET_EE )
1915 fprintf(stderr,
"R_MIPS_DVP_27_S4 can use only for EE.\n");
1918 data_7 = symvalue + (*(uint32_t *)daddr_1 & 0x7FFFFFF0);
1919 *(uint32_t *)daddr_1 &= 0x8000000F;
1920 *(uint32_t *)daddr_1 |= data_7 & 0x7FFFFFF0;
1923 rp->type = R_MIPS_NONE;
1931 case R_MIPS_GPREL32:
1932 case R_MIPS_GOTHI16:
1933 case R_MIPS_GOTLO16:
1934 case R_MIPS_CALLHI16:
1935 case R_MIPS_CALLLO16:
1936 fprintf(stderr,
"unacceptable relocation type: 0x%x\n", rp->type);
1940 fprintf(stderr,
"unknown relocation type: 0x%x\n", rp->type);
1944 for ( ; next > 0; next -= 1 )
1946 rp->rel.r_offset += relsect->info->shr.sh_addr;
1949 rp->symptr->refcount -= 1;
1960 unsigned int newentrise;
1967 for ( i_2 = 0; i_2 < entrise; i_2 += 1 )
1971 memcpy(d, s,
sizeof(
elf_rel));
1977 free(relsect->data);
1978 relsect->data = (uint8_t *)newtab;
1979 relsect->shr.sh_size = relsect->shr.sh_entsize * newentrise;
1985 return strlen(modinfo->modulename) + (
sizeof(
Elf32_IopMod) - 1);
1988static size_t eemod_size(
const Elf32_EeMod *modinfo)
1990 return strlen(modinfo->modulename) + (
sizeof(
Elf32_EeMod) - 1);
1996 unsigned int entrise;
1999 entrise = relsect->shr.sh_size / relsect->shr.sh_entsize;
2000 rp = (
elf_rel *)relsect->data;
2001 for ( i = 0; i < entrise; i += 1 )
2006 case R_MIPSSCE_MHI16:
2007 case R_MIPSSCE_ADDEND:
2010 if ( i == entrise + 1 || rp[1].type != R_MIPS_LO16 || (rp->symptr && rp[1].symptr != rp->symptr) )
2038 const char ***scnfpp;
2048 switch ( tp->target )
2050 case SRX_TARGET_IOP:
2060 printf(
"===============\nTarget is %s(%d)\n", v1, tp->target);
2061 printf(
"Segment list\n");
2062 for ( v8 = 0, scnfp = tp->segment_list; scnfp->name; v8 += 1, scnfp += 1 )
2064 printf(
" %2d:segment %s\n", v8, scnfp->name);
2066 " addr,size=0x%x,0x%x bitid,nsect= 0x%x,%d\n ", scnfp->addr, scnfp->size, scnfp->bitid, scnfp->nsect);
2067 if ( scnfp->sect_name_patterns )
2069 for ( strp = scnfp->sect_name_patterns; *strp; strp += 1 )
2071 printf(
"%s ", *strp);
2075 if ( scnfp->empty_section )
2077 printf(
" Auto add section: %s\n", scnfp->empty_section->name);
2081 for ( scp = scnfp->scp; *scp; scp += 1 )
2083 printf(
" %p: %s\n", *scp, (*scp)->name);
2086 segsig[v8] = *scnfp->name;
2088 printf(
"\nProgram header order\n");
2089 for ( scp_ = 0, phip = tp->program_header_order; phip->sw; scp_ += 1, phip += 1 )
2093 case SRX_PH_TYPE_MOD:
2094 printf(
" %2d: section %s\n", scp_, phip->d.section_name);
2096 case SRX_PH_TYPE_TEXT:
2097 printf(
" %2d: Segments ", scp_);
2098 for ( scnfpp = (
const char ***)phip->d.section_name; *scnfpp; scnfpp += 1 )
2100 printf(
"%s ", **scnfpp);
2108 printf(
"\nRemove section list\n");
2109 for ( scp_a = 0, strp = tp->removesection_list; *strp; scp_a += 1, strp += 1 )
2111 printf(
" %2d: %s\n", scp_a, *strp);
2113 printf(
"\nSection table order\n");
2114 for ( nsegment = 0, strp = tp->section_table_order; *strp; nsegment += 1, strp += 1 )
2116 printf(
" %2d: %s\n", nsegment, *strp);
2118 printf(
"\nFile layout order\n");
2119 for ( b = 0, strp = tp->file_layout_order; *strp; b += 1, strp += 1 )
2121 printf(
" %2d: %s\n", b, *strp);
2123 printf(
"\nmemory layout order\n");
2124 for ( i = 0, sctp = tp->section_list; sctp->sect_name_pattern; i += 1, sctp += 1 )
2126 printf(
" %2d: [", i);
2127 for ( scnfp_ = 0; scnfp_ < v8; scnfp_ += 1 )
2129 printf(
"%c", ((sctp->flag & (1 << scnfp_)) != 0) ? (
unsigned char)(segsig[scnfp_]) : 46);
2131 printf(
"] %s", sctp->sect_name_pattern);
2132 if ( sctp->secttype )
2134 printf(
"\t: Auto create type=%x flag=%x", sctp->secttype, sctp->sectflag);
2138 printf(
"\nReserved symbols\n");
2139 for ( csyms = tp->create_symbols; csyms->name; csyms += 1 )
2142 " %-8s: bind=%d, type=%d, shindex=0x%04x, seflag=%d, seg=%s, sect=%s\n",
2148 csyms->segment ? csyms->segment->name :
"-",
2149 csyms->sectname ?:
"-");