From 991cfeaf20eb2380e53822af54c21f9d739fb1fe Mon Sep 17 00:00:00 2001 From: julianb0 Date: Thu, 16 May 2019 21:42:23 +0200 Subject: [PATCH] disassembly --- .gitignore | 2 ++ Makefile | 6 ++-- as/k-as.py | 11 +++++++ pc/Makefile | 2 +- pc/arch.h | 23 ++++----------- pc/decd.c | 52 ++++++++++++++++++++++++--------- pc/disdec.c | 6 ++++ pc/dump.c | 35 ++++++++++++++++------ pc/except.c | 25 ++++++++++++++++ pc/main.c | 84 ++++++++++++++++++++++++++++++++++++----------------- 10 files changed, 175 insertions(+), 71 deletions(-) mode change 100644 => 100755 as/k-as.py create mode 100644 pc/disdec.c create mode 100644 pc/except.c diff --git a/.gitignore b/.gitignore index 27041d6..9afd788 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ *.exe *.out +*.bin *.o test* arch_i.h +*.dis diff --git a/Makefile b/Makefile index 7de064b..6d5ba5b 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,8 @@ # The OS/K Team licenses this file to you under the MIT license. # See the LICENSE file in the project root for more information. -all: kpc kas +all: kpc +# kas kpc: @cd pc && make --no-print-directory @@ -9,5 +10,6 @@ kpc: kas: @cd as && make --no-print-directory -test: all +test: kas + as/k-as.py as/testfile.asm as/testout.out diff --git a/as/k-as.py b/as/k-as.py old mode 100644 new mode 100755 index 5d6e925..300939a --- a/as/k-as.py +++ b/as/k-as.py @@ -3,5 +3,16 @@ # The OS/K Team licenses this file to you under the MIT license. # See the LICENSE file in the project root for more information. +import sys +if __name__ == '__main__': + if len(sys.argv) != 3: + print("Usage: {} input.asm output.bin".format(sys.argv[0])) + sys.exit(1) + + fi = open(sys.argv[1], "r") + out = open(sys.argv[2], "wb") + + out.close() + fi.close() diff --git a/pc/Makefile b/pc/Makefile index 0a506d4..d0d424d 100644 --- a/pc/Makefile +++ b/pc/Makefile @@ -3,7 +3,7 @@ all: k.exe -src = instrs.c decd.c main.c regs.c dump.c jumps.c +src = instrs.c decd.c main.c regs.c dump.c jumps.c except.c disdec.c obj = $(patsubst %.c,%.o,$(src)) diff --git a/pc/arch.h b/pc/arch.h index e534662..9e301d2 100644 --- a/pc/arch.h +++ b/pc/arch.h @@ -111,6 +111,9 @@ struct ctx_t // Read next instruction ushort (*get)(ctx_t *ctx); + + // For disassembly + FILE *disf; }; enum @@ -130,25 +133,9 @@ void dumpinstr(ctx_t *, ulong, ushort, acc_t *, acc_t *); void dumpmem(ctx_t *, ulong, ulong); void dumpfwstack(ctx_t *); -static inline void _except(ctx_t *ctx, int code, char *fmt, ...) -{ - va_list ap; - - log("\nException %d - ", code); - - va_start(ap, fmt); - vlog(fmt, ap); - va_end(ap); - - log("\n"); - - dumpregs(ctx); - dumpfwstack(ctx); - - free(ctx->mp); - exit(code+1); -} +void _except(ctx_t *, int, char *, ...); +void disasm(ctx_t *ctx); void decode(ctx_t *ctx); #define MEMOFF (1 * 1024 * 1024) diff --git a/pc/decd.c b/pc/decd.c index d0ee409..8f253c2 100644 --- a/pc/decd.c +++ b/pc/decd.c @@ -3,12 +3,33 @@ #include "arch.h" -void scan_param(ctx_t *ctx, acc_t *p) +#ifdef _NEED_DISASM +#define _except __except + +static inline void _except(ctx_t *ctx, int x, char *fmt, ...) +{ + va_list ap; + + log("Disassembly error: "); + + va_start(ap, fmt); + vlog(fmt, ap); + va_end(ap); + + log("\n"); + + if (ctx->disf) + fclose(ctx->disf); + + exit(-1); +} + +#endif + +static void scan_param(ctx_t *ctx, acc_t *p) { ushort c; reg_t *r; - - assert(p != 0); c = ctx->get(ctx); @@ -25,7 +46,10 @@ void scan_param(ctx_t *ctx, acc_t *p) } if (c >= A_IMM16) { - assert(p->type == A_REG); + // Check for double access code + if (p->type != A_REG) + _except(ctx, E_ILL, "Bad access code"); + p->type = c; c = ctx->get(ctx); } @@ -55,29 +79,26 @@ void scan_param(ctx_t *ctx, acc_t *p) } } +#ifndef _NEED_DISASM void decode(ctx_t *ctx) +#else +void disasm(ctx_t *ctx) +#endif { instr_t *i; acc_t p1 = { 0 }, p2 = { 0 }; ulong rip = ctx->r[RIP].val; ushort c = ctx->get(ctx); - - if (c == 0xFFFF) { - log("0x%016lX: stop\n", rip); - _except(ctx, E_SHT, "Shutdown INSTR"); - } - else if (ISPREF(c)) { + if (ISPREF(c)) { // nothing for now } else if (!ISINSTR(c)) { - _except(ctx, E_ILL, "Bad opcode 0x%4hX", c); + _except(ctx, E_ILL, "Bad opcode: 0x%4hX", c); } - // Scanning an instruction - i = &ctx->i[c]; // Scan for parameters @@ -87,8 +108,11 @@ void decode(ctx_t *ctx) scan_param(ctx, &p2); } } - + dumpinstr(ctx, rip, c, &p1, &p2); + +#ifndef _NEED_DISASM i->func(ctx, &p1, &p2); +#endif } diff --git a/pc/disdec.c b/pc/disdec.c new file mode 100644 index 0000000..357e767 --- /dev/null +++ b/pc/disdec.c @@ -0,0 +1,6 @@ +// The OS/K Team licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#define _NEED_DISASM +#include "decd.c" + diff --git a/pc/dump.c b/pc/dump.c index f82ffd4..7b05043 100644 --- a/pc/dump.c +++ b/pc/dump.c @@ -46,36 +46,53 @@ void dumpfwstack(ctx_t *ctx) //dumpmem(ctx, FWSTACK - 128, 128 + 64); } +void d_log(ctx_t *ctx, char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + + if (ctx->disf) { + vfprintf(ctx->disf, fmt, ap); + fflush(ctx->disf); + } + else + vlog(fmt, ap); + + va_end(ap); +} + void dumpinstr(ctx_t *ctx, ulong rip, ushort c, acc_t *p1, acc_t *p2) { acc_t *p = 0; instr_t *i = &ctx->i[c]; - log("0x%016lX: %s", rip, i->name); + + d_log(ctx, "0x%08lX: %s", rip, i->name); if (i->prm1 != NOPRM) p = p1; lp: if (p != 0) { - if (p->mem) log(" ["); - else log(" "); + if (p->mem) d_log(ctx, " ["); + else d_log(ctx, " "); if (p->type == A_REG) - log("%s", ctx->r[p->val].name); + d_log(ctx, "%s", ctx->r[p->val].name); else - log("0x%lX", p->val); + d_log(ctx, "0x%lX", p->val); if (p->mem) { if (p->off) - log("+%hd", p->off); - log("]"); + d_log(ctx, "+%hd", p->off); + d_log(ctx, "]"); } if (p == p1 && i->prm2 != NOPRM) { p = p2; - log(","); + d_log(ctx, ","); goto lp; } } - log("\n"); + d_log(ctx, "\n"); } diff --git a/pc/except.c b/pc/except.c new file mode 100644 index 0000000..4cae3bb --- /dev/null +++ b/pc/except.c @@ -0,0 +1,25 @@ +// The OS/K Team licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#include "arch.h" + +void _except(ctx_t *ctx, int code, char *fmt, ...) +{ + va_list ap; + + log("\nException %d - ", code); + + va_start(ap, fmt); + vlog(fmt, ap); + va_end(ap); + + log("\n"); + + dumpregs(ctx); + dumpfwstack(ctx); + + if (ctx->mp) + free(ctx->mp); + exit(code+1); +} + diff --git a/pc/main.c b/pc/main.c index e92de30..bf55710 100644 --- a/pc/main.c +++ b/pc/main.c @@ -14,18 +14,11 @@ ushort fwprog[] = { I_ADD_R_I, RBX, A_IMM16, 1, I_RET, - -/* - I_MOV_M_I, A_MEM, RBP, A_IMM16, 0xAC, - I_SUB_R_I, RBP, A_IMM16, 8, - I_ADD_M_R, A_OFF, 8, RBP, RSP, - I_MOV_R_M, RAX, A_MEM, RBP, -*/ }; ushort bget(ctx_t *ctx) { - if (addr2real(ctx->r[RIP].val) >= MEMSIZE) { + if (addr2real(ctx->r[RIP].val) >= ctx->mz) { _except(ctx, E_ACC, "Executing out of memory: 0x%016lX", ctx->r[RIP].val); } @@ -37,35 +30,72 @@ ushort bget(ctx_t *ctx) return c; } +ushort dget(ctx_t *ctx) +{ + static int i = 0; + + if (i >= sizeof(fwprog)/2) { + log("Finished disassembling\n"); + fclose(ctx->disf); + exit(0); + } + + ctx->r[RIP].val += 2; + return fwprog[i++]; +} + extern reg_t arch_r[NREGS]; extern instr_t arch_i[NINSTRS]; -int main(void) +int main(int argc, char **argv) { - static ctx_t main_ctx; + ctx_t main_ctx; main_ctx.r = arch_r; main_ctx.i = arch_i; - - main_ctx.mp = malloc(MEMSIZE); - main_ctx.mz = MEMSIZE; - - main_ctx.get = bget; - - main_ctx.r[RIP].val = MEMOFF; - - if (main_ctx.mp == 0) { - log("Couldn't allocate RAM"); - exit(-1); - } - - memcpy(&main_ctx.mp[addr2real(main_ctx.r[RIP].val)], fwprog, sizeof(fwprog)); - memset(&main_ctx.mp[addr2real(main_ctx.r[RIP].val) + sizeof(fwprog)/2], 0xFF, 0xFF); - while (1) { - decode(&main_ctx); + // Execute firmware + if (!(argc > 1 && !strcmp(argv[1], "-d"))) { + main_ctx.mp = malloc(MEMSIZE); + main_ctx.mz = MEMSIZE; + + main_ctx.get = bget; + main_ctx.disf = NULL; + + main_ctx.r[RIP].val = MEMOFF; + + if (main_ctx.mp == 0) { + log("Couldn't allocate RAM\n"); + exit(-1); + } + + memcpy(&main_ctx.mp[addr2real(main_ctx.r[RIP].val)], fwprog, sizeof(fwprog)); + + while (1) { + decode(&main_ctx); + } } + // Disassembly + else { + main_ctx.disf = fopen("fwprog.dis", "w"); + + if (main_ctx.disf == NULL) { + log("Couldn't open fwprog.dis\n"); + exit(-2); + } + + main_ctx.mp = NULL; + main_ctx.mz = 0; + + main_ctx.get = dget; + + while (1) { + disasm(&main_ctx); + } + } + + return 0; }