PS2SDK
PS2 Homebrew Libraries
srxgen.c
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright ps2dev - http://www.ps2dev.org
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
9 */
10 
11 #include "srxfixup_internal.h"
12 #include <stdint.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 
17 typedef struct sect_org_data_
18 {
19  unsigned int org_addr;
20  unsigned int org_gp_value;
22 
23 static int setup_start_entry(elf_file *elf, const char *entrysym, elf_section *modinfo, int needoutput);
24 static Elf_file_slot *search_order_slots(const char *ordstr, const elf_file *elf, Elf_file_slot *order);
25 static void fixlocation_an_rel(elf_section *relsect, unsigned int startaddr);
26 static void save_org_addrs(elf_file *elf);
27 static elf_section *add_iopmod(elf_file *elf);
28 static elf_section *add_eemod(elf_file *elf);
29 static void modify_eemod(elf_file *elf, elf_section *eemod);
30 static void add_reserved_symbol_table(
31  Srx_gen_table *tp,
32  const char *name,
33  int bind,
34  int type,
35  SegConf *segment,
36  const char *sectname,
37  int shindex,
38  int base);
39 static void define_special_section_symbols(elf_file *elf);
40 static void create_need_section(elf_file *elf);
41 static int sect_name_match(const char *pattern, const char *name);
42 static int reorder_section_table(elf_file *elf);
43 static void create_phdr(elf_file *elf);
44 static void check_change_bit(unsigned int oldbit, unsigned int newbit, unsigned int *up, unsigned int *down);
45 static void segment_start_setup(SegConf *seglist, unsigned int bitid, const unsigned int *moffset);
46 static void add_section_to_segment(SegConf *seglist, elf_section *scp, unsigned int bitid);
47 static void segment_end_setup(SegConf *seglist, unsigned int bitid, unsigned int *moffset, int ee);
48 static void update_modinfo(elf_file *elf);
49 static void update_mdebug(elf_file *elf);
50 static void update_programheader(elf_file *elf);
51 static void remove_unuse_section(elf_file *elf);
52 static int layout_srx_memory(elf_file *elf);
53 static CreateSymbolConf *is_reserve_symbol(Srx_gen_table *tp, const char *name);
54 static int check_undef_symboles_an_reloc(elf_section *relsect);
55 static int check_undef_symboles(elf_file *elf);
56 static int create_reserved_symbols(elf_file *elf);
57 static void symbol_value_update(elf_file *elf);
58 static void rebuild_relocation(elf_file *elf, unsigned int gpvalue);
59 static int check_irx12(elf_file *elf, int cause_irx1);
60 static void setup_module_info(elf_file *elf, elf_section *modsect, const char *modulesymbol);
61 static void rebuild_an_relocation(elf_section *relsect, unsigned int gpvalue, int target);
62 static size_t iopmod_size(const Elf32_IopMod *modinfo);
63 static size_t eemod_size(const Elf32_EeMod *modinfo);
64 
65 int convert_rel2srx(elf_file *elf, const char *entrysym, int needoutput, int cause_irx1)
66 {
67  Srx_gen_table *tp;
68  elf_section *modinfo;
69 
70  tp = (Srx_gen_table *)elf->optdata;
71  save_org_addrs(elf);
72  switch ( tp->target )
73  {
74  case SRX_TARGET_IOP:
75  modinfo = add_iopmod(elf);
76  break;
77  case SRX_TARGET_EE:
78  modinfo = add_eemod(elf);
79  break;
80  default:
81  fprintf(stderr, "Internal error: target unknown\n");
82  exit(1);
83  }
84  remove_unuse_section(elf);
85  define_special_section_symbols(elf);
86  create_need_section(elf);
87  reorder_section_table(elf);
88  create_phdr(elf);
89  if ( layout_srx_memory(elf) )
90  {
91  return 1;
92  }
93  modify_eemod(elf, modinfo);
94  if ( create_reserved_symbols(elf) )
95  {
96  return 1;
97  }
98  if ( check_undef_symboles(elf) )
99  {
100  return 1;
101  }
102  symbol_value_update(elf);
103  rebuild_relocation(elf, lookup_segment(tp, "GLOBALDATA", 1)->addr + 0x7FF0);
104  if ( check_irx12(elf, cause_irx1) )
105  {
106  return 1;
107  }
108  if ( setup_start_entry(elf, entrysym, modinfo, needoutput) )
109  {
110  return 1;
111  }
112  {
113  const char *module_info_symbol;
114  const elf_syment *syp;
115 
116  module_info_symbol = "Module";
117  syp = search_global_symbol("_irx_id", elf);
118  if ( is_defined_symbol(syp) != 0 )
119  {
120  module_info_symbol = "_irx_id";
121  }
122  setup_module_info(elf, modinfo, module_info_symbol);
123  }
124  return layout_srx_file(elf);
125 }
126 
127 static int setup_start_entry(elf_file *elf, const char *entrysym, elf_section *modinfo, int needoutput)
128 {
129  const elf_syment *syp;
130 
131  if ( entrysym )
132  {
133  syp = search_global_symbol(entrysym, elf);
134  if ( !is_defined_symbol(syp) )
135  {
136  fprintf(stderr, "Error: Cannot find entry symbol %s\n", entrysym);
137  return 1;
138  }
139  elf->ehp->e_entry = get_symbol_value(syp, elf);
140  }
141  else
142  {
143  syp = search_global_symbol("start", elf);
144  if ( !syp )
145  {
146  syp = search_global_symbol("_start", elf);
147  }
148  if ( !is_defined_symbol(syp) )
149  {
150  if ( modinfo->shr.sh_type == SHT_SCE_EEMOD )
151  {
152  elf->ehp->e_entry = -1;
153  }
154  else if ( needoutput )
155  {
156  fprintf(stderr, "warning: Cannot find entry symbol `start' and `_start'\n");
157  }
158  }
159  else
160  {
161  elf->ehp->e_entry = get_symbol_value(syp, elf);
162  }
163  }
164  switch ( modinfo->shr.sh_type )
165  {
166  case SHT_SCE_IOPMOD:
167  case SHT_SCE_EEMOD:
168  *((uint32_t *)modinfo->data + 1) = elf->ehp->e_entry;
169  break;
170  default:
171  break;
172  }
173  return 0;
174 }
175 
176 static Elf_file_slot *search_order_slots(const char *ordstr, const elf_file *elf, Elf_file_slot *order)
177 {
178  elf_section **scp;
179 
180  if ( !strcmp(ordstr, "@Section_header_table") )
181  {
182  for ( ; order->type != EFS_TYPE_END; order += 1 )
183  {
184  if ( order->type == EFS_TYPE_SECTION_HEADER_TABLE )
185  {
186  return order;
187  }
188  }
189  return 0;
190  }
191  if ( !strncmp(ordstr, "@Program_header_data ", 0x15) )
192  {
193  long n;
194 
195  n = strtol(ordstr + 21, NULL, 10);
196  for ( ; order->type != EFS_TYPE_END; order += 1 )
197  {
198  if ( order->type == EFS_TYPE_PROGRAM_HEADER_ENTRY && order->d.php == &elf->php[n] )
199  {
200  return order;
201  }
202  }
203  return 0;
204  }
205  for ( ; order->type != EFS_TYPE_END; order += 1 )
206  {
207  switch ( order->type )
208  {
209  case EFS_TYPE_PROGRAM_HEADER_ENTRY:
210  for ( scp = order->d.php->scp; *scp; scp += 1 )
211  {
212  if ( !sect_name_match(ordstr, (*scp)->name) )
213  {
214  return order;
215  }
216  }
217  break;
218  case EFS_TYPE_SECTION_DATA:
219  if ( !sect_name_match(ordstr, order->d.scp->name) )
220  {
221  return order;
222  }
223  break;
224  default:
225  break;
226  }
227  }
228  return 0;
229 }
230 
231 int layout_srx_file(elf_file *elf)
232 {
233  elf_section **scp;
234  const Srx_gen_table *tp;
235  Elf_file_slot *slotp_1;
236  Elf_file_slot *slotp_2;
237  Elf_file_slot *nslotp;
238  Elf_file_slot *neworder;
239  Elf_file_slot *order;
240  const char **ordstr;
241  unsigned int max_seg_align;
242  int error;
243  int maxslot;
244 
245  tp = (Srx_gen_table *)elf->optdata;
246  error = 0;
247  switch ( tp->target )
248  {
249  case SRX_TARGET_IOP:
250  max_seg_align = 16;
251  break;
252  case SRX_TARGET_EE:
253  max_seg_align = 0x10000;
254  break;
255  default:
256  fprintf(stderr, "Internal error: target unknown\n");
257  return 1;
258  }
259  reorder_symtab(elf);
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 )
264  {
265  ;
266  }
267  neworder = (Elf_file_slot *)calloc(maxslot + 1, sizeof(Elf_file_slot));
268  memcpy(neworder, order, sizeof(Elf_file_slot));
269  nslotp = neworder + 1;
270  order->type = EFS_TYPE_NONE;
271  if ( elf->ehp->e_phnum )
272  {
273  memcpy(nslotp, &order[1], sizeof(Elf_file_slot));
274  nslotp = neworder + 2;
275  order[1].type = EFS_TYPE_NONE;
276  }
277  for ( ordstr = tp->file_layout_order; *ordstr; ordstr += 1 )
278  {
279  for ( ;; )
280  {
281  slotp_1 = search_order_slots(*ordstr, elf, order);
282  if ( !slotp_1 )
283  {
284  break;
285  }
286  memcpy(nslotp, slotp_1, sizeof(Elf_file_slot));
287  nslotp += 1;
288  slotp_1->type = EFS_TYPE_NONE;
289  }
290  }
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 )
295  {
296  if (
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 )
299  {
300  fprintf(stderr, "Program Header Entry: unsupported align %u\n", slotp_2->align);
301  error += 1;
302  for ( scp = slotp_2->d.php->scp; *scp; scp += 1 )
303  {
304  if ( max_seg_align < (*scp)->shr.sh_addralign )
305  {
306  fprintf(
307  stderr, "Section '%s' : unsupported section align %d\n", (*scp)->name, (int)((*scp)->shr.sh_addralign));
308  error += 1;
309  }
310  }
311  }
312  }
313 
314  if (error && tp->target == SRX_TARGET_IOP)
315  {
316  fprintf(stderr, "LOADCORE limits possible alignment to 16 bytes\n");
317  }
318 
319  free(order);
320  free(neworder);
321  return error;
322 }
323 
324 void strip_elf(elf_file *elf)
325 {
326  elf_syment **syp;
327  elf_section *scp;
328  unsigned int entrise;
329  unsigned int d;
330  unsigned int s;
331 
332  remove_section(elf, SHT_MIPS_DEBUG);
333  scp = search_section(elf, SHT_SYMTAB);
334  if ( scp == NULL )
335  {
336  return;
337  }
338  entrise = scp->shr.sh_size / scp->shr.sh_entsize;
339  syp = (elf_syment **)scp->data;
340  d = 1;
341  for ( s = 1; s < entrise; s += 1 )
342  {
343  if ( syp[s]->refcount <= 0 )
344  {
345  syp[s]->number = -1;
346  }
347  else
348  {
349  syp[d] = syp[s];
350  d += 1;
351  }
352  }
353  scp->shr.sh_size = d * scp->shr.sh_entsize;
354 }
355 
356 SegConf *lookup_segment(Srx_gen_table *conf, const char *segname, int msgsw)
357 {
358  SegConf *i;
359 
360  for ( i = conf->segment_list; i->name; i += 1 )
361  {
362  if ( !strcmp(segname, i->name) )
363  {
364  return i;
365  }
366  }
367  if ( msgsw )
368  {
369  fprintf(stderr, "segment '%s' not found \n", segname);
370  }
371  return 0;
372 }
373 
374 static void fixlocation_an_rel(elf_section *relsect, unsigned int startaddr)
375 {
376  int daddr1;
377  unsigned int data_1;
378  uint32_t data_2;
379  int data_3;
380  unsigned int data_4;
381  uint16_t data_5;
382  elf_syment **symp;
383  elf_rel *rp;
384  unsigned int entrise;
385  unsigned int i;
386 
387  entrise = relsect->shr.sh_size / relsect->shr.sh_entsize;
388  rp = (elf_rel *)relsect->data;
389  symp = (elf_syment **)relsect->link->data;
390  for ( i = 0; i < entrise; i += 1 )
391  {
392  uint8_t *datal;
393 
394  if ( rp->symptr && *symp != rp->symptr )
395  {
396  fprintf(stderr, "Internal error: Illegal relocation entry\n");
397  exit(1);
398  }
399  if (
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 )
402  {
403  fprintf(
404  stderr,
405  "Panic !! relocation #%u offset=0x%x range out (section limit addr=0x%x-0x%x)\n",
406  i,
407  rp->rel.r_offset,
408  relsect->info->shr.sh_addr,
409  relsect->info->shr.sh_size + relsect->info->shr.sh_addr);
410  exit(1);
411  }
412  datal = &relsect->info->data[rp->rel.r_offset - relsect->info->shr.sh_addr];
413  switch ( rp->type )
414  {
415  case R_MIPS_NONE:
416  break;
417  case R_MIPS_16:
418  data_1 = startaddr + (int16_t)*(uint32_t *)datal;
419  if ( (uint16_t)(data_1 >> 16) )
420  {
421  if ( (uint16_t)(data_1 >> 16) != 0xFFFF )
422  {
423  fprintf(stderr, "REFHALF data overflow\n");
424  exit(1);
425  }
426  }
427  *(uint32_t *)datal &= 0xFFFF0000;
428  *(uint32_t *)datal |= (uint16_t)data_1;
429  break;
430  case R_MIPS_32:
431  *(uint32_t *)datal += startaddr;
432  break;
433  case R_MIPS_26:
434  if ( rp->symptr && rp->symptr->bind != STB_LOCAL )
435  {
436  fprintf(stderr, "R_MIPS_26 Unexcepted bind\n");
437  exit(1);
438  }
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;
442  break;
443  case R_MIPS_HI16:
444  if ( i == entrise + 1 || rp[1].type != R_MIPS_LO16 || (rp->symptr && rp[1].symptr != rp->symptr) )
445  {
446  fprintf(stderr, "R_MIPS_HI16 without R_MIPS_LO16\n");
447  exit(1);
448  }
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);
453  break;
454  case R_MIPS_LO16:
455  data_5 = startaddr + *(uint32_t *)datal;
456  *(uint32_t *)datal &= 0xFFFF0000;
457  *(uint32_t *)datal |= data_5;
458  break;
459  case R_MIPS_GPREL16:
460  fprintf(stderr, "Unexcepted R_MIPS_GPREL16\n");
461  exit(1);
462  return;
463  case R_MIPS_LITERAL:
464  fprintf(stderr, "Unexcepted R_MIPS_LITERAL\n");
465  exit(1);
466  return;
467  case R_MIPSSCE_MHI16:
468  if ( i == entrise + 1 || rp[1].type != R_MIPSSCE_ADDEND )
469  {
470  fprintf(stderr, "R_MIPSSCE_MHI16 without R_MIPSSCE_ADDEND\n");
471  exit(1);
472  }
473  data_3 = (uint16_t)((((startaddr + rp[1].rel.r_offset) >> 15) + 1) >> 1);
474  for ( daddr1 = 1; daddr1; datal += daddr1 )
475  {
476  daddr1 = *(uint16_t *)datal << 16 >> 14;
477  *(uint32_t *)datal &= 0xFFFF0000;
478  *(uint32_t *)datal |= data_3;
479  }
480  rp += 1;
481  i += 1;
482  break;
483  case R_MIPS_REL32:
484  case R_MIPS_GOT16:
485  case R_MIPS_PC16:
486  case R_MIPS_CALL16:
487  case R_MIPS_GPREL32:
488  case R_MIPS_GOTHI16:
489  case R_MIPS_GOTLO16:
490  case R_MIPS_CALLHI16:
491  case R_MIPS_CALLLO16:
492  fprintf(stderr, "unacceptable relocation type: 0x%x\n", rp->type);
493  exit(1);
494  return;
495  default:
496  fprintf(stderr, "unknown relocation type: 0x%x\n", rp->type);
497  exit(1);
498  return;
499  }
500  rp += 1;
501  }
502 }
503 
504 void fixlocation_elf(elf_file *elf, unsigned int startaddr)
505 {
506  unsigned int entrise;
507  int i;
508  unsigned int k;
509  int d;
510  int s;
511  int j;
512  elf_syment **syp;
513  elf_section *scp;
514  elf_section *modsect_1;
515  elf_section *modsect_2;
516 
517  if ( elf->scp == NULL )
518  {
519  return;
520  }
521  d = 1;
522  for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
523  {
524  if ( elf->scp[s]->shr.sh_type == SHT_REL )
525  {
526  fixlocation_an_rel(elf->scp[s], startaddr);
527  }
528  else
529  {
530  elf->scp[d] = elf->scp[s];
531  d += 1;
532  }
533  }
534  elf->ehp->e_shnum = d;
535  elf->ehp->e_entry += startaddr;
536  modsect_1 = search_section(elf, SHT_SCE_IOPMOD);
537  if ( modsect_1 )
538  {
539  Elf32_IopMod *iopmodinfo;
540 
541  iopmodinfo = (Elf32_IopMod *)modsect_1->data;
542  if ( iopmodinfo->moduleinfo != (Elf32_Word)(-1) )
543  {
544  iopmodinfo->moduleinfo += startaddr;
545  }
546  iopmodinfo->entry += startaddr;
547  iopmodinfo->gp_value += startaddr;
548  }
549  modsect_2 = search_section(elf, SHT_SCE_EEMOD);
550  if ( modsect_2 )
551  {
552  Elf32_EeMod *eemodinfo;
553 
554  eemodinfo = (Elf32_EeMod *)modsect_2->data;
555  if ( eemodinfo->moduleinfo != (Elf32_Word)(-1) )
556  {
557  eemodinfo->moduleinfo += startaddr;
558  }
559  eemodinfo->entry += startaddr;
560  eemodinfo->gp_value += startaddr;
561  }
562  for ( i = 0; i < elf->ehp->e_phnum; i += 1 )
563  {
564  if ( elf->php[i].phdr.p_type == PT_LOAD )
565  {
566  elf->php[i].phdr.p_vaddr = startaddr;
567  elf->php[i].phdr.p_paddr = startaddr;
568  break;
569  }
570  }
571  for ( j = 1; j < elf->ehp->e_shnum; j += 1 )
572  {
573  switch ( elf->scp[j]->shr.sh_type )
574  {
575  case SHT_PROGBITS:
576  case SHT_NOBITS:
577  elf->scp[j]->shr.sh_addr += startaddr;
578  break;
579  default:
580  break;
581  }
582  }
583  scp = search_section(elf, SHT_SYMTAB);
584  if ( scp == NULL )
585  {
586  return;
587  }
588  entrise = scp->shr.sh_size / scp->shr.sh_entsize;
589  syp = (elf_syment **)scp->data;
590  for ( k = 1; k < entrise; k += 1 )
591  {
592  if ( syp[k]->sym.st_shndx == SHN_RADDR || (syp[k]->sym.st_shndx && syp[k]->sym.st_shndx <= 0xFEFF) )
593  {
594  syp[k]->sym.st_value += startaddr;
595  }
596  if ( syp[k]->sym.st_shndx == SHN_RADDR )
597  {
598  syp[k]->sym.st_shndx = -15;
599  }
600  }
601 }
602 
603 static void save_org_addrs(elf_file *elf)
604 {
605  Elf32_RegInfo *data;
606  const Elf32_RegInfo *reginfop;
607  elf_section *reginfosec;
608  int i;
609 
610  reginfosec = search_section(elf, SHT_MIPS_REGINFO);
611  if ( reginfosec )
612  {
613  data = (Elf32_RegInfo *)reginfosec->data;
614  }
615  else
616  {
617  data = 0;
618  }
619  reginfop = data;
620  for ( i = 1; i < elf->ehp->e_shnum; i += 1 )
621  {
622  Sect_org_data *org;
623 
624  org = (Sect_org_data *)calloc(1, sizeof(Sect_org_data));
625  org->org_addr = elf->scp[i]->shr.sh_addr;
626  if ( reginfop )
627  {
628  org->org_gp_value = reginfop->ri_gp_value;
629  }
630  elf->scp[i]->optdata = (void *)org;
631  }
632 }
633 
634 static elf_section *add_iopmod(elf_file *elf)
635 {
636  Elf32_IopMod *iopmodp;
637  elf_section *modsect;
638 
639  modsect = (elf_section *)malloc(sizeof(elf_section));
640  memset(modsect, 0, sizeof(elf_section));
641  iopmodp = (Elf32_IopMod *)malloc(sizeof(Elf32_IopMod));
642  memset(iopmodp, 0, sizeof(Elf32_IopMod));
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);
651  return modsect;
652 }
653 
654 static elf_section *add_eemod(elf_file *elf)
655 {
656  Elf32_EeMod *eemodp;
657  elf_section *modsect;
658 
659  modsect = (elf_section *)malloc(sizeof(elf_section));
660  memset(modsect, 0, sizeof(elf_section));
661  eemodp = (Elf32_EeMod *)malloc(sizeof(Elf32_EeMod));
662  memset(eemodp, 0, sizeof(Elf32_EeMod));
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);
671  return modsect;
672 }
673 
674 static void modify_eemod(elf_file *elf, elf_section *eemod)
675 {
676  elf_section *scp_1;
677  elf_section *scp_2;
678  Elf32_EeMod *moddata;
679 
680  if ( eemod->shr.sh_type != SHT_SCE_EEMOD )
681  {
682  return;
683  }
684  moddata = (Elf32_EeMod *)eemod->data;
685  scp_1 = search_section_by_name(elf, ".erx.lib");
686  if ( scp_1 )
687  {
688  moddata->erx_lib_addr = scp_1->shr.sh_addr;
689  moddata->erx_lib_size = scp_1->shr.sh_size;
690  }
691  else
692  {
693  moddata->erx_lib_addr = -1;
694  moddata->erx_lib_size = 0;
695  }
696  scp_2 = search_section_by_name(elf, ".erx.stub");
697  if ( scp_2 )
698  {
699  moddata->erx_stub_addr = scp_2->shr.sh_addr;
700  moddata->erx_stub_size = scp_2->shr.sh_size;
701  }
702  else
703  {
704  moddata->erx_stub_addr = -1;
705  moddata->erx_stub_size = 0;
706  }
707 }
708 
709 static void add_reserved_symbol_table(
710  Srx_gen_table *tp,
711  const char *name,
712  int bind,
713  int type,
714  SegConf *segment,
715  const char *sectname,
716  int shindex,
717  int base)
718 {
719  CreateSymbolConf *newent_1;
720  CreateSymbolConf *newent_2;
721  int entries;
722 
723  entries = 1;
724  for ( newent_1 = tp->create_symbols; newent_1->name; newent_1 += 1 )
725  {
726  entries += 1;
727  }
728  tp->create_symbols = (CreateSymbolConf *)realloc(tp->create_symbols, (entries + 1) * sizeof(CreateSymbolConf));
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;
738 }
739 
740 const char *bos_str = "_begin_of_section_";
741 const char *eos_str = "_end_of_section_";
742 static void define_special_section_symbols(elf_file *elf)
743 {
744  char *sectname;
745  int sectname_len;
746  const elf_syment *sym;
747  elf_syment **syp;
748  elf_section *scp;
749  unsigned int entrise;
750  unsigned int i;
751  Srx_gen_table *tp;
752 
753  tp = (Srx_gen_table *)(elf->optdata);
754  scp = search_section(elf, SHT_SYMTAB);
755  if ( scp == NULL )
756  {
757  return;
758  }
759  sectname_len = ((elf->shstrptr->shr.sh_size + 22) >> 2) << 2;
760  sectname = (char *)__builtin_alloca(sectname_len);
761  entrise = scp->shr.sh_size / scp->shr.sh_entsize;
762  syp = (elf_syment **)(scp->data);
763  for ( i = 1; i < entrise; i += 1 )
764  {
765  sym = syp[i];
766  if ( sym->bind == STB_GLOBAL && !sym->sym.st_shndx )
767  {
768  if ( !strncmp(bos_str, sym->name, strlen(bos_str)) )
769  {
770  snprintf(sectname, sectname_len, ".%s", &sym->name[strlen(bos_str)]);
771  add_reserved_symbol_table(tp, sym->name, 2, 1, 0, sectname, 0, 0);
772  }
773  if ( !strncmp(eos_str, sym->name, strlen(eos_str)) )
774  {
775  snprintf(sectname, sectname_len, ".%s", &sym->name[strlen(eos_str)]);
776  add_reserved_symbol_table(tp, sym->name, 2, 1, 0, sectname, 65311, 1);
777  }
778  }
779  }
780 }
781 
782 static void create_need_section(elf_file *elf)
783 {
784  elf_section *scp;
785  unsigned int i;
786  CreateSymbolConf *csym;
787  Srx_gen_table *tp;
788 
789  tp = (Srx_gen_table *)elf->optdata;
790  scp = search_section(elf, SHT_SYMTAB);
791  if ( scp == NULL )
792  {
793  return;
794  }
795  for ( i = 1; i < (scp->shr.sh_size / scp->shr.sh_entsize); i += 1 )
796  {
797  const elf_syment *syment;
798 
799  syment = *(elf_syment **)&scp->data[i * sizeof(void *)];
800  if ( !syment->sym.st_shndx )
801  {
802  csym = is_reserve_symbol(tp, syment->name);
803  if ( csym )
804  {
805  if ( csym->segment )
806  {
807  elf_section *addscp_1;
808 
809  addscp_1 = csym->segment->empty_section;
810  if ( addscp_1 )
811  {
812  if ( !search_section_by_name(elf, addscp_1->name) )
813  {
814  add_section(elf, addscp_1);
815  }
816  }
817  }
818  else if ( csym->sectname && !search_section_by_name(elf, csym->sectname) )
819  {
820  SectConf *odr;
821 
822  for ( odr = tp->section_list; odr->sect_name_pattern; odr += 1 )
823  {
824  if ( !sect_name_match(odr->sect_name_pattern, csym->sectname) && odr->secttype && odr->sectflag )
825  {
826  elf_section *addscp_2;
827 
828  addscp_2 = (elf_section *)calloc(1, sizeof(elf_section));
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);
836  break;
837  }
838  }
839  }
840  }
841  }
842  }
843 }
844 
845 static int sect_name_match(const char *pattern, const char *name)
846 {
847  for ( ; *pattern && *name && *pattern != '*'; pattern += 1, name += 1 )
848  {
849  if ( *name > *pattern )
850  {
851  return -1;
852  }
853  if ( *name < *pattern )
854  {
855  return 1;
856  }
857  }
858  if ( !*pattern && !*name )
859  {
860  return 0;
861  }
862  if ( *pattern == '*' && !pattern[1] )
863  {
864  return 0;
865  }
866  if ( *pattern != '*' )
867  {
868  return strcmp(pattern, name);
869  }
870  pattern += 1;
871  if ( strlen(name) < strlen(pattern) )
872  {
873  return strcmp(pattern, name);
874  }
875  return strcmp(pattern, &name[strlen(name) - strlen(pattern)]);
876 }
877 
878 static int reorder_section_table(elf_file *elf)
879 {
880  const char **secorder;
881  int sections;
882  elf_section **scp;
883  int d;
884  int s;
885 
886  sections = elf->ehp->e_shnum;
887  secorder = ((Srx_gen_table *)elf->optdata)->section_table_order;
888  scp = (elf_section **)calloc(sections + 1, sizeof(elf_section *));
889  memcpy(scp, elf->scp, sections * sizeof(elf_section *));
890  *elf->scp = *scp;
891  d = 1;
892  for ( ; *secorder; secorder += 1 )
893  {
894  for ( s = 1; s < sections; s += 1 )
895  {
896  if ( scp[s] )
897  {
898  if ( !sect_name_match(*secorder, scp[s]->name) )
899  {
900  elf->scp[d] = scp[s];
901  scp[s] = 0;
902  d += 1;
903  }
904  }
905  }
906  }
907  free(scp);
908  reorder_symtab(elf);
909  return 0;
910 }
911 
912 static void create_phdr(elf_file *elf)
913 {
914  const PheaderInfo *phip;
915  int i;
916 
917  phip = ((Srx_gen_table *)(elf->optdata))->program_header_order;
918  for ( i = 0; phip[i].sw; i += 1 )
919  {
920  ;
921  }
922  elf->php = (i != 0) ? (elf_proghead *)malloc(i * sizeof(elf_proghead)) : NULL;
923  if ( elf->php != NULL )
924  {
925  memset(elf->php, 0, i * sizeof(elf_proghead));
926  }
927  elf->ehp->e_phentsize = sizeof(Elf32_Phdr);
928  elf->ehp->e_phnum = i;
929  if ( elf->php != NULL )
930  {
931  int j;
932 
933  for ( j = 0; phip[j].sw; j += 1 )
934  {
935  switch ( phip[j].sw )
936  {
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) )
941  {
942  elf->php[j].phdr.p_type = PT_SCE_IOPMOD;
943  elf->php[j].phdr.p_filesz = sizeof(Elf32_IopMod);
944  elf->php[j].scp = (elf_section **)calloc(2, sizeof(elf_section *));
945  *elf->php[j].scp = search_section(elf, SHT_SCE_IOPMOD);
946  }
947  else if ( !strcmp(".eemod", phip[j].d.section_name) )
948  {
949  elf->php[j].phdr.p_type = PT_SCE_EEMOD;
950  elf->php[j].phdr.p_filesz = sizeof(Elf32_EeMod);
951  elf->php[j].scp = (elf_section **)calloc(2, sizeof(elf_section *));
952  *elf->php[j].scp = search_section(elf, SHT_SCE_EEMOD);
953  }
954  else
955  {
956  fprintf(stderr, "Unsuport section '%s' for program header\n", phip[j].d.section_name);
957  }
958  break;
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;
963  break;
964  default:
965  break;
966  }
967  }
968  }
969 }
970 
971 static void check_change_bit(unsigned int oldbit, unsigned int newbit, unsigned int *up, unsigned int *down)
972 {
973  *up = ~oldbit & newbit & (newbit ^ oldbit);
974  *down = ~newbit & oldbit & (newbit ^ oldbit);
975 }
976 
977 static void segment_start_setup(SegConf *seglist, unsigned int bitid, const unsigned int *moffset)
978 {
979  for ( ; seglist->name; seglist += 1 )
980  {
981  if ( (seglist->bitid & bitid) != 0 )
982  {
983  seglist->addr = *moffset;
984  seglist->size = 0;
985  }
986  }
987 }
988 
989 static void add_section_to_segment(SegConf *seglist, elf_section *scp, unsigned int bitid)
990 {
991  for ( ; seglist->name; seglist += 1 )
992  {
993  if ( (seglist->bitid & bitid) != 0 )
994  {
995  if ( !seglist->nsect )
996  {
997  seglist->addr = scp->shr.sh_addr;
998  }
999  seglist->nsect += 1;
1000  seglist->scp = (elf_section **)realloc(seglist->scp, (seglist->nsect + 1) * sizeof(elf_section *));
1001  seglist->scp[seglist->nsect - 1] = scp;
1002  seglist->scp[seglist->nsect] = 0;
1003  }
1004  }
1005 }
1006 
1007 static void segment_end_setup(SegConf *seglist, unsigned int bitid, unsigned int *moffset, int ee)
1008 {
1009  for ( ; seglist->name; seglist += 1 )
1010  {
1011  if ( (seglist->bitid & bitid) != 0 )
1012  {
1013  if ( ee )
1014  {
1015  if ( !strcmp(seglist->name, "TEXT") )
1016  {
1017  *moffset += 32;
1018  }
1019  }
1020  seglist->size = *moffset - seglist->addr;
1021  }
1022  }
1023 }
1024 
1025 static void update_modinfo(elf_file *elf)
1026 {
1027  Srx_gen_table *tp;
1028  const SegConf *seginfo;
1029  const SegConf *seginfo_4;
1030  const SegConf *seginfo_8;
1031  const SegConf *seginfo_12;
1032  elf_section *scp_1;
1033  elf_section *scp_2;
1034 
1035  tp = (Srx_gen_table *)elf->optdata;
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 )
1041  {
1042  fprintf(stderr, "TEXT,DATA,BSS,GLOBALDATA segment missing abort");
1043  exit(1);
1044  }
1045  scp_1 = search_section(elf, SHT_SCE_IOPMOD);
1046  if ( scp_1 )
1047  {
1048  Elf32_IopMod *imp;
1049 
1050  scp_1->shr.sh_addr = 0;
1051  imp = (Elf32_IopMod *)scp_1->data;
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;
1056  }
1057  scp_2 = search_section(elf, SHT_SCE_EEMOD);
1058  if ( scp_2 )
1059  {
1060  Elf32_EeMod *emp;
1061 
1062  scp_2->shr.sh_addr = 0;
1063  emp = (Elf32_EeMod *)scp_2->data;
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;
1068  }
1069 }
1070 
1071 static void update_mdebug(elf_file *elf)
1072 {
1073  elf_section *scp;
1074 
1075  scp = search_section(elf, SHT_MIPS_DEBUG);
1076  if ( scp )
1077  {
1078  scp->shr.sh_addr = 0;
1079  }
1080 }
1081 
1082 static void update_programheader(elf_file *elf)
1083 {
1084  Srx_gen_table *tp;
1085  SegConf **segp;
1086  elf_section **scp;
1087  PheaderInfo *phip;
1088  unsigned int minsegalign;
1089  unsigned int align;
1090  int nsect_1;
1091  int nsect_2;
1092  int nseg_1;
1093  int nseg_2;
1094  int s;
1095  int n;
1096 
1097  tp = (Srx_gen_table *)elf->optdata;
1098  phip = tp->program_header_order;
1099  switch ( tp->target )
1100  {
1101  case SRX_TARGET_IOP:
1102  minsegalign = 16;
1103  break;
1104  case SRX_TARGET_EE:
1105  minsegalign = 128;
1106  break;
1107  default:
1108  fprintf(stderr, "Internal error: target unknown\n");
1109  exit(1);
1110  return;
1111  }
1112  for ( n = 0; phip[n].sw; n += 1 )
1113  {
1114  if ( phip[n].sw == SRX_PH_TYPE_TEXT )
1115  {
1116  segp = phip[n].d.segment_list;
1117  if ( segp )
1118  {
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 )
1122  {
1123  ;
1124  }
1125  scp = (elf_section **)calloc(nsect_1 + 1, sizeof(elf_section *));
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 )
1128  {
1129  memcpy(&scp[nsect_2], segp[nseg_2]->scp, segp[nseg_2]->nsect * sizeof(elf_section *));
1130  }
1131  for ( s = 0; s < nsect_2 && scp[s]->shr.sh_type == SHT_PROGBITS; s += 1 )
1132  {
1133  if ( scp[s]->shr.sh_addralign > align )
1134  {
1135  align = scp[s]->shr.sh_addralign;
1136  }
1137  }
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 )
1141  {
1142  if ( scp[s]->shr.sh_addralign > align )
1143  {
1144  align = scp[s]->shr.sh_addralign;
1145  }
1146  }
1147  elf->php[n].phdr.p_align = align;
1148  }
1149  }
1150  }
1151 }
1152 
1153 static void remove_unuse_section(elf_file *elf)
1154 {
1155  const char **sectnames;
1156  int sections;
1157  elf_section **dscp;
1158  int d;
1159  int i;
1160  int j;
1161 
1162  sections = elf->ehp->e_shnum;
1163  sectnames = ((Srx_gen_table *)(elf->optdata))->removesection_list;
1164  dscp = (elf_section **)calloc(sections + 1, sizeof(elf_section *));
1165  memset(dscp, 0, sections * sizeof(elf_section *));
1166  d = 0;
1167  for ( ; *sectnames; sectnames += 1 )
1168  {
1169  for ( i = 1; i < sections; i += 1 )
1170  {
1171  if ( elf->scp[i] )
1172  {
1173  if ( !sect_name_match(*sectnames, elf->scp[i]->name) )
1174  {
1175  dscp[d] = elf->scp[i];
1176  d += 1;
1177  }
1178  }
1179  }
1180  }
1181  for ( j = 0; j < sections; j += 1 )
1182  {
1183  if ( dscp[j] )
1184  {
1185  remove_section_by_name(elf, dscp[j]->name);
1186  }
1187  }
1188  free(dscp);
1189 }
1190 
1191 static int layout_srx_memory(elf_file *elf)
1192 {
1193  int s_3;
1194  elf_section **scp;
1195  SectConf *odr;
1196  Srx_gen_table *tp;
1197  int error;
1198  int is_ee;
1199  int sections;
1200  int s_1;
1201  int s_2;
1202  unsigned int downdelta;
1203  unsigned int updelta;
1204  unsigned int oldbitid;
1205  unsigned int moffset;
1206 
1207  tp = (Srx_gen_table *)elf->optdata;
1208  moffset = 0;
1209  oldbitid = 0;
1210  error = 0;
1211  is_ee = tp->target == SRX_TARGET_EE;
1212  if ( !elf->scp )
1213  {
1214  return 1;
1215  }
1216  sections = elf->ehp->e_shnum;
1217  scp = (elf_section **)calloc(sections + 1, sizeof(elf_section *));
1218  memcpy(scp, elf->scp, sections * sizeof(elf_section *));
1219  for ( odr = tp->section_list; odr->sect_name_pattern; odr += 1 )
1220  {
1221  check_change_bit(oldbitid, odr->flag, &updelta, &downdelta);
1222  if ( updelta )
1223  {
1224  segment_start_setup(tp->segment_list, updelta, &moffset);
1225  }
1226  for ( s_1 = 1; s_1 < sections; s_1 += 1 )
1227  {
1228  if (
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 )
1231  {
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);
1236  scp[s_1] = 0;
1237  }
1238  }
1239  oldbitid = odr->flag;
1240  check_change_bit(oldbitid, odr[1].flag, &updelta, &downdelta);
1241  if ( downdelta )
1242  {
1243  segment_end_setup(tp->segment_list, downdelta, &moffset, is_ee);
1244  }
1245  }
1246  for ( s_2 = 1; s_2 < sections; s_2 += 1 )
1247  {
1248  if ( scp[s_2] && (scp[s_2]->shr.sh_flags & SHF_ALLOC) != 0 )
1249  {
1250  for (
1251  s_3 = 1;
1252  s_3 < sections
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);
1254  s_3 += 1 )
1255  {
1256  ;
1257  }
1258  if ( sections > s_3 )
1259  {
1260  fprintf(
1261  stderr,
1262  "Error: section '%s' needs allocation and has relocation data but not in program segment\n",
1263  scp[s_2]->name);
1264  scp[s_3] = 0;
1265  error += 1;
1266  }
1267  else
1268  {
1269  fprintf(stderr, "Warning: section '%s' needs allocation but not in program segment\n", scp[s_2]->name);
1270  scp[s_2] = 0;
1271  }
1272  }
1273  }
1274  free(scp);
1275  if ( !error )
1276  {
1277  update_modinfo(elf);
1278  update_mdebug(elf);
1279  update_programheader(elf);
1280  }
1281  return error;
1282 }
1283 
1284 static CreateSymbolConf *is_reserve_symbol(Srx_gen_table *tp, const char *name)
1285 {
1286  CreateSymbolConf *csyms;
1287 
1288  if ( !name )
1289  {
1290  return 0;
1291  }
1292  for ( csyms = tp->create_symbols; csyms->name; csyms += 1 )
1293  {
1294  if ( !strcmp(csyms->name, name) )
1295  {
1296  return csyms;
1297  }
1298  }
1299  return 0;
1300 }
1301 
1302 static int check_undef_symboles_an_reloc(elf_section *relsect)
1303 {
1304  elf_syment **symp;
1305  elf_rel *rp;
1306  int undefcount;
1307  unsigned int entrise;
1308  unsigned int i;
1309 
1310  entrise = relsect->shr.sh_size / relsect->shr.sh_entsize;
1311  rp = (elf_rel *)relsect->data;
1312  symp = (elf_syment **)relsect->link->data;
1313  undefcount = 0;
1314  for ( i = 0; i < entrise; i += 1 )
1315  {
1316  if ( rp->symptr && *symp != rp->symptr )
1317  {
1318  if ( rp->symptr->sym.st_shndx )
1319  {
1320  if (
1321  rp->symptr->sym.st_shndx > 0xFEFF && rp->symptr->sym.st_shndx != SHN_ABS
1322  && rp->symptr->sym.st_shndx != SHN_RADDR )
1323  {
1324  if ( rp->symptr->sym.st_shndx == SHN_COMMON )
1325  {
1326  fprintf(stderr, " unallocated variable `%s'\n", rp->symptr->name);
1327  }
1328  else
1329  {
1330  fprintf(stderr, " `%s' unknown symbol type %x\n", rp->symptr->name, rp->symptr->sym.st_shndx);
1331  }
1332  undefcount += 1;
1333  }
1334  }
1335  else if ( rp->symptr->bind != STB_WEAK )
1336  {
1337  fprintf(stderr, " undefined reference to `%s'\n", rp->symptr->name);
1338  undefcount += 1;
1339  }
1340  }
1341  rp += 1;
1342  }
1343  return undefcount;
1344 }
1345 
1346 static int check_undef_symboles(elf_file *elf)
1347 {
1348  int err;
1349  int s;
1350 
1351  if ( !elf->scp )
1352  {
1353  return 0;
1354  }
1355  err = 0;
1356  for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
1357  {
1358  if ( elf->scp[s]->shr.sh_type == SHT_REL )
1359  {
1360  err += check_undef_symboles_an_reloc(elf->scp[s]);
1361  }
1362  }
1363  return err;
1364 }
1365 
1366 #if 0
1367 // clang-format off
1368 static const char * const SymbolType[] =
1369 {
1370 #define X(d) #d,
1371  XEACH_SymbolType_enum()
1372 #undef X
1373 };
1374 // clang-format on
1375 #endif
1376 static int create_reserved_symbols(elf_file *elf)
1377 {
1378  int csyms_;
1379  unsigned int sh_size;
1380  unsigned int sh_addr;
1381  elf_section *scp;
1382  CreateSymbolConf *csyms;
1383  Srx_gen_table *tp;
1384 
1385  tp = (Srx_gen_table *)elf->optdata;
1386  csyms_ = 0;
1387  if ( !search_section(elf, SHT_SYMTAB) )
1388  {
1389  return 1;
1390  }
1391  for ( csyms = tp->create_symbols; csyms->name; csyms += 1 )
1392  {
1393  elf_syment *sym;
1394 
1395  sym = search_global_symbol(csyms->name, elf);
1396  if ( !sym
1397  && (csyms->shindex > 0xFEFF
1398  || (csyms->segment && csyms->segment->scp)
1399  || (!csyms->segment && csyms->sectname && search_section_by_name(elf, csyms->sectname))) )
1400  {
1401  sym = add_symbol(elf, csyms->name, csyms->bind, 0, 0, 0, 0);
1402  }
1403  if ( sym )
1404  {
1405  sh_size = 0;
1406  sh_addr = 0;
1407  scp = 0;
1408  if ( csyms->segment )
1409  {
1410  sh_addr = csyms->segment->addr;
1411  sh_size = csyms->segment->size;
1412  if ( csyms->shindex <= 0xFEFF )
1413  {
1414  scp = *csyms->segment->scp;
1415  }
1416  }
1417  else if ( csyms->sectname != NULL )
1418  {
1419  scp = search_section_by_name(elf, csyms->sectname);
1420  if ( scp )
1421  {
1422  sh_addr = scp->shr.sh_addr;
1423  sh_size = scp->shr.sh_size;
1424  }
1425  }
1426  if ( csyms->segment || scp )
1427  {
1428  // FIXME: disable this check because it trips on _gp, _end symbols
1429 #if 0
1430  if ( sym->sym.st_shndx )
1431  {
1432  fprintf(stderr, "Unexcepted Symbol \"%s\":%s \n", sym->name, SymbolType[sym->type]);
1433  csyms_ += 1;
1434  }
1435  else
1436 #endif
1437  {
1438  sym->bind = csyms->bind;
1439  if ( !sym->type )
1440  {
1441  sym->type = csyms->type;
1442  }
1443  sym->sym.st_info = ((csyms->bind & 0xFF) << 4) + (csyms->type & 0xF);
1444  if ( csyms->shindex > 0xFEFF )
1445  {
1446  sym->sym.st_shndx = csyms->shindex;
1447  sym->shptr = 0;
1448  switch ( csyms->seflag )
1449  {
1450  case 0:
1451  sym->sym.st_value = sh_addr;
1452  break;
1453  case 1:
1454  sym->sym.st_value = sh_size + sh_addr;
1455  break;
1456  case 2:
1457  sym->sym.st_value = sh_addr + 0x7FF0;
1458  break;
1459  default:
1460  break;
1461  }
1462  }
1463  else
1464  {
1465  sym->sym.st_shndx = 1;
1466  sym->shptr = scp;
1467  switch ( csyms->seflag )
1468  {
1469  case 0:
1470  sym->sym.st_value = 0;
1471  break;
1472  case 1:
1473  sym->sym.st_value = sh_size;
1474  break;
1475  default:
1476  break;
1477  }
1478  }
1479  }
1480  continue;
1481  }
1482  if ( csyms->bind == STB_WEAK && (sym->bind == STB_GLOBAL || sym->bind == STB_WEAK) && !sym->sym.st_shndx )
1483  {
1484  if ( !sym->type )
1485  {
1486  sym->type = csyms->type;
1487  }
1488  sym->bind = csyms->bind;
1489  sym->sym.st_info = ((csyms->bind & 0xFF) << 4) + (csyms->type & 0xF);
1490  }
1491  }
1492  }
1493  return csyms_;
1494 }
1495 
1496 static void symbol_value_update(elf_file *elf)
1497 {
1498  unsigned int entrise;
1499  unsigned int i;
1500  elf_syment **syp;
1501  elf_section *scp;
1502  int target;
1503 
1504  target = ((Srx_gen_table *)(elf->optdata))->target;
1505  if ( elf->ehp->e_type != ET_REL )
1506  {
1507  return;
1508  }
1509  switch ( target )
1510  {
1511  case SRX_TARGET_IOP:
1512  elf->ehp->e_type = ET_SCE_IOPRELEXEC;
1513  break;
1514  case SRX_TARGET_EE:
1515  elf->ehp->e_type = ET_SCE_EERELEXEC2;
1516  break;
1517  default:
1518  break;
1519  }
1520  scp = search_section(elf, SHT_SYMTAB);
1521  if ( scp == NULL )
1522  {
1523  return;
1524  }
1525  entrise = scp->shr.sh_size / scp->shr.sh_entsize;
1526  syp = (elf_syment **)scp->data;
1527  for ( i = 1; i < entrise; i += 1 )
1528  {
1529  if ( syp[i]->sym.st_shndx )
1530  {
1531  if ( syp[i]->sym.st_shndx <= 0xFEFF )
1532  {
1533  syp[i]->sym.st_value += syp[i]->shptr->shr.sh_addr;
1534  }
1535  }
1536  }
1537 }
1538 
1539 static void rebuild_relocation(elf_file *elf, unsigned int gpvalue)
1540 {
1541  int s;
1542 
1543  if ( elf->scp == NULL )
1544  {
1545  return;
1546  }
1547  for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
1548  {
1549  if ( elf->scp[s]->shr.sh_type == SHT_REL )
1550  {
1551  rebuild_an_relocation(elf->scp[s], gpvalue, ((Srx_gen_table *)(elf->optdata))->target);
1552  }
1553  }
1554 }
1555 
1556 static int check_irx12(elf_file *elf, int cause_irx1)
1557 {
1558  int s;
1559 
1560  if ( elf->ehp->e_type != ET_SCE_IOPRELEXEC )
1561  {
1562  return 0;
1563  }
1564  for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
1565  {
1566  if ( elf->scp[s]->shr.sh_type == SHT_REL && relocation_is_version2(elf->scp[s]) )
1567  {
1568  if ( cause_irx1 )
1569  {
1570  fprintf(stderr, "R_MIPS_LO16 without R_MIPS_HI16\n");
1571  return 1;
1572  }
1573  elf->ehp->e_type = ET_SCE_IOPRELEXEC2;
1574  }
1575  }
1576  return 0;
1577 }
1578 
1579 static void setup_module_info(elf_file *elf, elf_section *modsect, const char *modulesymbol)
1580 {
1581  unsigned int *section_data;
1582  int i;
1583  char *buf;
1584  const char *name;
1585  unsigned int woff;
1586  size_t buflen;
1587  const unsigned int *modnamep;
1588  unsigned int *modidatap;
1589  unsigned int modiaddr;
1590  const elf_syment *syp;
1591 
1592  syp = search_global_symbol(modulesymbol, elf);
1593  if ( is_defined_symbol(syp) == 0 )
1594  {
1595  return;
1596  }
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);
1606  name = &buf[woff];
1607  switch ( modsect->shr.sh_type )
1608  {
1609  case SHT_SCE_IOPMOD:
1610  {
1611  Elf32_IopMod *iopmodp_1;
1612  Elf32_IopMod *iopmodp_2;
1613 
1614  iopmodp_1 = (Elf32_IopMod *)modsect->data;
1615  iopmodp_1->moduleinfo = modiaddr;
1616  iopmodp_1->moduleversion = *((uint16_t *)modidatap + 2);
1617  // HACK FIXME: Don't place the name in the header
1618  name = "";
1619  iopmodp_2 = (Elf32_IopMod *)realloc(iopmodp_1, strlen(name) + sizeof(Elf32_IopMod));
1620  strcpy(iopmodp_2->modulename, name);
1621  modsect->data = (uint8_t *)iopmodp_2;
1622  modsect->shr.sh_size = iopmod_size(iopmodp_2);
1623  break;
1624  }
1625  case SHT_SCE_EEMOD:
1626  {
1627  Elf32_EeMod *eemodp_1;
1628  Elf32_EeMod *eemodp_2;
1629  eemodp_1 = (Elf32_EeMod *)modsect->data;
1630  eemodp_1->moduleinfo = modiaddr;
1631  eemodp_1->moduleversion = *((uint16_t *)modidatap + 2);
1632  eemodp_2 = (Elf32_EeMod *)realloc(eemodp_1, strlen(name) + sizeof(Elf32_EeMod));
1633  strcpy(eemodp_2->modulename, name);
1634  modsect->data = (uint8_t *)eemodp_2;
1635  modsect->shr.sh_size = eemod_size(eemodp_2);
1636  break;
1637  }
1638  default:
1639  break;
1640  }
1641  free(buf);
1642  if ( elf->php == NULL )
1643  {
1644  return;
1645  }
1646  for ( i = 0; i < elf->ehp->e_phnum; i += 1 )
1647  {
1648  if ( elf->php[i].scp && (modsect == *elf->php[i].scp) )
1649  {
1650  elf->php[i].phdr.p_filesz = modsect->shr.sh_size;
1651  }
1652  }
1653 }
1654 
1655 static void rebuild_an_relocation(elf_section *relsect, unsigned int gpvalue, int target)
1656 {
1657  elf_rel *newtab;
1658  void *daddr_2;
1659  void *daddr_3;
1660  uint32_t data32_1;
1661  int data32_2;
1662  uint32_t datah;
1663  uint32_t data_1;
1664  uint32_t data_2;
1665  uint32_t data_33;
1666  uint16_t data_4;
1667  unsigned int data_5;
1668  unsigned int data_6;
1669  uint32_t data_7;
1670  uint32_t step;
1671  elf_syment **symp;
1672  elf_rel *rp;
1673  int rmflag;
1674  unsigned int entrise;
1675  unsigned int j_1;
1676  unsigned int j_2;
1677  unsigned int j_3;
1678  unsigned int i_1;
1679 
1680  entrise = relsect->shr.sh_size / relsect->shr.sh_entsize;
1681  rp = (elf_rel *)relsect->data;
1682  symp = (elf_syment **)relsect->link->data;
1683  rmflag = 0;
1684  for ( i_1 = 0; i_1 < entrise; )
1685  {
1686  int v4;
1687  uint32_t symvalue;
1688  void *daddr_1;
1689  unsigned int next;
1690 
1691  if ( relsect->info->shr.sh_size <= rp->rel.r_offset )
1692  {
1693  fprintf(
1694  stderr,
1695  "Panic !! relocation #%u offset=0x%x overflow (section size=0x%x)\n",
1696  i_1,
1697  rp->rel.r_offset,
1698  relsect->info->shr.sh_size);
1699  exit(1);
1700  }
1701  next = 1;
1702  daddr_1 = (void *)&relsect->info->data[rp->rel.r_offset];
1703  symvalue = 0;
1704  if ( rp->symptr )
1705  {
1706  if ( rp->symptr->sym.st_shndx )
1707  {
1708  symvalue = rp->symptr->sym.st_value;
1709  }
1710  }
1711  v4 = 0;
1712  if (
1713  !rp->symptr || (rp->symptr->sym.st_shndx && rp->symptr->sym.st_shndx <= 0xFEFF)
1714  || rp->symptr->sym.st_shndx == SHN_RADDR )
1715  {
1716  v4 = 1;
1717  }
1718  switch ( rp->type )
1719  {
1720  case R_MIPS_NONE:
1721  rmflag = 1;
1722  break;
1723  case R_MIPS_16:
1724  data_1 = symvalue + (int16_t)*(uint32_t *)daddr_1;
1725  if ( (uint16_t)(data_1 >> 16) && (uint16_t)(data_1 >> 16) != 0xFFFF )
1726  {
1727  fprintf(stderr, "REFHALF data overflow\n");
1728  exit(1);
1729  }
1730  *(uint32_t *)daddr_1 &= 0xFFFF0000;
1731  *(uint32_t *)daddr_1 |= (uint16_t)data_1;
1732  if ( !v4 )
1733  {
1734  rp->type = R_MIPS_NONE;
1735  rmflag = 1;
1736  }
1737  break;
1738  case R_MIPS_32:
1739  *(uint32_t *)daddr_1 += symvalue;
1740  if ( !v4 )
1741  {
1742  rp->type = R_MIPS_NONE;
1743  rmflag = 1;
1744  }
1745  break;
1746  case R_MIPS_26:
1747  data_2 = *(uint32_t *)daddr_1;
1748  if ( rp->symptr && rp->symptr->bind != STB_LOCAL )
1749  {
1750  data_33 = data_2 << 6 >> 4;
1751  }
1752  else
1753  {
1754  data_33 = ((relsect->info->shr.sh_addr + rp->rel.r_offset) & 0xF0000000) | (4 * (data_2 & 0x3FFFFFF));
1755  }
1756  *(uint32_t *)daddr_1 &= 0xFC000000;
1757  *(uint32_t *)daddr_1 |= (16 * (symvalue + data_33)) >> 6;
1758  if ( !v4 )
1759  {
1760  rp->type = R_MIPS_NONE;
1761  rmflag = 1;
1762  }
1763  break;
1764  case R_MIPS_HI16:
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 )
1767  {
1768  if ( rp->symptr && rp[next].symptr != rp->symptr )
1769  {
1770  fprintf(stderr, "R_MIPS_HI16 without R_MIPS_LO16\n");
1771  exit(1);
1772  }
1773  if ( relsect->info->shr.sh_size <= rp[next].rel.r_offset )
1774  {
1775  fprintf(
1776  stderr,
1777  "Panic !! relocation #%u offset=0x%x overflow (section size=0x%x)\n",
1778  i_1 + next,
1779  rp[next].rel.r_offset,
1780  relsect->info->shr.sh_size);
1781  exit(1);
1782  }
1783  daddr_1 = (void *)&relsect->info->data[rp[next].rel.r_offset];
1784  if ( datah != *(uint32_t *)daddr_1 << 16 )
1785  {
1786  fprintf(stderr, "R_MIPS_HI16s not same offsets\n");
1787  exit(1);
1788  }
1789  next += 1;
1790  }
1791  if ( j_1 == entrise + 1 || rp[next].type != R_MIPS_LO16 || (rp->symptr && rp[next].symptr != rp->symptr) )
1792  {
1793  fprintf(stderr, "R_MIPS_HI16 without R_MIPS_LO16\n");
1794  exit(1);
1795  }
1796  data32_1 = symvalue + (int16_t)*(uint32_t *)&relsect->info->data[rp[next].rel.r_offset] + datah;
1797  if ( next == 1 )
1798  {
1799  *(uint32_t *)daddr_1 &= 0xFFFF0000;
1800  *(uint32_t *)daddr_1 |= (uint16_t)(((data32_1 >> 15) + 1) >> 1);
1801  if ( !v4 )
1802  {
1803  rp->type = R_MIPS_NONE;
1804  rmflag = 1;
1805  }
1806  }
1807  else if ( v4 )
1808  {
1809  for ( j_2 = 0; j_2 < next; j_2 += 1 )
1810  {
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 )
1814  {
1815  step = rp[j_2 + 1].rel.r_offset - rp[j_2].rel.r_offset;
1816  if ( step >> 18 && step >> 18 != 0x3FFF )
1817  {
1818  fprintf(stderr, "R_MIPS_HI16s too long distance\n");
1819  exit(1);
1820  }
1821  *(uint32_t *)daddr_2 |= (uint16_t)(step >> 2);
1822  }
1823  rp[j_2].type = R_MIPS_NONE;
1824  if ( rp[j_2].symptr )
1825  {
1826  rp[j_2].symptr->refcount -= 1;
1827  rp[j_2].symptr = *symp;
1828  }
1829  }
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;
1834  rmflag = 1;
1835  rp += next;
1836  i_1 += next;
1837  next = 0;
1838  }
1839  else
1840  {
1841  data32_2 = (uint16_t)(((data32_1 >> 15) + 1) >> 1);
1842  for ( j_3 = 0; j_3 < next; j_3 += 1 )
1843  {
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;
1848  }
1849  rmflag = 1;
1850  }
1851  break;
1852  case R_MIPS_LO16:
1853  data_4 = symvalue + *(uint32_t *)daddr_1;
1854  *(uint32_t *)daddr_1 &= 0xFFFF0000;
1855  *(uint32_t *)daddr_1 |= data_4;
1856  if ( !v4 )
1857  {
1858  rp->type = R_MIPS_NONE;
1859  rmflag = 1;
1860  }
1861  break;
1862  case R_MIPS_GPREL16:
1863  data_5 = (int16_t)*(uint32_t *)daddr_1;
1864  if ( rp->symptr )
1865  {
1866  if ( rp->symptr->type == STT_SECTION )
1867  {
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;
1870  }
1871  else if ( rp->symptr->bind == STB_GLOBAL || (rp->symptr->bind == STB_WEAK && rp->symptr->sym.st_shndx) )
1872  {
1873  data_5 += symvalue - gpvalue;
1874  }
1875  else if ( rp->symptr->bind != STB_WEAK || rp->symptr->sym.st_shndx )
1876  {
1877  fprintf(stderr, "R_MIPS_GPREL16 unknown case abort\n");
1878  exit(1);
1879  }
1880  }
1881  else
1882  {
1883  fprintf(stderr, "R_MIPS_GPREL16 no symtab\n");
1884  exit(1);
1885  }
1886  if ( (uint16_t)(data_5 >> 16) && (uint16_t)(data_5 >> 16) != 0xFFFF )
1887  {
1888  fprintf(stderr, "R_MIPS_GPREL16 data overflow\n");
1889  exit(1);
1890  }
1891  *(uint32_t *)daddr_1 &= 0xFFFF0000;
1892  *(uint32_t *)daddr_1 |= (uint16_t)data_5;
1893  rp->type = R_MIPS_NONE;
1894  rmflag = 1;
1895  break;
1896  case R_MIPS_LITERAL:
1897  if ( !rp->symptr || rp->symptr->type != STT_SECTION )
1898  {
1899  fprintf(stderr, "R_MIPS_LITERAL unknown case abort\n");
1900  exit(1);
1901  }
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 )
1905  {
1906  fprintf(stderr, "R_MIPS_LITERAL data overflow\n");
1907  exit(1);
1908  }
1909  *(uint32_t *)daddr_1 &= 0xFFFF0000;
1910  *(uint32_t *)daddr_1 |= (uint16_t)data_6;
1911  rp->type = R_MIPS_NONE;
1912  rmflag = 1;
1913  break;
1914  case R_MIPS_DVP_27_S4:
1915  if ( target != SRX_TARGET_EE )
1916  {
1917  fprintf(stderr, "R_MIPS_DVP_27_S4 can use only for EE.\n");
1918  exit(1);
1919  }
1920  data_7 = symvalue + (*(uint32_t *)daddr_1 & 0x7FFFFFF0);
1921  *(uint32_t *)daddr_1 &= 0x8000000F;
1922  *(uint32_t *)daddr_1 |= data_7 & 0x7FFFFFF0;
1923  if ( !v4 )
1924  {
1925  rp->type = R_MIPS_NONE;
1926  rmflag = 1;
1927  }
1928  break;
1929  case R_MIPS_REL32:
1930  case R_MIPS_GOT16:
1931  case R_MIPS_PC16:
1932  case R_MIPS_CALL16:
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);
1939  exit(1);
1940  return;
1941  default:
1942  fprintf(stderr, "unknown relocation type: 0x%x\n", rp->type);
1943  exit(1);
1944  return;
1945  }
1946  for ( ; next > 0; next -= 1 )
1947  {
1948  rp->rel.r_offset += relsect->info->shr.sh_addr;
1949  if ( rp->symptr )
1950  {
1951  rp->symptr->refcount -= 1;
1952  rp->symptr = *symp;
1953  }
1954  i_1 += 1;
1955  rp += 1;
1956  }
1957  }
1958  if ( rmflag > 0 )
1959  {
1960  elf_rel *s;
1961  elf_rel *d;
1962  unsigned int newentrise;
1963  unsigned int i_2;
1964 
1965  newtab = (elf_rel *)calloc(entrise, sizeof(elf_rel));
1966  d = newtab;
1967  s = (elf_rel *)relsect->data;
1968  newentrise = 0;
1969  for ( i_2 = 0; i_2 < entrise; i_2 += 1 )
1970  {
1971  if ( s->type )
1972  {
1973  memcpy(d, s, sizeof(elf_rel));
1974  d += 1;
1975  newentrise += 1;
1976  }
1977  s += 1;
1978  }
1979  free(relsect->data);
1980  relsect->data = (uint8_t *)newtab;
1981  relsect->shr.sh_size = relsect->shr.sh_entsize * newentrise;
1982  }
1983 }
1984 
1985 static size_t iopmod_size(const Elf32_IopMod *modinfo)
1986 {
1987  return strlen(modinfo->modulename) + (sizeof(Elf32_IopMod) - 1);
1988 }
1989 
1990 static size_t eemod_size(const Elf32_EeMod *modinfo)
1991 {
1992  return strlen(modinfo->modulename) + (sizeof(Elf32_EeMod) - 1);
1993 }
1994 
1995 int relocation_is_version2(elf_section *relsect)
1996 {
1997  elf_rel *rp;
1998  unsigned int entrise;
1999  unsigned int i;
2000 
2001  entrise = relsect->shr.sh_size / relsect->shr.sh_entsize;
2002  rp = (elf_rel *)relsect->data;
2003  for ( i = 0; i < entrise; i += 1 )
2004  {
2005  switch ( rp->type )
2006  {
2007  case R_MIPS_LO16:
2008  case R_MIPSSCE_MHI16:
2009  case R_MIPSSCE_ADDEND:
2010  return 1;
2011  case R_MIPS_HI16:
2012  if ( i == entrise + 1 || rp[1].type != R_MIPS_LO16 || (rp->symptr && rp[1].symptr != rp->symptr) )
2013  {
2014  return 1;
2015  }
2016  rp += 1;
2017  i += 1;
2018  break;
2019  default:
2020  break;
2021  }
2022  rp += 1;
2023  }
2024  return 0;
2025 }
2026 
2027 void dump_srx_gen_table(Srx_gen_table *tp)
2028 {
2029  const char *v1;
2030  int scnfp_;
2031  int v8;
2032  int scp_;
2033  int scp_a;
2034  int nsegment;
2035  int b;
2036  int i;
2037  CreateSymbolConf *csyms;
2038  PheaderInfo *phip;
2039  SectConf *sctp;
2040  const char ***scnfpp;
2041  SegConf *scnfp;
2042  elf_section **scp;
2043  char segsig[32];
2044  const char **strp;
2045 
2046  if ( tp == NULL )
2047  {
2048  return;
2049  }
2050  switch ( tp->target )
2051  {
2052  case SRX_TARGET_IOP:
2053  v1 = "IOP";
2054  break;
2055  case SRX_TARGET_EE:
2056  v1 = "EE";
2057  break;
2058  default:
2059  v1 = "??";
2060  break;
2061  }
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 )
2065  {
2066  printf(" %2d:segment %s\n", v8, scnfp->name);
2067  printf(
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 )
2070  {
2071  for ( strp = scnfp->sect_name_patterns; *strp; strp += 1 )
2072  {
2073  printf("%s ", *strp);
2074  }
2075  printf("\n");
2076  }
2077  if ( scnfp->empty_section )
2078  {
2079  printf(" Auto add section: %s\n", scnfp->empty_section->name);
2080  }
2081  if ( scnfp->scp )
2082  {
2083  for ( scp = scnfp->scp; *scp; scp += 1 )
2084  {
2085  printf(" %p: %s\n", *scp, (*scp)->name);
2086  }
2087  }
2088  segsig[v8] = *scnfp->name;
2089  }
2090  printf("\nProgram header order\n");
2091  for ( scp_ = 0, phip = tp->program_header_order; phip->sw; scp_ += 1, phip += 1 )
2092  {
2093  switch ( phip->sw )
2094  {
2095  case SRX_PH_TYPE_MOD:
2096  printf(" %2d: section %s\n", scp_, phip->d.section_name);
2097  break;
2098  case SRX_PH_TYPE_TEXT:
2099  printf(" %2d: Segments ", scp_);
2100  for ( scnfpp = (const char ***)phip->d.section_name; *scnfpp; scnfpp += 1 )
2101  {
2102  printf("%s ", **scnfpp);
2103  }
2104  printf("\n");
2105  break;
2106  default:
2107  break;
2108  }
2109  }
2110  printf("\nRemove section list\n");
2111  for ( scp_a = 0, strp = tp->removesection_list; *strp; scp_a += 1, strp += 1 )
2112  {
2113  printf(" %2d: %s\n", scp_a, *strp);
2114  }
2115  printf("\nSection table order\n");
2116  for ( nsegment = 0, strp = tp->section_table_order; *strp; nsegment += 1, strp += 1 )
2117  {
2118  printf(" %2d: %s\n", nsegment, *strp);
2119  }
2120  printf("\nFile layout order\n");
2121  for ( b = 0, strp = tp->file_layout_order; *strp; b += 1, strp += 1 )
2122  {
2123  printf(" %2d: %s\n", b, *strp);
2124  }
2125  printf("\nmemory layout order\n");
2126  for ( i = 0, sctp = tp->section_list; sctp->sect_name_pattern; i += 1, sctp += 1 )
2127  {
2128  printf(" %2d: [", i);
2129  for ( scnfp_ = 0; scnfp_ < v8; scnfp_ += 1 )
2130  {
2131  printf("%c", ((sctp->flag & (1 << scnfp_)) != 0) ? (unsigned char)(segsig[scnfp_]) : 46);
2132  }
2133  printf("] %s", sctp->sect_name_pattern);
2134  if ( sctp->secttype )
2135  {
2136  printf("\t: Auto create type=%x flag=%x", sctp->secttype, sctp->sectflag);
2137  }
2138  printf("\n");
2139  }
2140  printf("\nReserved symbols\n");
2141  for ( csyms = tp->create_symbols; csyms->name; csyms += 1 )
2142  {
2143  printf(
2144  " %-8s: bind=%d, type=%d, shindex=0x%04x, seflag=%d, seg=%s, sect=%s\n",
2145  csyms->name,
2146  csyms->bind,
2147  csyms->type,
2148  csyms->shindex,
2149  csyms->seflag,
2150  csyms->segment ? csyms->segment->name : "-",
2151  csyms->sectname ?: "-");
2152  }
2153  printf("\n\n");
2154 }
_segconf
Definition: srxfixup_internal.h:311
_Elf32_EeMod
Definition: srxfixup_internal.h:104
s_info
Definition: xprintf.c:78
elf_rel
Definition: loadcore.c:71
_elffile
Definition: srxfixup_internal.h:285
_Elf32_RegInfo
Definition: srxfixup_internal.h:87
_elf_section
Definition: srxfixup_internal.h:253
Elf32_Phdr
Definition: elftypes.h:207
_sectconf
Definition: srxfixup_internal.h:331
_elf_proghead
Definition: srxfixup_internal.h:279
stdio.h
_Elf32_IopMod
Definition: srxfixup_internal.h:93
sect_org_data_
Definition: srxgen.c:17
_srx_gen_table
Definition: srxfixup_internal.h:348
_elf_file_slot
Definition: srxfixup_internal.h:296
_crtsymconf
Definition: srxfixup_internal.h:338
_pheader_info
Definition: srxfixup_internal.h:322
stdlib.h
_syment
Definition: srxfixup_internal.h:263