Automate tests
[centaur.git] / src / modelops / dump.c
1 #include <assert.h>
2 #include <libelfu/libelfu.h>
3
4
5 static char* segmentTypeStr(Elf32_Word p_type)
6 {
7   switch(p_type) {
8     case PT_NULL: /* 0 */
9       return "NULL";
10     case PT_LOAD: /* 1 */
11       return "LOAD";
12     case PT_DYNAMIC: /* 2 */
13       return "DYNAMIC";
14     case PT_INTERP: /* 3 */
15       return "INTERP";
16     case PT_NOTE: /* 4 */
17       return "NOTE";
18     case PT_SHLIB: /* 5 */
19       return "SHLIB";
20     case PT_PHDR: /* 6 */
21       return "PHDR";
22     case PT_TLS: /* 7 */
23       return "TLS";
24     case PT_NUM: /* 8 */
25       return "NUM";
26     case PT_GNU_EH_FRAME: /* 0x6474e550 */
27       return "GNU_EH_FRAME";
28     case PT_GNU_STACK: /* 0x6474e551 */
29       return "GNU_STACK";
30     case PT_GNU_RELRO: /* 0x6474e552 */
31       return "GNU_RELRO";
32   }
33
34   return "-?-";
35 }
36
37 static char* sectionTypeStr(Elf32_Word sh_type)
38 {
39   switch(sh_type) {
40     case SHT_NULL: /* 0 */
41       return "NULL";
42     case SHT_PROGBITS: /* 1 */
43       return "PROGBITS";
44     case SHT_SYMTAB: /* 2 */
45       return "SYMTAB";
46     case SHT_STRTAB: /* 3 */
47       return "STRTAB";
48     case SHT_RELA: /* 4 */
49       return "RELA";
50     case SHT_HASH: /* 5 */
51       return "HASH";
52     case SHT_DYNAMIC: /* 6 */
53       return "DYNAMIC";
54     case SHT_NOTE: /* 7 */
55       return "NOTE";
56     case SHT_NOBITS: /* 8 */
57       return "NOBITS";
58     case SHT_REL: /* 9 */
59       return "REL";
60     case SHT_SHLIB: /* 10 */
61       return "SHLIB";
62     case SHT_DYNSYM: /* 11 */
63       return "DYNSYM";
64     case SHT_INIT_ARRAY: /* 14 */
65       return "INIT_ARRAY";
66     case SHT_FINI_ARRAY: /* 15 */
67       return "FINI_ARRAY";
68     case SHT_PREINIT_ARRAY: /* 16 */
69       return "PREINIT_ARRAY";
70     case SHT_GROUP: /* 17 */
71       return "SHT_GROUP";
72     case SHT_SYMTAB_SHNDX: /* 18 */
73       return "SYMTAB_SHNDX";
74     case SHT_NUM: /* 19 */
75       return "NUM";
76
77     case SHT_GNU_ATTRIBUTES: /* 0x6ffffff5 */
78       return "GNU_ATTRIBUTES";
79     case SHT_GNU_HASH: /* 0x6ffffff6 */
80       return "GNU_HASH";
81     case SHT_GNU_LIBLIST: /* 0x6ffffff7 */
82       return "GNU_LIBLIST";
83     case SHT_GNU_verdef: /* 0x6ffffffd */
84       return "GNU_verdef";
85     case SHT_GNU_verneed: /* 0x6ffffffe */
86       return "GNU_verneed";
87     case SHT_GNU_versym: /* 0x6fffffff */
88       return "GNU_versym";
89   }
90
91   return "-?-";
92 }
93
94
95
96
97 void elfu_mDumpPhdr(ElfuElf *me, ElfuPhdr *mp)
98 {
99   assert(me);
100   assert(mp);
101
102   ELFU_INFO("%12s %8x %8x %8x %8x %8x %8x %8x %8x\n",
103             segmentTypeStr(mp->phdr.p_type),
104             (unsigned)mp->phdr.p_type,
105             (unsigned)mp->phdr.p_offset,
106             (unsigned)mp->phdr.p_vaddr,
107             (unsigned)mp->phdr.p_paddr,
108             (unsigned)mp->phdr.p_filesz,
109             (unsigned)mp->phdr.p_memsz,
110             (unsigned)mp->phdr.p_flags,
111             (unsigned)mp->phdr.p_align);
112
113   if (!CIRCLEQ_EMPTY(&mp->childPhdrList)) {
114     ElfuPhdr *mpc;
115
116     ELFU_INFO("      -> Child PHDRs:\n");
117     CIRCLEQ_FOREACH(mpc, &mp->childPhdrList, elemChildPhdr) {
118       ELFU_INFO("        * %-8s @ %8x\n",
119                 segmentTypeStr(mpc->phdr.p_type),
120                 (unsigned)mpc->phdr.p_vaddr);
121     }
122   }
123
124   if (!CIRCLEQ_EMPTY(&mp->childScnList)) {
125     ElfuScn *msc;
126
127     ELFU_INFO("      -> Child sections:\n");
128     CIRCLEQ_FOREACH(msc, &mp->childScnList, elemChildScn) {
129       ELFU_INFO("        * %-17s @ %8x\n",
130                 elfu_mScnName(me, msc),
131                 (unsigned)msc->shdr.sh_addr);
132     }
133   }
134 }
135
136
137 void elfu_mDumpScn(ElfuElf *me, ElfuScn *ms)
138 {
139   char *namestr, *typestr, *linkstr, *infostr;
140
141   assert(me);
142   assert(ms);
143
144   namestr = elfu_mScnName(me, ms);
145   typestr = sectionTypeStr(ms->shdr.sh_type);
146   linkstr = ms->linkptr ? elfu_mScnName(me, ms->linkptr) : "";
147   infostr = ms->infoptr ? elfu_mScnName(me, ms->infoptr) : "";
148
149   ELFU_INFO("%-17s %-15s %8x %9x %8x %2x %2x %2d %-17s %-17s\n",
150             namestr,
151             typestr,
152             (unsigned)ms->shdr.sh_addr,
153             (unsigned)ms->shdr.sh_offset,
154             (unsigned)ms->shdr.sh_size,
155             (unsigned)ms->shdr.sh_entsize,
156             (unsigned)ms->shdr.sh_flags,
157             (unsigned)ms->shdr.sh_addralign,
158             linkstr,
159             infostr);
160 }
161
162
163 void elfu_mDumpEhdr(ElfuElf *me)
164 {
165   assert(me);
166
167   ELFU_INFO("ELF header:\n");
168   ELFU_INFO("   %d-bit ELF object\n", me->elfclass == ELFCLASS32 ? 32 : 64);
169
170   ELFU_INFO("   EHDR:\n");
171
172   ELFU_INFO("     e_type       %8x\n", me->ehdr.e_type);
173   ELFU_INFO("     e_machine    %8x\n", me->ehdr.e_machine);
174   ELFU_INFO("     e_version    %8x\n", me->ehdr.e_version);
175   ELFU_INFO("     e_entry      %8x\n", (unsigned)me->ehdr.e_entry);
176   ELFU_INFO("     e_phoff      %8x\n", (unsigned)me->ehdr.e_phoff);
177   ELFU_INFO("     e_shoff      %8x\n", (unsigned)me->ehdr.e_shoff);
178   ELFU_INFO("     e_flags      %8x\n", me->ehdr.e_flags);
179   ELFU_INFO("     e_ehsize     %8x\n", me->ehdr.e_ehsize);
180   ELFU_INFO("     e_phentsize  %8x\n", me->ehdr.e_phentsize);
181   ELFU_INFO("     e_shentsize  %8x\n", me->ehdr.e_shentsize);
182
183   ELFU_INFO("   shstrtab: %s\n", me->shstrtab ? elfu_mScnName(me, me->shstrtab) : "(none)");
184 }
185
186
187
188 static void* subScnDump(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
189 {
190   (void) aux1;
191   (void) aux2;
192
193   printf(" [%4d] ", elfu_mScnIndex(me, ms));
194   elfu_mDumpScn(me, ms);
195
196   return NULL;
197 }
198
199
200 void elfu_mDumpElf(ElfuElf *me)
201 {
202   ElfuPhdr *mp;
203   ElfuScn *ms;
204   size_t i;
205
206   assert(me);
207
208
209   elfu_mDumpEhdr(me);
210   ELFU_INFO("\n");
211
212
213   ELFU_INFO("Segments:\n");
214   ELFU_INFO("     #        (type)   p_type p_offset  p_vaddr  p_paddr p_filesz  p_memsz  p_flags  p_align\n");
215   ELFU_INFO("       |            |        |        |        |        |        |        |        |        \n");
216   i = 0;
217   CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
218     printf(" [%4d] ", i);
219     elfu_mDumpPhdr(me, mp);
220     i++;
221   }
222   ELFU_INFO("\n");
223
224
225   ELFU_INFO("Orphaned sections:\n");
226   CIRCLEQ_FOREACH(ms, &me->orphanScnList, elemChildScn) {
227     ELFU_INFO("        * %-17s @ %8x\n",
228               elfu_mScnName(me, ms),
229               (unsigned)ms->shdr.sh_addr);
230   }
231   ELFU_INFO("\n");
232
233
234   ELFU_INFO("Sections:\n");
235   ELFU_INFO("     #  Name              sh_type          sh_addr sh_offset  sh_size ES Fl Al sh_link           sh_info          \n");
236   ELFU_INFO("       |                 |               |        |         |        |  |  |  |                 |                 \n");
237   elfu_mScnForall(me, subScnDump, &i, NULL);
238   ELFU_INFO("\n");
239 }