diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Wasabi/api/script/debugger/disasm.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Wasabi/api/script/debugger/disasm.cpp')
-rw-r--r-- | Src/Wasabi/api/script/debugger/disasm.cpp | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/Src/Wasabi/api/script/debugger/disasm.cpp b/Src/Wasabi/api/script/debugger/disasm.cpp new file mode 100644 index 00000000..7b3c17ee --- /dev/null +++ b/Src/Wasabi/api/script/debugger/disasm.cpp @@ -0,0 +1,193 @@ +#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); + } + } +} + |