From 94ec051bd16a6c954254cf18d77e9dd30032431e Mon Sep 17 00:00:00 2001 From: Mike Pavone Date: Wed, 12 Dec 2012 20:17:11 -0800 Subject: Add logic for following control flow based on logic in the translator --- dis.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) (limited to 'dis.c') diff --git a/dis.c b/dis.c index af153d3..8826864 100644 --- a/dis.c +++ b/dis.c @@ -2,6 +2,38 @@ #include #include +uint8_t visited[(16*1024*1024)/16]; + +void visit(uint32_t address) +{ + address &= 0xFFFFFF; + visited[address/16] |= 1 << ((address / 2) % 8); +} + +uint8_t is_visited(uint32_t address) +{ + address &= 0xFFFFFF; + return visited[address/16] & (1 << ((address / 2) % 8)); +} + +typedef struct deferred { + uint32_t address; + struct deferred *next; +} deferred; + +deferred * defer(uint32_t address, deferred * next) +{ + if (is_visited(address)) { + return next; + } + deferred * d = malloc(sizeof(deferred)); + d->address = address; + d->next = next; + return d; +} + +#define SIMPLE 0 + int main(int argc, char ** argv) { long filesize; @@ -20,6 +52,74 @@ int main(int argc, char ** argv) { *cur = (*cur >> 8) | (*cur << 8); } + uint32_t address = filebuf[2] << 16 | filebuf[3], tmp_addr; + #if !SIMPLE + uint16_t *encoded, *next; + uint32_t size; + deferred *def = NULL, *tmpd; + def = defer(address, def); + def = defer(filebuf[0x68/2] << 16 | filebuf[0x6A/2], def); + def = defer(filebuf[0x70/2] << 16 | filebuf[0x72/2], def); + def = defer(filebuf[0x78/2] << 16 | filebuf[0x7A/2], def); + while(def) { + do { + encoded = NULL; + address = def->address; + if (!is_visited(address)) { + encoded = filebuf + address/2; + } + tmpd = def; + def = def->next; + free(tmpd); + } while(def && encoded == NULL); + if (!encoded) { + break; + } + for(;;) { + visit(instbuf.address); + next = m68k_decode(encoded, &instbuf, address); + address += (next-encoded)*2; + encoded = next; + m68k_disasm(&instbuf, disbuf); + if (instbuf.op == M68K_ILLEGAL || instbuf.op == M68K_RTS || instbuf.op == M68K_RTE) { + break; + } else if (instbuf.op == M68K_BCC || instbuf.op == M68K_DBCC || instbuf.op == M68K_BSR) { + if (instbuf.op == M68K_BCC && instbuf.extra.cond == COND_TRUE) { + address = instbuf.address + 2 + instbuf.src.params.immed; + encoded = filebuf + address/2; + if (is_visited(address)) { + break; + } + } else { + tmp_addr = instbuf.address + 2 + instbuf.src.params.immed; + def = defer(tmp_addr, def); + } + } else if(instbuf.op == M68K_JMP) { + if (instbuf.src.addr_mode == MODE_ABSOLUTE || MODE_ABSOLUTE_SHORT) { + address = instbuf.src.params.immed; + encoded = filebuf + address/2; + if (is_visited(address)) { + break; + } + } else { + break; + } + } else if(instbuf.op == M68K_JSR) { + if (instbuf.src.addr_mode == MODE_ABSOLUTE || MODE_ABSOLUTE_SHORT) { + def = defer(instbuf.src.params.immed, def); + } + } + } + } + for (address = 0; address < filesize; address+=2) { + if (is_visited(address)) { + encoded = filebuf + address/2; + m68k_decode(encoded, &instbuf, address); + m68k_disasm(&instbuf, disbuf); + printf("%X: %s\n", instbuf.address, disbuf); + } + } + #else for(cur = filebuf + 0x100; (cur - filebuf) < (filesize/2); ) { //printf("cur: %p: %x\n", cur, *cur); @@ -28,5 +128,6 @@ int main(int argc, char ** argv) m68k_disasm(&instbuf, disbuf); printf("%X: %s\n", instbuf.address, disbuf); } + #endif return 0; } -- cgit v1.2.3