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];
418 data_1 = startaddr + (int16_t)*(uint32_t *)datal;
419 if ( (uint16_t)(data_1 >> 16) )
421 if ( (uint16_t)(data_1 >> 16) != 0xFFFF )
423 fprintf(stderr,
"REFHALF data overflow\n");
427 *(uint32_t *)datal &= 0xFFFF0000;
428 *(uint32_t *)datal |= (uint16_t)data_1;
431 *(uint32_t *)datal += startaddr;
434 if ( rp->symptr && rp->symptr->bind != STB_LOCAL )
436 fprintf(stderr,
"R_MIPS_26 Unexcepted bind\n");
439 data_2 = startaddr + ((rp->rel.r_offset & 0xF0000000) | (4 * (*(uint32_t *)datal & 0x3FFFFFF)));
440 *(uint32_t *)datal &= 0xFC000000;
441 *(uint32_t *)datal |= (16 * data_2) >> 6;
444 if ( i == entrise + 1 || rp[1].type != R_MIPS_LO16 || (rp->symptr && rp[1].symptr != rp->symptr) )
446 fprintf(stderr,
"R_MIPS_HI16 without R_MIPS_LO16\n");
449 data_4 = startaddr + (int16_t)*(uint32_t *)&relsect->info->data[rp[1].rel.r_offset - relsect->info->shr.sh_addr]
450 + (*(uint32_t *)datal << 16);
451 *(uint32_t *)datal &= 0xFFFF0000;
452 *(uint32_t *)datal |= (uint16_t)(((data_4 >> 15) + 1) >> 1);
455 data_5 = startaddr + *(uint32_t *)datal;
456 *(uint32_t *)datal &= 0xFFFF0000;
457 *(uint32_t *)datal |= data_5;
460 fprintf(stderr,
"Unexcepted R_MIPS_GPREL16\n");
464 fprintf(stderr,
"Unexcepted R_MIPS_LITERAL\n");
467 case R_MIPSSCE_MHI16:
468 if ( i == entrise + 1 || rp[1].type != R_MIPSSCE_ADDEND )
470 fprintf(stderr,
"R_MIPSSCE_MHI16 without R_MIPSSCE_ADDEND\n");
473 data_3 = (uint16_t)((((startaddr + rp[1].rel.r_offset) >> 15) + 1) >> 1);
474 for ( daddr1 = 1; daddr1; datal += daddr1 )
476 daddr1 = *(uint16_t *)datal << 16 >> 14;
477 *(uint32_t *)datal &= 0xFFFF0000;
478 *(uint32_t *)datal |= data_3;
490 case R_MIPS_CALLHI16:
491 case R_MIPS_CALLLO16:
492 fprintf(stderr,
"unacceptable relocation type: 0x%x\n", rp->type);
496 fprintf(stderr,
"unknown relocation type: 0x%x\n", rp->type);
504void fixlocation_elf(
elf_file *elf,
unsigned int startaddr)
506 unsigned int entrise;
517 if ( elf->scp == NULL )
522 for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
524 if ( elf->scp[s]->shr.sh_type == SHT_REL )
526 fixlocation_an_rel(elf->scp[s], startaddr);
530 elf->scp[d] = elf->scp[s];
534 elf->ehp->e_shnum = d;
535 elf->ehp->e_entry += startaddr;
536 modsect_1 = search_section(elf, SHT_SCE_IOPMOD);
542 if ( iopmodinfo->moduleinfo != (Elf32_Word)(-1) )
544 iopmodinfo->moduleinfo += startaddr;
546 iopmodinfo->entry += startaddr;
547 iopmodinfo->gp_value += startaddr;
549 modsect_2 = search_section(elf, SHT_SCE_EEMOD);
555 if ( eemodinfo->moduleinfo != (Elf32_Word)(-1) )
557 eemodinfo->moduleinfo += startaddr;
559 eemodinfo->entry += startaddr;
560 eemodinfo->gp_value += startaddr;
562 for ( i = 0; i < elf->ehp->e_phnum; i += 1 )
564 if ( elf->php[i].phdr.p_type == PT_LOAD )
566 elf->php[i].phdr.p_vaddr = startaddr;
567 elf->php[i].phdr.p_paddr = startaddr;
571 for ( j = 1; j < elf->ehp->e_shnum; j += 1 )
573 switch ( elf->scp[j]->shr.sh_type )
577 elf->scp[j]->shr.sh_addr += startaddr;
583 scp = search_section(elf, SHT_SYMTAB);
588 entrise = scp->shr.sh_size / scp->shr.sh_entsize;
590 for ( k = 1; k < entrise; k += 1 )
592 if ( syp[k]->sym.st_shndx == SHN_RADDR || (syp[k]->sym.st_shndx && syp[k]->sym.st_shndx <= 0xFEFF) )
594 syp[k]->sym.st_value += startaddr;
596 if ( syp[k]->sym.st_shndx == SHN_RADDR )
598 syp[k]->sym.st_shndx = -15;
603static void save_org_addrs(
elf_file *elf)
610 reginfosec = search_section(elf, SHT_MIPS_REGINFO);
620 for ( i = 1; i < elf->ehp->e_shnum; i += 1 )
625 org->org_addr = elf->scp[i]->shr.sh_addr;
628 org->org_gp_value = reginfop->ri_gp_value;
630 elf->scp[i]->optdata = (
void *)org;
643 iopmodp->moduleinfo = -1;
644 modsect->name = strdup(
".iopmod");
645 modsect->data = (uint8_t *)iopmodp;
646 modsect->shr.sh_type = SHT_SCE_IOPMOD;
647 modsect->shr.sh_size = iopmod_size(iopmodp);
648 modsect->shr.sh_addralign = 4;
649 modsect->shr.sh_entsize = 0;
650 add_section(elf, modsect);
663 eemodp->moduleinfo = -1;
664 modsect->name = strdup(
".eemod");
665 modsect->data = (uint8_t *)eemodp;
666 modsect->shr.sh_type = SHT_SCE_EEMOD;
667 modsect->shr.sh_size = eemod_size(eemodp);
668 modsect->shr.sh_addralign = 4;
669 modsect->shr.sh_entsize = 0;
670 add_section(elf, modsect);
680 if ( eemod->shr.sh_type != SHT_SCE_EEMOD )
685 scp_1 = search_section_by_name(elf,
".erx.lib");
688 moddata->erx_lib_addr = scp_1->shr.sh_addr;
689 moddata->erx_lib_size = scp_1->shr.sh_size;
693 moddata->erx_lib_addr = -1;
694 moddata->erx_lib_size = 0;
696 scp_2 = search_section_by_name(elf,
".erx.stub");
699 moddata->erx_stub_addr = scp_2->shr.sh_addr;
700 moddata->erx_stub_size = scp_2->shr.sh_size;
704 moddata->erx_stub_addr = -1;
705 moddata->erx_stub_size = 0;
709static void add_reserved_symbol_table(
715 const char *sectname,
724 for ( newent_1 = tp->create_symbols; newent_1->name; newent_1 += 1 )
729 memset(&tp->create_symbols[entries], 0,
sizeof(tp->create_symbols[entries]));
730 newent_2 = &tp->create_symbols[entries - 1];
731 newent_2->name = strdup(name);
732 newent_2->bind = bind;
733 newent_2->type = type;
734 newent_2->segment = segment;
735 newent_2->sectname = strdup(sectname);
736 newent_2->shindex = shindex;
737 newent_2->seflag = base;
740const char *bos_str =
"_begin_of_section_";
741const char *eos_str =
"_end_of_section_";
742static void define_special_section_symbols(
elf_file *elf)
748 unsigned int entrise;
753 scp = search_section(elf, SHT_SYMTAB);
758 sectname = (
char *)__builtin_alloca(((elf->shstrptr->shr.sh_size + 22) >> 2) << 2);
759 entrise = scp->shr.sh_size / scp->shr.sh_entsize;
761 for ( i = 1; i < entrise; i += 1 )
764 if ( sym->bind == STB_GLOBAL && !sym->sym.st_shndx )
766 if ( !strncmp(bos_str, sym->name, strlen(bos_str)) )
768 strcpy(sectname,
".");
769 strcat(sectname, &sym->name[strlen(bos_str)]);
770 add_reserved_symbol_table(tp, sym->name, 2, 1, 0, sectname, 0, 0);
772 if ( !strncmp(eos_str, sym->name, strlen(eos_str)) )
774 strcpy(sectname,
".");
775 strcat(sectname, &sym->name[strlen(eos_str)]);
776 add_reserved_symbol_table(tp, sym->name, 2, 1, 0, sectname, 65311, 1);
782static void create_need_section(
elf_file *elf)
790 scp = search_section(elf, SHT_SYMTAB);
795 for ( i = 1; i < (scp->shr.sh_size / scp->shr.sh_entsize); i += 1 )
799 syment = *(
elf_syment **)&scp->data[i *
sizeof(
void *)];
800 if ( !syment->sym.st_shndx )
802 csym = is_reserve_symbol(tp, syment->name);
809 addscp_1 = csym->segment->empty_section;
812 if ( !search_section_by_name(elf, addscp_1->name) )
814 add_section(elf, addscp_1);
818 else if ( csym->sectname && !search_section_by_name(elf, csym->sectname) )
822 for ( odr = tp->section_list; odr->sect_name_pattern; odr += 1 )
824 if ( !sect_name_match(odr->sect_name_pattern, csym->sectname) && odr->secttype && odr->sectflag )
829 addscp_2->name = strdup(csym->sectname);
830 addscp_2->shr.sh_type = odr->secttype;
831 addscp_2->shr.sh_flags = odr->sectflag;
832 addscp_2->shr.sh_size = 0;
833 addscp_2->shr.sh_addralign = 4;
834 addscp_2->shr.sh_entsize = 0;
835 add_section(elf, addscp_2);
845static int sect_name_match(
const char *pattern,
const char *name)
847 for ( ; *pattern && *name && *pattern !=
'*'; pattern += 1, name += 1 )
849 if ( *name > *pattern )
853 if ( *name < *pattern )
858 if ( !*pattern && !*name )
862 if ( *pattern ==
'*' && !pattern[1] )
866 if ( *pattern !=
'*' )
868 return strcmp(pattern, name);
871 if ( strlen(name) < strlen(pattern) )
873 return strcmp(pattern, name);
875 return strcmp(pattern, &name[strlen(name) - strlen(pattern)]);
878static int reorder_section_table(
elf_file *elf)
880 const char **secorder;
886 sections = elf->ehp->e_shnum;
887 secorder = ((
Srx_gen_table *)elf->optdata)->section_table_order;
889 memcpy(scp, elf->scp, sections *
sizeof(
elf_section *));
892 for ( ; *secorder; secorder += 1 )
894 for ( s = 1; s < sections; s += 1 )
898 if ( !sect_name_match(*secorder, scp[s]->name) )
900 elf->scp[d] = scp[s];
912static void create_phdr(
elf_file *elf)
917 phip = ((
Srx_gen_table *)(elf->optdata))->program_header_order;
918 for ( i = 0; phip[i].sw; i += 1 )
923 if ( elf->php != NULL )
928 elf->ehp->e_phnum = i;
929 if ( elf->php != NULL )
933 for ( j = 0; phip[j].sw; j += 1 )
935 switch ( phip[j].sw )
937 case SRX_PH_TYPE_MOD:
938 elf->php[j].phdr.p_flags = PF_R;
939 elf->php[j].phdr.p_align = 4;
940 if ( !strcmp(
".iopmod", phip[j].d.section_name) )
942 elf->php[j].phdr.p_type = PT_SCE_IOPMOD;
945 *elf->php[j].scp = search_section(elf, SHT_SCE_IOPMOD);
947 else if ( !strcmp(
".eemod", phip[j].d.section_name) )
949 elf->php[j].phdr.p_type = PT_SCE_EEMOD;
952 *elf->php[j].scp = search_section(elf, SHT_SCE_EEMOD);
956 fprintf(stderr,
"Unsuport section '%s' for program header\n", phip[j].d.section_name);
959 case SRX_PH_TYPE_TEXT:
960 elf->php[j].phdr.p_type = PT_LOAD;
961 elf->php[j].phdr.p_flags = PF_X | PF_W | PF_R;
962 elf->php[j].phdr.p_align = 16;
971static void check_change_bit(
unsigned int oldbit,
unsigned int newbit,
unsigned int *up,
unsigned int *down)
973 *up = ~oldbit & newbit & (newbit ^ oldbit);
974 *down = ~newbit & oldbit & (newbit ^ oldbit);
977static void segment_start_setup(
SegConf *seglist,
unsigned int bitid,
const unsigned int *moffset)
979 for ( ; seglist->name; seglist += 1 )
981 if ( (seglist->bitid & bitid) != 0 )
983 seglist->addr = *moffset;
989static void add_section_to_segment(
SegConf *seglist,
elf_section *scp,
unsigned int bitid)
991 for ( ; seglist->name; seglist += 1 )
993 if ( (seglist->bitid & bitid) != 0 )
995 if ( !seglist->nsect )
997 seglist->addr = scp->shr.sh_addr;
1001 seglist->scp[seglist->nsect - 1] = scp;
1002 seglist->scp[seglist->nsect] = 0;
1007static void segment_end_setup(
SegConf *seglist,
unsigned int bitid,
unsigned int *moffset,
int ee)
1009 for ( ; seglist->name; seglist += 1 )
1011 if ( (seglist->bitid & bitid) != 0 )
1015 if ( !strcmp(seglist->name,
"TEXT") )
1020 seglist->size = *moffset - seglist->addr;
1025static void update_modinfo(
elf_file *elf)
1036 seginfo = lookup_segment(tp,
"TEXT", 1);
1037 seginfo_4 = lookup_segment(tp,
"DATA", 1);
1038 seginfo_8 = lookup_segment(tp,
"BSS", 1);
1039 seginfo_12 = lookup_segment(tp,
"GLOBALDATA", 1);
1040 if ( !seginfo || !seginfo_4 || !seginfo_8 || !seginfo_12 )
1042 fprintf(stderr,
"TEXT,DATA,BSS,GLOBALDATA segment missing abort");
1045 scp_1 = search_section(elf, SHT_SCE_IOPMOD);
1050 scp_1->shr.sh_addr = 0;
1052 imp->text_size = seginfo_4->addr - seginfo->addr;
1053 imp->data_size = seginfo_8->addr - seginfo_4->addr;
1054 imp->bss_size = seginfo_8->size;
1055 imp->gp_value = seginfo_12->addr + 0x7FF0;
1057 scp_2 = search_section(elf, SHT_SCE_EEMOD);
1062 scp_2->shr.sh_addr = 0;
1064 emp->text_size = seginfo_4->addr - seginfo->addr;
1065 emp->data_size = seginfo_8->addr - seginfo_4->addr;
1066 emp->bss_size = seginfo_8->size;
1067 emp->gp_value = seginfo_12->addr + 0x7FF0;
1071static void update_mdebug(
elf_file *elf)
1075 scp = search_section(elf, SHT_MIPS_DEBUG);
1078 scp->shr.sh_addr = 0;
1082static void update_programheader(
elf_file *elf)
1088 unsigned int minsegalign;
1098 phip = tp->program_header_order;
1099 switch ( tp->target )
1101 case SRX_TARGET_IOP:
1108 fprintf(stderr,
"Internal error: target unknown\n");
1112 for ( n = 0; phip[n].sw; n += 1 )
1114 if ( phip[n].sw == SRX_PH_TYPE_TEXT )
1116 segp = phip[n].d.segment_list;
1119 elf->php[n].phdr.p_vaddr = (*segp)->addr;
1120 align = minsegalign;
1121 for ( nsect_1 = 0, nseg_1 = 0; segp[nseg_1]; nsect_1 += segp[nseg_1]->nsect, nseg_1 += 1 )
1126 elf->php[n].scp = scp;
1127 for ( nsect_2 = 0, nseg_2 = 0; segp[nseg_2]; nsect_2 += segp[nseg_2]->nsect, nseg_2 += 1 )
1129 memcpy(&scp[nsect_2], segp[nseg_2]->scp, segp[nseg_2]->nsect *
sizeof(
elf_section *));
1131 for ( s = 0; s < nsect_2 && scp[s]->shr.sh_type == SHT_PROGBITS; s += 1 )
1133 if ( scp[s]->shr.sh_addralign > align )
1135 align = scp[s]->shr.sh_addralign;
1138 elf->php[n].phdr.p_filesz = scp[s - 1]->shr.sh_size + scp[s - 1]->shr.sh_addr - (*scp)->shr.sh_addr;
1139 elf->php[n].phdr.p_memsz = scp[nsect_2 - 1]->shr.sh_size + scp[nsect_2 - 1]->shr.sh_addr - (*scp)->shr.sh_addr;
1140 for ( ; s < nsect_2; s += 1 )
1142 if ( scp[s]->shr.sh_addralign > align )
1144 align = scp[s]->shr.sh_addralign;
1147 elf->php[n].phdr.p_align = align;
1153static void remove_unuse_section(
elf_file *elf)
1155 const char **sectnames;
1162 sections = elf->ehp->e_shnum;
1163 sectnames = ((
Srx_gen_table *)(elf->optdata))->removesection_list;
1165 memset(dscp, 0, sections *
sizeof(
elf_section *));
1167 for ( ; *sectnames; sectnames += 1 )
1169 for ( i = 1; i < sections; i += 1 )
1173 if ( !sect_name_match(*sectnames, elf->scp[i]->name) )
1175 dscp[d] = elf->scp[i];
1181 for ( j = 0; j < sections; j += 1 )
1185 remove_section_by_name(elf, dscp[j]->name);
1191static int layout_srx_memory(
elf_file *elf)
1202 unsigned int downdelta;
1203 unsigned int updelta;
1204 unsigned int oldbitid;
1205 unsigned int moffset;
1211 is_ee = tp->target == SRX_TARGET_EE;
1216 sections = elf->ehp->e_shnum;
1218 memcpy(scp, elf->scp, sections *
sizeof(
elf_section *));
1219 for ( odr = tp->section_list; odr->sect_name_pattern; odr += 1 )
1221 check_change_bit(oldbitid, odr->flag, &updelta, &downdelta);
1224 segment_start_setup(tp->segment_list, updelta, &moffset);
1226 for ( s_1 = 1; s_1 < sections; s_1 += 1 )
1229 scp[s_1] && !sect_name_match(odr->sect_name_pattern, scp[s_1]->name)
1230 && (scp[s_1]->shr.sh_flags & SHF_ALLOC) != 0 )
1232 moffset = adjust_align(moffset, scp[s_1]->shr.sh_addralign);
1233 scp[s_1]->shr.sh_addr = moffset;
1234 moffset += scp[s_1]->shr.sh_size;
1235 add_section_to_segment(tp->segment_list, scp[s_1], odr->flag);
1239 oldbitid = odr->flag;
1240 check_change_bit(oldbitid, odr[1].flag, &updelta, &downdelta);
1243 segment_end_setup(tp->segment_list, downdelta, &moffset, is_ee);
1246 for ( s_2 = 1; s_2 < sections; s_2 += 1 )
1248 if ( scp[s_2] && (scp[s_2]->shr.sh_flags & SHF_ALLOC) != 0 )
1253 && (!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);
1258 if ( sections > s_3 )
1262 "Error: section '%s' needs allocation and has relocation data but not in program segment\n",
1269 fprintf(stderr,
"Warning: section '%s' needs allocation but not in program segment\n", scp[s_2]->name);
1277 update_modinfo(elf);
1279 update_programheader(elf);
1292 for ( csyms = tp->create_symbols; csyms->name; csyms += 1 )
1294 if ( !strcmp(csyms->name, name) )
1302static int check_undef_symboles_an_reloc(
elf_section *relsect)
1307 unsigned int entrise;
1310 entrise = relsect->shr.sh_size / relsect->shr.sh_entsize;
1311 rp = (
elf_rel *)relsect->data;
1314 for ( i = 0; i < entrise; i += 1 )
1316 if ( rp->symptr && *symp != rp->symptr )
1318 if ( rp->symptr->sym.st_shndx )
1321 rp->symptr->sym.st_shndx > 0xFEFF && rp->symptr->sym.st_shndx != SHN_ABS
1322 && rp->symptr->sym.st_shndx != SHN_RADDR )
1324 if ( rp->symptr->sym.st_shndx == SHN_COMMON )
1326 fprintf(stderr,
" unallocated variable `%s'\n", rp->symptr->name);
1330 fprintf(stderr,
" `%s' unknown symbol type %x\n", rp->symptr->name, rp->symptr->sym.st_shndx);
1335 else if ( rp->symptr->bind != STB_WEAK )
1337 fprintf(stderr,
" undefined reference to `%s'\n", rp->symptr->name);
1346static int check_undef_symboles(
elf_file *elf)
1356 for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
1358 if ( elf->scp[s]->shr.sh_type == SHT_REL )
1360 err += check_undef_symboles_an_reloc(elf->scp[s]);
1368static const char *
const SymbolType[] =
1371 XEACH_SymbolType_enum()
1376static int create_reserved_symbols(
elf_file *elf)
1379 unsigned int sh_size;
1380 unsigned int sh_addr;
1387 if ( !search_section(elf, SHT_SYMTAB) )
1391 for ( csyms = tp->create_symbols; csyms->name; csyms += 1 )
1395 sym = search_global_symbol(csyms->name, elf);
1397 && (csyms->shindex > 0xFEFF
1398 || (csyms->segment && csyms->segment->scp)
1399 || (!csyms->segment && csyms->sectname && search_section_by_name(elf, csyms->sectname))) )
1401 sym = add_symbol(elf, csyms->name, csyms->bind, 0, 0, 0, 0);
1408 if ( csyms->segment )
1410 sh_addr = csyms->segment->addr;
1411 sh_size = csyms->segment->size;
1412 if ( csyms->shindex <= 0xFEFF )
1414 scp = *csyms->segment->scp;
1417 else if ( csyms->sectname != NULL )
1419 scp = search_section_by_name(elf, csyms->sectname);
1422 sh_addr = scp->shr.sh_addr;
1423 sh_size = scp->shr.sh_size;
1426 if ( csyms->segment || scp )
1430 if ( sym->sym.st_shndx )
1432 fprintf(stderr,
"Unexcepted Symbol \"%s\":%s \n", sym->name, SymbolType[sym->type]);
1438 sym->bind = csyms->bind;
1441 sym->type = csyms->type;
1443 sym->sym.st_info = ((csyms->bind & 0xFF) << 4) + (csyms->type & 0xF);
1444 if ( csyms->shindex > 0xFEFF )
1446 sym->sym.st_shndx = csyms->shindex;
1448 switch ( csyms->seflag )
1451 sym->sym.st_value = sh_addr;
1454 sym->sym.st_value = sh_size + sh_addr;
1457 sym->sym.st_value = sh_addr + 0x7FF0;
1465 sym->sym.st_shndx = 1;
1467 switch ( csyms->seflag )
1470 sym->sym.st_value = 0;
1473 sym->sym.st_value = sh_size;
1482 if ( csyms->bind == STB_WEAK && (sym->bind == STB_GLOBAL || sym->bind == STB_WEAK) && !sym->sym.st_shndx )
1486 sym->type = csyms->type;
1488 sym->bind = csyms->bind;
1489 sym->sym.st_info = ((csyms->bind & 0xFF) << 4) + (csyms->type & 0xF);
1496static void symbol_value_update(
elf_file *elf)
1498 unsigned int entrise;
1505 if ( elf->ehp->e_type != ET_REL )
1511 case SRX_TARGET_IOP:
1512 elf->ehp->e_type = ET_SCE_IOPRELEXEC;
1515 elf->ehp->e_type = ET_SCE_EERELEXEC2;
1520 scp = search_section(elf, SHT_SYMTAB);
1525 entrise = scp->shr.sh_size / scp->shr.sh_entsize;
1527 for ( i = 1; i < entrise; i += 1 )
1529 if ( syp[i]->sym.st_shndx )
1531 if ( syp[i]->sym.st_shndx <= 0xFEFF )
1533 syp[i]->sym.st_value += syp[i]->shptr->shr.sh_addr;
1539static void rebuild_relocation(
elf_file *elf,
unsigned int gpvalue)
1543 if ( elf->scp == NULL )
1547 for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
1549 if ( elf->scp[s]->shr.sh_type == SHT_REL )
1551 rebuild_an_relocation(elf->scp[s], gpvalue, ((
Srx_gen_table *)(elf->optdata))->target);
1556static int check_irx12(
elf_file *elf,
int cause_irx1)
1560 if ( elf->ehp->e_type != ET_SCE_IOPRELEXEC )
1564 for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
1566 if ( elf->scp[s]->shr.sh_type == SHT_REL && relocation_is_version2(elf->scp[s]) )
1570 fprintf(stderr,
"R_MIPS_LO16 without R_MIPS_HI16\n");
1573 elf->ehp->e_type = ET_SCE_IOPRELEXEC2;
1579static void setup_module_info(
elf_file *elf,
elf_section *modsect,
const char *modulesymbol)
1581 unsigned int *section_data;
1587 const unsigned int *modnamep;
1588 unsigned int *modidatap;
1589 unsigned int modiaddr;
1592 syp = search_global_symbol(modulesymbol, elf);
1593 if ( is_defined_symbol(syp) == 0 )
1597 modiaddr = get_symbol_value(syp, elf);
1598 modidatap = get_section_data(elf, modiaddr);
1599 section_data = get_section_data(elf, *modidatap);
1600 woff = (uintptr_t)section_data & 3;
1601 modnamep = (
unsigned int *)((
char *)section_data - woff);
1602 buflen = (strlen((
const char *)section_data - woff + 4) + 15) & 0xFFFFFFFC;
1603 buf = (
char *)malloc(buflen);
1604 memcpy(buf, modnamep, buflen);
1605 swapmemory(buf,
"l", buflen >> 2);
1607 switch ( modsect->shr.sh_type )
1609 case SHT_SCE_IOPMOD:
1615 iopmodp_1->moduleinfo = modiaddr;
1616 iopmodp_1->moduleversion = *((uint16_t *)modidatap + 2);
1620 strcpy(iopmodp_2->modulename, name);
1621 modsect->data = (uint8_t *)iopmodp_2;
1622 modsect->shr.sh_size = iopmod_size(iopmodp_2);
1630 eemodp_1->moduleinfo = modiaddr;
1631 eemodp_1->moduleversion = *((uint16_t *)modidatap + 2);
1633 strcpy(eemodp_2->modulename, name);
1634 modsect->data = (uint8_t *)eemodp_2;
1635 modsect->shr.sh_size = eemod_size(eemodp_2);
1642 if ( elf->php == NULL )
1646 for ( i = 0; i < elf->ehp->e_phnum; i += 1 )
1648 if ( elf->php[i].scp && (modsect == *elf->php[i].scp) )
1650 elf->php[i].phdr.p_filesz = modsect->shr.sh_size;
1655static void rebuild_an_relocation(
elf_section *relsect,
unsigned int gpvalue,
int target)
1667 unsigned int data_5;
1668 unsigned int data_6;
1674 unsigned int entrise;
1680 entrise = relsect->shr.sh_size / relsect->shr.sh_entsize;
1681 rp = (
elf_rel *)relsect->data;
1684 for ( i_1 = 0; i_1 < entrise; )
1691 if ( relsect->info->shr.sh_size <= rp->rel.r_offset )
1695 "Panic !! relocation #%u offset=0x%x overflow (section size=0x%x)\n",
1698 relsect->info->shr.sh_size);
1702 daddr_1 = (
void *)&relsect->info->data[rp->rel.r_offset];
1706 if ( rp->symptr->sym.st_shndx )
1708 symvalue = rp->symptr->sym.st_value;
1713 !rp->symptr || (rp->symptr->sym.st_shndx && rp->symptr->sym.st_shndx <= 0xFEFF)
1714 || rp->symptr->sym.st_shndx == SHN_RADDR )
1724 data_1 = symvalue + (int16_t)*(uint32_t *)daddr_1;
1725 if ( (uint16_t)(data_1 >> 16) && (uint16_t)(data_1 >> 16) != 0xFFFF )
1727 fprintf(stderr,
"REFHALF data overflow\n");
1730 *(uint32_t *)daddr_1 &= 0xFFFF0000;
1731 *(uint32_t *)daddr_1 |= (uint16_t)data_1;
1734 rp->type = R_MIPS_NONE;
1739 *(uint32_t *)daddr_1 += symvalue;
1742 rp->type = R_MIPS_NONE;
1747 data_2 = *(uint32_t *)daddr_1;
1748 if ( rp->symptr && rp->symptr->bind != STB_LOCAL )
1750 data_33 = data_2 << 6 >> 4;
1754 data_33 = ((relsect->info->shr.sh_addr + rp->rel.r_offset) & 0xF0000000) | (4 * (data_2 & 0x3FFFFFF));
1756 *(uint32_t *)daddr_1 &= 0xFC000000;
1757 *(uint32_t *)daddr_1 |= (16 * (symvalue + data_33)) >> 6;
1760 rp->type = R_MIPS_NONE;
1765 datah = *(uint32_t *)daddr_1 << 16;
1766 for ( j_1 = i_1 + 1; j_1 < entrise && rp[next].type == R_MIPS_HI16; j_1 += 1 )
1768 if ( rp->symptr && rp[next].symptr != rp->symptr )
1770 fprintf(stderr,
"R_MIPS_HI16 without R_MIPS_LO16\n");
1773 if ( relsect->info->shr.sh_size <= rp[next].rel.r_offset )
1777 "Panic !! relocation #%u offset=0x%x overflow (section size=0x%x)\n",
1779 rp[next].rel.r_offset,
1780 relsect->info->shr.sh_size);
1783 daddr_1 = (
void *)&relsect->info->data[rp[next].rel.r_offset];
1784 if ( datah != *(uint32_t *)daddr_1 << 16 )
1786 fprintf(stderr,
"R_MIPS_HI16s not same offsets\n");
1791 if ( j_1 == entrise + 1 || rp[next].type != R_MIPS_LO16 || (rp->symptr && rp[next].symptr != rp->symptr) )
1793 fprintf(stderr,
"R_MIPS_HI16 without R_MIPS_LO16\n");
1796 data32_1 = symvalue + (int16_t)*(uint32_t *)&relsect->info->data[rp[next].rel.r_offset] + datah;
1799 *(uint32_t *)daddr_1 &= 0xFFFF0000;
1800 *(uint32_t *)daddr_1 |= (uint16_t)(((data32_1 >> 15) + 1) >> 1);
1803 rp->type = R_MIPS_NONE;
1809 for ( j_2 = 0; j_2 < next; j_2 += 1 )
1811 daddr_2 = (
void *)&relsect->info->data[rp[j_2].rel.r_offset];
1812 *(uint32_t *)daddr_2 &= 0xFFFF0000;
1813 if ( j_2 < next - 1 )
1815 step = rp[j_2 + 1].rel.r_offset - rp[j_2].rel.r_offset;
1816 if ( step >> 18 && step >> 18 != 0x3FFF )
1818 fprintf(stderr,
"R_MIPS_HI16s too long distance\n");
1821 *(uint32_t *)daddr_2 |= (uint16_t)(step >> 2);
1823 rp[j_2].type = R_MIPS_NONE;
1824 if ( rp[j_2].symptr )
1826 rp[j_2].symptr->refcount -= 1;
1827 rp[j_2].symptr = *symp;
1830 rp->type = R_MIPSSCE_MHI16;
1831 rp->rel.r_offset += relsect->info->shr.sh_addr;
1832 rp[1].type = R_MIPSSCE_ADDEND;
1833 rp[1].rel.r_offset = data32_1;
1841 data32_2 = (uint16_t)(((data32_1 >> 15) + 1) >> 1);
1842 for ( j_3 = 0; j_3 < next; j_3 += 1 )
1844 daddr_3 = (
void *)&relsect->info->data[rp[j_3].rel.r_offset];
1845 *(uint32_t *)daddr_3 &= 0xFFFF0000;
1846 *(uint32_t *)daddr_3 |= data32_2;
1847 rp[j_3].type = R_MIPS_NONE;
1853 data_4 = symvalue + *(uint32_t *)daddr_1;
1854 *(uint32_t *)daddr_1 &= 0xFFFF0000;
1855 *(uint32_t *)daddr_1 |= data_4;
1858 rp->type = R_MIPS_NONE;
1862 case R_MIPS_GPREL16:
1863 data_5 = (int16_t)*(uint32_t *)daddr_1;
1866 if ( rp->symptr->type == STT_SECTION )
1868 data_5 += ((
Sect_org_data *)(rp->symptr->shptr->optdata))->org_gp_value + symvalue
1869 - ((
Sect_org_data *)(rp->symptr->shptr->optdata))->org_addr - gpvalue;
1871 else if ( rp->symptr->bind == STB_GLOBAL || (rp->symptr->bind == STB_WEAK && rp->symptr->sym.st_shndx) )
1873 data_5 += symvalue - gpvalue;
1875 else if ( rp->symptr->bind != STB_WEAK || rp->symptr->sym.st_shndx )
1877 fprintf(stderr,
"R_MIPS_GPREL16 unknown case abort\n");
1883 fprintf(stderr,
"R_MIPS_GPREL16 no symtab\n");
1886 if ( (uint16_t)(data_5 >> 16) && (uint16_t)(data_5 >> 16) != 0xFFFF )
1888 fprintf(stderr,
"R_MIPS_GPREL16 data overflow\n");
1891 *(uint32_t *)daddr_1 &= 0xFFFF0000;
1892 *(uint32_t *)daddr_1 |= (uint16_t)data_5;
1893 rp->type = R_MIPS_NONE;
1896 case R_MIPS_LITERAL:
1897 if ( !rp->symptr || rp->symptr->type != STT_SECTION )
1899 fprintf(stderr,
"R_MIPS_LITERAL unknown case abort\n");
1902 data_6 = ((
Sect_org_data *)(rp->symptr->shptr->optdata))->org_gp_value + symvalue
1903 - ((
Sect_org_data *)(rp->symptr->shptr->optdata))->org_addr - gpvalue + (int16_t)*(uint32_t *)daddr_1;
1904 if ( (uint16_t)(data_6 >> 16) && (uint16_t)(data_6 >> 16) != 0xFFFF )
1906 fprintf(stderr,
"R_MIPS_LITERAL data overflow\n");
1909 *(uint32_t *)daddr_1 &= 0xFFFF0000;
1910 *(uint32_t *)daddr_1 |= (uint16_t)data_6;
1911 rp->type = R_MIPS_NONE;
1914 case R_MIPS_DVP_27_S4:
1915 if ( target != SRX_TARGET_EE )
1917 fprintf(stderr,
"R_MIPS_DVP_27_S4 can use only for EE.\n");
1920 data_7 = symvalue + (*(uint32_t *)daddr_1 & 0x7FFFFFF0);
1921 *(uint32_t *)daddr_1 &= 0x8000000F;
1922 *(uint32_t *)daddr_1 |= data_7 & 0x7FFFFFF0;
1925 rp->type = R_MIPS_NONE;
1933 case R_MIPS_GPREL32:
1934 case R_MIPS_GOTHI16:
1935 case R_MIPS_GOTLO16:
1936 case R_MIPS_CALLHI16:
1937 case R_MIPS_CALLLO16:
1938 fprintf(stderr,
"unacceptable relocation type: 0x%x\n", rp->type);
1942 fprintf(stderr,
"unknown relocation type: 0x%x\n", rp->type);
1946 for ( ; next > 0; next -= 1 )
1948 rp->rel.r_offset += relsect->info->shr.sh_addr;
1951 rp->symptr->refcount -= 1;
1962 unsigned int newentrise;
1969 for ( i_2 = 0; i_2 < entrise; i_2 += 1 )
1973 memcpy(d, s,
sizeof(
elf_rel));
1979 free(relsect->data);
1980 relsect->data = (uint8_t *)newtab;
1981 relsect->shr.sh_size = relsect->shr.sh_entsize * newentrise;
1987 return strlen(modinfo->modulename) + (
sizeof(
Elf32_IopMod) - 1);
1990static size_t eemod_size(
const Elf32_EeMod *modinfo)
1992 return strlen(modinfo->modulename) + (
sizeof(
Elf32_EeMod) - 1);
1998 unsigned int entrise;
2001 entrise = relsect->shr.sh_size / relsect->shr.sh_entsize;
2002 rp = (
elf_rel *)relsect->data;
2003 for ( i = 0; i < entrise; i += 1 )
2008 case R_MIPSSCE_MHI16:
2009 case R_MIPSSCE_ADDEND:
2012 if ( i == entrise + 1 || rp[1].type != R_MIPS_LO16 || (rp->symptr && rp[1].symptr != rp->symptr) )
2040 const char ***scnfpp;
2050 switch ( tp->target )
2052 case SRX_TARGET_IOP:
2062 printf(
"===============\nTarget is %s(%d)\n", v1, tp->target);
2063 printf(
"Segment list\n");
2064 for ( v8 = 0, scnfp = tp->segment_list; scnfp->name; v8 += 1, scnfp += 1 )
2066 printf(
" %2d:segment %s\n", v8, scnfp->name);
2068 " addr,size=0x%x,0x%x bitid,nsect= 0x%x,%d\n ", scnfp->addr, scnfp->size, scnfp->bitid, scnfp->nsect);
2069 if ( scnfp->sect_name_patterns )
2071 for ( strp = scnfp->sect_name_patterns; *strp; strp += 1 )
2073 printf(
"%s ", *strp);
2077 if ( scnfp->empty_section )
2079 printf(
" Auto add section: %s\n", scnfp->empty_section->name);
2083 for ( scp = scnfp->scp; *scp; scp += 1 )
2085 printf(
" %p: %s\n", *scp, (*scp)->name);
2088 segsig[v8] = *scnfp->name;
2090 printf(
"\nProgram header order\n");
2091 for ( scp_ = 0, phip = tp->program_header_order; phip->sw; scp_ += 1, phip += 1 )
2095 case SRX_PH_TYPE_MOD:
2096 printf(
" %2d: section %s\n", scp_, phip->d.section_name);
2098 case SRX_PH_TYPE_TEXT:
2099 printf(
" %2d: Segments ", scp_);
2100 for ( scnfpp = (
const char ***)phip->d.section_name; *scnfpp; scnfpp += 1 )
2102 printf(
"%s ", **scnfpp);
2110 printf(
"\nRemove section list\n");
2111 for ( scp_a = 0, strp = tp->removesection_list; *strp; scp_a += 1, strp += 1 )
2113 printf(
" %2d: %s\n", scp_a, *strp);
2115 printf(
"\nSection table order\n");
2116 for ( nsegment = 0, strp = tp->section_table_order; *strp; nsegment += 1, strp += 1 )
2118 printf(
" %2d: %s\n", nsegment, *strp);
2120 printf(
"\nFile layout order\n");
2121 for ( b = 0, strp = tp->file_layout_order; *strp; b += 1, strp += 1 )
2123 printf(
" %2d: %s\n", b, *strp);
2125 printf(
"\nmemory layout order\n");
2126 for ( i = 0, sctp = tp->section_list; sctp->sect_name_pattern; i += 1, sctp += 1 )
2128 printf(
" %2d: [", i);
2129 for ( scnfp_ = 0; scnfp_ < v8; scnfp_ += 1 )
2131 printf(
"%c", ((sctp->flag & (1 << scnfp_)) != 0) ? (
unsigned char)(segsig[scnfp_]) : 46);
2133 printf(
"] %s", sctp->sect_name_pattern);
2134 if ( sctp->secttype )
2136 printf(
"\t: Auto create type=%x flag=%x", sctp->secttype, sctp->sectflag);
2140 printf(
"\nReserved symbols\n");
2141 for ( csyms = tp->create_symbols; csyms->name; csyms += 1 )
2144 " %-8s: bind=%d, type=%d, shindex=0x%04x, seflag=%d, seg=%s, sect=%s\n",
2150 csyms->segment ? csyms->segment->name :
"-",
2151 csyms->sectname ?:
"-");