PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
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
17typedef struct sect_org_data_
18{
19 unsigned int org_addr;
20 unsigned int org_gp_value;
22
23static int setup_start_entry(elf_file *elf, const char *entrysym, elf_section *modinfo, int needoutput);
24static Elf_file_slot *search_order_slots(const char *ordstr, const elf_file *elf, Elf_file_slot *order);
25static void fixlocation_an_rel(elf_section *relsect, unsigned int startaddr);
26static void save_org_addrs(elf_file *elf);
27static elf_section *add_iopmod(elf_file *elf);
28static elf_section *add_eemod(elf_file *elf);
29static void modify_eemod(elf_file *elf, elf_section *eemod);
30static 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);
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);
53static CreateSymbolConf *is_reserve_symbol(Srx_gen_table *tp, const char *name);
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);
62static size_t iopmod_size(const Elf32_IopMod *modinfo);
63static size_t eemod_size(const Elf32_EeMod *modinfo);
64
65int 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
127static 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
176static 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
231int 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
324void 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
356SegConf *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
374static 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
504void 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
603static 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
634static 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
654static 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
674static 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
709static 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
740const char *bos_str = "_begin_of_section_";
741const char *eos_str = "_end_of_section_";
742static void define_special_section_symbols(elf_file *elf)
743{
744 char *sectname;
745 const elf_syment *sym;
746 elf_syment **syp;
747 elf_section *scp;
748 unsigned int entrise;
749 unsigned int i;
750 Srx_gen_table *tp;
751
752 tp = (Srx_gen_table *)(elf->optdata);
753 scp = search_section(elf, SHT_SYMTAB);
754 if ( scp == NULL )
755 {
756 return;
757 }
758 sectname = (char *)__builtin_alloca(((elf->shstrptr->shr.sh_size + 22) >> 2) << 2);
759 entrise = scp->shr.sh_size / scp->shr.sh_entsize;
760 syp = (elf_syment **)(scp->data);
761 for ( i = 1; i < entrise; i += 1 )
762 {
763 sym = syp[i];
764 if ( sym->bind == STB_GLOBAL && !sym->sym.st_shndx )
765 {
766 if ( !strncmp(bos_str, sym->name, strlen(bos_str)) )
767 {
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);
771 }
772 if ( !strncmp(eos_str, sym->name, strlen(eos_str)) )
773 {
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);
777 }
778 }
779 }
780}
781
782static 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
845static 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
878static 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
912static 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
971static 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
977static 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
989static 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
1007static 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
1025static 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
1071static 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
1082static 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
1153static 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
1191static 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
1284static 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
1302static 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
1346static 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
1368static const char * const SymbolType[] =
1369{
1370#define X(d) #d,
1371 XEACH_SymbolType_enum()
1372#undef X
1373};
1374// clang-format on
1375#endif
1376static 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
1496static 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
1539static 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
1556static 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
1579static 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
1655static 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
1985static size_t iopmod_size(const Elf32_IopMod *modinfo)
1986{
1987 return strlen(modinfo->modulename) + (sizeof(Elf32_IopMod) - 1);
1988}
1989
1990static size_t eemod_size(const Elf32_EeMod *modinfo)
1991{
1992 return strlen(modinfo->modulename) + (sizeof(Elf32_EeMod) - 1);
1993}
1994
1995int 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
2027void 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}