disassembly

This commit is contained in:
julianb0 2019-05-16 21:42:23 +02:00
parent bb7730d3ce
commit 991cfeaf20
No known key found for this signature in database
GPG Key ID: DDF8325C95299A62
10 changed files with 175 additions and 71 deletions

2
.gitignore vendored
View File

@ -1,6 +1,8 @@
*.exe *.exe
*.out *.out
*.bin
*.o *.o
test* test*
arch_i.h arch_i.h
*.dis

View File

@ -1,7 +1,8 @@
# The OS/K Team licenses this file to you under the MIT license. # The OS/K Team licenses this file to you under the MIT license.
# See the LICENSE file in the project root for more information. # See the LICENSE file in the project root for more information.
all: kpc kas all: kpc
# kas
kpc: kpc:
@cd pc && make --no-print-directory @cd pc && make --no-print-directory
@ -9,5 +10,6 @@ kpc:
kas: kas:
@cd as && make --no-print-directory @cd as && make --no-print-directory
test: all test: kas
as/k-as.py as/testfile.asm as/testout.out

11
as/k-as.py Normal file → Executable file
View File

@ -3,5 +3,16 @@
# The OS/K Team licenses this file to you under the MIT license. # The OS/K Team licenses this file to you under the MIT license.
# See the LICENSE file in the project root for more information. # 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()

View File

@ -3,7 +3,7 @@
all: k.exe 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)) obj = $(patsubst %.c,%.o,$(src))

View File

@ -111,6 +111,9 @@ struct ctx_t
// Read next instruction // Read next instruction
ushort (*get)(ctx_t *ctx); ushort (*get)(ctx_t *ctx);
// For disassembly
FILE *disf;
}; };
enum enum
@ -130,25 +133,9 @@ void dumpinstr(ctx_t *, ulong, ushort, acc_t *, acc_t *);
void dumpmem(ctx_t *, ulong, ulong); void dumpmem(ctx_t *, ulong, ulong);
void dumpfwstack(ctx_t *); void dumpfwstack(ctx_t *);
static inline void _except(ctx_t *ctx, int code, char *fmt, ...) void _except(ctx_t *, int, char *, ...);
{
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 disasm(ctx_t *ctx);
void decode(ctx_t *ctx); void decode(ctx_t *ctx);
#define MEMOFF (1 * 1024 * 1024) #define MEMOFF (1 * 1024 * 1024)

View File

@ -3,12 +3,33 @@
#include "arch.h" #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; ushort c;
reg_t *r; reg_t *r;
assert(p != 0);
c = ctx->get(ctx); c = ctx->get(ctx);
@ -25,7 +46,10 @@ void scan_param(ctx_t *ctx, acc_t *p)
} }
if (c >= A_IMM16) { 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; p->type = c;
c = ctx->get(ctx); 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) void decode(ctx_t *ctx)
#else
void disasm(ctx_t *ctx)
#endif
{ {
instr_t *i; instr_t *i;
acc_t p1 = { 0 }, p2 = { 0 }; acc_t p1 = { 0 }, p2 = { 0 };
ulong rip = ctx->r[RIP].val; ulong rip = ctx->r[RIP].val;
ushort c = ctx->get(ctx); 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 // nothing for now
} }
else if (!ISINSTR(c)) { 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]; i = &ctx->i[c];
// Scan for parameters // Scan for parameters
@ -87,8 +108,11 @@ void decode(ctx_t *ctx)
scan_param(ctx, &p2); scan_param(ctx, &p2);
} }
} }
dumpinstr(ctx, rip, c, &p1, &p2); dumpinstr(ctx, rip, c, &p1, &p2);
#ifndef _NEED_DISASM
i->func(ctx, &p1, &p2); i->func(ctx, &p1, &p2);
#endif
} }

6
pc/disdec.c Normal file
View File

@ -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"

View File

@ -46,36 +46,53 @@ void dumpfwstack(ctx_t *ctx)
//dumpmem(ctx, FWSTACK - 128, 128 + 64); //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) void dumpinstr(ctx_t *ctx, ulong rip, ushort c, acc_t *p1, acc_t *p2)
{ {
acc_t *p = 0; acc_t *p = 0;
instr_t *i = &ctx->i[c]; 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) if (i->prm1 != NOPRM)
p = p1; p = p1;
lp: lp:
if (p != 0) { if (p != 0) {
if (p->mem) log(" ["); if (p->mem) d_log(ctx, " [");
else log(" "); else d_log(ctx, " ");
if (p->type == A_REG) if (p->type == A_REG)
log("%s", ctx->r[p->val].name); d_log(ctx, "%s", ctx->r[p->val].name);
else else
log("0x%lX", p->val); d_log(ctx, "0x%lX", p->val);
if (p->mem) { if (p->mem) {
if (p->off) if (p->off)
log("+%hd", p->off); d_log(ctx, "+%hd", p->off);
log("]"); d_log(ctx, "]");
} }
if (p == p1 && i->prm2 != NOPRM) { if (p == p1 && i->prm2 != NOPRM) {
p = p2; p = p2;
log(","); d_log(ctx, ",");
goto lp; goto lp;
} }
} }
log("\n"); d_log(ctx, "\n");
} }

25
pc/except.c Normal file
View File

@ -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);
}

View File

@ -14,18 +14,11 @@ ushort fwprog[] = {
I_ADD_R_I, RBX, A_IMM16, 1, I_ADD_R_I, RBX, A_IMM16, 1,
I_RET, 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) 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", _except(ctx, E_ACC, "Executing out of memory: 0x%016lX",
ctx->r[RIP].val); ctx->r[RIP].val);
} }
@ -37,35 +30,72 @@ ushort bget(ctx_t *ctx)
return c; 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 reg_t arch_r[NREGS];
extern instr_t arch_i[NINSTRS]; 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.r = arch_r;
main_ctx.i = arch_i; 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) { // Execute firmware
decode(&main_ctx); 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; return 0;
} }