FreeCalypso > hg > freecalypso-reveng
diff 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 |
line wrap: on
line diff
--- a/ticoff/disasm.c Fri Apr 04 08:12:29 2014 +0000 +++ b/ticoff/disasm.c Fri Apr 04 18:39:01 2014 +0000 @@ -75,6 +75,40 @@ } void +disasm_end_of_section(sec, symnum) + struct internal_scnhdr *sec; + unsigned symnum; +{ + struct internal_syment *sym; + char *sym_comment; + + putchar('\n'); + while (symnum < sec->nsymbols) { + sym = sec->sorted_symbols[symnum]; + if (sym->value != sec->size) { + printf("error: expecting symbol at end of section\n"); + return; + } + switch (sym->class) { + case C_EXT: + sym_comment = "Global"; + break; + case C_STAT: + sym_comment = "static"; + break; + case C_LABEL: + sym_comment = "label"; + break; + default: + sym_comment = "unexpected class!"; + } + printf("%s:\t; %s\n", sym->name, sym_comment); + symnum++; + } + printf("%8x:\t<end of section>\n", sec->size); +} + +void disasm_text_section(sec) struct internal_scnhdr *sec; { @@ -201,6 +235,101 @@ return; } } + if (symnum < sec->nsymbols) + disasm_end_of_section(sec, symnum); +} + +void +disasm_data_section(sec) + struct internal_scnhdr *sec; +{ + unsigned symnum, relnum; + unsigned pos, incr, headroom; + int linebrk = 0; + struct internal_syment *sym; + struct internal_reloc *rel; + char *sym_comment; + + printf("Disassembling data section:\n"); + if (sec->nsymbols) + sort_symbols_of_sec(sec); + if (sec->nreloc) + get_relocs_of_sec(sec); + symnum = relnum = 0; + for (pos = 0; pos < sec->size; pos += incr) { + headroom = sec->size - pos; + while (symnum < sec->nsymbols) { + sym = sec->sorted_symbols[symnum]; + if (sym->value > pos) { + if (sym->value - pos < headroom) + headroom = sym->value - pos; + break; + } + /* hit symbol */ + if (!linebrk) { + putchar('\n'); + linebrk = 1; + } + switch (sym->class) { + case C_EXT: + sym_comment = "Global"; + break; + case C_STAT: + sym_comment = "static"; + break; + case C_LABEL: + sym_comment = "label"; + break; + default: + sym_comment = "unexpected class!"; + } + printf("%s:\t; %s\n", sym->name, sym_comment); + symnum++; + } + if (relnum < sec->nreloc) { + rel = sec->int_relocs + relnum; + if (rel->location == pos) + relnum++; /* it's ours */ + else { + if (rel->location - pos < headroom) + headroom = rel->location - pos; + rel = 0; /* no reloc for current pos */ + } + } else + rel = 0; + printf("%8x:\t", pos); + if (rel) { + if (rel->type != RTYPE_LONG) { + printf("error: reloc other than word32 in data section\n"); + return; + } + if (pos & 3) { + printf("MISALIGNED pos for word32 reloc, aborting\n"); + return; + } + disasm_word32_reloc(sec, rel); + incr = 4; + } else if (pos & 1 || headroom < 2) { + printf("%02x\n", filemap[sec->data_offset + pos]); + incr = 1; + } else if (pos & 2 || headroom < 4) { + printf("%04x\n", + get_u16(filemap + sec->data_offset + pos)); + incr = 2; + } else { + printf("%08x\n", + get_u32(filemap + sec->data_offset + pos)); + incr = 4; + } + linebrk = 0; + if (incr > headroom) { + printf("error: increment %u > headroom %u, aborting\n", + incr, headroom); + return; + } + } + if (symnum < sec->nsymbols) + disasm_end_of_section(sec, symnum); } void @@ -209,6 +338,12 @@ { if (!strncmp(sec->name, ".text", 5)) disasm_text_section(sec); + else if (!strcmp(sec->name, ".const")) + disasm_data_section(sec); + else if (!strcmp(sec->name, ".cinit")) + disasm_data_section(sec); + else if (!strcmp(sec->name, ".data")) + disasm_data_section(sec); /* other section types to be added */ else printf("Unrecognized section type, skipped\n");