PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
elflib.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 <errno.h>
13#include <stdint.h>
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17
18static int is_in_range(unsigned int top, unsigned int size, unsigned int pos);
19static void read_symtab(elf_file *elf, int sctindex, FILE *fp);
20static void read_rel(elf_file *elf, int sctindex, FILE *fp);
21static elf_mips_symbolic_data *read_mips_symbolic(FILE *fp);
22static void renumber_a_symtab(elf_section *scp);
23static void renumber_symtab(elf_file *elf);
24static void write_symtab(elf_file *elf, int sctindex, FILE *fp);
25static void write_rel(elf_file *elf, int sctindex, FILE *fp);
26static void write_mips_symbolic(elf_mips_symbolic_data *sycb, unsigned int basepos, FILE *fp);
27static void reorder_an_symtab(elf_file *elf, elf_section *scp);
28static size_t search_string_table(const char *tbltop, size_t endindex, const char *str);
29static void rebuild_a_symbol_name_strings(elf_section *scp);
30static int comp_Elf_file_slot(const void *a1, const void *a2);
31
32elf_file *read_elf(const char *filename)
33{
34 uint32_t ident;
35 elf_file *elf;
36 FILE *fp;
37
38 fp = fopen(filename, "rb");
39 if ( !fp )
40 {
41 fprintf(stderr, "\"%s\" can't open (errno=%d)\n", filename, errno);
42 return 0;
43 }
44 elf = (elf_file *)calloc(1, sizeof(elf_file));
45 elf->ehp = (Elf32_Ehdr *)malloc(sizeof(Elf32_Ehdr));
46 if ( fread(elf->ehp, sizeof(Elf32_Ehdr), 1, fp) != 1 )
47 {
48 fprintf(stderr, "%s: Could not read ELF header (errno=%d)\n", filename, errno);
49 exit(1);
50 }
51 swapmemory(elf->ehp, "ccccccccccccccccsslllllssssss", 1);
52 ident = *(uint32_t *)elf->ehp->e_ident;
53 swapmemory(&ident, "l", 1);
54 if ( ident != 0x464C457F )
55 {
56 fprintf(stderr, "%s: not elf format\n", filename);
57 free(elf->ehp);
58 free(elf);
59 fclose(fp);
60 return 0;
61 }
62 if ( elf->ehp->e_ident[4] != ELFCLASS32 || elf->ehp->e_ident[5] != ELFDATA2LSB || elf->ehp->e_ident[6] != EV_CURRENT )
63 {
64 fprintf(stderr, "%s: Not 32-bit object or Not little endian or Invalid Elf version\n", filename);
65 free(elf->ehp);
66 free(elf);
67 fclose(fp);
68 return 0;
69 }
70 if ( elf->ehp->e_machine != EM_MIPS )
71 {
72 fprintf(stderr, "%s: not EM_MIPS\n", filename);
73 free(elf->ehp);
74 free(elf);
75 fclose(fp);
76 return 0;
77 }
78 if ( elf->ehp->e_phentsize && elf->ehp->e_phentsize != sizeof(Elf32_Phdr) )
79 {
80 fprintf(stderr, "%s: Unknown program header size\n", filename);
81 free(elf->ehp);
82 free(elf);
83 fclose(fp);
84 return 0;
85 }
86 if ( elf->ehp->e_shentsize && elf->ehp->e_shentsize != sizeof(Elf32_Shdr) )
87 {
88 fprintf(stderr, "%s: Unknown sectoin header size\n", filename);
89 free(elf->ehp);
90 free(elf);
91 fclose(fp);
92 return 0;
93 }
94 if ( elf->ehp->e_phnum && elf->ehp->e_phentsize )
95 {
96 signed int count_1;
97 unsigned int pos_1;
98 int i_1;
99
100 count_1 = elf->ehp->e_phnum;
101 pos_1 = elf->ehp->e_phoff;
102 elf->php = (elf_proghead *)calloc(count_1, sizeof(elf_proghead));
103 fseek(fp, pos_1, SEEK_SET);
104 for ( i_1 = 0; count_1 > i_1; i_1 += 1 )
105 {
106 if ( fread(&elf->php[i_1], sizeof(Elf32_Phdr), 1, fp) != 1 )
107 {
108 fprintf(stderr, "%s: Could not read ELF program header (errno=%d)\n", filename, errno);
109 exit(1);
110 }
111 swapmemory(&elf->php[i_1], "llllllll", 1);
112 }
113 }
114 if ( elf->ehp->e_shnum && elf->ehp->e_shentsize )
115 {
116 signed int count_2;
117 unsigned int pos_2;
118 int i_2;
119 int i_3;
120 int i_4;
121
122 pos_2 = elf->ehp->e_shoff;
123 count_2 = elf->ehp->e_shnum;
124 elf->scp = (elf_section **)calloc(count_2 + 1, sizeof(elf_section *));
125 fseek(fp, pos_2, SEEK_SET);
126 for ( i_2 = 0; count_2 > i_2; i_2 += 1 )
127 {
128 elf->scp[i_2] = (elf_section *)calloc(1, sizeof(elf_section));
129 if ( fread(elf->scp[i_2], sizeof(Elf32_Shdr), 1, fp) != 1 )
130 {
131 fprintf(stderr, "%s: Could not read ELF section header (errno=%d)\n", filename, errno);
132 exit(1);
133 }
134 swapmemory(elf->scp[i_2], "llllllllll", 1);
135 }
136 for ( i_3 = 0; count_2 > i_3; i_3 += 1 )
137 {
138 switch ( elf->scp[i_3]->shr.sh_type )
139 {
140#pragma GCC diagnostic push
141#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
142 case SHT_RELA:
143 case SHT_REL:
144 elf->scp[i_3]->info = elf->scp[elf->scp[i_3]->shr.sh_info];
145 case SHT_SYMTAB:
146 case SHT_HASH:
147 case SHT_DYNAMIC:
148 case SHT_DYNSYM:
149 elf->scp[i_3]->link = elf->scp[elf->scp[i_3]->shr.sh_link];
150 break;
151#pragma GCC diagnostic pop
152 default:
153 break;
154 }
155 if ( i_3 == elf->ehp->e_shstrndx )
156 {
157 elf->shstrptr = elf->scp[i_3];
158 }
159 }
160 for ( i_4 = 0;; i_4 += 1 )
161 {
162 unsigned int size;
163 unsigned int pos_3;
164
165 if ( count_2 <= i_4 )
166 {
167 int i_5;
168 int i_6;
169 int i_7;
170 int i_8;
171
172 for ( i_5 = 0; count_2 > i_5; i_5 += 1 )
173 {
174 unsigned int pos_4;
175
176 pos_4 = elf->scp[i_5]->shr.sh_offset;
177 switch ( elf->scp[i_5]->shr.sh_type )
178 {
179 case SHT_SYMTAB:
180 case SHT_DYNSYM:
181 if ( pos_4 != 0 && elf->scp[i_5]->shr.sh_size )
182 {
183 fseek(fp, pos_4, SEEK_SET);
184 read_symtab(elf, i_5, fp);
185 }
186 break;
187 default:
188 break;
189 }
190 }
191 for ( i_6 = 0; count_2 > i_6; i_6 += 1 )
192 {
193 unsigned int pos_5;
194
195 pos_5 = elf->scp[i_6]->shr.sh_offset;
196 if ( elf->scp[i_6]->shr.sh_type == SHT_REL && pos_5 != 0 && elf->scp[i_6]->shr.sh_size )
197 {
198 fseek(fp, pos_5, SEEK_SET);
199 read_rel(elf, i_6, fp);
200 }
201 }
202 for ( i_7 = 0; count_2 > i_7; i_7 += 1 )
203 {
204 elf->scp[i_7]->name =
205 strdup((elf->shstrptr != NULL) ? ((char *)&elf->shstrptr->data[elf->scp[i_7]->shr.sh_name]) : "");
206 }
207 for ( i_8 = 0; i_8 < elf->ehp->e_phnum; i_8 += 1 )
208 {
209 int d;
210 int s;
211
212 switch ( elf->php[i_8].phdr.p_type )
213 {
214 case PT_LOAD:
215 elf->php[i_8].scp = (elf_section **)calloc(count_2, sizeof(elf_section *));
216 d = 0;
217 for ( s = 1; s < count_2; s += 1 )
218 {
219 unsigned int p_filesz;
220 unsigned int p_offset;
221
222 p_offset = elf->php[i_8].phdr.p_offset;
223 p_filesz = elf->php[i_8].phdr.p_filesz;
224 switch ( elf->scp[s]->shr.sh_type )
225 {
226 case SHT_PROGBITS:
227 if (
228 is_in_range(p_offset, p_filesz, elf->scp[s]->shr.sh_offset)
229 || (!elf->scp[s]->shr.sh_size && elf->scp[s]->shr.sh_offset == p_filesz + p_offset) )
230 {
231 elf->php[i_8].scp[d] = elf->scp[s];
232 d += 1;
233 }
234 break;
235 case SHT_NOBITS:
236 if (
237 is_in_range(elf->php[i_8].phdr.p_vaddr, elf->php[i_8].phdr.p_memsz, elf->scp[s]->shr.sh_addr)
238 || (!elf->scp[s]->shr.sh_size && elf->scp[s]->shr.sh_offset == p_filesz + p_offset) )
239 {
240 elf->php[i_8].scp[d] = elf->scp[s];
241 d += 1;
242 }
243 break;
244 default:
245 break;
246 }
247 }
248 break;
249 case PT_MIPS_REGINFO:
250 elf->php[i_8].scp = (elf_section **)calloc(2, sizeof(elf_section *));
251 *elf->php[i_8].scp = search_section(elf, SHT_MIPS_REGINFO);
252 break;
253 case PT_SCE_IOPMOD:
254 elf->php[i_8].scp = (elf_section **)calloc(2, sizeof(elf_section *));
255 *elf->php[i_8].scp = search_section(elf, SHT_SCE_IOPMOD);
256 break;
257 case PT_SCE_EEMOD:
258 elf->php[i_8].scp = (elf_section **)calloc(2, sizeof(elf_section *));
259 *elf->php[i_8].scp = search_section(elf, SHT_SCE_EEMOD);
260 break;
261 default:
262 break;
263 }
264 }
265 // Workaround for malformed file: make distance between sh_addr agree with sh_offset
266 switch ( elf->ehp->e_type )
267 {
268 case ET_SCE_IOPRELEXEC:
269 case ET_SCE_IOPRELEXEC2:
270 case ET_SCE_EERELEXEC:
271 case ET_SCE_EERELEXEC2:
272 for ( i_8 = 0; i_8 < elf->ehp->e_phnum; i_8 += 1 )
273 {
274 int s;
275 elf_section **scp;
276
277 switch ( elf->php[i_8].phdr.p_type )
278 {
279 case PT_LOAD:
280 scp = elf->php[i_8].scp;
281 for ( s = 1; scp[s]; s += 1 )
282 {
283 if ( scp[s]->shr.sh_type != SHT_NOBITS )
284 {
285 unsigned int addrdiff;
286 unsigned int offsetdiff;
287
288 addrdiff = scp[s]->shr.sh_addr - scp[s - 1]->shr.sh_addr;
289 offsetdiff = scp[s]->shr.sh_offset - scp[s - 1]->shr.sh_offset;
290 if ( addrdiff != offsetdiff )
291 {
292 scp[s]->shr.sh_addr = scp[s - 1]->shr.sh_addr + offsetdiff;
293 }
294 }
295 }
296 break;
297 default:
298 break;
299 }
300 }
301 break;
302 default:
303 break;
304 }
305 return elf;
306 }
307 pos_3 = elf->scp[i_4]->shr.sh_offset;
308 size = elf->scp[i_4]->shr.sh_size;
309 if ( pos_3 != 0 && size != 0 )
310 {
311 fseek(fp, pos_3, SEEK_SET);
312 switch ( elf->scp[i_4]->shr.sh_type )
313 {
314 case SHT_PROGBITS:
315 case SHT_RELA:
316 case SHT_HASH:
317 case SHT_DYNAMIC:
318 case SHT_MIPS_REGINFO:
319 elf->scp[i_4]->data = (uint8_t *)malloc(size);
320 if ( fread(elf->scp[i_4]->data, size, 1, fp) != 1 )
321 {
322 fprintf(stderr, "%s: Could not read ELF section contents, (errno=%d)\n", filename, errno);
323 exit(1);
324 }
325 swapmemory(elf->scp[i_4]->data, "l", size >> 2);
326 break;
327 case SHT_SYMTAB:
328 case SHT_NOBITS:
329 case SHT_DYNSYM:
330 break;
331 case SHT_MIPS_DEBUG:
332 elf->scp[i_4]->data = (uint8_t *)read_mips_symbolic(fp);
333 break;
334 case SHT_SCE_IOPMOD:
335 elf->scp[i_4]->data = (uint8_t *)malloc(size);
336 if ( fread(elf->scp[i_4]->data, size, 1, fp) != 1 )
337 {
338 fprintf(stderr, "%s: Could not read ELF section contents (errno=%d)\n", filename, errno);
339 exit(1);
340 }
341 swapmemory(elf->scp[i_4]->data, "lllllls", 1);
342 break;
343 case SHT_SCE_EEMOD:
344 elf->scp[i_4]->data = (uint8_t *)malloc(size);
345 if ( fread(elf->scp[i_4]->data, size, 1, fp) != 1 )
346 {
347 fprintf(stderr, "%s: Could not read ELF section contents (errno=%d)\n", filename, errno);
348 exit(1);
349 }
350 swapmemory(elf->scp[i_4]->data, "lllllllllls", 1);
351 break;
352 default:
353 elf->scp[i_4]->data = (uint8_t *)malloc(size);
354 if ( fread(elf->scp[i_4]->data, size, 1, fp) != 1 )
355 {
356 fprintf(stderr, "%s: Could not read ELF section contents (errno=%d)\n", filename, errno);
357 exit(1);
358 }
359 break;
360 }
361 }
362 }
363 }
364 fclose(fp);
365 return elf;
366}
367
368static int is_in_range(unsigned int top, unsigned int size, unsigned int pos)
369{
370 if ( pos >= top && pos < size + top )
371 {
372 return 1;
373 }
374 return 0;
375}
376
377static void read_symtab(elf_file *elf, int sctindex, FILE *fp)
378{
379 elf_syment **result;
380 elf_section *sp_x;
381 unsigned int entrise;
382 unsigned int i;
383
384 sp_x = elf->scp[sctindex];
385 entrise = sp_x->shr.sh_size / sp_x->shr.sh_entsize;
386 result = (elf_syment **)calloc(entrise, sizeof(elf_syment *));
387 sp_x->data = (uint8_t *)result;
388 for ( i = 0; entrise > i; i += 1 )
389 {
390 result[i] = (elf_syment *)calloc(1, sizeof(elf_syment));
391 if ( fread(result[i], sp_x->shr.sh_entsize, 1, fp) != 1 )
392 {
393 fprintf(stderr, "elflib: Could not read ELF symbol table (errno=%d)\n", errno);
394 exit(1);
395 }
396 swapmemory(result[i], "lllccs", 1);
397 result[i]->bind = result[i]->sym.st_info >> 4;
398 result[i]->type = result[i]->sym.st_info & 0xF;
399 result[i]->name = 0;
400 if ( result[i]->sym.st_name )
401 {
402 result[i]->name = strdup((char *)&sp_x->link->data[result[i]->sym.st_name]);
403 }
404 if ( result[i]->sym.st_shndx && result[i]->sym.st_shndx <= 0xFEFF )
405 {
406 result[i]->shptr = elf->scp[result[i]->sym.st_shndx];
407 }
408 else
409 {
410 result[i]->shptr = 0;
411 }
412 }
413}
414
415static void read_rel(elf_file *elf, int sctindex, FILE *fp)
416{
417 elf_syment **symp;
418 elf_rel *result;
419 elf_section *sp_x;
420 unsigned int entrise;
421 unsigned int i;
422
423 sp_x = elf->scp[sctindex];
424 entrise = sp_x->shr.sh_size / sp_x->shr.sh_entsize;
425 result = (elf_rel *)calloc(entrise, sizeof(elf_rel));
426 sp_x->data = (uint8_t *)result;
427 symp = (elf_syment **)sp_x->link->data;
428 for ( i = 0; entrise > i; i += 1 )
429 {
430 if ( fread(&result[i], sp_x->shr.sh_entsize, 1, fp) != 1 )
431 {
432 fprintf(stderr, "elflib: Could not read ELF relocations (errno=%d)\n", errno);
433 exit(1);
434 }
435 swapmemory(&result[i], "ll", 1);
436 result[i].type = result[i].rel.r_info & 0xFF;
437 // Workaround for malformed file: Handle case of missing .symtab/.strtab section
438 if ( symp )
439 {
440 result[i].symptr = symp[result[i].rel.r_info >> 8];
441 result[i].symptr->refcount += 1;
442 }
443 }
444}
445
446static elf_mips_symbolic_data *read_mips_symbolic(FILE *fp)
447{
449
450 sycb = (elf_mips_symbolic_data *)malloc(sizeof(elf_mips_symbolic_data));
451 if ( fread(sycb, sizeof(hdrr), 1, fp) != 1 )
452 {
453 fprintf(stderr, "elflib: Could not read ELF debug info contents (errno=%d)\n", errno);
454 exit(1);
455 }
456 swapmemory(sycb, "sslllllllllllllllllllllll", 1);
457 if ( sycb->head.cbLineOffset > 0 )
458 {
459 size_t size_1;
460
461 size_1 = sycb->head.cbLine;
462 sycb->cbLine_Ptr = (char *)malloc(size_1);
463 fseek(fp, sycb->head.cbLineOffset, SEEK_SET);
464 if ( fread(sycb->cbLine_Ptr, size_1, 1, fp) != 1 )
465 {
466 fprintf(stderr, "elflib: Could not read ELF debug info contents (errno=%d)\n", errno);
467 exit(1);
468 }
469 }
470 if ( sycb->head.cbDnOffset > 0 )
471 {
472 size_t size_2;
473
474 size_2 = 8L * sycb->head.idnMax;
475 sycb->cbDn_Ptr = (char *)malloc(size_2);
476 fseek(fp, sycb->head.cbDnOffset, SEEK_SET);
477 if ( fread(sycb->cbDn_Ptr, size_2, 1, fp) != 1 )
478 {
479 fprintf(stderr, "elflib: Could not read ELF debug info contents (errno=%d)\n", errno);
480 exit(1);
481 }
482 swapmemory(sycb->cbDn_Ptr, "ll", sycb->head.idnMax);
483 }
484 if ( sycb->head.cbPdOffset > 0 )
485 {
486 size_t size_3;
487
488 size_3 = 52L * sycb->head.ipdMax;
489 sycb->cbPd_Ptr = (char *)malloc(size_3);
490 fseek(fp, sycb->head.cbPdOffset, SEEK_SET);
491 if ( fread(sycb->cbPd_Ptr, size_3, 1, fp) != 1 )
492 {
493 fprintf(stderr, "elflib: Could not read ELF debug info contents (errno=%d)\n", errno);
494 exit(1);
495 }
496 swapmemory(sycb->cbPd_Ptr, "lllllllllsslll", sycb->head.ipdMax);
497 }
498 if ( sycb->head.cbSymOffset > 0 )
499 {
500 size_t size_4;
501
502 size_4 = 12L * sycb->head.isymMax;
503 sycb->cbSym_Ptr = (char *)malloc(size_4);
504 fseek(fp, sycb->head.cbSymOffset, SEEK_SET);
505 if ( fread(sycb->cbSym_Ptr, size_4, 1, fp) != 1 )
506 {
507 fprintf(stderr, "elflib: Could not read ELF debug info contents (errno=%d)\n", errno);
508 exit(1);
509 }
510 swapmemory(sycb->cbSym_Ptr, "lll", sycb->head.isymMax);
511 }
512 if ( sycb->head.cbOptOffset > 0 )
513 {
514 size_t size_5;
515
516 size_5 = 12L * sycb->head.ioptMax;
517 sycb->cbOpt_Ptr = (char *)malloc(size_5);
518 fseek(fp, sycb->head.cbOptOffset, SEEK_SET);
519 if ( fread(sycb->cbOpt_Ptr, size_5, 1, fp) != 1 )
520 {
521 fprintf(stderr, "elflib: Could not read ELF debug info contents (errno=%d)\n", errno);
522 exit(1);
523 }
524 swapmemory(sycb->cbOpt_Ptr, "lll", sycb->head.ioptMax);
525 }
526 if ( sycb->head.cbAuxOffset > 0 )
527 {
528 size_t size_6;
529
530 size_6 = 4L * sycb->head.iauxMax;
531 sycb->cbAux_Ptr = (char *)malloc(size_6);
532 fseek(fp, sycb->head.cbAuxOffset, SEEK_SET);
533 if ( fread(sycb->cbAux_Ptr, size_6, 1, fp) != 1 )
534 {
535 fprintf(stderr, "elflib: Could not read ELF debug info contents (errno=%d)\n", errno);
536 exit(1);
537 }
538 swapmemory(sycb->cbAux_Ptr, "l", sycb->head.iauxMax);
539 }
540 if ( sycb->head.cbSsOffset > 0 )
541 {
542 size_t size_7;
543
544 size_7 = sycb->head.issMax;
545 sycb->cbSs_Ptr = (char *)malloc(size_7);
546 fseek(fp, sycb->head.cbSsOffset, SEEK_SET);
547 if ( fread(sycb->cbSs_Ptr, size_7, 1, fp) != 1 )
548 {
549 fprintf(stderr, "elflib: Could not read ELF debug info contents (errno=%d)\n", errno);
550 exit(1);
551 }
552 }
553 if ( sycb->head.cbSsExtOffset > 0 )
554 {
555 size_t size_8;
556
557 size_8 = sycb->head.issExtMax;
558 sycb->cbSsExt_Ptr = (char *)malloc(size_8);
559 fseek(fp, sycb->head.cbSsExtOffset, SEEK_SET);
560 if ( fread(sycb->cbSsExt_Ptr, size_8, 1, fp) != 1 )
561 {
562 fprintf(stderr, "elflib: Could not read ELF debug info contents (errno=%d)\n", errno);
563 exit(1);
564 }
565 }
566 if ( sycb->head.cbFdOffset > 0 )
567 {
568 size_t size_9;
569
570 size_9 = 72L * sycb->head.ifdMax;
571 sycb->cbFd_Ptr = (char *)malloc(size_9);
572 fseek(fp, sycb->head.cbFdOffset, SEEK_SET);
573 if ( fread(sycb->cbFd_Ptr, size_9, 1, fp) != 1 )
574 {
575 fprintf(stderr, "elflib: Could not read ELF debug info contents (errno=%d)\n", errno);
576 exit(1);
577 }
578 swapmemory(sycb->cbFd_Ptr, "llllllllllsslllllll", sycb->head.ifdMax);
579 }
580 if ( sycb->head.cbRfdOffset > 0 )
581 {
582 size_t size_A;
583
584 size_A = 4L * sycb->head.crfd;
585 sycb->cbRfd_Ptr = (char *)malloc(size_A);
586 fseek(fp, sycb->head.cbRfdOffset, SEEK_SET);
587 if ( fread(sycb->cbRfd_Ptr, size_A, 1, fp) != 1 )
588 {
589 fprintf(stderr, "elflib: Could not read ELF debug info contents (errno=%d)\n", errno);
590 exit(1);
591 }
592 swapmemory(sycb->cbRfd_Ptr, "l", sycb->head.crfd);
593 }
594 if ( sycb->head.cbExtOffset > 0 )
595 {
596 size_t size_B;
597
598 size_B = 16L * sycb->head.iextMax;
599 sycb->cbExt_Ptr = (char *)malloc(size_B);
600 fseek(fp, sycb->head.cbExtOffset, SEEK_SET);
601 if ( fread(sycb->cbExt_Ptr, size_B, 1, fp) != 1 )
602 {
603 fprintf(stderr, "elflib: Could not read ELF debug info contents (errno=%d)\n", errno);
604 exit(1);
605 }
606 swapmemory(sycb->cbExt_Ptr, "sslll", sycb->head.iextMax);
607 }
608 return sycb;
609}
610
611int layout_elf_file(elf_file *elf)
612{
613 Elf_file_slot *order;
614
615 reorder_symtab(elf);
616 rebuild_section_name_strings(elf);
617 rebuild_symbol_name_strings(elf);
618 order = build_file_order_list(elf);
619 shrink_file_order_list(order);
620 writeback_file_order_list(elf, order);
621 free(order);
622 return 0;
623}
624
625int write_elf(elf_file *elf, const char *filename)
626{
627 FILE *fp;
628
629 fp = fopen(filename, "wb");
630 if ( !fp )
631 {
632 fprintf(stderr, "\"%s\" can't open (errno=%d)\n", filename, errno);
633 return 1;
634 }
635 renumber_symtab(elf);
636 if ( elf->ehp->e_shnum && elf->ehp->e_shentsize )
637 {
638 int i_1;
639 int i_2;
640
641 for ( i_1 = 0; i_1 < elf->ehp->e_shnum; i_1 += 1 )
642 {
643 elf->scp[i_1]->number = i_1;
644 }
645 for ( i_2 = 0; i_2 < elf->ehp->e_shnum; i_2 += 1 )
646 {
647 switch ( elf->scp[i_2]->shr.sh_type )
648 {
649#pragma GCC diagnostic push
650#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
651 case SHT_RELA:
652 case SHT_REL:
653 elf->scp[i_2]->shr.sh_info = elf->scp[i_2]->info->number;
654 case SHT_SYMTAB:
655 case SHT_HASH:
656 case SHT_DYNAMIC:
657 case SHT_DYNSYM:
658 elf->scp[i_2]->shr.sh_link = elf->scp[i_2]->link->number;
659 break;
660#pragma GCC diagnostic pop
661 default:
662 break;
663 }
664 if ( elf->scp[i_2] == elf->shstrptr )
665 {
666 elf->ehp->e_shstrndx = elf->scp[i_2]->number;
667 }
668 }
669 }
670 swapmemory(elf->ehp, "ccccccccccccccccsslllllssssss", 1);
671 fwrite(elf->ehp, sizeof(Elf32_Ehdr), 1, fp);
672 swapmemory(elf->ehp, "ccccccccccccccccsslllllssssss", 1);
673 if ( elf->ehp->e_phnum && elf->ehp->e_phentsize )
674 {
675 int count_1;
676 int i_3;
677
678 count_1 = elf->ehp->e_phnum;
679 fseek(fp, elf->ehp->e_phoff, SEEK_SET);
680 for ( i_3 = 0; count_1 > i_3; i_3 += 1 )
681 {
682 swapmemory(&elf->php[i_3], "llllllll", 1);
683 fwrite(&elf->php[i_3], sizeof(Elf32_Phdr), 1, fp);
684 swapmemory(&elf->php[i_3], "llllllll", 1);
685 }
686 }
687 if ( elf->ehp->e_shnum && elf->ehp->e_shentsize )
688 {
689 int count_2;
690 int i_4;
691 int i_5;
692
693 count_2 = elf->ehp->e_shnum;
694 fseek(fp, elf->ehp->e_shoff, SEEK_SET);
695 for ( i_4 = 0; count_2 > i_4; i_4 += 1 )
696 {
697 swapmemory(elf->scp[i_4], "llllllllll", 1);
698 fwrite(elf->scp[i_4], sizeof(Elf32_Shdr), 1, fp);
699 swapmemory(elf->scp[i_4], "llllllllll", 1);
700 }
701 for ( i_5 = 0; count_2 > i_5; i_5 += 1 )
702 {
703 unsigned int size;
704 unsigned int pos;
705
706 pos = elf->scp[i_5]->shr.sh_offset;
707 size = elf->scp[i_5]->shr.sh_size;
708 if ( pos != 0 && size != 0 )
709 {
710 fseek(fp, pos, SEEK_SET);
711 switch ( elf->scp[i_5]->shr.sh_type )
712 {
713 case SHT_PROGBITS:
714 case SHT_RELA:
715 case SHT_HASH:
716 case SHT_DYNAMIC:
717 case SHT_MIPS_REGINFO:
718 swapmemory(elf->scp[i_5]->data, "l", size >> 2);
719 fwrite(elf->scp[i_5]->data, size, 1, fp);
720 swapmemory(elf->scp[i_5]->data, "l", size >> 2);
721 break;
722 case SHT_SYMTAB:
723 case SHT_DYNSYM:
724 write_symtab(elf, i_5, fp);
725 break;
726 case SHT_NOBITS:
727 break;
728 case SHT_REL:
729 write_rel(elf, i_5, fp);
730 break;
731 case SHT_MIPS_DEBUG:
732 write_mips_symbolic((elf_mips_symbolic_data *)elf->scp[i_5]->data, pos, fp);
733 break;
734 case SHT_SCE_IOPMOD:
735 swapmemory(elf->scp[i_5]->data, "lllllls", 1);
736 fwrite(elf->scp[i_5]->data, size, 1, fp);
737 swapmemory(elf->scp[i_5]->data, "lllllls", 1);
738 break;
739 case SHT_SCE_EEMOD:
740 swapmemory(elf->scp[i_5]->data, "lllllllllls", 1);
741 fwrite(elf->scp[i_5]->data, size, 1, fp);
742 swapmemory(elf->scp[i_5]->data, "lllllllllls", 1);
743 break;
744 default:
745 fwrite(elf->scp[i_5]->data, size, 1, fp);
746 break;
747 }
748 }
749 }
750 }
751 fclose(fp);
752 return 0;
753}
754
755static void renumber_a_symtab(elf_section *scp)
756{
757 elf_syment **syp;
758 unsigned int entrise;
759 unsigned int i;
760
761 entrise = scp->shr.sh_size / scp->shr.sh_entsize;
762 syp = (elf_syment **)scp->data;
763 for ( i = 0; entrise > i; i += 1 )
764 {
765 syp[i]->number = i;
766 }
767}
768
769static void renumber_symtab(elf_file *elf)
770{
771 int sc;
772
773 for ( sc = 1; sc < elf->ehp->e_shnum; sc += 1 )
774 {
775 switch ( elf->scp[sc]->shr.sh_type )
776 {
777 case SHT_SYMTAB:
778 case SHT_DYNSYM:
779 renumber_a_symtab(elf->scp[sc]);
780 break;
781 default:
782 break;
783 }
784 }
785}
786
787static void write_symtab(elf_file *elf, int sctindex, FILE *fp)
788{
789 Elf32_Sym sym;
790 elf_syment **syp;
791 elf_section *sp_x;
792 unsigned int entrise;
793 unsigned int i;
794
795 sp_x = elf->scp[sctindex];
796 entrise = sp_x->shr.sh_size / sp_x->shr.sh_entsize;
797 syp = (elf_syment **)sp_x->data;
798 fseek(fp, sp_x->shr.sh_offset, SEEK_SET);
799 for ( i = 0; entrise > i; i += 1 )
800 {
801 memcpy(&sym, syp[i], sizeof(sym));
802 if ( syp[i]->shptr )
803 {
804 sym.st_shndx = syp[i]->shptr->number;
805 }
806 swapmemory(&sym, "lllccs", 1);
807 fwrite(&sym, sizeof(Elf32_Sym), 1, fp);
808 }
809}
810
811static void write_rel(elf_file *elf, int sctindex, FILE *fp)
812{
813 Elf32_Rel rel;
814 elf_rel *rp;
815 elf_section *sp_x;
816 unsigned int entrise;
817 unsigned int i;
818
819 sp_x = elf->scp[sctindex];
820 entrise = sp_x->shr.sh_size / sp_x->shr.sh_entsize;
821 rp = (elf_rel *)sp_x->data;
822 fseek(fp, sp_x->shr.sh_offset, SEEK_SET);
823 for ( i = 0; entrise > i; i += 1 )
824 {
825 memcpy(&rel, &rp[i], sizeof(rel));
826 if ( rp[i].symptr && rp[i].symptr->number == (unsigned int)(-1) )
827 {
828 fprintf(stderr, "Internal error !!\n");
829 fprintf(stderr, " relocation entry have no symbol\nabort\n");
830 exit(1);
831 }
832 rel.r_info = ((rp[i].symptr ? rp[i].symptr->number : sp_x->info->number) << 8) + (rp[i].type & 0xFF);
833 swapmemory(&rel, "ll", 1);
834 fwrite(&rel, sizeof(Elf32_Rel), 1, fp);
835 }
836}
837
838static void write_mips_symbolic(elf_mips_symbolic_data *sycb, unsigned int basepos, FILE *fp)
839{
840 unsigned int pos;
841
842 pos = basepos + 96;
843 if ( sycb->head.cbLineOffset > 0 )
844 {
845 size_t size_1;
846
847 size_1 = sycb->head.cbLine;
848 sycb->head.cbLineOffset = pos;
849 pos += size_1;
850 fseek(fp, sycb->head.cbLineOffset, SEEK_SET);
851 fwrite(sycb->cbLine_Ptr, size_1, 1, fp);
852 }
853 if ( sycb->head.cbDnOffset > 0 )
854 {
855 size_t size_2;
856
857 size_2 = 8L * sycb->head.idnMax;
858 sycb->head.cbDnOffset = pos;
859 pos += size_2;
860 fseek(fp, sycb->head.cbDnOffset, SEEK_SET);
861 swapmemory(sycb->cbDn_Ptr, "ll", sycb->head.idnMax);
862 fwrite(sycb->cbDn_Ptr, size_2, 1, fp);
863 swapmemory(sycb->cbDn_Ptr, "ll", sycb->head.idnMax);
864 }
865 if ( sycb->head.cbPdOffset > 0 )
866 {
867 size_t size_3;
868
869 size_3 = 52L * sycb->head.ipdMax;
870 sycb->head.cbPdOffset = pos;
871 pos += size_3;
872 fseek(fp, sycb->head.cbPdOffset, SEEK_SET);
873 swapmemory(sycb->cbPd_Ptr, "lllllllllsslll", sycb->head.ipdMax);
874 fwrite(sycb->cbPd_Ptr, size_3, 1, fp);
875 swapmemory(sycb->cbPd_Ptr, "lllllllllsslll", sycb->head.ipdMax);
876 }
877 if ( sycb->head.cbSymOffset > 0 )
878 {
879 size_t size_4;
880
881 size_4 = 12L * sycb->head.isymMax;
882 sycb->head.cbSymOffset = pos;
883 pos += size_4;
884 fseek(fp, sycb->head.cbSymOffset, SEEK_SET);
885 swapmemory(sycb->cbSym_Ptr, "lll", sycb->head.isymMax);
886 fwrite(sycb->cbSym_Ptr, size_4, 1, fp);
887 swapmemory(sycb->cbSym_Ptr, "lll", sycb->head.isymMax);
888 }
889 if ( sycb->head.cbOptOffset > 0 )
890 {
891 size_t size_5;
892
893 size_5 = 12L * sycb->head.ioptMax;
894 pos += size_5;
895 fseek(fp, sycb->head.cbOptOffset, SEEK_SET);
896 swapmemory(sycb->cbOpt_Ptr, "lll", sycb->head.ioptMax);
897 fwrite(sycb->cbOpt_Ptr, size_5, 1, fp);
898 swapmemory(sycb->cbOpt_Ptr, "lll", sycb->head.ioptMax);
899 }
900 if ( sycb->head.cbAuxOffset > 0 )
901 {
902 size_t size_6;
903
904 size_6 = 4L * sycb->head.iauxMax;
905 sycb->head.cbAuxOffset = pos;
906 pos += size_6;
907 fseek(fp, sycb->head.cbAuxOffset, SEEK_SET);
908 swapmemory(sycb->cbAux_Ptr, "l", sycb->head.iauxMax);
909 fwrite(sycb->cbAux_Ptr, size_6, 1, fp);
910 swapmemory(sycb->cbAux_Ptr, "l", sycb->head.iauxMax);
911 }
912 if ( sycb->head.cbSsOffset > 0 )
913 {
914 size_t size_7;
915
916 size_7 = sycb->head.issMax;
917 sycb->head.cbSsOffset = pos;
918 pos += size_7;
919 fseek(fp, sycb->head.cbSsOffset, SEEK_SET);
920 fwrite(sycb->cbSs_Ptr, size_7, 1, fp);
921 }
922 if ( sycb->head.cbSsExtOffset > 0 )
923 {
924 size_t size_8;
925
926 size_8 = sycb->head.issExtMax;
927 sycb->head.cbSsExtOffset = pos;
928 pos += size_8;
929 fseek(fp, sycb->head.cbSsExtOffset, SEEK_SET);
930 fwrite(sycb->cbSsExt_Ptr, size_8, 1, fp);
931 }
932 if ( sycb->head.cbFdOffset > 0 )
933 {
934 size_t size_9;
935
936 size_9 = 72L * sycb->head.ifdMax;
937 sycb->head.cbFdOffset = pos;
938 pos += size_9;
939 fseek(fp, sycb->head.cbFdOffset, SEEK_SET);
940 swapmemory(sycb->cbFd_Ptr, "llllllllllsslllllll", sycb->head.ifdMax);
941 fwrite(sycb->cbFd_Ptr, size_9, 1, fp);
942 swapmemory(sycb->cbFd_Ptr, "llllllllllsslllllll", sycb->head.ifdMax);
943 }
944 if ( sycb->head.cbRfdOffset > 0 )
945 {
946 size_t size_A;
947
948 size_A = 4L * sycb->head.crfd;
949 sycb->head.cbRfdOffset = pos;
950 pos += size_A;
951 fseek(fp, sycb->head.cbRfdOffset, SEEK_SET);
952 swapmemory(sycb->cbRfd_Ptr, "l", sycb->head.crfd);
953 fwrite(sycb->cbRfd_Ptr, size_A, 1, fp);
954 swapmemory(sycb->cbRfd_Ptr, "l", sycb->head.crfd);
955 }
956 if ( sycb->head.cbExtOffset > 0 )
957 {
958 size_t size_B;
959
960 size_B = 16L * sycb->head.iextMax;
961 sycb->head.cbExtOffset = pos;
962 fseek(fp, sycb->head.cbExtOffset, SEEK_SET);
963 swapmemory(sycb->cbExt_Ptr, "sslll", sycb->head.iextMax);
964 fwrite(sycb->cbExt_Ptr, size_B, 1, fp);
965 swapmemory(sycb->cbExt_Ptr, "sslll", sycb->head.iextMax);
966 }
967 fseek(fp, basepos, SEEK_SET);
968 swapmemory(sycb, "sslllllllllllllllllllllll", 1);
969 fwrite(sycb, sizeof(hdrr), 1, fp);
970 swapmemory(sycb, "sslllllllllllllllllllllll", 1);
971}
972
973void add_section(elf_file *elf, elf_section *scp)
974{
975 Elf32_Ehdr *ehp;
976 int count;
977
978 ehp = elf->ehp;
979 ehp->e_shnum += 1;
980 count = ehp->e_shnum;
981 elf->scp = (elf_section **)realloc(elf->scp, (count + 1) * sizeof(elf_section *));
982 elf->scp[count - 1] = scp;
983 elf->scp[count] = 0;
984 add_symbol(elf, 0, 0, 3, 0, scp, 0);
985}
986
987elf_section *remove_section(elf_file *elf, Elf32_Word shtype)
988{
989 elf_section *rmsec;
990 int s;
991
992 rmsec = 0;
993 for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
994 {
995 if ( shtype == elf->scp[s]->shr.sh_type )
996 {
997 elf->ehp->e_shnum -= 1;
998 rmsec = elf->scp[s];
999 break;
1000 }
1001 }
1002 for ( ; s < elf->ehp->e_shnum; s += 1 )
1003 {
1004 elf->scp[s] = elf->scp[s + 1];
1005 }
1006 return rmsec;
1007}
1008
1009elf_section *remove_section_by_name(elf_file *elf, const char *secname)
1010{
1011 elf_section *rmsec;
1012 int s;
1013
1014 rmsec = 0;
1015 for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
1016 {
1017 if ( !strcmp(elf->scp[s]->name, secname) )
1018 {
1019 elf->ehp->e_shnum -= 1;
1020 rmsec = elf->scp[s];
1021 break;
1022 }
1023 }
1024 for ( ; s < elf->ehp->e_shnum; s += 1 )
1025 {
1026 elf->scp[s] = elf->scp[s + 1];
1027 }
1028 return rmsec;
1029}
1030
1031elf_section *search_section(elf_file *elf, Elf32_Word stype)
1032{
1033 int i;
1034
1035 for ( i = 1; i < elf->ehp->e_shnum; i += 1 )
1036 {
1037 if ( stype == elf->scp[i]->shr.sh_type )
1038 {
1039 return elf->scp[i];
1040 }
1041 }
1042 return 0;
1043}
1044
1045elf_section *search_section_by_name(elf_file *elf, const char *secname)
1046{
1047 int i;
1048
1049 for ( i = 1; i < elf->ehp->e_shnum; i += 1 )
1050 {
1051 if ( !strcmp(elf->scp[i]->name, secname) )
1052 {
1053 return elf->scp[i];
1054 }
1055 }
1056 return 0;
1057}
1058
1059unsigned int *get_section_data(elf_file *elf, unsigned int addr)
1060{
1061 int i;
1062
1063 for ( i = 1; i < elf->ehp->e_shnum; i += 1 )
1064 {
1065 if (
1066 elf->scp[i]->shr.sh_type == SHT_PROGBITS && addr >= elf->scp[i]->shr.sh_addr
1067 && addr < elf->scp[i]->shr.sh_size + elf->scp[i]->shr.sh_addr )
1068 {
1069 return (unsigned int *)&elf->scp[i]->data[addr - elf->scp[i]->shr.sh_addr];
1070 }
1071 }
1072 return 0;
1073}
1074
1075elf_syment *search_global_symbol(const char *name, elf_file *elf)
1076{
1077 unsigned int entrise;
1078 unsigned int i;
1079 elf_syment **syp;
1080 elf_section *scp;
1081
1082 scp = search_section(elf, SHT_SYMTAB);
1083 if ( !scp )
1084 {
1085 return 0;
1086 }
1087 entrise = scp->shr.sh_size / scp->shr.sh_entsize;
1088 syp = (elf_syment **)scp->data;
1089 for ( i = 1; entrise > i; i += 1 )
1090 {
1091 if ( syp[i]->name && syp[i]->bind == STB_GLOBAL && !strcmp(syp[i]->name, name) )
1092 {
1093 return syp[i];
1094 }
1095 }
1096 return 0;
1097}
1098
1099int is_defined_symbol(const elf_syment *sym)
1100{
1101 if ( !sym )
1102 {
1103 return 0;
1104 }
1105 if ( !sym->sym.st_shndx )
1106 {
1107 return 0;
1108 }
1109 if ( sym->sym.st_shndx <= 0xFEFF )
1110 {
1111 return 1;
1112 }
1113 return sym->sym.st_shndx == SHN_ABS;
1114}
1115
1116elf_syment *add_symbol(elf_file *elf, const char *name, int bind, int type, int value, elf_section *scp, int st_shndx)
1117{
1118 unsigned int entrise;
1119 elf_syment *sym;
1120 elf_syment **newtab;
1121 elf_section *symtbl;
1122
1123 symtbl = search_section(elf, SHT_SYMTAB);
1124 if ( !symtbl )
1125 {
1126 return 0;
1127 }
1128 entrise = symtbl->shr.sh_size / symtbl->shr.sh_entsize;
1129 newtab = (elf_syment **)realloc(symtbl->data, (entrise + 1) * sizeof(elf_syment *));
1130 sym = (elf_syment *)calloc(1, sizeof(elf_syment));
1131 newtab[entrise] = sym;
1132 symtbl->shr.sh_size += symtbl->shr.sh_entsize;
1133 symtbl->data = (uint8_t *)newtab;
1134 if ( name )
1135 {
1136 sym->name = strdup(name);
1137 }
1138 sym->bind = bind;
1139 sym->type = type;
1140 sym->sym.st_info = (type & 0xF) + 16 * bind;
1141 sym->sym.st_value = value;
1142 sym->shptr = scp;
1143 if ( scp )
1144 {
1145 sym->sym.st_shndx = 1;
1146 }
1147 else
1148 {
1149 sym->sym.st_shndx = st_shndx;
1150 }
1151 return sym;
1152}
1153
1154unsigned int get_symbol_value(const elf_syment *sym, const elf_file *elf)
1155{
1156 if ( !is_defined_symbol(sym) )
1157 {
1158 return 0;
1159 }
1160 if ( sym->sym.st_shndx != SHN_ABS && elf->ehp->e_type == ET_REL )
1161 {
1162 return sym->shptr->shr.sh_addr + sym->sym.st_value;
1163 }
1164 return sym->sym.st_value;
1165}
1166
1167static void reorder_an_symtab(elf_file *elf, elf_section *scp)
1168{
1169 int sections;
1170 elf_syment **oldtab;
1171 elf_syment **newtab;
1172 unsigned int entrise;
1173 int sc;
1174 unsigned int d;
1175 unsigned int i;
1176 unsigned int j;
1177 unsigned int k;
1178 unsigned int m;
1179
1180 sections = elf->ehp->e_shnum;
1181 entrise = scp->shr.sh_size / scp->shr.sh_entsize;
1182 oldtab = (elf_syment **)malloc(entrise * sizeof(elf_syment *));
1183 memcpy(oldtab, (elf_syment **)scp->data, entrise * sizeof(elf_syment *));
1184 newtab = (elf_syment **)calloc(entrise, sizeof(elf_syment *));
1185 scp->data = (uint8_t *)newtab;
1186 *newtab = *oldtab;
1187 d = 1;
1188 for ( sc = 1; sections > sc; sc += 1 )
1189 {
1190 for ( i = 1; entrise > i; i += 1 )
1191 {
1192 if (
1193 oldtab[i] && oldtab[i]->type == STT_SECTION && !oldtab[i]->name && oldtab[i]->shptr
1194 && !strcmp(oldtab[i]->shptr->name, elf->scp[sc]->name) )
1195 {
1196 newtab[d] = oldtab[i];
1197 d += 1;
1198 oldtab[i] = 0;
1199 break;
1200 }
1201 }
1202 }
1203 for ( j = 1; entrise > j; j += 1 )
1204 {
1205 if ( oldtab[j] && oldtab[j]->type == STT_SECTION && !oldtab[j]->name )
1206 {
1207 oldtab[j] = 0;
1208 }
1209 }
1210 for ( k = 1; entrise > k; k += 1 )
1211 {
1212 if ( oldtab[k] && !oldtab[k]->bind )
1213 {
1214 newtab[d] = oldtab[k];
1215 d += 1;
1216 oldtab[k] = 0;
1217 }
1218 }
1219 scp->shr.sh_info = d;
1220 for ( m = 1; entrise > m; m += 1 )
1221 {
1222 if ( oldtab[m] )
1223 {
1224 newtab[d] = oldtab[m];
1225 d += 1;
1226 oldtab[m] = 0;
1227 }
1228 }
1229 scp->shr.sh_size = scp->shr.sh_entsize * d;
1230 free(oldtab);
1231}
1232
1233void reorder_symtab(elf_file *elf)
1234{
1235 int s;
1236
1237 for ( s = 1; s < elf->ehp->e_shnum; s += 1 )
1238 {
1239 switch ( elf->scp[s]->shr.sh_type )
1240 {
1241 case SHT_SYMTAB:
1242 case SHT_DYNSYM:
1243 reorder_an_symtab(elf, elf->scp[s]);
1244 break;
1245 default:
1246 break;
1247 }
1248 }
1249}
1250
1251unsigned int adjust_align(unsigned int value, unsigned int align)
1252{
1253 return ~(align - 1) & (align + value - 1);
1254}
1255
1256void rebuild_section_name_strings(elf_file *elf)
1257{
1258 unsigned int offset;
1259 size_t namesize;
1260 int i_1;
1261 int i_2;
1262
1263 namesize = 1;
1264 if ( elf->scp == NULL )
1265 {
1266 return;
1267 }
1268 for ( i_1 = 1; i_1 < elf->ehp->e_shnum; i_1 += 1 )
1269 {
1270 namesize += strlen(elf->scp[i_1]->name) + 1;
1271 }
1272 if ( elf->shstrptr->data )
1273 {
1274 free(elf->shstrptr->data);
1275 }
1276 elf->shstrptr->data = (uint8_t *)calloc(1, namesize);
1277 elf->shstrptr->shr.sh_size = namesize;
1278 offset = 1;
1279 for ( i_2 = 1; i_2 < elf->ehp->e_shnum; i_2 += 1 )
1280 {
1281 strcpy((char *)&elf->shstrptr->data[offset], elf->scp[i_2]->name);
1282 elf->scp[i_2]->shr.sh_name = offset;
1283 offset += strlen(elf->scp[i_2]->name) + 1;
1284 }
1285}
1286
1287static size_t search_string_table(const char *tbltop, size_t endindex, const char *str)
1288{
1289 size_t idx;
1290
1291 for ( idx = 1; idx < endindex; idx += strlen(&tbltop[idx]) + 1 )
1292 {
1293 if ( !strcmp(str, &tbltop[idx]) )
1294 {
1295 return idx;
1296 }
1297 }
1298 return 0;
1299}
1300
1301static void rebuild_a_symbol_name_strings(elf_section *scp)
1302{
1303 elf_section *strtab;
1304 elf_syment **syp;
1305 size_t offset;
1306 size_t namesize;
1307 unsigned int entrise;
1308 unsigned int i_1;
1309 unsigned int i_2;
1310
1311 entrise = scp->shr.sh_size / scp->shr.sh_entsize;
1312 strtab = scp->link;
1313 syp = (elf_syment **)scp->data;
1314 namesize = 1;
1315 for ( i_1 = 1; i_1 < entrise; i_1 += 1 )
1316 {
1317 namesize = (syp[i_1] != NULL && syp[i_1]->name != NULL) ? (strlen(syp[i_1]->name) + namesize + 1) : namesize;
1318 }
1319 if ( strtab->data )
1320 {
1321 free(strtab->data);
1322 }
1323 strtab->data = (uint8_t *)calloc(1, namesize);
1324 offset = 1;
1325 for ( i_2 = 1; i_2 < entrise; i_2 += 1 )
1326 {
1327 if ( syp[i_2] != NULL && syp[i_2]->name != NULL )
1328 {
1329 syp[i_2]->sym.st_name = search_string_table((char *)strtab->data, offset, syp[i_2]->name);
1330 if ( !syp[i_2]->sym.st_name )
1331 {
1332 strcpy((char *)&strtab->data[offset], syp[i_2]->name);
1333 syp[i_2]->sym.st_name = offset;
1334 offset += strlen(syp[i_2]->name) + 1;
1335 }
1336 }
1337 }
1338 strtab->shr.sh_size = offset;
1339}
1340
1341void rebuild_symbol_name_strings(elf_file *elf)
1342{
1343 int sc;
1344
1345 if ( elf->scp == NULL )
1346 {
1347 return;
1348 }
1349 for ( sc = 1; sc < elf->ehp->e_shnum; sc += 1 )
1350 {
1351 switch ( elf->scp[sc]->shr.sh_type )
1352 {
1353 case SHT_SYMTAB:
1354 case SHT_DYNSYM:
1355 rebuild_a_symbol_name_strings(elf->scp[sc]);
1356 break;
1357 default:
1358 break;
1359 }
1360 }
1361}
1362
1363static int comp_Elf_file_slot(const void *a1, const void *a2)
1364{
1365 const Elf_file_slot *p1;
1366 const Elf_file_slot *p2;
1367
1368 p1 = a1;
1369 p2 = a2;
1370
1371 if ( p1->type == EFS_TYPE_ELF_HEADER && p2->type == EFS_TYPE_ELF_HEADER )
1372 {
1373 return 0;
1374 }
1375 if ( p1->type == EFS_TYPE_ELF_HEADER )
1376 {
1377 return -1;
1378 }
1379 if ( p2->type == EFS_TYPE_ELF_HEADER )
1380 {
1381 return 1;
1382 }
1383 if ( p1->type == EFS_TYPE_PROGRAM_HEADER_TABLE && p2->type == EFS_TYPE_PROGRAM_HEADER_TABLE )
1384 {
1385 return 0;
1386 }
1387 if ( p1->type == EFS_TYPE_PROGRAM_HEADER_TABLE )
1388 {
1389 return -1;
1390 }
1391 if ( p2->type == EFS_TYPE_PROGRAM_HEADER_TABLE )
1392 {
1393 return 1;
1394 }
1395 if ( !p1->type && !p2->type )
1396 {
1397 return 0;
1398 }
1399 if ( !p1->type )
1400 {
1401 return 1;
1402 }
1403 if ( !p2->type )
1404 {
1405 return -1;
1406 }
1407 if ( p1->type == EFS_TYPE_END && p2->type == EFS_TYPE_END )
1408 {
1409 return 0;
1410 }
1411 if ( p1->type == EFS_TYPE_END )
1412 {
1413 return 1;
1414 }
1415 if ( p2->type == EFS_TYPE_END )
1416 {
1417 return -1;
1418 }
1419 if ( p1->type == EFS_TYPE_PROGRAM_HEADER_ENTRY && p2->type == EFS_TYPE_SECTION_HEADER_TABLE )
1420 {
1421 return -1;
1422 }
1423 if ( p1->type == EFS_TYPE_SECTION_HEADER_TABLE && p2->type == EFS_TYPE_PROGRAM_HEADER_ENTRY )
1424 {
1425 return 1;
1426 }
1427 if ( p2->offset == p1->offset )
1428 {
1429 return 0;
1430 }
1431 if ( p2->offset >= p1->offset )
1432 {
1433 return -1;
1434 }
1435 return 1;
1436}
1437
1438Elf_file_slot *build_file_order_list(const elf_file *elf)
1439{
1440 int sections;
1441 elf_section **scp;
1442 Elf_file_slot *resolt;
1443 int s_2;
1444 int d_1;
1445 size_t d_2;
1446 int maxent;
1447
1448 sections = elf->ehp->e_shnum;
1449 scp = (elf_section **)calloc(sections + 1, sizeof(elf_section *));
1450 memcpy(scp, elf->scp, sections * sizeof(elf_section *));
1451 maxent = elf->ehp->e_shnum + 2;
1452 if ( elf->ehp->e_phnum )
1453 {
1454 maxent = elf->ehp->e_phnum + elf->ehp->e_shnum + 3;
1455 }
1456 resolt = (Elf_file_slot *)calloc(maxent, sizeof(Elf_file_slot));
1457 resolt->type = EFS_TYPE_ELF_HEADER;
1458 resolt->offset = 0;
1459 resolt->size = sizeof(Elf32_Ehdr);
1460 resolt->align = 4;
1461 d_1 = 1;
1462 if ( elf->ehp->e_phnum )
1463 {
1464 int seg;
1465
1466 resolt[1].type = EFS_TYPE_PROGRAM_HEADER_TABLE;
1467 resolt[1].offset = resolt->size;
1468 resolt[1].size = sizeof(Elf32_Phdr) * elf->ehp->e_phnum;
1469 resolt[1].align = 4;
1470 for ( seg = 0, d_1 = 2; seg < elf->ehp->e_phnum; seg += 1, d_1 += 1 )
1471 {
1472 elf_section **phdscp;
1473
1474 resolt[d_1].type = EFS_TYPE_PROGRAM_HEADER_ENTRY;
1475 resolt[d_1].d.php = &elf->php[seg];
1476 resolt[d_1].offset = elf->php[seg].phdr.p_offset;
1477 resolt[d_1].size = elf->php[seg].phdr.p_filesz;
1478 resolt[d_1].align = elf->php[seg].phdr.p_align;
1479 for ( phdscp = elf->php[seg].scp; *phdscp; phdscp += 1 )
1480 {
1481 int s_1;
1482
1483 for ( s_1 = 0; s_1 < sections; s_1 += 1 )
1484 {
1485 if ( *phdscp == scp[s_1] )
1486 {
1487 scp[s_1] = 0;
1488 break;
1489 }
1490 }
1491 }
1492 }
1493 }
1494 resolt[d_1].type = EFS_TYPE_SECTION_HEADER_TABLE;
1495 resolt[d_1].offset = elf->ehp->e_shoff ?: (Elf32_Off)(-256);
1496 resolt[d_1].size = sizeof(Elf32_Shdr) * elf->ehp->e_shnum;
1497 resolt[d_1].align = 4;
1498 d_2 = d_1 + 1;
1499 for ( s_2 = 1; s_2 < sections; s_2 += 1 )
1500 {
1501 if ( scp[s_2] )
1502 {
1503 resolt[d_2].type = EFS_TYPE_SECTION_DATA;
1504 resolt[d_2].d.scp = scp[s_2];
1505 resolt[d_2].offset = scp[s_2]->shr.sh_offset;
1506 resolt[d_2].size = scp[s_2]->shr.sh_size;
1507 resolt[d_2].align = scp[s_2]->shr.sh_addralign;
1508 scp[s_2] = 0;
1509 d_2 += 1;
1510 }
1511 }
1512 resolt[d_2].type = EFS_TYPE_END;
1513 free(scp);
1514 qsort(resolt, d_2, sizeof(Elf_file_slot), comp_Elf_file_slot);
1515 return resolt;
1516}
1517
1518void shrink_file_order_list(Elf_file_slot *efs)
1519{
1520 unsigned int slot;
1521
1522 slot = 0;
1523 for ( ; efs->type != EFS_TYPE_END; efs += 1 )
1524 {
1525 unsigned int foffset;
1526
1527 foffset = adjust_align(slot, efs->align);
1528 efs->offset = foffset;
1529 slot = efs->size + foffset;
1530 }
1531}
1532
1533void writeback_file_order_list(elf_file *elf, Elf_file_slot *efs)
1534{
1535 elf_section **scp;
1536 unsigned int segoffset;
1537 int i;
1538
1539 for ( ; efs->type != EFS_TYPE_END; efs += 1 )
1540 {
1541 switch ( efs->type )
1542 {
1543 case EFS_TYPE_PROGRAM_HEADER_TABLE:
1544 elf->ehp->e_phoff = efs->offset;
1545 break;
1546 case EFS_TYPE_PROGRAM_HEADER_ENTRY:
1547 efs->d.php->phdr.p_offset = efs->offset;
1548 scp = efs->d.php->scp;
1549 segoffset = efs->offset;
1550 (*scp)->shr.sh_offset = efs->offset;
1551 for ( i = 1; scp[i]; i += 1 )
1552 {
1553 if ( scp[i]->shr.sh_type != SHT_NOBITS )
1554 {
1555 segoffset = scp[i]->shr.sh_addr + efs->offset - (*scp)->shr.sh_addr;
1556 }
1557 scp[i]->shr.sh_offset = segoffset;
1558 if ( scp[i]->shr.sh_type != SHT_NOBITS )
1559 {
1560 segoffset += scp[i]->shr.sh_size;
1561 }
1562 }
1563 break;
1564 case EFS_TYPE_SECTION_HEADER_TABLE:
1565 elf->ehp->e_shoff = efs->offset;
1566 break;
1567 case EFS_TYPE_SECTION_DATA:
1568 efs->d.php->phdr.p_filesz = efs->offset;
1569 break;
1570 default:
1571 break;
1572 }
1573 }
1574}
1575
1576void dump_file_order_list(const elf_file *elf, const Elf_file_slot *efs)
1577{
1578 unsigned int offset;
1579 unsigned int size_tmp;
1580 unsigned int offset_tmp;
1581 char tmp[100];
1582 const char *name;
1583 elf_section **scp;
1584 const Elf_file_slot *slot;
1585 int i;
1586
1587 offset_tmp = efs->offset;
1588 printf("\n");
1589 for ( slot = efs; slot->type != EFS_TYPE_END; slot += 1 )
1590 {
1591 unsigned int oldend_1;
1592 unsigned int size_1;
1593 unsigned int startpos_1;
1594
1595 oldend_1 = slot->size;
1596 startpos_1 = slot->offset;
1597 if ( oldend_1 == 0 )
1598 {
1599 offset = slot->offset;
1600 }
1601 else
1602 {
1603 offset = oldend_1 + startpos_1 - 1;
1604 }
1605 size_1 = offset;
1606 switch ( slot->type )
1607 {
1608 case EFS_TYPE_ELF_HEADER:
1609 name = "[Elf header]";
1610 break;
1611 case EFS_TYPE_PROGRAM_HEADER_TABLE:
1612 name = "[Proram Header Table]";
1613 break;
1614 case EFS_TYPE_PROGRAM_HEADER_ENTRY:
1615 sprintf(tmp, "[Proram Header entry %d]", (int)(0xCCCCCCCD * ((char *)slot->d.php - (char *)elf->php)) >> 3);
1616 name = tmp;
1617 break;
1618 case EFS_TYPE_SECTION_HEADER_TABLE:
1619 name = "[Section Header Table]";
1620 break;
1621 case EFS_TYPE_SECTION_DATA:
1622 sprintf(tmp, "%s data", slot->d.scp->name);
1623 name = tmp;
1624 break;
1625 default:
1626 name = "internal error Unknown EFS type !!!!";
1627 break;
1628 }
1629 if ( startpos_1 > offset_tmp + 1 )
1630 {
1631 printf("%36s = %08x-%08x (%06x)\n", "**Blank**", offset_tmp + 1, startpos_1 - 1, startpos_1 - offset_tmp - 1);
1632 }
1633 offset_tmp = size_1;
1634 printf("%36s = %08x-%08x (%06x)\n", name, startpos_1, size_1, oldend_1);
1635 if ( slot->type == EFS_TYPE_PROGRAM_HEADER_ENTRY )
1636 {
1637 scp = slot->d.php->scp;
1638 (*scp)->shr.sh_offset = slot->offset;
1639 size_tmp = slot->offset;
1640 for ( i = 0; scp[i]; i += 1 )
1641 {
1642 unsigned int oldend_2;
1643 unsigned int size_2;
1644 unsigned int startpos_2;
1645
1646 if ( scp[i]->shr.sh_type == SHT_NOBITS )
1647 {
1648 oldend_2 = 0;
1649 }
1650 else
1651 {
1652 oldend_2 = scp[i]->shr.sh_size;
1653 }
1654 startpos_2 = scp[i]->shr.sh_offset;
1655 size_2 = (oldend_2 == 0) ? (scp[i]->shr.sh_offset) : (Elf32_Off)(oldend_2 + startpos_2 - 1);
1656 sprintf(tmp, "(%s)", scp[i]->name);
1657 name = tmp;
1658 if ( startpos_2 > size_tmp + 1 )
1659 {
1660 printf("%36s | %08x-%08x (%06x)\n", "**Blank**", size_tmp + 1, startpos_2 - 1, startpos_2 - size_tmp - 1);
1661 }
1662 size_tmp = size_2;
1663 printf("%36s | %08x-%08x (%06x)\n", name, startpos_2, size_2, scp[i]->shr.sh_size);
1664 }
1665 }
1666 }
1667}
u32 count
start sector of fragmented bd/file