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_16:
416 data_1 = startaddr + (int16_t)*(uint32_t *)datal;
417 if ( (uint16_t)(data_1 >> 16) )
418 {
419 if ( (uint16_t)(data_1 >> 16) != 0xFFFF )
420 {
421 fprintf(stderr, "REFHALF data overflow\n");
422 exit(1);
423 }
424 }
425 *(uint32_t *)datal &= 0xFFFF0000;
426 *(uint32_t *)datal |= (uint16_t)data_1;
427 break;
428 case R_MIPS_32:
429 *(uint32_t *)datal += startaddr;
430 break;
431 case R_MIPS_26:
432 if ( rp->symptr && rp->symptr->bind != STB_LOCAL )
433 {
434 fprintf(stderr, "R_MIPS_26 Unexcepted bind\n");
435 exit(1);
436 }
437 data_2 = startaddr + ((rp->rel.r_offset & 0xF0000000) | (4 * (*(uint32_t *)datal & 0x3FFFFFF)));
438 *(uint32_t *)datal &= 0xFC000000;
439 *(uint32_t *)datal |= (16 * data_2) >> 6;
440 break;
441 case R_MIPS_HI16:
442 if ( i == entrise + 1 || rp[1].type != R_MIPS_LO16 || (rp->symptr && rp[1].symptr != rp->symptr) )
443 {
444 fprintf(stderr, "R_MIPS_HI16 without R_MIPS_LO16\n");
445 exit(1);
446 }
447 data_4 = startaddr + (int16_t)*(uint32_t *)&relsect->info->data[rp[1].rel.r_offset - relsect->info->shr.sh_addr]
448 + (*(uint32_t *)datal << 16);
449 *(uint32_t *)datal &= 0xFFFF0000;
450 *(uint32_t *)datal |= (uint16_t)(((data_4 >> 15) + 1) >> 1);
451 break;
452 case R_MIPS_LO16:
453 data_5 = startaddr + *(uint32_t *)datal;
454 *(uint32_t *)datal &= 0xFFFF0000;
455 *(uint32_t *)datal |= data_5;
456 break;
457 case R_MIPS_GPREL16:
458 fprintf(stderr, "Unexcepted R_MIPS_GPREL16\n");
459 exit(1);
460 return;
461 case R_MIPS_LITERAL:
462 fprintf(stderr, "Unexcepted R_MIPS_LITERAL\n");
463 exit(1);
464 return;
465 case R_MIPSSCE_MHI16:
466 if ( i == entrise + 1 || rp[1].type != R_MIPSSCE_ADDEND )
467 {
468 fprintf(stderr, "R_MIPSSCE_MHI16 without R_MIPSSCE_ADDEND\n");
469 exit(1);
470 }
471 data_3 = (uint16_t)((((startaddr + rp[1].rel.r_offset) >> 15) + 1) >> 1);
472 for ( daddr1 = 1; daddr1; datal += daddr1 )
473 {
474 daddr1 = *(uint16_t *)datal << 16 >> 14;
475 *(uint32_t *)datal &= 0xFFFF0000;
476 *(uint32_t *)datal |= data_3;
477 }
478 rp += 1;
479 i += 1;
480 break;
481 case R_MIPS_REL32:
482 case R_MIPS_GOT16:
483 case R_MIPS_PC16:
484 case R_MIPS_CALL16:
485 case R_MIPS_GPREL32:
486 case R_MIPS_GOTHI16:
487 case R_MIPS_GOTLO16:
488 case R_MIPS_CALLHI16:
489 case R_MIPS_CALLLO16:
490 fprintf(stderr, "unacceptable relocation type: 0x%x\n", rp->type);
491 exit(1);
492 return;
493 default:
494 fprintf(stderr, "unknown relocation type: 0x%x\n", rp->type);
495 exit(1);
496 return;
497 }
498 rp += 1;
499 }
500}
501
502void fixlocation_elf(elf_file *elf, unsigned int startaddr)
503{
504 unsigned int entrise;
505 int i;
506 unsigned int k;
507 int d;
508 int s;
509 int j;
510 elf_syment **syp;
511 elf_section *scp;
512 elf_section *modsect_1;
513 elf_section *modsect_2;
514
515 if ( elf->scp == NULL )
516 {
517 return;
518 }
519 d = 1;
520 for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
521 {
522 if ( elf->scp[s]->shr.sh_type == SHT_REL )
523 {
524 fixlocation_an_rel(elf->scp[s], startaddr);
525 }
526 else
527 {
528 elf->scp[d] = elf->scp[s];
529 d += 1;
530 }
531 }
532 elf->ehp->e_shnum = d;
533 elf->ehp->e_entry += startaddr;
534 modsect_1 = search_section(elf, SHT_SCE_IOPMOD);
535 if ( modsect_1 )
536 {
537 Elf32_IopMod *iopmodinfo;
538
539 iopmodinfo = (Elf32_IopMod *)modsect_1->data;
540 if ( iopmodinfo->moduleinfo != (Elf32_Word)(-1) )
541 {
542 iopmodinfo->moduleinfo += startaddr;
543 }
544 iopmodinfo->entry += startaddr;
545 iopmodinfo->gp_value += startaddr;
546 }
547 modsect_2 = search_section(elf, SHT_SCE_EEMOD);
548 if ( modsect_2 )
549 {
550 Elf32_EeMod *eemodinfo;
551
552 eemodinfo = (Elf32_EeMod *)modsect_2->data;
553 if ( eemodinfo->moduleinfo != (Elf32_Word)(-1) )
554 {
555 eemodinfo->moduleinfo += startaddr;
556 }
557 eemodinfo->entry += startaddr;
558 eemodinfo->gp_value += startaddr;
559 }
560 for ( i = 0; i < elf->ehp->e_phnum; i += 1 )
561 {
562 if ( elf->php[i].phdr.p_type == PT_LOAD )
563 {
564 elf->php[i].phdr.p_vaddr = startaddr;
565 elf->php[i].phdr.p_paddr = startaddr;
566 break;
567 }
568 }
569 for ( j = 1; j < elf->ehp->e_shnum; j += 1 )
570 {
571 switch ( elf->scp[j]->shr.sh_type )
572 {
573 case SHT_PROGBITS:
574 case SHT_NOBITS:
575 elf->scp[j]->shr.sh_addr += startaddr;
576 break;
577 default:
578 break;
579 }
580 }
581 scp = search_section(elf, SHT_SYMTAB);
582 if ( scp == NULL )
583 {
584 return;
585 }
586 entrise = scp->shr.sh_size / scp->shr.sh_entsize;
587 syp = (elf_syment **)scp->data;
588 for ( k = 1; k < entrise; k += 1 )
589 {
590 if ( syp[k]->sym.st_shndx == SHN_RADDR || (syp[k]->sym.st_shndx && syp[k]->sym.st_shndx <= 0xFEFF) )
591 {
592 syp[k]->sym.st_value += startaddr;
593 }
594 if ( syp[k]->sym.st_shndx == SHN_RADDR )
595 {
596 syp[k]->sym.st_shndx = -15;
597 }
598 }
599}
600
601static void save_org_addrs(elf_file *elf)
602{
603 Elf32_RegInfo *data;
604 const Elf32_RegInfo *reginfop;
605 elf_section *reginfosec;
606 int i;
607
608 reginfosec = search_section(elf, SHT_MIPS_REGINFO);
609 if ( reginfosec )
610 {
611 data = (Elf32_RegInfo *)reginfosec->data;
612 }
613 else
614 {
615 data = 0;
616 }
617 reginfop = data;
618 for ( i = 1; i < elf->ehp->e_shnum; i += 1 )
619 {
620 Sect_org_data *org;
621
622 org = (Sect_org_data *)calloc(1, sizeof(Sect_org_data));
623 org->org_addr = elf->scp[i]->shr.sh_addr;
624 if ( reginfop )
625 {
626 org->org_gp_value = reginfop->ri_gp_value;
627 }
628 elf->scp[i]->optdata = (void *)org;
629 }
630}
631
632static elf_section *add_iopmod(elf_file *elf)
633{
634 Elf32_IopMod *iopmodp;
635 elf_section *modsect;
636
637 modsect = (elf_section *)malloc(sizeof(elf_section));
638 memset(modsect, 0, sizeof(elf_section));
639 iopmodp = (Elf32_IopMod *)malloc(sizeof(Elf32_IopMod));
640 memset(iopmodp, 0, sizeof(Elf32_IopMod));
641 iopmodp->moduleinfo = -1;
642 modsect->name = strdup(".iopmod");
643 modsect->data = (uint8_t *)iopmodp;
644 modsect->shr.sh_type = SHT_SCE_IOPMOD;
645 modsect->shr.sh_size = iopmod_size(iopmodp);
646 modsect->shr.sh_addralign = 4;
647 modsect->shr.sh_entsize = 0;
648 add_section(elf, modsect);
649 return modsect;
650}
651
652static elf_section *add_eemod(elf_file *elf)
653{
654 Elf32_EeMod *eemodp;
655 elf_section *modsect;
656
657 modsect = (elf_section *)malloc(sizeof(elf_section));
658 memset(modsect, 0, sizeof(elf_section));
659 eemodp = (Elf32_EeMod *)malloc(sizeof(Elf32_EeMod));
660 memset(eemodp, 0, sizeof(Elf32_EeMod));
661 eemodp->moduleinfo = -1;
662 modsect->name = strdup(".eemod");
663 modsect->data = (uint8_t *)eemodp;
664 modsect->shr.sh_type = SHT_SCE_EEMOD;
665 modsect->shr.sh_size = eemod_size(eemodp);
666 modsect->shr.sh_addralign = 4;
667 modsect->shr.sh_entsize = 0;
668 add_section(elf, modsect);
669 return modsect;
670}
671
672static void modify_eemod(elf_file *elf, elf_section *eemod)
673{
674 elf_section *scp_1;
675 elf_section *scp_2;
676 Elf32_EeMod *moddata;
677
678 if ( eemod->shr.sh_type != SHT_SCE_EEMOD )
679 {
680 return;
681 }
682 moddata = (Elf32_EeMod *)eemod->data;
683 scp_1 = search_section_by_name(elf, ".erx.lib");
684 if ( scp_1 )
685 {
686 moddata->erx_lib_addr = scp_1->shr.sh_addr;
687 moddata->erx_lib_size = scp_1->shr.sh_size;
688 }
689 else
690 {
691 moddata->erx_lib_addr = -1;
692 moddata->erx_lib_size = 0;
693 }
694 scp_2 = search_section_by_name(elf, ".erx.stub");
695 if ( scp_2 )
696 {
697 moddata->erx_stub_addr = scp_2->shr.sh_addr;
698 moddata->erx_stub_size = scp_2->shr.sh_size;
699 }
700 else
701 {
702 moddata->erx_stub_addr = -1;
703 moddata->erx_stub_size = 0;
704 }
705}
706
707static void add_reserved_symbol_table(
708 Srx_gen_table *tp,
709 const char *name,
710 int bind,
711 int type,
712 SegConf *segment,
713 const char *sectname,
714 int shindex,
715 int base)
716{
717 CreateSymbolConf *newent_1;
718 CreateSymbolConf *newent_2;
719 int entries;
720
721 entries = 1;
722 for ( newent_1 = tp->create_symbols; newent_1->name; newent_1 += 1 )
723 {
724 entries += 1;
725 }
726 tp->create_symbols = (CreateSymbolConf *)realloc(tp->create_symbols, (entries + 1) * sizeof(CreateSymbolConf));
727 memset(&tp->create_symbols[entries], 0, sizeof(tp->create_symbols[entries]));
728 newent_2 = &tp->create_symbols[entries - 1];
729 newent_2->name = strdup(name);
730 newent_2->bind = bind;
731 newent_2->type = type;
732 newent_2->segment = segment;
733 newent_2->sectname = strdup(sectname);
734 newent_2->shindex = shindex;
735 newent_2->seflag = base;
736}
737
738const char *bos_str = "_begin_of_section_";
739const char *eos_str = "_end_of_section_";
740static void define_special_section_symbols(elf_file *elf)
741{
742 char *sectname;
743 const elf_syment *sym;
744 elf_syment **syp;
745 elf_section *scp;
746 unsigned int entrise;
747 unsigned int i;
748 Srx_gen_table *tp;
749
750 tp = (Srx_gen_table *)(elf->optdata);
751 scp = search_section(elf, SHT_SYMTAB);
752 if ( scp == NULL )
753 {
754 return;
755 }
756 sectname = (char *)__builtin_alloca(((elf->shstrptr->shr.sh_size + 22) >> 2) << 2);
757 entrise = scp->shr.sh_size / scp->shr.sh_entsize;
758 syp = (elf_syment **)(scp->data);
759 for ( i = 1; i < entrise; i += 1 )
760 {
761 sym = syp[i];
762 if ( sym->bind == STB_GLOBAL && !sym->sym.st_shndx )
763 {
764 if ( !strncmp(bos_str, sym->name, strlen(bos_str)) )
765 {
766 strcpy(sectname, ".");
767 strcat(sectname, &sym->name[strlen(bos_str)]);
768 add_reserved_symbol_table(tp, sym->name, 2, 1, 0, sectname, 0, 0);
769 }
770 if ( !strncmp(eos_str, sym->name, strlen(eos_str)) )
771 {
772 strcpy(sectname, ".");
773 strcat(sectname, &sym->name[strlen(eos_str)]);
774 add_reserved_symbol_table(tp, sym->name, 2, 1, 0, sectname, 65311, 1);
775 }
776 }
777 }
778}
779
780static void create_need_section(elf_file *elf)
781{
782 elf_section *scp;
783 unsigned int i;
784 CreateSymbolConf *csym;
785 Srx_gen_table *tp;
786
787 tp = (Srx_gen_table *)elf->optdata;
788 scp = search_section(elf, SHT_SYMTAB);
789 if ( scp == NULL )
790 {
791 return;
792 }
793 for ( i = 1; i < (scp->shr.sh_size / scp->shr.sh_entsize); i += 1 )
794 {
795 const elf_syment *syment;
796
797 syment = *(elf_syment **)&scp->data[i * sizeof(void *)];
798 if ( !syment->sym.st_shndx )
799 {
800 csym = is_reserve_symbol(tp, syment->name);
801 if ( csym )
802 {
803 if ( csym->segment )
804 {
805 elf_section *addscp_1;
806
807 addscp_1 = csym->segment->empty_section;
808 if ( addscp_1 )
809 {
810 if ( !search_section_by_name(elf, addscp_1->name) )
811 {
812 add_section(elf, addscp_1);
813 }
814 }
815 }
816 else if ( csym->sectname && !search_section_by_name(elf, csym->sectname) )
817 {
818 SectConf *odr;
819
820 for ( odr = tp->section_list; odr->sect_name_pattern; odr += 1 )
821 {
822 if ( !sect_name_match(odr->sect_name_pattern, csym->sectname) && odr->secttype && odr->sectflag )
823 {
824 elf_section *addscp_2;
825
826 addscp_2 = (elf_section *)calloc(1, sizeof(elf_section));
827 addscp_2->name = strdup(csym->sectname);
828 addscp_2->shr.sh_type = odr->secttype;
829 addscp_2->shr.sh_flags = odr->sectflag;
830 addscp_2->shr.sh_size = 0;
831 addscp_2->shr.sh_addralign = 4;
832 addscp_2->shr.sh_entsize = 0;
833 add_section(elf, addscp_2);
834 break;
835 }
836 }
837 }
838 }
839 }
840 }
841}
842
843static int sect_name_match(const char *pattern, const char *name)
844{
845 for ( ; *pattern && *name && *pattern != '*'; pattern += 1, name += 1 )
846 {
847 if ( *name > *pattern )
848 {
849 return -1;
850 }
851 if ( *name < *pattern )
852 {
853 return 1;
854 }
855 }
856 if ( !*pattern && !*name )
857 {
858 return 0;
859 }
860 if ( *pattern == '*' && !pattern[1] )
861 {
862 return 0;
863 }
864 if ( *pattern != '*' )
865 {
866 return strcmp(pattern, name);
867 }
868 pattern += 1;
869 if ( strlen(name) < strlen(pattern) )
870 {
871 return strcmp(pattern, name);
872 }
873 return strcmp(pattern, &name[strlen(name) - strlen(pattern)]);
874}
875
876static int reorder_section_table(elf_file *elf)
877{
878 const char **secorder;
879 int sections;
880 elf_section **scp;
881 int d;
882 int s;
883
884 sections = elf->ehp->e_shnum;
885 secorder = ((Srx_gen_table *)elf->optdata)->section_table_order;
886 scp = (elf_section **)calloc(sections + 1, sizeof(elf_section *));
887 memcpy(scp, elf->scp, sections * sizeof(elf_section *));
888 *elf->scp = *scp;
889 d = 1;
890 for ( ; *secorder; secorder += 1 )
891 {
892 for ( s = 1; s < sections; s += 1 )
893 {
894 if ( scp[s] )
895 {
896 if ( !sect_name_match(*secorder, scp[s]->name) )
897 {
898 elf->scp[d] = scp[s];
899 scp[s] = 0;
900 d += 1;
901 }
902 }
903 }
904 }
905 free(scp);
906 reorder_symtab(elf);
907 return 0;
908}
909
910static void create_phdr(elf_file *elf)
911{
912 const PheaderInfo *phip;
913 int i;
914
915 phip = ((Srx_gen_table *)(elf->optdata))->program_header_order;
916 for ( i = 0; phip[i].sw; i += 1 )
917 {
918 ;
919 }
920 elf->php = (i != 0) ? (elf_proghead *)malloc(i * sizeof(elf_proghead)) : NULL;
921 if ( elf->php != NULL )
922 {
923 memset(elf->php, 0, i * sizeof(elf_proghead));
924 }
925 elf->ehp->e_phentsize = sizeof(Elf32_Phdr);
926 elf->ehp->e_phnum = i;
927 if ( elf->php != NULL )
928 {
929 int j;
930
931 for ( j = 0; phip[j].sw; j += 1 )
932 {
933 switch ( phip[j].sw )
934 {
935 case SRX_PH_TYPE_MOD:
936 elf->php[j].phdr.p_flags = PF_R;
937 elf->php[j].phdr.p_align = 4;
938 if ( !strcmp(".iopmod", phip[j].d.section_name) )
939 {
940 elf->php[j].phdr.p_type = PT_SCE_IOPMOD;
941 elf->php[j].phdr.p_filesz = sizeof(Elf32_IopMod);
942 elf->php[j].scp = (elf_section **)calloc(2, sizeof(elf_section *));
943 *elf->php[j].scp = search_section(elf, SHT_SCE_IOPMOD);
944 }
945 else if ( !strcmp(".eemod", phip[j].d.section_name) )
946 {
947 elf->php[j].phdr.p_type = PT_SCE_EEMOD;
948 elf->php[j].phdr.p_filesz = sizeof(Elf32_EeMod);
949 elf->php[j].scp = (elf_section **)calloc(2, sizeof(elf_section *));
950 *elf->php[j].scp = search_section(elf, SHT_SCE_EEMOD);
951 }
952 else
953 {
954 fprintf(stderr, "Unsuport section '%s' for program header\n", phip[j].d.section_name);
955 }
956 break;
957 case SRX_PH_TYPE_TEXT:
958 elf->php[j].phdr.p_type = PT_LOAD;
959 elf->php[j].phdr.p_flags = PF_X | PF_W | PF_R;
960 elf->php[j].phdr.p_align = 16;
961 break;
962 default:
963 break;
964 }
965 }
966 }
967}
968
969static void check_change_bit(unsigned int oldbit, unsigned int newbit, unsigned int *up, unsigned int *down)
970{
971 *up = ~oldbit & newbit & (newbit ^ oldbit);
972 *down = ~newbit & oldbit & (newbit ^ oldbit);
973}
974
975static void segment_start_setup(SegConf *seglist, unsigned int bitid, const unsigned int *moffset)
976{
977 for ( ; seglist->name; seglist += 1 )
978 {
979 if ( (seglist->bitid & bitid) != 0 )
980 {
981 seglist->addr = *moffset;
982 seglist->size = 0;
983 }
984 }
985}
986
987static void add_section_to_segment(SegConf *seglist, elf_section *scp, unsigned int bitid)
988{
989 for ( ; seglist->name; seglist += 1 )
990 {
991 if ( (seglist->bitid & bitid) != 0 )
992 {
993 if ( !seglist->nsect )
994 {
995 seglist->addr = scp->shr.sh_addr;
996 }
997 seglist->nsect += 1;
998 seglist->scp = (elf_section **)realloc(seglist->scp, (seglist->nsect + 1) * sizeof(elf_section *));
999 seglist->scp[seglist->nsect - 1] = scp;
1000 seglist->scp[seglist->nsect] = 0;
1001 }
1002 }
1003}
1004
1005static void segment_end_setup(SegConf *seglist, unsigned int bitid, unsigned int *moffset, int ee)
1006{
1007 for ( ; seglist->name; seglist += 1 )
1008 {
1009 if ( (seglist->bitid & bitid) != 0 )
1010 {
1011 if ( ee )
1012 {
1013 if ( !strcmp(seglist->name, "TEXT") )
1014 {
1015 *moffset += 32;
1016 }
1017 }
1018 seglist->size = *moffset - seglist->addr;
1019 }
1020 }
1021}
1022
1023static void update_modinfo(elf_file *elf)
1024{
1025 Srx_gen_table *tp;
1026 const SegConf *seginfo;
1027 const SegConf *seginfo_4;
1028 const SegConf *seginfo_8;
1029 const SegConf *seginfo_12;
1030 elf_section *scp_1;
1031 elf_section *scp_2;
1032
1033 tp = (Srx_gen_table *)elf->optdata;
1034 seginfo = lookup_segment(tp, "TEXT", 1);
1035 seginfo_4 = lookup_segment(tp, "DATA", 1);
1036 seginfo_8 = lookup_segment(tp, "BSS", 1);
1037 seginfo_12 = lookup_segment(tp, "GLOBALDATA", 1);
1038 if ( !seginfo || !seginfo_4 || !seginfo_8 || !seginfo_12 )
1039 {
1040 fprintf(stderr, "TEXT,DATA,BSS,GLOBALDATA segment missing abort");
1041 exit(1);
1042 }
1043 scp_1 = search_section(elf, SHT_SCE_IOPMOD);
1044 if ( scp_1 )
1045 {
1046 Elf32_IopMod *imp;
1047
1048 scp_1->shr.sh_addr = 0;
1049 imp = (Elf32_IopMod *)scp_1->data;
1050 imp->text_size = seginfo_4->addr - seginfo->addr;
1051 imp->data_size = seginfo_8->addr - seginfo_4->addr;
1052 imp->bss_size = seginfo_8->size;
1053 imp->gp_value = seginfo_12->addr + 0x7FF0;
1054 }
1055 scp_2 = search_section(elf, SHT_SCE_EEMOD);
1056 if ( scp_2 )
1057 {
1058 Elf32_EeMod *emp;
1059
1060 scp_2->shr.sh_addr = 0;
1061 emp = (Elf32_EeMod *)scp_2->data;
1062 emp->text_size = seginfo_4->addr - seginfo->addr;
1063 emp->data_size = seginfo_8->addr - seginfo_4->addr;
1064 emp->bss_size = seginfo_8->size;
1065 emp->gp_value = seginfo_12->addr + 0x7FF0;
1066 }
1067}
1068
1069static void update_mdebug(elf_file *elf)
1070{
1071 elf_section *scp;
1072
1073 scp = search_section(elf, SHT_MIPS_DEBUG);
1074 if ( scp )
1075 {
1076 scp->shr.sh_addr = 0;
1077 }
1078}
1079
1080static void update_programheader(elf_file *elf)
1081{
1082 Srx_gen_table *tp;
1083 SegConf **segp;
1084 elf_section **scp;
1085 PheaderInfo *phip;
1086 unsigned int minsegalign;
1087 unsigned int align;
1088 int nsect_1;
1089 int nsect_2;
1090 int nseg_1;
1091 int nseg_2;
1092 int s;
1093 int n;
1094
1095 tp = (Srx_gen_table *)elf->optdata;
1096 phip = tp->program_header_order;
1097 switch ( tp->target )
1098 {
1099 case SRX_TARGET_IOP:
1100 minsegalign = 16;
1101 break;
1102 case SRX_TARGET_EE:
1103 minsegalign = 128;
1104 break;
1105 default:
1106 fprintf(stderr, "Internal error: target unknown\n");
1107 exit(1);
1108 return;
1109 }
1110 for ( n = 0; phip[n].sw; n += 1 )
1111 {
1112 if ( phip[n].sw == SRX_PH_TYPE_TEXT )
1113 {
1114 segp = phip[n].d.segment_list;
1115 if ( segp )
1116 {
1117 elf->php[n].phdr.p_vaddr = (*segp)->addr;
1118 align = minsegalign;
1119 for ( nsect_1 = 0, nseg_1 = 0; segp[nseg_1]; nsect_1 += segp[nseg_1]->nsect, nseg_1 += 1 )
1120 {
1121 ;
1122 }
1123 scp = (elf_section **)calloc(nsect_1 + 1, sizeof(elf_section *));
1124 elf->php[n].scp = scp;
1125 for ( nsect_2 = 0, nseg_2 = 0; segp[nseg_2]; nsect_2 += segp[nseg_2]->nsect, nseg_2 += 1 )
1126 {
1127 memcpy(&scp[nsect_2], segp[nseg_2]->scp, segp[nseg_2]->nsect * sizeof(elf_section *));
1128 }
1129 for ( s = 0; s < nsect_2 && scp[s]->shr.sh_type == SHT_PROGBITS; s += 1 )
1130 {
1131 if ( scp[s]->shr.sh_addralign > align )
1132 {
1133 align = scp[s]->shr.sh_addralign;
1134 }
1135 }
1136 elf->php[n].phdr.p_filesz = scp[s - 1]->shr.sh_size + scp[s - 1]->shr.sh_addr - (*scp)->shr.sh_addr;
1137 elf->php[n].phdr.p_memsz = scp[nsect_2 - 1]->shr.sh_size + scp[nsect_2 - 1]->shr.sh_addr - (*scp)->shr.sh_addr;
1138 for ( ; s < nsect_2; s += 1 )
1139 {
1140 if ( scp[s]->shr.sh_addralign > align )
1141 {
1142 align = scp[s]->shr.sh_addralign;
1143 }
1144 }
1145 elf->php[n].phdr.p_align = align;
1146 }
1147 }
1148 }
1149}
1150
1151static void remove_unuse_section(elf_file *elf)
1152{
1153 const char **sectnames;
1154 int sections;
1155 elf_section **dscp;
1156 int d;
1157 int i;
1158 int j;
1159
1160 sections = elf->ehp->e_shnum;
1161 sectnames = ((Srx_gen_table *)(elf->optdata))->removesection_list;
1162 dscp = (elf_section **)calloc(sections + 1, sizeof(elf_section *));
1163 memset(dscp, 0, sections * sizeof(elf_section *));
1164 d = 0;
1165 for ( ; *sectnames; sectnames += 1 )
1166 {
1167 for ( i = 1; i < sections; i += 1 )
1168 {
1169 if ( elf->scp[i] )
1170 {
1171 if ( !sect_name_match(*sectnames, elf->scp[i]->name) )
1172 {
1173 dscp[d] = elf->scp[i];
1174 d += 1;
1175 }
1176 }
1177 }
1178 }
1179 for ( j = 0; j < sections; j += 1 )
1180 {
1181 if ( dscp[j] )
1182 {
1183 remove_section_by_name(elf, dscp[j]->name);
1184 }
1185 }
1186 free(dscp);
1187}
1188
1189static int layout_srx_memory(elf_file *elf)
1190{
1191 int s_3;
1192 elf_section **scp;
1193 SectConf *odr;
1194 Srx_gen_table *tp;
1195 int error;
1196 int is_ee;
1197 int sections;
1198 int s_1;
1199 int s_2;
1200 unsigned int downdelta;
1201 unsigned int updelta;
1202 unsigned int oldbitid;
1203 unsigned int moffset;
1204
1205 tp = (Srx_gen_table *)elf->optdata;
1206 moffset = 0;
1207 oldbitid = 0;
1208 error = 0;
1209 is_ee = tp->target == SRX_TARGET_EE;
1210 if ( !elf->scp )
1211 {
1212 return 1;
1213 }
1214 sections = elf->ehp->e_shnum;
1215 scp = (elf_section **)calloc(sections + 1, sizeof(elf_section *));
1216 memcpy(scp, elf->scp, sections * sizeof(elf_section *));
1217 for ( odr = tp->section_list; odr->sect_name_pattern; odr += 1 )
1218 {
1219 check_change_bit(oldbitid, odr->flag, &updelta, &downdelta);
1220 if ( updelta )
1221 {
1222 segment_start_setup(tp->segment_list, updelta, &moffset);
1223 }
1224 for ( s_1 = 1; s_1 < sections; s_1 += 1 )
1225 {
1226 if (
1227 scp[s_1] && !sect_name_match(odr->sect_name_pattern, scp[s_1]->name)
1228 && (scp[s_1]->shr.sh_flags & SHF_ALLOC) != 0 )
1229 {
1230 moffset = adjust_align(moffset, scp[s_1]->shr.sh_addralign);
1231 scp[s_1]->shr.sh_addr = moffset;
1232 moffset += scp[s_1]->shr.sh_size;
1233 add_section_to_segment(tp->segment_list, scp[s_1], odr->flag);
1234 scp[s_1] = 0;
1235 }
1236 }
1237 oldbitid = odr->flag;
1238 check_change_bit(oldbitid, odr[1].flag, &updelta, &downdelta);
1239 if ( downdelta )
1240 {
1241 segment_end_setup(tp->segment_list, downdelta, &moffset, is_ee);
1242 }
1243 }
1244 for ( s_2 = 1; s_2 < sections; s_2 += 1 )
1245 {
1246 if ( scp[s_2] && (scp[s_2]->shr.sh_flags & SHF_ALLOC) != 0 )
1247 {
1248 for (
1249 s_3 = 1;
1250 s_3 < sections
1251 && (!scp[s_3] || (scp[s_3]->shr.sh_type != SHT_RELA && scp[s_3]->shr.sh_type != SHT_REL) || scp[s_2] != scp[s_3]->info);
1252 s_3 += 1 )
1253 {
1254 ;
1255 }
1256 if ( sections > s_3 )
1257 {
1258 fprintf(
1259 stderr,
1260 "Error: section '%s' needs allocation and has relocation data but not in program segment\n",
1261 scp[s_2]->name);
1262 scp[s_3] = 0;
1263 error += 1;
1264 }
1265 else
1266 {
1267 fprintf(stderr, "Warning: section '%s' needs allocation but not in program segment\n", scp[s_2]->name);
1268 scp[s_2] = 0;
1269 }
1270 }
1271 }
1272 free(scp);
1273 if ( !error )
1274 {
1275 update_modinfo(elf);
1276 update_mdebug(elf);
1277 update_programheader(elf);
1278 }
1279 return error;
1280}
1281
1282static CreateSymbolConf *is_reserve_symbol(Srx_gen_table *tp, const char *name)
1283{
1284 CreateSymbolConf *csyms;
1285
1286 if ( !name )
1287 {
1288 return 0;
1289 }
1290 for ( csyms = tp->create_symbols; csyms->name; csyms += 1 )
1291 {
1292 if ( !strcmp(csyms->name, name) )
1293 {
1294 return csyms;
1295 }
1296 }
1297 return 0;
1298}
1299
1300static int check_undef_symboles_an_reloc(elf_section *relsect)
1301{
1302 elf_syment **symp;
1303 elf_rel *rp;
1304 int undefcount;
1305 unsigned int entrise;
1306 unsigned int i;
1307
1308 entrise = relsect->shr.sh_size / relsect->shr.sh_entsize;
1309 rp = (elf_rel *)relsect->data;
1310 symp = (elf_syment **)relsect->link->data;
1311 undefcount = 0;
1312 for ( i = 0; i < entrise; i += 1 )
1313 {
1314 if ( rp->symptr && *symp != rp->symptr )
1315 {
1316 if ( rp->symptr->sym.st_shndx )
1317 {
1318 if (
1319 rp->symptr->sym.st_shndx > 0xFEFF && rp->symptr->sym.st_shndx != SHN_ABS
1320 && rp->symptr->sym.st_shndx != SHN_RADDR )
1321 {
1322 if ( rp->symptr->sym.st_shndx == SHN_COMMON )
1323 {
1324 fprintf(stderr, " unallocated variable `%s'\n", rp->symptr->name);
1325 }
1326 else
1327 {
1328 fprintf(stderr, " `%s' unknown symbol type %x\n", rp->symptr->name, rp->symptr->sym.st_shndx);
1329 }
1330 undefcount += 1;
1331 }
1332 }
1333 else if ( rp->symptr->bind != STB_WEAK )
1334 {
1335 fprintf(stderr, " undefined reference to `%s'\n", rp->symptr->name);
1336 undefcount += 1;
1337 }
1338 }
1339 rp += 1;
1340 }
1341 return undefcount;
1342}
1343
1344static int check_undef_symboles(elf_file *elf)
1345{
1346 int err;
1347 int s;
1348
1349 if ( !elf->scp )
1350 {
1351 return 0;
1352 }
1353 err = 0;
1354 for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
1355 {
1356 if ( elf->scp[s]->shr.sh_type == SHT_REL )
1357 {
1358 err += check_undef_symboles_an_reloc(elf->scp[s]);
1359 }
1360 }
1361 return err;
1362}
1363
1364#if 0
1365// clang-format off
1366static const char * const SymbolType[] =
1367{
1368#define X(d) #d,
1369 XEACH_SymbolType_enum()
1370#undef X
1371};
1372// clang-format on
1373#endif
1374static int create_reserved_symbols(elf_file *elf)
1375{
1376 int csyms_;
1377 unsigned int sh_size;
1378 unsigned int sh_addr;
1379 elf_section *scp;
1380 CreateSymbolConf *csyms;
1381 Srx_gen_table *tp;
1382
1383 tp = (Srx_gen_table *)elf->optdata;
1384 csyms_ = 0;
1385 if ( !search_section(elf, SHT_SYMTAB) )
1386 {
1387 return 1;
1388 }
1389 for ( csyms = tp->create_symbols; csyms->name; csyms += 1 )
1390 {
1391 elf_syment *sym;
1392
1393 sym = search_global_symbol(csyms->name, elf);
1394 if ( !sym
1395 && (csyms->shindex > 0xFEFF
1396 || (csyms->segment && csyms->segment->scp)
1397 || (!csyms->segment && csyms->sectname && search_section_by_name(elf, csyms->sectname))) )
1398 {
1399 sym = add_symbol(elf, csyms->name, csyms->bind, 0, 0, 0, 0);
1400 }
1401 if ( sym )
1402 {
1403 sh_size = 0;
1404 sh_addr = 0;
1405 scp = 0;
1406 if ( csyms->segment )
1407 {
1408 sh_addr = csyms->segment->addr;
1409 sh_size = csyms->segment->size;
1410 if ( csyms->shindex <= 0xFEFF )
1411 {
1412 scp = *csyms->segment->scp;
1413 }
1414 }
1415 else if ( csyms->sectname != NULL )
1416 {
1417 scp = search_section_by_name(elf, csyms->sectname);
1418 if ( scp )
1419 {
1420 sh_addr = scp->shr.sh_addr;
1421 sh_size = scp->shr.sh_size;
1422 }
1423 }
1424 if ( csyms->segment || scp )
1425 {
1426 // FIXME: disable this check because it trips on _gp, _end symbols
1427#if 0
1428 if ( sym->sym.st_shndx )
1429 {
1430 fprintf(stderr, "Unexcepted Symbol \"%s\":%s \n", sym->name, SymbolType[sym->type]);
1431 csyms_ += 1;
1432 }
1433 else
1434#endif
1435 {
1436 sym->bind = csyms->bind;
1437 if ( !sym->type )
1438 {
1439 sym->type = csyms->type;
1440 }
1441 sym->sym.st_info = ((csyms->bind & 0xFF) << 4) + (csyms->type & 0xF);
1442 if ( csyms->shindex > 0xFEFF )
1443 {
1444 sym->sym.st_shndx = csyms->shindex;
1445 sym->shptr = 0;
1446 switch ( csyms->seflag )
1447 {
1448 case 0:
1449 sym->sym.st_value = sh_addr;
1450 break;
1451 case 1:
1452 sym->sym.st_value = sh_size + sh_addr;
1453 break;
1454 case 2:
1455 sym->sym.st_value = sh_addr + 0x7FF0;
1456 break;
1457 default:
1458 break;
1459 }
1460 }
1461 else
1462 {
1463 sym->sym.st_shndx = 1;
1464 sym->shptr = scp;
1465 switch ( csyms->seflag )
1466 {
1467 case 0:
1468 sym->sym.st_value = 0;
1469 break;
1470 case 1:
1471 sym->sym.st_value = sh_size;
1472 break;
1473 default:
1474 break;
1475 }
1476 }
1477 }
1478 continue;
1479 }
1480 if ( csyms->bind == STB_WEAK && (sym->bind == STB_GLOBAL || sym->bind == STB_WEAK) && !sym->sym.st_shndx )
1481 {
1482 if ( !sym->type )
1483 {
1484 sym->type = csyms->type;
1485 }
1486 sym->bind = csyms->bind;
1487 sym->sym.st_info = ((csyms->bind & 0xFF) << 4) + (csyms->type & 0xF);
1488 }
1489 }
1490 }
1491 return csyms_;
1492}
1493
1494static void symbol_value_update(elf_file *elf)
1495{
1496 unsigned int entrise;
1497 unsigned int i;
1498 elf_syment **syp;
1499 elf_section *scp;
1500 int target;
1501
1502 target = ((Srx_gen_table *)(elf->optdata))->target;
1503 if ( elf->ehp->e_type != ET_REL )
1504 {
1505 return;
1506 }
1507 switch ( target )
1508 {
1509 case SRX_TARGET_IOP:
1510 elf->ehp->e_type = ET_SCE_IOPRELEXEC;
1511 break;
1512 case SRX_TARGET_EE:
1513 elf->ehp->e_type = ET_SCE_EERELEXEC2;
1514 break;
1515 default:
1516 break;
1517 }
1518 scp = search_section(elf, SHT_SYMTAB);
1519 if ( scp == NULL )
1520 {
1521 return;
1522 }
1523 entrise = scp->shr.sh_size / scp->shr.sh_entsize;
1524 syp = (elf_syment **)scp->data;
1525 for ( i = 1; i < entrise; i += 1 )
1526 {
1527 if ( syp[i]->sym.st_shndx )
1528 {
1529 if ( syp[i]->sym.st_shndx <= 0xFEFF )
1530 {
1531 syp[i]->sym.st_value += syp[i]->shptr->shr.sh_addr;
1532 }
1533 }
1534 }
1535}
1536
1537static void rebuild_relocation(elf_file *elf, unsigned int gpvalue)
1538{
1539 int s;
1540
1541 if ( elf->scp == NULL )
1542 {
1543 return;
1544 }
1545 for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
1546 {
1547 if ( elf->scp[s]->shr.sh_type == SHT_REL )
1548 {
1549 rebuild_an_relocation(elf->scp[s], gpvalue, ((Srx_gen_table *)(elf->optdata))->target);
1550 }
1551 }
1552}
1553
1554static int check_irx12(elf_file *elf, int cause_irx1)
1555{
1556 int s;
1557
1558 if ( elf->ehp->e_type != ET_SCE_IOPRELEXEC )
1559 {
1560 return 0;
1561 }
1562 for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
1563 {
1564 if ( elf->scp[s]->shr.sh_type == SHT_REL && relocation_is_version2(elf->scp[s]) )
1565 {
1566 if ( cause_irx1 )
1567 {
1568 fprintf(stderr, "R_MIPS_LO16 without R_MIPS_HI16\n");
1569 return 1;
1570 }
1571 elf->ehp->e_type = ET_SCE_IOPRELEXEC2;
1572 }
1573 }
1574 return 0;
1575}
1576
1577static void setup_module_info(elf_file *elf, elf_section *modsect, const char *modulesymbol)
1578{
1579 unsigned int *section_data;
1580 int i;
1581 char *buf;
1582 const char *name;
1583 unsigned int woff;
1584 size_t buflen;
1585 const unsigned int *modnamep;
1586 unsigned int *modidatap;
1587 unsigned int modiaddr;
1588 const elf_syment *syp;
1589
1590 syp = search_global_symbol(modulesymbol, elf);
1591 if ( is_defined_symbol(syp) == 0 )
1592 {
1593 return;
1594 }
1595 modiaddr = get_symbol_value(syp, elf);
1596 modidatap = get_section_data(elf, modiaddr);
1597 section_data = get_section_data(elf, *modidatap);
1598 woff = (uintptr_t)section_data & 3;
1599 modnamep = (unsigned int *)((char *)section_data - woff);
1600 buflen = (strlen((const char *)section_data - woff + 4) + 15) & 0xFFFFFFFC;
1601 buf = (char *)malloc(buflen);
1602 memcpy(buf, modnamep, buflen);
1603 swapmemory(buf, "l", buflen >> 2);
1604 name = &buf[woff];
1605 switch ( modsect->shr.sh_type )
1606 {
1607 case SHT_SCE_IOPMOD:
1608 {
1609 Elf32_IopMod *iopmodp_1;
1610 Elf32_IopMod *iopmodp_2;
1611
1612 iopmodp_1 = (Elf32_IopMod *)modsect->data;
1613 iopmodp_1->moduleinfo = modiaddr;
1614 iopmodp_1->moduleversion = *((uint16_t *)modidatap + 2);
1615 // HACK FIXME: Don't place the name in the header
1616 name = "";
1617 iopmodp_2 = (Elf32_IopMod *)realloc(iopmodp_1, strlen(name) + sizeof(Elf32_IopMod));
1618 strcpy(iopmodp_2->modulename, name);
1619 modsect->data = (uint8_t *)iopmodp_2;
1620 modsect->shr.sh_size = iopmod_size(iopmodp_2);
1621 break;
1622 }
1623 case SHT_SCE_EEMOD:
1624 {
1625 Elf32_EeMod *eemodp_1;
1626 Elf32_EeMod *eemodp_2;
1627 eemodp_1 = (Elf32_EeMod *)modsect->data;
1628 eemodp_1->moduleinfo = modiaddr;
1629 eemodp_1->moduleversion = *((uint16_t *)modidatap + 2);
1630 eemodp_2 = (Elf32_EeMod *)realloc(eemodp_1, strlen(name) + sizeof(Elf32_EeMod));
1631 strcpy(eemodp_2->modulename, name);
1632 modsect->data = (uint8_t *)eemodp_2;
1633 modsect->shr.sh_size = eemod_size(eemodp_2);
1634 break;
1635 }
1636 default:
1637 break;
1638 }
1639 free(buf);
1640 if ( elf->php == NULL )
1641 {
1642 return;
1643 }
1644 for ( i = 0; i < elf->ehp->e_phnum; i += 1 )
1645 {
1646 if ( elf->php[i].scp && (modsect == *elf->php[i].scp) )
1647 {
1648 elf->php[i].phdr.p_filesz = modsect->shr.sh_size;
1649 }
1650 }
1651}
1652
1653static void rebuild_an_relocation(elf_section *relsect, unsigned int gpvalue, int target)
1654{
1655 elf_rel *newtab;
1656 void *daddr_2;
1657 void *daddr_3;
1658 uint32_t data32_1;
1659 int data32_2;
1660 uint32_t datah;
1661 uint32_t data_1;
1662 uint32_t data_2;
1663 uint32_t data_33;
1664 uint16_t data_4;
1665 unsigned int data_5;
1666 unsigned int data_6;
1667 uint32_t data_7;
1668 uint32_t step;
1669 elf_syment **symp;
1670 elf_rel *rp;
1671 int rmflag;
1672 unsigned int entrise;
1673 unsigned int j_1;
1674 unsigned int j_2;
1675 unsigned int j_3;
1676 unsigned int i_1;
1677
1678 entrise = relsect->shr.sh_size / relsect->shr.sh_entsize;
1679 rp = (elf_rel *)relsect->data;
1680 symp = (elf_syment **)relsect->link->data;
1681 rmflag = 0;
1682 for ( i_1 = 0; i_1 < entrise; )
1683 {
1684 int v4;
1685 uint32_t symvalue;
1686 void *daddr_1;
1687 unsigned int next;
1688
1689 if ( relsect->info->shr.sh_size <= rp->rel.r_offset )
1690 {
1691 fprintf(
1692 stderr,
1693 "Panic !! relocation #%u offset=0x%x overflow (section size=0x%x)\n",
1694 i_1,
1695 rp->rel.r_offset,
1696 relsect->info->shr.sh_size);
1697 exit(1);
1698 }
1699 next = 1;
1700 daddr_1 = (void *)&relsect->info->data[rp->rel.r_offset];
1701 symvalue = 0;
1702 if ( rp->symptr )
1703 {
1704 if ( rp->symptr->sym.st_shndx )
1705 {
1706 symvalue = rp->symptr->sym.st_value;
1707 }
1708 }
1709 v4 = 0;
1710 if (
1711 !rp->symptr || (rp->symptr->sym.st_shndx && rp->symptr->sym.st_shndx <= 0xFEFF)
1712 || rp->symptr->sym.st_shndx == SHN_RADDR )
1713 {
1714 v4 = 1;
1715 }
1716 switch ( rp->type )
1717 {
1718 case R_MIPS_NONE:
1719 rmflag = 1;
1720 break;
1721 case R_MIPS_16:
1722 data_1 = symvalue + (int16_t)*(uint32_t *)daddr_1;
1723 if ( (uint16_t)(data_1 >> 16) && (uint16_t)(data_1 >> 16) != 0xFFFF )
1724 {
1725 fprintf(stderr, "REFHALF data overflow\n");
1726 exit(1);
1727 }
1728 *(uint32_t *)daddr_1 &= 0xFFFF0000;
1729 *(uint32_t *)daddr_1 |= (uint16_t)data_1;
1730 if ( !v4 )
1731 {
1732 rp->type = R_MIPS_NONE;
1733 rmflag = 1;
1734 }
1735 break;
1736 case R_MIPS_32:
1737 *(uint32_t *)daddr_1 += symvalue;
1738 if ( !v4 )
1739 {
1740 rp->type = R_MIPS_NONE;
1741 rmflag = 1;
1742 }
1743 break;
1744 case R_MIPS_26:
1745 data_2 = *(uint32_t *)daddr_1;
1746 if ( rp->symptr && rp->symptr->bind != STB_LOCAL )
1747 {
1748 data_33 = data_2 << 6 >> 4;
1749 }
1750 else
1751 {
1752 data_33 = ((relsect->info->shr.sh_addr + rp->rel.r_offset) & 0xF0000000) | (4 * (data_2 & 0x3FFFFFF));
1753 }
1754 *(uint32_t *)daddr_1 &= 0xFC000000;
1755 *(uint32_t *)daddr_1 |= (16 * (symvalue + data_33)) >> 6;
1756 if ( !v4 )
1757 {
1758 rp->type = R_MIPS_NONE;
1759 rmflag = 1;
1760 }
1761 break;
1762 case R_MIPS_HI16:
1763 datah = *(uint32_t *)daddr_1 << 16;
1764 for ( j_1 = i_1 + 1; j_1 < entrise && rp[next].type == R_MIPS_HI16; j_1 += 1 )
1765 {
1766 if ( rp->symptr && rp[next].symptr != rp->symptr )
1767 {
1768 fprintf(stderr, "R_MIPS_HI16 without R_MIPS_LO16\n");
1769 exit(1);
1770 }
1771 if ( relsect->info->shr.sh_size <= rp[next].rel.r_offset )
1772 {
1773 fprintf(
1774 stderr,
1775 "Panic !! relocation #%u offset=0x%x overflow (section size=0x%x)\n",
1776 i_1 + next,
1777 rp[next].rel.r_offset,
1778 relsect->info->shr.sh_size);
1779 exit(1);
1780 }
1781 daddr_1 = (void *)&relsect->info->data[rp[next].rel.r_offset];
1782 if ( datah != *(uint32_t *)daddr_1 << 16 )
1783 {
1784 fprintf(stderr, "R_MIPS_HI16s not same offsets\n");
1785 exit(1);
1786 }
1787 next += 1;
1788 }
1789 if ( j_1 == entrise + 1 || rp[next].type != R_MIPS_LO16 || (rp->symptr && rp[next].symptr != rp->symptr) )
1790 {
1791 fprintf(stderr, "R_MIPS_HI16 without R_MIPS_LO16\n");
1792 exit(1);
1793 }
1794 data32_1 = symvalue + (int16_t)*(uint32_t *)&relsect->info->data[rp[next].rel.r_offset] + datah;
1795 if ( next == 1 )
1796 {
1797 *(uint32_t *)daddr_1 &= 0xFFFF0000;
1798 *(uint32_t *)daddr_1 |= (uint16_t)(((data32_1 >> 15) + 1) >> 1);
1799 if ( !v4 )
1800 {
1801 rp->type = R_MIPS_NONE;
1802 rmflag = 1;
1803 }
1804 }
1805 else if ( v4 )
1806 {
1807 for ( j_2 = 0; j_2 < next; j_2 += 1 )
1808 {
1809 daddr_2 = (void *)&relsect->info->data[rp[j_2].rel.r_offset];
1810 *(uint32_t *)daddr_2 &= 0xFFFF0000;
1811 if ( j_2 < next - 1 )
1812 {
1813 step = rp[j_2 + 1].rel.r_offset - rp[j_2].rel.r_offset;
1814 if ( step >> 18 && step >> 18 != 0x3FFF )
1815 {
1816 fprintf(stderr, "R_MIPS_HI16s too long distance\n");
1817 exit(1);
1818 }
1819 *(uint32_t *)daddr_2 |= (uint16_t)(step >> 2);
1820 }
1821 rp[j_2].type = R_MIPS_NONE;
1822 if ( rp[j_2].symptr )
1823 {
1824 rp[j_2].symptr->refcount -= 1;
1825 rp[j_2].symptr = *symp;
1826 }
1827 }
1828 rp->type = R_MIPSSCE_MHI16;
1829 rp->rel.r_offset += relsect->info->shr.sh_addr;
1830 rp[1].type = R_MIPSSCE_ADDEND;
1831 rp[1].rel.r_offset = data32_1;
1832 rmflag = 1;
1833 rp += next;
1834 i_1 += next;
1835 next = 0;
1836 }
1837 else
1838 {
1839 data32_2 = (uint16_t)(((data32_1 >> 15) + 1) >> 1);
1840 for ( j_3 = 0; j_3 < next; j_3 += 1 )
1841 {
1842 daddr_3 = (void *)&relsect->info->data[rp[j_3].rel.r_offset];
1843 *(uint32_t *)daddr_3 &= 0xFFFF0000;
1844 *(uint32_t *)daddr_3 |= data32_2;
1845 rp[j_3].type = R_MIPS_NONE;
1846 }
1847 rmflag = 1;
1848 }
1849 break;
1850 case R_MIPS_LO16:
1851 data_4 = symvalue + *(uint32_t *)daddr_1;
1852 *(uint32_t *)daddr_1 &= 0xFFFF0000;
1853 *(uint32_t *)daddr_1 |= data_4;
1854 if ( !v4 )
1855 {
1856 rp->type = R_MIPS_NONE;
1857 rmflag = 1;
1858 }
1859 break;
1860 case R_MIPS_GPREL16:
1861 data_5 = (int16_t)*(uint32_t *)daddr_1;
1862 if ( rp->symptr )
1863 {
1864 if ( rp->symptr->type == STT_SECTION )
1865 {
1866 data_5 += ((Sect_org_data *)(rp->symptr->shptr->optdata))->org_gp_value + symvalue
1867 - ((Sect_org_data *)(rp->symptr->shptr->optdata))->org_addr - gpvalue;
1868 }
1869 else if ( rp->symptr->bind == STB_GLOBAL || (rp->symptr->bind == STB_WEAK && rp->symptr->sym.st_shndx) )
1870 {
1871 data_5 += symvalue - gpvalue;
1872 }
1873 else if ( rp->symptr->bind != STB_WEAK || rp->symptr->sym.st_shndx )
1874 {
1875 fprintf(stderr, "R_MIPS_GPREL16 unknown case abort\n");
1876 exit(1);
1877 }
1878 }
1879 else
1880 {
1881 fprintf(stderr, "R_MIPS_GPREL16 no symtab\n");
1882 exit(1);
1883 }
1884 if ( (uint16_t)(data_5 >> 16) && (uint16_t)(data_5 >> 16) != 0xFFFF )
1885 {
1886 fprintf(stderr, "R_MIPS_GPREL16 data overflow\n");
1887 exit(1);
1888 }
1889 *(uint32_t *)daddr_1 &= 0xFFFF0000;
1890 *(uint32_t *)daddr_1 |= (uint16_t)data_5;
1891 rp->type = R_MIPS_NONE;
1892 rmflag = 1;
1893 break;
1894 case R_MIPS_LITERAL:
1895 if ( !rp->symptr || rp->symptr->type != STT_SECTION )
1896 {
1897 fprintf(stderr, "R_MIPS_LITERAL unknown case abort\n");
1898 exit(1);
1899 }
1900 data_6 = ((Sect_org_data *)(rp->symptr->shptr->optdata))->org_gp_value + symvalue
1901 - ((Sect_org_data *)(rp->symptr->shptr->optdata))->org_addr - gpvalue + (int16_t)*(uint32_t *)daddr_1;
1902 if ( (uint16_t)(data_6 >> 16) && (uint16_t)(data_6 >> 16) != 0xFFFF )
1903 {
1904 fprintf(stderr, "R_MIPS_LITERAL data overflow\n");
1905 exit(1);
1906 }
1907 *(uint32_t *)daddr_1 &= 0xFFFF0000;
1908 *(uint32_t *)daddr_1 |= (uint16_t)data_6;
1909 rp->type = R_MIPS_NONE;
1910 rmflag = 1;
1911 break;
1912 case R_MIPS_DVP_27_S4:
1913 if ( target != SRX_TARGET_EE )
1914 {
1915 fprintf(stderr, "R_MIPS_DVP_27_S4 can use only for EE.\n");
1916 exit(1);
1917 }
1918 data_7 = symvalue + (*(uint32_t *)daddr_1 & 0x7FFFFFF0);
1919 *(uint32_t *)daddr_1 &= 0x8000000F;
1920 *(uint32_t *)daddr_1 |= data_7 & 0x7FFFFFF0;
1921 if ( !v4 )
1922 {
1923 rp->type = R_MIPS_NONE;
1924 rmflag = 1;
1925 }
1926 break;
1927 case R_MIPS_REL32:
1928 case R_MIPS_GOT16:
1929 case R_MIPS_PC16:
1930 case R_MIPS_CALL16:
1931 case R_MIPS_GPREL32:
1932 case R_MIPS_GOTHI16:
1933 case R_MIPS_GOTLO16:
1934 case R_MIPS_CALLHI16:
1935 case R_MIPS_CALLLO16:
1936 fprintf(stderr, "unacceptable relocation type: 0x%x\n", rp->type);
1937 exit(1);
1938 return;
1939 default:
1940 fprintf(stderr, "unknown relocation type: 0x%x\n", rp->type);
1941 exit(1);
1942 return;
1943 }
1944 for ( ; next > 0; next -= 1 )
1945 {
1946 rp->rel.r_offset += relsect->info->shr.sh_addr;
1947 if ( rp->symptr )
1948 {
1949 rp->symptr->refcount -= 1;
1950 rp->symptr = *symp;
1951 }
1952 i_1 += 1;
1953 rp += 1;
1954 }
1955 }
1956 if ( rmflag > 0 )
1957 {
1958 elf_rel *s;
1959 elf_rel *d;
1960 unsigned int newentrise;
1961 unsigned int i_2;
1962
1963 newtab = (elf_rel *)calloc(entrise, sizeof(elf_rel));
1964 d = newtab;
1965 s = (elf_rel *)relsect->data;
1966 newentrise = 0;
1967 for ( i_2 = 0; i_2 < entrise; i_2 += 1 )
1968 {
1969 if ( s->type )
1970 {
1971 memcpy(d, s, sizeof(elf_rel));
1972 d += 1;
1973 newentrise += 1;
1974 }
1975 s += 1;
1976 }
1977 free(relsect->data);
1978 relsect->data = (uint8_t *)newtab;
1979 relsect->shr.sh_size = relsect->shr.sh_entsize * newentrise;
1980 }
1981}
1982
1983static size_t iopmod_size(const Elf32_IopMod *modinfo)
1984{
1985 return strlen(modinfo->modulename) + (sizeof(Elf32_IopMod) - 1);
1986}
1987
1988static size_t eemod_size(const Elf32_EeMod *modinfo)
1989{
1990 return strlen(modinfo->modulename) + (sizeof(Elf32_EeMod) - 1);
1991}
1992
1993int relocation_is_version2(elf_section *relsect)
1994{
1995 elf_rel *rp;
1996 unsigned int entrise;
1997 unsigned int i;
1998
1999 entrise = relsect->shr.sh_size / relsect->shr.sh_entsize;
2000 rp = (elf_rel *)relsect->data;
2001 for ( i = 0; i < entrise; i += 1 )
2002 {
2003 switch ( rp->type )
2004 {
2005 case R_MIPS_LO16:
2006 case R_MIPSSCE_MHI16:
2007 case R_MIPSSCE_ADDEND:
2008 return 1;
2009 case R_MIPS_HI16:
2010 if ( i == entrise + 1 || rp[1].type != R_MIPS_LO16 || (rp->symptr && rp[1].symptr != rp->symptr) )
2011 {
2012 return 1;
2013 }
2014 rp += 1;
2015 i += 1;
2016 break;
2017 default:
2018 break;
2019 }
2020 rp += 1;
2021 }
2022 return 0;
2023}
2024
2025void dump_srx_gen_table(Srx_gen_table *tp)
2026{
2027 const char *v1;
2028 int scnfp_;
2029 int v8;
2030 int scp_;
2031 int scp_a;
2032 int nsegment;
2033 int b;
2034 int i;
2035 CreateSymbolConf *csyms;
2036 PheaderInfo *phip;
2037 SectConf *sctp;
2038 const char ***scnfpp;
2039 SegConf *scnfp;
2040 elf_section **scp;
2041 char segsig[32];
2042 const char **strp;
2043
2044 if ( tp == NULL )
2045 {
2046 return;
2047 }
2048 switch ( tp->target )
2049 {
2050 case SRX_TARGET_IOP:
2051 v1 = "IOP";
2052 break;
2053 case SRX_TARGET_EE:
2054 v1 = "EE";
2055 break;
2056 default:
2057 v1 = "??";
2058 break;
2059 }
2060 printf("===============\nTarget is %s(%d)\n", v1, tp->target);
2061 printf("Segment list\n");
2062 for ( v8 = 0, scnfp = tp->segment_list; scnfp->name; v8 += 1, scnfp += 1 )
2063 {
2064 printf(" %2d:segment %s\n", v8, scnfp->name);
2065 printf(
2066 " addr,size=0x%x,0x%x bitid,nsect= 0x%x,%d\n ", scnfp->addr, scnfp->size, scnfp->bitid, scnfp->nsect);
2067 if ( scnfp->sect_name_patterns )
2068 {
2069 for ( strp = scnfp->sect_name_patterns; *strp; strp += 1 )
2070 {
2071 printf("%s ", *strp);
2072 }
2073 printf("\n");
2074 }
2075 if ( scnfp->empty_section )
2076 {
2077 printf(" Auto add section: %s\n", scnfp->empty_section->name);
2078 }
2079 if ( scnfp->scp )
2080 {
2081 for ( scp = scnfp->scp; *scp; scp += 1 )
2082 {
2083 printf(" %p: %s\n", *scp, (*scp)->name);
2084 }
2085 }
2086 segsig[v8] = *scnfp->name;
2087 }
2088 printf("\nProgram header order\n");
2089 for ( scp_ = 0, phip = tp->program_header_order; phip->sw; scp_ += 1, phip += 1 )
2090 {
2091 switch ( phip->sw )
2092 {
2093 case SRX_PH_TYPE_MOD:
2094 printf(" %2d: section %s\n", scp_, phip->d.section_name);
2095 break;
2096 case SRX_PH_TYPE_TEXT:
2097 printf(" %2d: Segments ", scp_);
2098 for ( scnfpp = (const char ***)phip->d.section_name; *scnfpp; scnfpp += 1 )
2099 {
2100 printf("%s ", **scnfpp);
2101 }
2102 printf("\n");
2103 break;
2104 default:
2105 break;
2106 }
2107 }
2108 printf("\nRemove section list\n");
2109 for ( scp_a = 0, strp = tp->removesection_list; *strp; scp_a += 1, strp += 1 )
2110 {
2111 printf(" %2d: %s\n", scp_a, *strp);
2112 }
2113 printf("\nSection table order\n");
2114 for ( nsegment = 0, strp = tp->section_table_order; *strp; nsegment += 1, strp += 1 )
2115 {
2116 printf(" %2d: %s\n", nsegment, *strp);
2117 }
2118 printf("\nFile layout order\n");
2119 for ( b = 0, strp = tp->file_layout_order; *strp; b += 1, strp += 1 )
2120 {
2121 printf(" %2d: %s\n", b, *strp);
2122 }
2123 printf("\nmemory layout order\n");
2124 for ( i = 0, sctp = tp->section_list; sctp->sect_name_pattern; i += 1, sctp += 1 )
2125 {
2126 printf(" %2d: [", i);
2127 for ( scnfp_ = 0; scnfp_ < v8; scnfp_ += 1 )
2128 {
2129 printf("%c", ((sctp->flag & (1 << scnfp_)) != 0) ? (unsigned char)(segsig[scnfp_]) : 46);
2130 }
2131 printf("] %s", sctp->sect_name_pattern);
2132 if ( sctp->secttype )
2133 {
2134 printf("\t: Auto create type=%x flag=%x", sctp->secttype, sctp->sectflag);
2135 }
2136 printf("\n");
2137 }
2138 printf("\nReserved symbols\n");
2139 for ( csyms = tp->create_symbols; csyms->name; csyms += 1 )
2140 {
2141 printf(
2142 " %-8s: bind=%d, type=%d, shindex=0x%04x, seflag=%d, seg=%s, sect=%s\n",
2143 csyms->name,
2144 csyms->bind,
2145 csyms->type,
2146 csyms->shindex,
2147 csyms->seflag,
2148 csyms->segment ? csyms->segment->name : "-",
2149 csyms->sectname ?: "-");
2150 }
2151 printf("\n\n");
2152}