PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
elfdump.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
17struct rellink
18{
19 int rid;
20 const elf_rel *rp;
21 const elf_rel *mhrp;
22};
24{
25 const char *name;
26 unsigned int num;
27};
28
29static void search_rel_section(
30 const elf_file *elf, const elf_section *scp, elf_rel **result, unsigned int *relentries, unsigned int *baseoff);
31static void search_rel_data(const elf_rel *rpbase, unsigned int relentries, unsigned int addr, struct rellink *result);
32static void dumpb(const char *head, unsigned int address, unsigned int size, const uint8_t *data);
33static void dumph(const char *head, unsigned int address, unsigned int size, const uint16_t *data);
34static void dumpw(const char *head, unsigned int address, unsigned int size, const uint32_t *data);
35static const char *num2name(const struct name2num *table, unsigned int num);
36
37void print_elf(const elf_file *elf, unsigned int flag)
38{
39 if ( elf == NULL )
40 {
41 return;
42 }
43 print_elf_ehdr(elf, flag);
44 print_elf_phdr(elf, flag);
45 print_elf_sections(elf, flag);
46 if ( (flag & 0x100) != 0 )
47 {
48 Elf_file_slot *order;
49
50 order = build_file_order_list(elf);
51 dump_file_order_list(elf, order);
52 free(order);
53 }
54}
55
56// clang-format off
57static const struct name2num Ei_class_name[] =
58{
59#define X(d) { #d, d },
60 XEACH_Ei_class_name_enum()
61#undef X
62 { NULL, 0 },
63};
64static const struct name2num E_type_name[] =
65{
66#define X(d) { #d, d },
67 XEACH_E_type_name_enum()
68#undef X
69 { NULL, 0 },
70};
71static const struct name2num Ei_data_name[] =
72{
73#define X(d) { #d, d },
74 XEACH_Ei_data_name_enum()
75#undef X
76 { NULL, 0 },
77};
78static const struct name2num E_version_name[] =
79{
80#define X(d) { #d, d },
81 XEACH_E_version_name_enum()
82#undef X
83 { NULL, 0 },
84};
85static const struct name2num E_machine_name[] =
86{
87#define X(d) { #d, d },
88 XEACH_E_machine_name_enum()
89#undef X
90 { NULL, 0 },
91};
92// clang-format on
93
94void print_elf_ehdr(const elf_file *elf, unsigned int flag)
95{
96 if ( (flag & 1) == 0 )
97 {
98 return;
99 }
100 printf(" Elf header\n");
101 printf(
102 " e_ident = 0x%02x+\"%c%c%c\", class = %s, encode = %s\n",
103 elf->ehp->e_ident[0],
104 elf->ehp->e_ident[1],
105 elf->ehp->e_ident[2],
106 elf->ehp->e_ident[3],
107 num2name(Ei_class_name, elf->ehp->e_ident[4]),
108 num2name(Ei_data_name, elf->ehp->e_ident[5]));
109 printf(" version = %s\n", num2name(E_version_name, elf->ehp->e_ident[6]));
110 printf(
111 " e_type = %s, e_machine = %s, e_version = %s\n",
112 num2name(E_type_name, elf->ehp->e_type),
113 num2name(E_machine_name, elf->ehp->e_machine),
114 num2name(E_version_name, elf->ehp->e_version));
115 printf(
116 " e_entry = 0x%08x, e_phoff = 0x%08x, e_shoff = 0x%08x\n",
117 elf->ehp->e_entry,
118 elf->ehp->e_phoff,
119 elf->ehp->e_shoff);
120 printf(" e_flags = 0x%08x ", elf->ehp->e_flags);
121 if ( (elf->ehp->e_flags & EF_MIPS_NOREORDER) != 0 )
122 {
123 printf("EF_MIPS_NOREORDER ");
124 }
125 if ( (elf->ehp->e_flags & EF_MIPS_PIC) != 0 )
126 {
127 printf("EF_MIPS_PIC");
128 }
129 if ( (elf->ehp->e_flags & EF_MIPS_CPIC) != 0 )
130 {
131 printf("EF_MIPS_CPIC");
132 }
133 printf("\n");
134 printf(
135 " e_ehsize = 0x%04x, e_phentsize = 0x%04x, e_phnum = 0x%04x\n",
136 elf->ehp->e_ehsize,
137 elf->ehp->e_phentsize,
138 elf->ehp->e_phnum);
139 printf(
140 " e_shentsize = 0x%04x, e_shnum = 0x%04x, e_shstrndx = 0x%04x\n",
141 elf->ehp->e_shentsize,
142 elf->ehp->e_shnum,
143 elf->ehp->e_shstrndx);
144}
145
146// clang-format off
147static const struct name2num P_type_name[] =
148{
149#define X(d) { #d, d },
150 XEACH_P_type_name_enum()
151#undef X
152 { NULL, 0 },
153};
154// clang-format on
155
156void print_elf_phdr(const elf_file *elf, unsigned int flag)
157{
158 int i;
159
160 if ( elf->php == NULL || (flag & 1) == 0 )
161 {
162 return;
163 }
164 printf(" Program header\n");
165 for ( i = 0; i < elf->ehp->e_phnum; i += 1 )
166 {
167 printf(" %2d: p_type=%s, ", i, num2name(P_type_name, elf->php[i].phdr.p_type));
168 printf(
169 "p_offset=0x%06x, p_vaddr,p_paddr=0x%06x,0x%06x\n",
170 elf->php[i].phdr.p_offset,
171 elf->php[i].phdr.p_vaddr,
172 elf->php[i].phdr.p_paddr);
173 printf(
174 " p_filesz=0x%06x, p_memsiz=0x%06x, p_align=%d\n",
175 elf->php[i].phdr.p_filesz,
176 elf->php[i].phdr.p_memsz,
177 (int)(elf->php[i].phdr.p_align));
178 printf(" p_flags=0x%08x ( ", elf->php[i].phdr.p_flags);
179 if ( (elf->php[i].phdr.p_flags & PF_X) != 0 )
180 {
181 printf("PF_X ");
182 }
183 if ( (elf->php[i].phdr.p_flags & PF_W) != 0 )
184 {
185 printf("PF_W ");
186 }
187 if ( (elf->php[i].phdr.p_flags & PF_R) != 0 )
188 {
189 printf("PF_R ");
190 }
191 printf(")\n");
192 if ( elf->php[i].scp )
193 {
194 int j;
195
196 printf(" include sections = ");
197 for ( j = 0; elf->php[i].scp[j]; j += 1 )
198 {
199 printf("%s ", elf->php[i].scp[j]->name);
200 }
201 printf("\n");
202 }
203 }
204}
205
206// clang-format off
207static const struct name2num S_type_name[] =
208{
209#define X(d) { #d, d },
210 XEACH_S_type_name_enum()
211#undef X
212 { NULL, 0 },
213};
214// clang-format on
215
216void print_elf_sections(const elf_file *elf, unsigned int flag)
217{
218 int i;
219
220 if ( elf->scp == NULL )
221 {
222 return;
223 }
224 if ( (flag & 1) != 0 )
225 {
226 printf(" Section header\n");
227 }
228 for ( i = 1; i < elf->ehp->e_shnum; i += 1 )
229 {
230 if ( (flag & 1) != 0 || ((flag & 2) != 0 && elf->scp[i]->shr.sh_type == SHT_REL) )
231 {
232 printf(
233 " %2d: %-12s sh_name=0x%04x sh_type=%s\n",
234 i,
235 elf->scp[i]->name,
236 elf->scp[i]->shr.sh_name,
237 num2name(S_type_name, elf->scp[i]->shr.sh_type));
238 printf(" sh_flas=0x%08x ( ", elf->scp[i]->shr.sh_flags);
239 if ( (elf->scp[i]->shr.sh_flags & SHF_WRITE) != 0 )
240 {
241 printf("SHF_WRITE ");
242 }
243 if ( (elf->scp[i]->shr.sh_flags & SHF_ALLOC) != 0 )
244 {
245 printf("SHF_ALLOC ");
246 }
247 if ( (elf->scp[i]->shr.sh_flags & SHF_EXECINSTR) != 0 )
248 {
249 printf("SHF_EXECINSTR ");
250 }
251 if ( (elf->scp[i]->shr.sh_flags & SHF_MIPS_GPREL) != 0 )
252 {
253 printf("SHF_MIPS_GPREL ");
254 }
255 printf(")\n");
256 printf(
257 " sh_addr,sh_offset,sh_size=0x%06x,0x%06x,0x%06x, sh_addralign=%2d\n",
258 elf->scp[i]->shr.sh_addr,
259 elf->scp[i]->shr.sh_offset,
260 elf->scp[i]->shr.sh_size,
261 (int)(elf->scp[i]->shr.sh_addralign));
262 printf(
263 " sh_link=0x%08x, sh_info=0x%08x, sh_entsize=0x%02x(%d)\n",
264 elf->scp[i]->shr.sh_link,
265 elf->scp[i]->shr.sh_info,
266 elf->scp[i]->shr.sh_entsize,
267 (int)(elf->scp[i]->shr.sh_entsize));
268 }
269 switch ( elf->scp[i]->shr.sh_type )
270 {
271 case SHT_SYMTAB:
272 case SHT_DYNSYM:
273 print_elf_symtbl(elf->scp[i], flag);
274 continue;
275 case SHT_REL:
276 print_elf_reloc(elf->scp[i], flag);
277 continue;
278 case SHT_MIPS_DEBUG:
279 print_elf_mips_symbols((elf_mips_symbolic_data *)elf->scp[i]->data, flag);
280 continue;
281 case SHT_SCE_IOPMOD:
282 if ( (flag & 1) != 0 )
283 {
284 const Elf32_IopMod *data;
285
286 data = (Elf32_IopMod *)elf->scp[i]->data;
287 printf(
288 " moduleinfo=0x%08x, entry=0x%08x, gpvalue=0x%08x\n", data->moduleinfo, data->entry, data->gp_value);
289 printf(
290 " text_size=0x%08x, data_size=0x%08x, bss_size=0x%08x\n",
291 data->text_size,
292 data->data_size,
293 data->bss_size);
294 }
295 break;
296 case SHT_SCE_EEMOD:
297 if ( (flag & 1) != 0 )
298 {
299 const Elf32_EeMod *data;
300
301 data = (Elf32_EeMod *)elf->scp[i]->data;
302 printf(
303 " moduleinfo=0x%08x, entry=0x%08x, gpvalue=0x%08x\n", data->moduleinfo, data->entry, data->gp_value);
304 printf(
305 " text_size=0x%08x, data_size=0x%08x, bss_size=0x%08x\n",
306 data->text_size,
307 data->data_size,
308 data->bss_size);
309 printf(" erx_lib_addr=0x%08x, erx_lib_size=0x%08x\n", data->erx_lib_addr, data->erx_lib_size);
310 printf(" erx_stub_addr=0x%08x, erx_stub_size=0x%08x\n", data->erx_stub_addr, data->erx_stub_size);
311 }
312 break;
313 case SHT_MIPS_REGINFO:
314 if ( (flag & 1) != 0 )
315 {
316 const Elf32_RegInfo *data;
317
318 data = (Elf32_RegInfo *)elf->scp[i]->data;
319 printf(
320 " gpmask=0x08x, cprmask=%08x,%08x,%08x,%08x\n",
321 data->ri_gprmask,
322 data->ri_cprmask[0],
323 data->ri_cprmask[1],
324 data->ri_cprmask[3]);
325 printf(" gp=0x%08x\n", data->ri_gp_value);
326 }
327 break;
328 default:
329 break;
330 }
331 if ( elf->scp[i]->data )
332 {
333 if ( (elf->scp[i]->shr.sh_flags & SHF_EXECINSTR) != 0 && elf->ehp->e_machine == EM_MIPS )
334 {
335 if (
336 ((elf->ehp->e_flags & EF_MIPS_MACH) == EF_MIPS_MACH_5900)
337 && ((elf->ehp->e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_3) )
338 {
339 initdisasm(2, -1, 0, 0, 0);
340 }
341 else
342 {
343 initdisasm(1, -1, 0, 0, 0);
344 }
345 print_elf_disasm(elf, elf->scp[i], flag);
346 }
347 else
348 {
349 print_elf_datadump(elf, elf->scp[i], flag);
350 }
351 }
352 }
353}
354
355// clang-format off
356static const struct name2num R_MIPS_Type[] =
357{
358#define X(d) { #d, d },
359 XEACH_R_MIPS_Type_enum()
360#undef X
361 { NULL, 0 },
362};
363// clang-format on
364
365void print_elf_reloc(const elf_section *scp, unsigned int flag)
366{
367 const elf_rel *rp;
368 unsigned int entrise;
369 unsigned int i;
370
371 if ( (flag & 2) == 0 )
372 {
373 return;
374 }
375 entrise = scp->shr.sh_size / scp->shr.sh_entsize;
376 if ( entrise != 0 )
377 {
378 printf(" ###: r_offset r_type r_sym\n");
379 printf(" --- -------- -------------------- -----------------------------------\n");
380 }
381 rp = (elf_rel *)scp->data;
382 for ( i = 0; i < entrise; i += 1 )
383 {
384 printf(" %3u: 0x%06x 0x%02x %-16s ", i, rp[i].rel.r_offset, rp[i].type, num2name(R_MIPS_Type, rp[i].type));
385 if ( rp[i].symptr && rp[i].symptr->type == STT_SECTION )
386 {
387 printf("0x%03x[%s]\n", rp[i].rel.r_info >> 8, rp[i].symptr->shptr->name);
388 }
389 else
390 {
391 printf("0x%03x %s\n", rp[i].rel.r_info >> 8, (rp[i].symptr && rp[i].symptr->name) ? rp[i].symptr->name : "");
392 }
393 }
394 printf("\n");
395}
396
397void print_elf_disasm(const elf_file *elf, const elf_section *scp, unsigned int flag)
398{
399 int v7;
400 const elf_rel *rp;
401 elf_rel *rpbase;
402 struct rellink *rel;
403 Disasm_result **dis;
404 char pb[200];
405 unsigned int baseoff;
406 unsigned int addr;
407 const unsigned int *codes;
408 unsigned int relentries;
409 size_t steps;
410 int d;
411 unsigned int i;
412
413 if ( (flag & 8) == 0 )
414 {
415 return;
416 }
417 steps = scp->shr.sh_size >> 2;
418 codes = (unsigned int *)scp->data;
419 dis = (Disasm_result **)malloc(steps * sizeof(Disasm_result *));
420 search_rel_section(elf, scp, &rpbase, &relentries, &baseoff);
421 rel = (struct rellink *)calloc(steps, sizeof(struct rellink));
422 for ( i = 0, addr = 0; i < steps; i += 1, addr += 4 )
423 {
424 dis[i] = disassemble(addr, codes[i]);
425 gen_asmmacro(dis[i]);
426 search_rel_data(rpbase, relentries, baseoff + addr, &rel[i]);
427 }
428 for ( i = 0; i < steps; i += 1 )
429 {
430 if ( rel[i].rp && rel[i].rp->type == R_MIPSSCE_MHI16 )
431 {
432 unsigned int j;
433
434 j = i;
435 for ( d = (int16_t)(codes[i] & 0xFFFF); d; d = (int16_t)(codes[j] & 0xFFFF) )
436 {
437 j += d;
438 rel[j].rid = rel[i].rid;
439 rel[j].mhrp = rel[i].rp;
440 }
441 }
442 }
443 for ( i = 0; i < steps; i += 1 )
444 {
445 format_disasm(dis[i], pb);
446 if ( rel[i].rp || rel[i].mhrp )
447 {
448 size_t k;
449
450 for ( k = strlen(pb); k <= 47; k += 1 )
451 {
452 pb[k] = 32;
453 }
454 pb[48] = 0;
455 sprintf(&pb[strlen(pb)], "%3d:", rel[i].rid);
456 if ( rel[i].rp )
457 {
458 rp = rel[i].rp;
459 strcat(pb, " ");
460 }
461 else
462 {
463 rp = rel[i].mhrp;
464 strcat(pb, ">");
465 }
466 if ( rp->symptr && rp->symptr->type == STT_SECTION )
467 {
468 sprintf(
469 &pb[strlen(pb)],
470 " %s %d '%s'",
471 num2name(R_MIPS_Type, rp->type),
472 (int)(rp->rel.r_info >> 8),
473 rp->symptr->shptr->name);
474 }
475 else
476 {
477 v7 = ' ';
478 if ( rp->symptr )
479 {
480 switch ( rp->symptr->bind )
481 {
482 case STB_GLOBAL:
483 v7 = 'E';
484 break;
485 case STB_LOCAL:
486 v7 = 'l';
487 break;
488 case STB_WEAK:
489 v7 = 'w';
490 break;
491 default:
492 break;
493 }
494 }
495 sprintf(
496 &pb[strlen(pb)],
497 "%c %s %d %s",
498 v7,
499 num2name(R_MIPS_Type, rp->type),
500 (int)(rp->rel.r_info >> 8),
501 (rp->symptr && rp->symptr->name) ? rp->symptr->name : "");
502 }
503 }
504 printf(" %s\n", pb);
505 free(dis[i]);
506 }
507 printf("\n");
508 free(dis);
509 free(rel);
510}
511
512static void search_rel_section(
513 const elf_file *elf, const elf_section *scp, elf_rel **result, unsigned int *relentries, unsigned int *baseoff)
514{
515 elf_section *relscp;
516 int i;
517
518 relscp = 0;
519 for ( i = 1; i < elf->ehp->e_shnum; i += 1 )
520 {
521 relscp = elf->scp[i];
522 if ( relscp->shr.sh_type == SHT_REL && scp == relscp->info )
523 {
524 break;
525 }
526 }
527 if ( i < elf->ehp->e_shnum )
528 {
529 *result = (elf_rel *)relscp->data;
530 *relentries = relscp->shr.sh_size / relscp->shr.sh_entsize;
531 *baseoff = 0;
532 switch ( elf->ehp->e_type )
533 {
534 case ET_SCE_IOPRELEXEC:
535 case ET_SCE_IOPRELEXEC2:
536 case ET_SCE_EERELEXEC:
537 case ET_SCE_EERELEXEC2:
538 *baseoff = scp->shr.sh_addr;
539 break;
540 default:
541 break;
542 }
543 }
544 else
545 {
546 *result = 0;
547 *relentries = 0;
548 *baseoff = 0;
549 }
550}
551
552static void search_rel_data(const elf_rel *rpbase, unsigned int relentries, unsigned int addr, struct rellink *result)
553{
554 int j;
555
556 result->rid = -1;
557 result->rp = 0;
558 for ( j = 0; j < (int)relentries; j += 1 )
559 {
560 if ( rpbase[j].type != R_MIPSSCE_ADDEND && addr == rpbase[j].rel.r_offset )
561 {
562 result->rid = j;
563 result->rp = &rpbase[j];
564 return;
565 }
566 }
567}
568
569static void dumpb(const char *head, unsigned int address, unsigned int size, const uint8_t *data)
570{
571 uint8_t cbuf[20];
572 unsigned int addr;
573 unsigned int off2;
574 unsigned int off1;
575
576 addr = address & ~0xF;
577 off1 = 0;
578 off2 = size;
579 strcpy((char *)cbuf, "........ ........");
580 for ( ; off1 < off2; addr += 1 )
581 {
582 if ( (addr & 0xF) == 0 )
583 {
584 printf("%s%08x: ", head, addr);
585 }
586 if ( address > addr )
587 {
588 printf("-- ");
589 }
590 else
591 {
592 printf("%02x ", data[off1]);
593 if ( data[off1] > 0x1F && data[off1] <= 0x7E )
594 {
595 unsigned int v4;
596 uint8_t *v5;
597
598 v4 = addr & 0xF;
599 if ( v4 <= 7 )
600 {
601 v5 = &cbuf[v4];
602 }
603 else
604 {
605 v5 = &cbuf[v4 + 1];
606 }
607 *v5 = data[off1];
608 }
609 }
610 if ( (((uint8_t)addr + 1) & 3) == 0 )
611 {
612 printf(" ");
613 }
614 if ( (addr & 0xF) == 15 )
615 {
616 printf("%s", cbuf);
617 printf("\n");
618 strcpy((char *)cbuf, "........ ........");
619 }
620 if ( address <= addr )
621 {
622 off1 += 1;
623 }
624 }
625 for ( ; (addr & 0xF) != 0; addr += 1 )
626 {
627 printf("-- ");
628 if ( (((uint8_t)addr + 1) & 3) == 0 )
629 {
630 printf(" ");
631 }
632 if ( (addr & 0xF) == 15 )
633 {
634 printf("%s", cbuf);
635 printf("\n");
636 strcpy((char *)cbuf, "........ ........");
637 }
638 }
639}
640
641static void dumph(const char *head, unsigned int address, unsigned int size, const uint16_t *data)
642{
643 unsigned int addr;
644 unsigned int off2;
645 unsigned int off1;
646
647 addr = address & ~0xF;
648 off2 = addr;
649 off1 = 0;
650 for ( ; off1 < size; off2 += 2 )
651 {
652 if ( (off2 & 0xF) == 0 )
653 {
654 printf("%s%08x: ", head, off2);
655 }
656 if ( address > off2 )
657 {
658 printf("---- ");
659 }
660 else
661 {
662 printf("%04x ", data[off1 >> 1]);
663 }
664 if ( (((uint8_t)off2 + 2) & 3) == 0 )
665 {
666 printf(" ");
667 }
668 if ( (off2 & 0xF) == 14 )
669 {
670 printf("\n");
671 }
672 if ( address <= off2 )
673 {
674 off1 += 2;
675 }
676 }
677 for ( ; (off2 & 0xF) != 0; off2 += 2 )
678 {
679 printf("---- ");
680 if ( (((uint8_t)off2 + 2) & 3) == 0 )
681 {
682 printf(" ");
683 }
684 if ( (off2 & 0xF) == 14 )
685 {
686 printf("\n");
687 }
688 }
689}
690
691static void dumpw(const char *head, unsigned int address, unsigned int size, const uint32_t *data)
692{
693 unsigned int off1;
694 unsigned int addr;
695
696 addr = address & ~0xF;
697 off1 = 0;
698 for ( ; off1 < size; addr += 4 )
699 {
700 if ( (addr & 0xF) == 0 )
701 {
702 printf("%s%08x: ", head, addr);
703 }
704 if ( address > addr )
705 {
706 printf("-------- ");
707 }
708 else
709 {
710 printf("%08x ", data[off1 >> 2]);
711 }
712 if ( (addr & 0xF) == 12 )
713 {
714 printf("\n");
715 }
716 if ( address <= addr )
717 {
718 off1 += 4;
719 }
720 }
721 for ( ; (addr & 0xF) != 0; addr += 4 )
722 {
723 printf("-------- ");
724 if ( (addr & 0xF) == 12 )
725 {
726 printf("\n");
727 }
728 }
729}
730
731void print_elf_datadump(const elf_file *elf, const elf_section *scp, unsigned int flag)
732{
733 elf_rel *rpbase;
734 struct rellink rel;
735 unsigned int relentries;
736 unsigned int baseoff;
737 unsigned int *dumpbuf;
738
739 if ( (flag & 0xF0) == 0 )
740 {
741 return;
742 }
743 dumpbuf = (unsigned int *)calloc(1, scp->shr.sh_size + 4);
744 memcpy(dumpbuf, scp->data, scp->shr.sh_size);
745 switch ( scp->shr.sh_type )
746 {
747 case SHT_PROGBITS:
748 case SHT_HASH:
749 case SHT_DYNAMIC:
750 case SHT_MIPS_REGINFO:
751 swapmemory(dumpbuf, "l", (scp->shr.sh_size + 1) >> 2);
752 break;
753 default:
754 break;
755 }
756 printf("\n");
757 if ( (flag & 0x10) != 0 )
758 {
759 dumpb("", 0, scp->shr.sh_size, (uint8_t *)dumpbuf);
760 printf("\n");
761 }
762 if ( (flag & 0x20) != 0 )
763 {
764 dumph(" ", 0, scp->shr.sh_size, (uint16_t *)dumpbuf);
765 printf("\n");
766 }
767 if ( (flag & 0xC0) != 0 )
768 {
769 unsigned int offset;
770
771 search_rel_section(elf, scp, &rpbase, &relentries, &baseoff);
772 for ( offset = 0; offset < scp->shr.sh_size; offset += 16 )
773 {
774 dumpw(
775 " ",
776 offset,
777 (scp->shr.sh_size > offset + 16) ? 16 : (scp->shr.sh_size - offset),
778 &dumpbuf[offset / 4]);
779 if ( (flag & 0x80) != 0 )
780 {
781 int i;
782
783 for ( i = 0; i <= 15 && (offset + i) < scp->shr.sh_size; i += 4 )
784 {
785 search_rel_data(rpbase, relentries, baseoff + offset + i, &rel);
786 if ( rel.rid >= 0 )
787 {
788 printf(" +%02x:", i);
789 printf(" [%3d]", rel.rid);
790 if ( rel.rp->symptr && rel.rp->symptr->type == STT_SECTION )
791 {
792 printf(
793 " %s %d '%s'",
794 num2name(R_MIPS_Type, rel.rp->type),
795 (int)(rel.rp->rel.r_info >> 8),
796 rel.rp->symptr->shptr->name);
797 }
798 else
799 {
800 int v7;
801
802 v7 = ' ';
803 if ( rel.rp->symptr )
804 {
805 switch ( rel.rp->symptr->bind )
806 {
807 case STB_GLOBAL:
808 v7 = 'E';
809 break;
810 case STB_LOCAL:
811 v7 = 'l';
812 break;
813 case STB_WEAK:
814 v7 = 'w';
815 break;
816 default:
817 break;
818 }
819 }
820 printf(
821 "%c %s %d %s",
822 v7,
823 num2name(R_MIPS_Type, rel.rp->type),
824 (int)(rel.rp->rel.r_info >> 8),
825 (rel.rp->symptr && rel.rp->symptr->name) ? rel.rp->symptr->name : "");
826 }
827 printf("\n");
828 }
829 }
830 }
831 }
832 printf("\n");
833 }
834 free(dumpbuf);
835}
836
837// clang-format off
838static const struct name2num SymbolBinding[] =
839{
840#define X(d) { #d, d },
841 XEACH_SymbolBinding_enum()
842#undef X
843 { NULL, 0 },
844};
845static const struct name2num SymbolType[] =
846{
847#define X(d) { #d, d },
848 XEACH_SymbolType_enum()
849#undef X
850 { NULL, 0 },
851};
852static const struct name2num SymbolSpSection[] =
853{
854#define X(d) { #d, d },
855 XEACH_SymbolSpSection_enum()
856#undef X
857 { NULL, 0 },
858};
859// clang-format on
860
861void print_elf_symtbl(const elf_section *scp, unsigned int flag)
862{
863 elf_syment **syp;
864 unsigned int entirse;
865 unsigned int i;
866
867 if ( (flag & 4) == 0 )
868 {
869 return;
870 }
871 entirse = scp->shr.sh_size / scp->shr.sh_entsize;
872 syp = (elf_syment **)scp->data;
873 if ( entirse > 1 )
874 {
875 printf(" ###: name bind type st_value st_size st_shndx\n");
876 printf(" --- ----------- ---------- ----------- ---------- ------ ------------------\n");
877 }
878 for ( i = 1; i < entirse; i += 1 )
879 {
880 printf(" %3u: ", i);
881 if ( syp[i]->name && strlen(syp[i]->name) > 0xB )
882 {
883 printf("%s\n ", syp[i]->name);
884 }
885 else
886 {
887 printf("%-11s ", syp[i]->name ?: "<no name>");
888 }
889 printf(
890 "%-10s %-11s 0x%08x 0x%04x ",
891 num2name(SymbolBinding, syp[i]->bind),
892 num2name(SymbolType, syp[i]->type),
893 syp[i]->sym.st_value,
894 syp[i]->sym.st_size);
895 if ( syp[i]->shptr )
896 {
897 printf("%2d '%s'", syp[i]->sym.st_shndx, syp[i]->shptr->name);
898 }
899 else
900 {
901 int st_shndx;
902
903 st_shndx = syp[i]->sym.st_shndx;
904 printf("%s(0x%x)", num2name(SymbolSpSection, st_shndx), st_shndx);
905 }
906 if ( syp[i]->sym.st_other )
907 {
908 printf(" st_other=0x%x", syp[i]->sym.st_other);
909 }
910 printf("\n");
911 }
912 printf("\n");
913}
914
915static const char *num2name(const struct name2num *table, unsigned int num)
916{
917 static char buf_28[30];
918
919 for ( ; table->name; table += 1 )
920 {
921 if ( num == table->num )
922 {
923 return table->name;
924 }
925 }
926 sprintf(buf_28, "? 0x%x", num);
927 return buf_28;
928}
929
930// clang-format off
931static const struct name2num SymbolTypes[] =
932{
933#define X(d) { #d, d },
934 XEACH_SymbolTypes_enum()
935#undef X
936 { NULL, 0 },
937};
938static const struct name2num StorageClasse[] =
939{
940#define X(d) { #d, d },
941 XEACH_StorageClasse_enum()
942#undef X
943 { NULL, 0 },
944};
945// clang-format on
946
947void print_elf_mips_symbols(const elf_mips_symbolic_data *symbol, unsigned int flag)
948{
949 fdr *fdrp;
950 unsigned int ifd;
951
952 if ( (flag & 0x200) == 0 || symbol == NULL )
953 {
954 return;
955 }
956 printf(" Symbol header\n");
957 printf(" magic=0x%x vstamp=0x%x\n", symbol->head.magic, symbol->head.vstamp);
958 printf(
959 " ilineMax= %4u cbLine= %6u cbLineOffset=%u(0x%05x)\n",
960 symbol->head.ilineMax,
961 symbol->head.cbLine,
962 symbol->head.cbLineOffset,
963 symbol->head.cbLineOffset);
964 printf(
965 " idnMax= %4u cbDnOffset= %6u(0x%05x)\n",
966 symbol->head.idnMax,
967 symbol->head.cbDnOffset,
968 symbol->head.cbDnOffset);
969 printf(
970 " ipdMax= %4u cbPdOffset= %6u(0x%05x)\n",
971 symbol->head.ipdMax,
972 symbol->head.cbPdOffset,
973 symbol->head.cbPdOffset);
974 printf(
975 " isymMax= %4u cbSymOffset= %6u(0x%05x)\n",
976 symbol->head.isymMax,
977 symbol->head.cbSymOffset,
978 symbol->head.cbSymOffset);
979 printf(
980 " ioptMax= %4u cbOptOffset= %6u(0x%05x)\n",
981 symbol->head.ioptMax,
982 symbol->head.cbOptOffset,
983 symbol->head.cbOptOffset);
984 printf(
985 " iauxMax= %4u cbAuxOffset= %6u(0x%05x)\n",
986 symbol->head.iauxMax,
987 symbol->head.cbAuxOffset,
988 symbol->head.cbAuxOffset);
989 printf(
990 " issMax= %4u cbSsOffset= %6u(0x%05x)\n",
991 symbol->head.issMax,
992 symbol->head.cbSsOffset,
993 symbol->head.cbSsOffset);
994 printf(
995 " issExtMax=%4u cbSsExtOffset=%6u(0x%05x)\n",
996 symbol->head.issExtMax,
997 symbol->head.cbSsExtOffset,
998 symbol->head.cbSsExtOffset);
999 printf(
1000 " ifdMax= %4u cbFdOffset= %6u(0x%05x)\n",
1001 symbol->head.ifdMax,
1002 symbol->head.cbFdOffset,
1003 symbol->head.cbFdOffset);
1004 printf(
1005 " crfd= %4u cbRfdOffset= %6u(0x%05x)\n",
1006 symbol->head.crfd,
1007 symbol->head.cbRfdOffset,
1008 symbol->head.cbRfdOffset);
1009 printf(
1010 " iextMax= %4u cbExtOffset= %6u(0x%05x)\n",
1011 symbol->head.iextMax,
1012 symbol->head.cbExtOffset,
1013 symbol->head.cbExtOffset);
1014 printf("\n");
1015 if ( symbol->head.issMax > 0 )
1016 {
1017 int i_1;
1018 const char *cp_1;
1019 const char *cpend_1;
1020
1021 cp_1 = symbol->cbSs_Ptr;
1022 cpend_1 = &cp_1[symbol->head.issMax];
1023 printf(" Local strings\n");
1024 for ( i_1 = 0; cp_1 < cpend_1; i_1 += 1 )
1025 {
1026 printf(" %3d(%5d): %s\n", i_1, (int)(cp_1 - symbol->cbSs_Ptr), cp_1);
1027 cp_1 += strlen(cp_1) + 1;
1028 }
1029 printf("\n");
1030 }
1031 if ( symbol->head.issExtMax > 0 )
1032 {
1033 int i_2;
1034 const char *cp_2;
1035 const char *cpend_2;
1036
1037 cp_2 = symbol->cbSsExt_Ptr;
1038 cpend_2 = &cp_2[symbol->head.issExtMax];
1039 printf(" External strings\n");
1040 for ( i_2 = 0; cp_2 < cpend_2; i_2 += 1 )
1041 {
1042 printf(" %3d(%5d): %s\n", i_2, (int)(cp_2 - symbol->cbSsExt_Ptr), cp_2);
1043 cp_2 += strlen(cp_2) + 1;
1044 }
1045 printf("\n");
1046 }
1047 if ( symbol->head.iextMax > 0 )
1048 {
1049 extr *ep;
1050 unsigned int i_3;
1051
1052 ep = (extr *)symbol->cbExt_Ptr;
1053 printf(" External symbols\n");
1054 for ( i_3 = 0; i_3 < symbol->head.iextMax; i_3 += 1 )
1055 {
1056 unsigned int idx_1;
1057 unsigned int class_1;
1058 unsigned int type_1;
1059
1060 type_1 = ep->asym.sy_bits & 0x3F;
1061 class_1 = (ep->asym.sy_bits >> 6) & 0x1F;
1062 idx_1 = ep->asym.sy_bits >> 12;
1063 printf(" %3u: res,ifd=%04x,%04hx", i_3, ep->reserved, (unsigned short)(ep->ifd));
1064 printf(", 0x%08x", ep->asym.value);
1065 printf(", %8s:%-7s 0x%05x ", num2name(SymbolTypes, type_1), num2name(StorageClasse, class_1), idx_1);
1066 printf("%s\n", &symbol->cbSsExt_Ptr[ep->asym.iss]);
1067 ep += 1;
1068 }
1069 printf("\n");
1070 }
1071 printf(" Local informations\n");
1072 fdrp = (fdr *)symbol->cbFd_Ptr;
1073 for ( ifd = 0; ifd < symbol->head.ifdMax; ifd += 1 )
1074 {
1075 const char *issBase;
1076
1077 issBase = &symbol->cbSs_Ptr[fdrp->issBase];
1078 printf(" %3u: %-40s addr=0x%08x \n", ifd, &issBase[fdrp->rss], fdrp->adr);
1079 if ( fdrp->csym > 0 )
1080 {
1081 symr *syp_1;
1082 int i_4;
1083
1084 syp_1 = (symr *)&symbol->cbSym_Ptr[sizeof(symr) * fdrp->isymBase];
1085 printf(" Local symbols\n");
1086 for ( i_4 = 0; i_4 < fdrp->csym; i_4 += 1 )
1087 {
1088 unsigned int idx_2;
1089 unsigned int class_2;
1090 unsigned int type_2;
1091
1092 type_2 = syp_1->sy_bits & 0x3F;
1093 class_2 = (syp_1->sy_bits >> 6) & 0x1F;
1094 idx_2 = syp_1->sy_bits >> 12;
1095 printf(" %3d: 0x%08x", i_4, syp_1->value);
1096 printf(", %10s:%-10s 0x%05x ", num2name(SymbolTypes, type_2), num2name(StorageClasse, class_2), idx_2);
1097 printf("%s\n", &issBase[syp_1->iss]);
1098 syp_1 += 1;
1099 }
1100 }
1101 if ( fdrp->cline > 0 )
1102 {
1103 printf(" Line numbers\n");
1104 printf(" ilinBase = %d, cline= %d\n", fdrp->ilineBase, fdrp->cline);
1105 }
1106 if ( fdrp->copt > 0 )
1107 {
1108 printf(" Optimization entries\n");
1109 printf(" ioptBase = %d, copt = %d\n", fdrp->ioptBase, fdrp->copt);
1110 }
1111 if ( fdrp->cpd > 0 )
1112 {
1113 pdr *pdrp_2;
1114 const symr *syp_2;
1115 int i_5;
1116
1117 syp_2 = (symr *)&symbol->cbSym_Ptr[sizeof(symr) * fdrp->isymBase];
1118 pdrp_2 = (pdr *)&symbol->cbPd_Ptr[sizeof(pdr) * fdrp->ipdFirst];
1119 printf(" Procedures\n");
1120 for ( i_5 = 0; i_5 < fdrp->cpd; i_5 += 1 )
1121 {
1122 printf(" %3d: 0x%08x %s\n", i_5, pdrp_2->adr, &issBase[syp_2[pdrp_2->isym].iss]);
1123 printf(
1124 " regmask=0x%08x, regoffset=%d, fregmask=0x%08x, fregoffset=%d\n",
1125 pdrp_2->regmask,
1126 pdrp_2->regoffset,
1127 pdrp_2->fregmask,
1128 pdrp_2->fregoffset);
1129 printf(
1130 " iopt=%d, frameoffset=%d, framereg=%d, pcreg=%d, line %d..%d\n",
1131 pdrp_2->iopt,
1132 pdrp_2->frameoffset,
1133 pdrp_2->framereg,
1134 pdrp_2->pcreg,
1135 pdrp_2->lnLow,
1136 pdrp_2->lnHigh);
1137 printf(" iline=%d, cbLineOffset=%d\n", pdrp_2->iline, (int)(pdrp_2->cbLineOffset));
1138 pdrp_2 += 1;
1139 }
1140 }
1141 if ( fdrp->caux > 0 )
1142 {
1143 const unsigned int *ip_1;
1144 int i_6;
1145
1146 printf(" Auxillary symbol entries\n");
1147 ip_1 = (unsigned int *)&symbol->cbAux_Ptr[sizeof(unsigned int) * fdrp->iauxBase];
1148 for ( i_6 = 0; i_6 < fdrp->caux; i_6 += 1 )
1149 {
1150 printf(" %3d: 0x%08lx \n", i_6, (unsigned long)(*ip_1));
1151 ip_1 += 1;
1152 }
1153 }
1154 if ( fdrp->crfd > 0 )
1155 {
1156 const unsigned int *ip_2;
1157 int i_7;
1158
1159 printf(" File indirect entries\n");
1160 ip_2 = (unsigned int *)&symbol->cbRfd_Ptr[sizeof(unsigned int) * fdrp->rfdBase];
1161 for ( i_7 = 0; i_7 < fdrp->crfd; i_7 += 1 )
1162 {
1163 printf(" %3d: 0x%08lx \n", i_7, (unsigned long)(*ip_2));
1164 ip_2 += 1;
1165 }
1166 }
1167 printf("\n");
1168 fdrp += 1;
1169 }
1170 printf("\n");
1171}
Definition main.c:242