FreeCalypso > hg > freecalypso-reveng
view ticoff/disasm.c @ 111:0f94d17899b3
tiobjd: disassembly integrated, no relocs or hints yet
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Thu, 03 Apr 2014 05:14:15 +0000 |
parents | |
children | 61a58677dc68 |
line wrap: on
line source
/* * Putting it all together: section-, symbol- and reloc-aware disassembly */ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include "intstruct.h" #include "coffconst.h" #include "globals.h" extern unsigned get_u16(), get_u32(); void disasm_text_section(sec) struct internal_scnhdr *sec; { unsigned symnum, relnum; unsigned pos, incr, headroom; int state = -1, linebrk = 0; struct internal_syment *sym; struct internal_reloc *rel; char *sym_comment; printf("Disassembling code 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"; if (!strcmp(sym->name, "$CODE16")) state = 1; else if (!strcmp(sym->name, "$CODE32")) state = 0; 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); switch (state) { case 0: /* ARM */ if (pos & 3) { printf("MISALIGNED pos in CODE32 state, aborting\n"); return; } /* reloc handling to be added */ arm_disasm_line(sec, pos); incr = 4; break; case 1: /* Thumb */ if (pos & 1) { printf("MISALIGNED pos in CODE16 state, aborting\n"); return; } /* reloc handling to be added */ if (headroom >= 4 && thumb_check_bl(sec, pos)) incr = 4; else { thumb_disasm_line(sec, pos); incr = 2; } break; default: printf("UNKNOWN T state, aborting\n"); return; } linebrk = 0; if (incr > headroom) { printf("error: increment %u > headroom %u, aborting\n", incr, headroom); return; } } } void disasm_sectype_by_name(sec) struct internal_scnhdr *sec; { if (!strncmp(sec->name, ".text", 5)) disasm_text_section(sec); /* other section types to be added */ else printf("Unrecognized section type, skipped\n"); } cmd_disasm() { struct internal_scnhdr *sec; unsigned secnum; printf("%s:\n", objfilename); dump_filehdr_info(); putchar('\n'); get_int_section_table(); get_int_symbol_table(); extern_profile_report("Module"); for (secnum = 0; secnum < nsections; secnum++) { sec = sections + secnum; printf("=== %s ===\n", sec->name); disasm_sectype_by_name(sec); putchar('\n'); } exit(0); }