aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/api/script/debugger/disasm.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Wasabi/api/script/debugger/disasm.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-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.cpp193
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);
+ }
+ }
+}
+