FreeCalypso > hg > freecalypso-reveng
comparison ticoff/disasm.c @ 124:700d77d5cf00
tiobjd disasm: data section handling added
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Fri, 04 Apr 2014 18:39:01 +0000 |
parents | 5f9cc99930a8 |
children | b8ac21536779 |
comparison
equal
deleted
inserted
replaced
123:5f9cc99930a8 | 124:700d77d5cf00 |
---|---|
70 | 70 |
71 word = get_u32(filemap + sec->data_offset + rel->location); | 71 word = get_u32(filemap + sec->data_offset + rel->location); |
72 printf("%08x R\t.word\t", word); | 72 printf("%08x R\t.word\t", word); |
73 disasm_reloc_target(sec, rel, word); | 73 disasm_reloc_target(sec, rel, word); |
74 putchar('\n'); | 74 putchar('\n'); |
75 } | |
76 | |
77 void | |
78 disasm_end_of_section(sec, symnum) | |
79 struct internal_scnhdr *sec; | |
80 unsigned symnum; | |
81 { | |
82 struct internal_syment *sym; | |
83 char *sym_comment; | |
84 | |
85 putchar('\n'); | |
86 while (symnum < sec->nsymbols) { | |
87 sym = sec->sorted_symbols[symnum]; | |
88 if (sym->value != sec->size) { | |
89 printf("error: expecting symbol at end of section\n"); | |
90 return; | |
91 } | |
92 switch (sym->class) { | |
93 case C_EXT: | |
94 sym_comment = "Global"; | |
95 break; | |
96 case C_STAT: | |
97 sym_comment = "static"; | |
98 break; | |
99 case C_LABEL: | |
100 sym_comment = "label"; | |
101 break; | |
102 default: | |
103 sym_comment = "unexpected class!"; | |
104 } | |
105 printf("%s:\t; %s\n", sym->name, sym_comment); | |
106 symnum++; | |
107 } | |
108 printf("%8x:\t<end of section>\n", sec->size); | |
75 } | 109 } |
76 | 110 |
77 void | 111 void |
78 disasm_text_section(sec) | 112 disasm_text_section(sec) |
79 struct internal_scnhdr *sec; | 113 struct internal_scnhdr *sec; |
199 printf("error: increment %u > headroom %u, aborting\n", | 233 printf("error: increment %u > headroom %u, aborting\n", |
200 incr, headroom); | 234 incr, headroom); |
201 return; | 235 return; |
202 } | 236 } |
203 } | 237 } |
238 if (symnum < sec->nsymbols) | |
239 disasm_end_of_section(sec, symnum); | |
240 } | |
241 | |
242 void | |
243 disasm_data_section(sec) | |
244 struct internal_scnhdr *sec; | |
245 { | |
246 unsigned symnum, relnum; | |
247 unsigned pos, incr, headroom; | |
248 int linebrk = 0; | |
249 struct internal_syment *sym; | |
250 struct internal_reloc *rel; | |
251 char *sym_comment; | |
252 | |
253 printf("Disassembling data section:\n"); | |
254 if (sec->nsymbols) | |
255 sort_symbols_of_sec(sec); | |
256 if (sec->nreloc) | |
257 get_relocs_of_sec(sec); | |
258 symnum = relnum = 0; | |
259 for (pos = 0; pos < sec->size; pos += incr) { | |
260 headroom = sec->size - pos; | |
261 while (symnum < sec->nsymbols) { | |
262 sym = sec->sorted_symbols[symnum]; | |
263 if (sym->value > pos) { | |
264 if (sym->value - pos < headroom) | |
265 headroom = sym->value - pos; | |
266 break; | |
267 } | |
268 /* hit symbol */ | |
269 if (!linebrk) { | |
270 putchar('\n'); | |
271 linebrk = 1; | |
272 } | |
273 switch (sym->class) { | |
274 case C_EXT: | |
275 sym_comment = "Global"; | |
276 break; | |
277 case C_STAT: | |
278 sym_comment = "static"; | |
279 break; | |
280 case C_LABEL: | |
281 sym_comment = "label"; | |
282 break; | |
283 default: | |
284 sym_comment = "unexpected class!"; | |
285 } | |
286 printf("%s:\t; %s\n", sym->name, sym_comment); | |
287 symnum++; | |
288 } | |
289 if (relnum < sec->nreloc) { | |
290 rel = sec->int_relocs + relnum; | |
291 if (rel->location == pos) | |
292 relnum++; /* it's ours */ | |
293 else { | |
294 if (rel->location - pos < headroom) | |
295 headroom = rel->location - pos; | |
296 rel = 0; /* no reloc for current pos */ | |
297 } | |
298 } else | |
299 rel = 0; | |
300 printf("%8x:\t", pos); | |
301 if (rel) { | |
302 if (rel->type != RTYPE_LONG) { | |
303 printf("error: reloc other than word32 in data section\n"); | |
304 return; | |
305 } | |
306 if (pos & 3) { | |
307 printf("MISALIGNED pos for word32 reloc, aborting\n"); | |
308 return; | |
309 } | |
310 disasm_word32_reloc(sec, rel); | |
311 incr = 4; | |
312 } else if (pos & 1 || headroom < 2) { | |
313 printf("%02x\n", filemap[sec->data_offset + pos]); | |
314 incr = 1; | |
315 } else if (pos & 2 || headroom < 4) { | |
316 printf("%04x\n", | |
317 get_u16(filemap + sec->data_offset + pos)); | |
318 incr = 2; | |
319 } else { | |
320 printf("%08x\n", | |
321 get_u32(filemap + sec->data_offset + pos)); | |
322 incr = 4; | |
323 } | |
324 linebrk = 0; | |
325 if (incr > headroom) { | |
326 printf("error: increment %u > headroom %u, aborting\n", | |
327 incr, headroom); | |
328 return; | |
329 } | |
330 } | |
331 if (symnum < sec->nsymbols) | |
332 disasm_end_of_section(sec, symnum); | |
204 } | 333 } |
205 | 334 |
206 void | 335 void |
207 disasm_sectype_by_name(sec) | 336 disasm_sectype_by_name(sec) |
208 struct internal_scnhdr *sec; | 337 struct internal_scnhdr *sec; |
209 { | 338 { |
210 if (!strncmp(sec->name, ".text", 5)) | 339 if (!strncmp(sec->name, ".text", 5)) |
211 disasm_text_section(sec); | 340 disasm_text_section(sec); |
341 else if (!strcmp(sec->name, ".const")) | |
342 disasm_data_section(sec); | |
343 else if (!strcmp(sec->name, ".cinit")) | |
344 disasm_data_section(sec); | |
345 else if (!strcmp(sec->name, ".data")) | |
346 disasm_data_section(sec); | |
212 /* other section types to be added */ | 347 /* other section types to be added */ |
213 else | 348 else |
214 printf("Unrecognized section type, skipped\n"); | 349 printf("Unrecognized section type, skipped\n"); |
215 } | 350 } |
216 | 351 |