96 lines
3.0 KiB
C
96 lines
3.0 KiB
C
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
#include "error.h"
|
|
#include "debug.h"
|
|
#include "vmstate.h"
|
|
#include "vmval.h"
|
|
#include "unit.h"
|
|
|
|
int debug_breakpoint(struct vm *vm) {
|
|
struct vm_func_entry *func;
|
|
struct vm_unit *unit;
|
|
uint64_t w0;
|
|
uint32_t opcode;
|
|
char line[256];
|
|
char *p;
|
|
|
|
unit = vector_ref(&vm->units, vm->lp);
|
|
func = vector_ref(&unit->functions, vm->fp);
|
|
opcode = func->bytecode[vm->ip];
|
|
|
|
fprintf(stderr, "%02zx:%02zx:%04zx: %08x\n", vm->lp, vm->fp, vm->ip, opcode);
|
|
|
|
while (1) {
|
|
fprintf(stderr, ">> ");
|
|
if (!fgets(line, sizeof(line), stdin)) {
|
|
return 0;
|
|
}
|
|
if ((p = strchr(line, '\n')) != NULL) {
|
|
*p = 0;
|
|
}
|
|
|
|
if (!strcmp(line, "s")) {
|
|
vm->flags |= VM_SINGLESTEP;
|
|
return 0;
|
|
} else if (!strcmp(line, "c")) {
|
|
vm->flags &= ~VM_SINGLESTEP;
|
|
return 0;
|
|
} else if (!strcmp(line, "q")) {
|
|
return -ERR_ERROR_EXIT;
|
|
} else if (!strcmp(line, "regs")) {
|
|
fprintf(stderr, " lp = 0x%04zx, fp = 0x%04zx\n", vm->lp, vm->fp);
|
|
fprintf(stderr, " ip = 0x%04zx\n", vm->ip);
|
|
fprintf(stderr, " dsp = 0x%04zx\n", vm->data_stack.sp);
|
|
fprintf(stderr, " csp = 0x%04zx, cbp = 0x%04zx\n", vm->call_stack.sp, vm->bp);
|
|
} else if (!strcmp(line, "locals")) {
|
|
fprintf(stderr, "Local variables:\n");
|
|
for (size_t i = 0; i < func->local_count; ++i) {
|
|
w0 = vm->call_stack.data[vm->bp - i - 1];
|
|
fprintf(stderr, "[bp - %zu]: ", i + 1);
|
|
vm_print(stderr, w0);
|
|
fprintf(stderr, "\n");
|
|
}
|
|
fprintf(stderr, "Arguments:\n");
|
|
for (size_t i = 0; i < func->argc; ++i) {
|
|
w0 = vm->call_stack.data[vm->bp + i];
|
|
fprintf(stderr, "[bp + %zu]: ", i);
|
|
vm_print(stderr, w0);
|
|
fprintf(stderr, "\n");
|
|
}
|
|
} else if (!strcmp(line, "bt")) {
|
|
fprintf(stderr, "Call frame trace:\n");
|
|
size_t bp, lp, fp, ip, sp;
|
|
size_t count;
|
|
struct vm_func_entry *f;
|
|
struct vm_unit *u;
|
|
|
|
bp = vm->bp;
|
|
lp = vm->lp;
|
|
fp = vm->fp;
|
|
ip = vm->ip;
|
|
count = 0;
|
|
while (1) {
|
|
u = vector_ref(&vm->units, lp);
|
|
f = vector_ref(&u->functions, fp);
|
|
sp = bp + f->argc;
|
|
fprintf(stderr, "%2zu: %02zx:%02zx:%04zx: %08x\n",
|
|
count, lp, fp, ip, f->bytecode[ip]);
|
|
|
|
if (count == 5) {
|
|
break;
|
|
}
|
|
bp = vm->call_stack.data[sp + 3];
|
|
lp = vm->call_stack.data[sp + 2];
|
|
fp = vm->call_stack.data[sp + 1];
|
|
ip = vm->call_stack.data[sp + 0];
|
|
++count;
|
|
|
|
if (bp == 0) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|