#include #include #include #include #include #include #include #include static int verbose = 0; #define LOGERR(fmt,args...) fprintf(stderr, "\nERROR: " fmt "\n", ## args); void printf_rdrb (uint32_t raw) { if (!verbose) return; printf ("r%d,r%d", (raw >> 8) & 0x1f, (raw >> 3) & 0x1f); } void printf_rdC (uint32_t raw, int limited) { if (!verbose) return; int val = raw & 0xff; if (limited) val = val >> 3; if (val > 15) printf ("r%d,%d\t// 0x%x", (raw >> 8) & 0x1f, val, val); else printf ("r%d,%d", (raw >> 8) & 0x1f, val); } void printf_label (uint32_t raw, int pc) { if (!verbose) return; int sign = (raw >> 11) & 1; raw &= 0x7ff; if (sign) pc -= (~raw + 1) & 0x7ff; else pc += raw; printf ("%d", pc); } void _disassemble (const uint8_t *data, int size) { uint32_t raw; int op, pc = 0; while (size >= 3) { raw = (data[0] << 16) | (data[1] << 8) | data[2]; if (verbose) printf ("[0x%04x] %08d:\t", pc * 3, pc); printf ("%x%02x%02x", data[0], data[1], data[2]); data += 3; size -= 3; if (!verbose) { printf ("\n"); pc++; continue; } printf ("\t"); op = raw >> 13; switch (op) { case 0: printf ("sub "); printf_rdrb (raw); break; case 1: printf ("subi "); printf_rdC (raw, 0); break; case 2: printf ("subc "); printf_rdrb (raw); break; case 3: printf ("subci "); printf_rdC (raw, 0); break; case 4: printf ("add "); printf_rdrb (raw); break; case 5: printf ("addi "); printf_rdC (raw, 0); break; case 6: printf ("addc "); printf_rdrb (raw); break; case 7: printf ("addci "); printf_rdC (raw, 0); break; case 8: if (((raw >> 3) & 0x3ff) == 0) printf ("nop"); else { printf ("mov "); printf_rdrb (raw); } break; case 9: printf ("movi "); printf_rdC (raw, 0); break; case 10: printf ("and "); printf_rdrb (raw); break; case 11: printf ("andi "); printf_rdC (raw, 0); break; case 12: printf ("or "); printf_rdrb (raw); break; case 13: printf ("ori "); printf_rdC (raw, 0); break; case 14: printf ("xor "); printf_rdrb (raw); break; case 15: printf ("xori "); printf_rdC (raw, 0); break; case 16: printf ("cmp "); printf_rdrb (raw); break; case 17: printf ("cmpi "); printf_rdC (raw, 0); break; case 18: printf ("test "); printf_rdrb (raw); break; case 19: printf ("testi "); printf_rdC (raw, 0); break; case 20: switch (raw & 0x3) { case 0: printf ("ror "); break; case 1: printf ("rol "); break; case 2: printf ("rorc "); break; case 3: printf ("rolc "); break; } printf_rdrb (raw); break; case 22: switch (raw & 0x07) { case 0: printf ("clrc"); break; case 1: printf ("setc"); break; case 2: printf ("clrz"); break; case 3: printf ("setz"); break; case 4: printf ("clri"); break; case 5: printf ("seti"); break; case 6: switch ((raw >> 3) & 0x1f) { case 0: printf ("rcsr r%d,ip", (raw >> 8) & 0x1f); break; case 1: printf ("rcsr r%d,im", (raw >> 8) & 0x1f); break; case 2: printf ("rcsr r%d,ie", (raw >> 8) & 0x1f); break; default: printf ("UNKNOWN "); break; } break; case 7: switch ((raw >> 8) & 0x1f) { case 0: printf ("wcsr ip,r%d", (raw >> 3) & 0x1f); break; case 1: printf ("wcsr im,r%d", (raw >> 3) & 0x1f); break; case 2: printf ("wcsr ie,r%d", (raw >> 3) & 0x1f); break; default: printf ("UNKNOWN "); break; } break; } break; case 23: switch (raw & 0x07) { case 0: printf ("export "); printf_rdC (raw, 1); break; case 1: printf ("import "); printf_rdC (raw, 1); break; case 2: printf ("exporti "); printf_rdrb (raw); break; case 3: printf ("importi "); printf_rdrb (raw); break; case 4: printf ("ssp "); printf_rdC (raw, 1); break; case 5: printf ("lsp "); printf_rdC (raw, 1); break; case 6: printf ("sspi "); printf_rdrb (raw); break; case 7: printf ("lspi "); printf_rdrb (raw); break; } break; case 24: if ((raw >> 12) & 0x01) printf ("bnz "); else printf ("bz "); printf_label(raw, pc); break; case 25: if ((raw >> 12) & 0x01) printf ("bnc "); else printf ("bc "); printf_label(raw, pc); break; case 26: if ((raw >> 12) & 0x01) printf ("callnz "); else printf ("callz "); printf_label(raw, pc); break; case 27: if ((raw >> 12) & 0x01) printf ("callnc "); else printf ("callc "); printf_label(raw, pc); break; case 28: if ((raw >> 12) & 0x01) printf ("ret"); else { printf ("call "); printf_label(raw, pc); } break; case 29: if ((raw >> 12) & 0x01) { printf ("b "); printf_label(raw, pc); } else printf ("iret"); break; default: printf ("UNKNOWN 0x%03x", raw); break; } printf ("\n"); pc++; } return; } int main (int argc, char *argv[]) { int fd = -1, rc = -1, raw = 0; uint8_t *buffer = NULL; struct stat stinfo; const char *filename = NULL; argc--; argv++; while (argc) { if (!strcmp (argv[0], "-v") || !strcmp (argv[0], "--verbose")) { verbose++; } else if (!strcmp (argv[0], "-r") || !strcmp (argv[0], "--raw")) { raw++; } else if (!filename) { filename = argv[0]; } else { } argc--; argv++; } do { if (stat (filename, &stinfo)) { LOGERR("Unable to stat file '%s' - %s", filename, strerror (errno)); break; } if ((fd = open (filename, O_RDONLY)) < 0) { LOGERR("Unable to open file '%s' - %s", filename, strerror (errno)); break; } buffer = (uint8_t *) malloc (stinfo.st_size); if (read (fd, buffer, stinfo.st_size) != stinfo.st_size) { LOGERR("Unable to read file '%s' - %s", filename, strerror (errno)); break; } if (raw) { int i; for (i = 0; i < stinfo.st_size; i++) printf ("%02x\n", buffer[i]); } else _disassemble (buffer, stinfo.st_size); rc = 0; } while (0); if (buffer) free (buffer); if (fd >= 0) close (fd); return rc; }