#include #include #include #include #include // --------------------------------------------------------------------- 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;igetPointer(); 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); } } }