123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- #include <precomp.h>
- #include <api/script/debugger/disasm.h>
- #include <api/script/opcodes.h>
- #include <api/script/vcpu.h>
- #include <api/script/debugger/sourcecodeline.h>
- // ---------------------------------------------------------------------
- typedef struct {
- const wchar_t *opname;
- unsigned __int8 opval;
- int type;
- } opentry;
- opentry _optable[] = {
- {L"nop", OPCODE_NOP, OPCODE_TYPE_VOID},
- {L"push", OPCODE_PUSH, OPCODE_TYPE_VAR},
- {L"popi", OPCODE_POPI, OPCODE_TYPE_VOID},
- {L"pop", OPCODE_POP, OPCODE_TYPE_VAR},
- {L"set ", OPCODE_SET, OPCODE_TYPE_VOID},
- {L"retf", OPCODE_RETF, OPCODE_TYPE_VOID},
- {L"call", OPCODE_CALLC, OPCODE_TYPE_PTR},
- {L"call", OPCODE_CALLM, OPCODE_TYPE_DLF},
- {L"call", OPCODE_CALLM2, OPCODE_TYPE_NDLF},
- {L"umv", OPCODE_UMV, OPCODE_TYPE_DISCARD},
- {L"cmpeq", OPCODE_CMPEQ, OPCODE_TYPE_VOID},
- {L"cmpne", OPCODE_CMPNE, OPCODE_TYPE_VOID},
- {L"cmpa", OPCODE_CMPA, OPCODE_TYPE_VOID},
- {L"cmpae", OPCODE_CMPAE, OPCODE_TYPE_VOID},
- {L"cmpb", OPCODE_CMPB, OPCODE_TYPE_VOID},
- {L"cmpbe", OPCODE_CMPBE, OPCODE_TYPE_VOID},
- {L"jiz", OPCODE_JIZ, OPCODE_TYPE_PTR},
- {L"jnz", OPCODE_JNZ, OPCODE_TYPE_PTR},
- {L"jmp", OPCODE_JMP, OPCODE_TYPE_PTR},
- {L"incs", OPCODE_INCS, OPCODE_TYPE_VOID},
- {L"decs", OPCODE_DECS, OPCODE_TYPE_VOID},
- {L"incp", OPCODE_INCP, OPCODE_TYPE_VOID},
- {L"decp", OPCODE_DECP, OPCODE_TYPE_VOID},
- {L"add", OPCODE_ADD, OPCODE_TYPE_VOID},
- {L"sub", OPCODE_SUB, OPCODE_TYPE_VOID},
- {L"mul", OPCODE_MUL, OPCODE_TYPE_VOID},
- {L"div", OPCODE_DIV, OPCODE_TYPE_VOID},
- {L"mod", OPCODE_MOD, OPCODE_TYPE_VOID},
- {L"neg", OPCODE_NEG, OPCODE_TYPE_VOID},
- {L"shl", OPCODE_SHL, OPCODE_TYPE_VOID},
- {L"shr", OPCODE_SHR, OPCODE_TYPE_VOID},
- {L"bnot", OPCODE_BNOT, OPCODE_TYPE_VOID},
- {L"bxor", OPCODE_XOR, OPCODE_TYPE_VOID},
- {L"band", OPCODE_AND, OPCODE_TYPE_VOID},
- {L"bor", OPCODE_OR, OPCODE_TYPE_VOID},
- {L"not", OPCODE_NOT, OPCODE_TYPE_VOID},
- {L"and", OPCODE_LAND, OPCODE_TYPE_VOID},
- {L"or", OPCODE_LOR, OPCODE_TYPE_VOID},
- {L"del", OPCODE_DELETE, OPCODE_TYPE_VOID},
- {L"new", OPCODE_NEW, OPCODE_TYPE_CLASSID},
- {L"cmpl", OPCODE_CMPLT, OPCODE_TYPE_VOID},
- };
- int MakiDisassembler::optable[256];
- int MakiDisassembler::optableready = 0;
- MakiDisassembler::MakiDisassembler(int _vcpuid) {
- if (!optableready) {
- MEMSET(optable, 0, sizeof(optable));
- for (int i=0;i<sizeof(_optable)/sizeof(opentry);i++) {
- opentry e = _optable[i];
- optable[e.opval] = i;
- }
- optableready = 1;
- }
- vcpuid = _vcpuid;
- disassemble();
- }
- MakiDisassembler::~MakiDisassembler() {
- lines.deleteAll();
- }
- int MakiDisassembler::getVCPUId() {
- return vcpuid;
- }
- int MakiDisassembler::getNumLines() {
- return lines.getNumItems();
- }
- SourceCodeLine *MakiDisassembler::enumLine(int n) {
- return lines.enumItem(n);
- }
- int MakiDisassembler::findLine(int pointer) {
- int i;
- for (i=0;i<lines.getNumItems();i++) {
- SourceCodeLine *l = lines.enumItem(i);
- int ip = l->getPointer();
- int il = l->getLength();
- if (pointer >= ip && pointer < ip+il) {
- return i;
- }
- }
- return -1;
- }
-
- void MakiDisassembler::disassemble() {
- int size;
- const char *codeblock = VCPU::getCodeBlock(vcpuid, &size);
- if (codeblock != NULL) {
- const char *p = codeblock;
- unsigned char opcode = OPCODE_NOP;
- while (p < codeblock+size) {
- const char *start_of_instruction = p;
- opcode = *p;
- p+=sizeof(opcode);
- StringW inst;
- int a = optable[opcode];
- int id;
- int size = 0;
- inst = _optable[a].opname;
- switch (_optable[a].type) {
- case OPCODE_TYPE_VOID:
- size = 1;
- break;
- case OPCODE_TYPE_VAR:
- id = *(int *)p; p+=sizeof(int);
- inst += StringPrintfW(L" var %08X", id);
- size = 5;
- break;
- case OPCODE_TYPE_PTR:
- id = *(int *)p; p+=sizeof(int);
- inst += StringPrintfW(L" %08X", id+(p-codeblock));
- size = 5;
- break;
- case OPCODE_TYPE_DLF: {
- id = *(int *)p; p+=sizeof(int);
- int np = *(int *)p;
- if ((np & 0xFFFF0000) == 0xFFFF0000) {
- p+=sizeof(int);
- np &= 0xFFFF;
- } else
- np = -1;
- int i = VCPU::dlfBase(vcpuid)+id;
- if (i != -1) {
- VCPUdlfEntry *e = VCPU::DLFentryTable.enumItem(i);
- if (e != NULL) {
- if (np != -1) inst += StringPrintfW(L"(%d)", np);
- inst += L" ";
- inst += e->functionName;
- }
- }
- size = 5 + ((np == -1) ? 0 : 4);
- break;
- }
- case OPCODE_TYPE_NDLF: {
- id = *(int *)p; p+=sizeof(int);
- int np = *p; p++;
- int i = VCPU::dlfBase(vcpuid)+id;
- if (i != -1) {
- VCPUdlfEntry *e = VCPU::DLFentryTable.enumItem(i);
- if (e != NULL) {
- inst += StringPrintfW(L"(%d) ", np);
- inst += e->functionName;
- }
- }
- size = 6;
- break;
- }
- case OPCODE_TYPE_CLASSID: {
- id = *(int *)p; p+=sizeof(int);
- const wchar_t *cn = WASABI_API_MAKI->vcpu_getClassName(vcpuid, id);
- inst += L" ";
- inst += cn;
- size = 5;
- break;
- }
- case OPCODE_TYPE_DISCARD:
- id = *(int *)p; p+=sizeof(int);
- size = 5;
- break;
- }
- SourceCodeLineI *scl = new SourceCodeLineI();
- scl->setLine(inst),
- scl->setPointer(start_of_instruction-codeblock);
- scl->setLength(size);
- lines.addItem(scl);
- }
- }
- }
|