FreeCalypso > hg > freecalypso-reveng
comparison leo-obj/tool/disasm.c @ 135:df432a4b1b84
tiobjd: disasm of code and data sections unified
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Mon, 07 Apr 2014 04:06:17 +0000 |
parents | daeaa5950d10 |
children | 81fc8da9a29c |
comparison
equal
deleted
inserted
replaced
134:c131238c56bf | 135:df432a4b1b84 |
---|---|
76 printf("%08x R\t.word\t", word); | 76 printf("%08x R\t.word\t", word); |
77 disasm_reloc_target(sec, rel, word); | 77 disasm_reloc_target(sec, rel, word); |
78 putchar('\n'); | 78 putchar('\n'); |
79 } | 79 } |
80 | 80 |
81 void | 81 static void |
82 disasm_end_of_section(sec, symnum) | 82 handle_symbol(sym, statep, linebrkp) |
83 struct internal_scnhdr *sec; | |
84 unsigned symnum; | |
85 { | |
86 struct internal_syment *sym; | 83 struct internal_syment *sym; |
84 int *statep, *linebrkp; | |
85 { | |
87 char *sym_comment; | 86 char *sym_comment; |
88 | 87 |
89 putchar('\n'); | 88 if (sym->class == C_FCN && !strcmp(sym->name, ".ef")) { |
90 while (symnum < sec->nsymbols) { | 89 printf("; End function\n"); |
91 sym = sec->sorted_symbols[symnum]; | 90 return; |
92 if (sym->value != sec->size) { | 91 } |
93 printf("error: expecting symbol at end of section\n"); | 92 if (!*linebrkp) { |
94 return; | 93 putchar('\n'); |
95 } | 94 *linebrkp = 1; |
96 switch (sym->class) { | 95 } |
97 case C_EXT: | 96 if (sym->class == C_FCN && !strcmp(sym->name, ".bf")) { |
98 sym_comment = "Global"; | 97 printf("; Begin function\n"); |
99 break; | 98 return; |
100 case C_STAT: | 99 } |
101 sym_comment = "static"; | 100 switch (sym->class) { |
102 break; | 101 case C_EXT: |
103 case C_LABEL: | 102 sym_comment = "Global"; |
104 sym_comment = "label"; | 103 break; |
105 break; | 104 case C_STAT: |
106 default: | 105 sym_comment = "static"; |
107 sym_comment = "unexpected class!"; | 106 break; |
108 } | 107 case C_LABEL: |
109 printf("%s:\t; %s\n", sym->name, sym_comment); | 108 sym_comment = "label"; |
110 symnum++; | 109 if (!strcmp(sym->name, "$CODE16")) |
111 } | 110 *statep = 1; |
112 printf("%8x:\t<end of section>\n", sec->size); | 111 else if (!strcmp(sym->name, "$CODE32")) |
113 } | 112 *statep = 0; |
114 | 113 break; |
115 void | 114 default: |
116 disasm_text_section(sec) | 115 sym_comment = "unexpected class!"; |
116 } | |
117 printf("%s:\t; %s\n", sym->name, sym_comment); | |
118 } | |
119 | |
120 void | |
121 disasm_codedata_section(sec) | |
117 struct internal_scnhdr *sec; | 122 struct internal_scnhdr *sec; |
118 { | 123 { |
119 unsigned symnum, relnum; | 124 unsigned symnum, relnum; |
120 unsigned pos, incr, headroom; | 125 unsigned pos, incr, headroom; |
121 int state = -1, linebrk = 0; | 126 int state = -1, linebrk = 0; |
122 struct internal_syment *sym; | 127 struct internal_syment *sym; |
123 struct internal_reloc *rel; | 128 struct internal_reloc *rel; |
124 char *sym_comment; | 129 |
125 | |
126 printf("Disassembling code section:\n"); | |
127 if (sec->nsymbols) | |
128 sort_symbols_of_sec(sec); | |
129 if (sec->nreloc) | 130 if (sec->nreloc) |
130 get_relocs_of_sec(sec); | 131 get_relocs_of_sec(sec); |
131 symnum = relnum = 0; | 132 symnum = relnum = 0; |
132 for (pos = 0; pos < sec->size; pos += incr) { | 133 for (pos = 0; pos < sec->size; pos += incr) { |
133 headroom = sec->size - pos; | 134 headroom = sec->size - pos; |
137 if (sym->value - pos < headroom) | 138 if (sym->value - pos < headroom) |
138 headroom = sym->value - pos; | 139 headroom = sym->value - pos; |
139 break; | 140 break; |
140 } | 141 } |
141 /* hit symbol */ | 142 /* hit symbol */ |
142 if (!linebrk) { | 143 handle_symbol(sym, &state, &linebrk); |
143 putchar('\n'); | |
144 linebrk = 1; | |
145 } | |
146 switch (sym->class) { | |
147 case C_EXT: | |
148 sym_comment = "Global"; | |
149 break; | |
150 case C_STAT: | |
151 sym_comment = "static"; | |
152 break; | |
153 case C_LABEL: | |
154 sym_comment = "label"; | |
155 if (!strcmp(sym->name, "$CODE16")) | |
156 state = 1; | |
157 else if (!strcmp(sym->name, "$CODE32")) | |
158 state = 0; | |
159 break; | |
160 default: | |
161 sym_comment = "unexpected class!"; | |
162 } | |
163 printf("%s:\t; %s\n", sym->name, sym_comment); | |
164 symnum++; | 144 symnum++; |
165 } | 145 } |
166 if (relnum < sec->nreloc) { | 146 if (relnum < sec->nreloc) { |
167 rel = sec->int_relocs + relnum; | 147 rel = sec->int_relocs + relnum; |
168 if (rel->location == pos) | 148 if (rel->location == pos) |
173 rel = 0; /* no reloc for current pos */ | 153 rel = 0; /* no reloc for current pos */ |
174 } | 154 } |
175 } else | 155 } else |
176 rel = 0; | 156 rel = 0; |
177 printf("%8x:\t", pos); | 157 printf("%8x:\t", pos); |
178 if (rel && rel->type == RTYPE_LONG) { | 158 if (rel) { |
179 if (pos & 3) { | 159 if (rel->type == RTYPE_LONG) { |
180 printf("MISALIGNED pos for word32 reloc, aborting\n"); | 160 if (pos & 3) { |
161 printf("MISALIGNED pos for word32 reloc, aborting\n"); | |
162 return; | |
163 } | |
164 disasm_word32_reloc(sec, rel); | |
165 incr = 4; | |
166 goto next; | |
167 } else if (sec->disasm_mode == DISASM_MODE_DATA) { | |
168 printf("error: reloc other than word32 in data section\n"); | |
181 return; | 169 return; |
182 } | 170 } |
183 disasm_word32_reloc(sec, rel); | |
184 incr = 4; | |
185 goto next; | |
186 } | 171 } |
187 if (pos & 1 || headroom < 2) { | 172 if (pos & 1 || headroom < 2) { |
188 if (rel) { | 173 if (rel) { |
189 printf("error: reloc at byte pos, aborting\n"); | 174 printf("error: reloc at byte pos, aborting\n"); |
190 return; | 175 return; |
191 } | 176 } |
192 printf("%02x\n", filemap[sec->data_offset + pos]); | 177 printf("%02x\n", filemap[sec->data_offset + pos]); |
193 incr = 1; | 178 incr = 1; |
179 goto next; | |
180 } | |
181 if (sec->disasm_mode == DISASM_MODE_DATA) { | |
182 if (pos & 2 || headroom < 4) { | |
183 printf("%04x\n", | |
184 get_u16(filemap+sec->data_offset+pos)); | |
185 incr = 2; | |
186 } else { | |
187 printf("%08x\n", | |
188 get_u32(filemap+sec->data_offset+pos)); | |
189 incr = 4; | |
190 } | |
194 goto next; | 191 goto next; |
195 } | 192 } |
196 switch (state) { | 193 switch (state) { |
197 case 0: /* ARM */ | 194 case 0: /* ARM */ |
198 if (pos & 3) { | 195 if (pos & 3) { |
237 printf("error: increment %u > headroom %u, aborting\n", | 234 printf("error: increment %u > headroom %u, aborting\n", |
238 incr, headroom); | 235 incr, headroom); |
239 return; | 236 return; |
240 } | 237 } |
241 } | 238 } |
242 if (symnum < sec->nsymbols) | 239 if (symnum == sec->nsymbols) |
243 disasm_end_of_section(sec, symnum); | 240 return; |
244 } | 241 while (symnum < sec->nsymbols) { |
245 | 242 sym = sec->sorted_symbols[symnum]; |
246 void | 243 if (sym->value != sec->size) { |
247 disasm_data_section(sec) | 244 printf("error: expecting symbol at end of section\n"); |
248 struct internal_scnhdr *sec; | |
249 { | |
250 unsigned symnum, relnum; | |
251 unsigned pos, incr, headroom; | |
252 int linebrk = 0; | |
253 struct internal_syment *sym; | |
254 struct internal_reloc *rel; | |
255 char *sym_comment; | |
256 | |
257 printf("Disassembling data section:\n"); | |
258 if (sec->nsymbols) | |
259 sort_symbols_of_sec(sec); | |
260 if (sec->nreloc) | |
261 get_relocs_of_sec(sec); | |
262 symnum = relnum = 0; | |
263 for (pos = 0; pos < sec->size; pos += incr) { | |
264 headroom = sec->size - pos; | |
265 while (symnum < sec->nsymbols) { | |
266 sym = sec->sorted_symbols[symnum]; | |
267 if (sym->value > pos) { | |
268 if (sym->value - pos < headroom) | |
269 headroom = sym->value - pos; | |
270 break; | |
271 } | |
272 /* hit symbol */ | |
273 if (!linebrk) { | |
274 putchar('\n'); | |
275 linebrk = 1; | |
276 } | |
277 switch (sym->class) { | |
278 case C_EXT: | |
279 sym_comment = "Global"; | |
280 break; | |
281 case C_STAT: | |
282 sym_comment = "static"; | |
283 break; | |
284 case C_LABEL: | |
285 sym_comment = "label"; | |
286 break; | |
287 default: | |
288 sym_comment = "unexpected class!"; | |
289 } | |
290 printf("%s:\t; %s\n", sym->name, sym_comment); | |
291 symnum++; | |
292 } | |
293 if (relnum < sec->nreloc) { | |
294 rel = sec->int_relocs + relnum; | |
295 if (rel->location == pos) | |
296 relnum++; /* it's ours */ | |
297 else { | |
298 if (rel->location - pos < headroom) | |
299 headroom = rel->location - pos; | |
300 rel = 0; /* no reloc for current pos */ | |
301 } | |
302 } else | |
303 rel = 0; | |
304 printf("%8x:\t", pos); | |
305 if (rel) { | |
306 if (rel->type != RTYPE_LONG) { | |
307 printf("error: reloc other than word32 in data section\n"); | |
308 return; | |
309 } | |
310 if (pos & 3) { | |
311 printf("MISALIGNED pos for word32 reloc, aborting\n"); | |
312 return; | |
313 } | |
314 disasm_word32_reloc(sec, rel); | |
315 incr = 4; | |
316 } else if (pos & 1 || headroom < 2) { | |
317 printf("%02x\n", filemap[sec->data_offset + pos]); | |
318 incr = 1; | |
319 } else if (pos & 2 || headroom < 4) { | |
320 printf("%04x\n", | |
321 get_u16(filemap + sec->data_offset + pos)); | |
322 incr = 2; | |
323 } else { | |
324 printf("%08x\n", | |
325 get_u32(filemap + sec->data_offset + pos)); | |
326 incr = 4; | |
327 } | |
328 linebrk = 0; | |
329 if (incr > headroom) { | |
330 printf("error: increment %u > headroom %u, aborting\n", | |
331 incr, headroom); | |
332 return; | 245 return; |
333 } | 246 } |
334 } | 247 handle_symbol(sym, &state, &linebrk); |
335 if (symnum < sec->nsymbols) | 248 symnum++; |
336 disasm_end_of_section(sec, symnum); | 249 } |
250 printf("%8x:\t<end of section>\n", sec->size); | |
337 } | 251 } |
338 | 252 |
339 void | 253 void |
340 disasm_bss(sec) | 254 disasm_bss(sec) |
341 struct internal_scnhdr *sec; | 255 struct internal_scnhdr *sec; |
358 disasm_sec_by_type(sec) | 272 disasm_sec_by_type(sec) |
359 struct internal_scnhdr *sec; | 273 struct internal_scnhdr *sec; |
360 { | 274 { |
361 switch (sec->disasm_mode) { | 275 switch (sec->disasm_mode) { |
362 case DISASM_MODE_CODE: | 276 case DISASM_MODE_CODE: |
363 disasm_text_section(sec); | 277 printf("Disassembling code section:\n"); |
278 disasm_codedata_section(sec); | |
364 return; | 279 return; |
365 case DISASM_MODE_DATA: | 280 case DISASM_MODE_DATA: |
366 disasm_data_section(sec); | 281 printf("Disassembling data section:\n"); |
282 disasm_codedata_section(sec); | |
367 return; | 283 return; |
368 case DISASM_MODE_BSS: | 284 case DISASM_MODE_BSS: |
369 disasm_bss(sec); | 285 disasm_bss(sec); |
370 return; | 286 return; |
371 default: | 287 default: |