disasm.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include <precomp.h>
  2. #include <api/script/debugger/disasm.h>
  3. #include <api/script/opcodes.h>
  4. #include <api/script/vcpu.h>
  5. #include <api/script/debugger/sourcecodeline.h>
  6. // ---------------------------------------------------------------------
  7. typedef struct {
  8. const wchar_t *opname;
  9. unsigned __int8 opval;
  10. int type;
  11. } opentry;
  12. opentry _optable[] = {
  13. {L"nop", OPCODE_NOP, OPCODE_TYPE_VOID},
  14. {L"push", OPCODE_PUSH, OPCODE_TYPE_VAR},
  15. {L"popi", OPCODE_POPI, OPCODE_TYPE_VOID},
  16. {L"pop", OPCODE_POP, OPCODE_TYPE_VAR},
  17. {L"set ", OPCODE_SET, OPCODE_TYPE_VOID},
  18. {L"retf", OPCODE_RETF, OPCODE_TYPE_VOID},
  19. {L"call", OPCODE_CALLC, OPCODE_TYPE_PTR},
  20. {L"call", OPCODE_CALLM, OPCODE_TYPE_DLF},
  21. {L"call", OPCODE_CALLM2, OPCODE_TYPE_NDLF},
  22. {L"umv", OPCODE_UMV, OPCODE_TYPE_DISCARD},
  23. {L"cmpeq", OPCODE_CMPEQ, OPCODE_TYPE_VOID},
  24. {L"cmpne", OPCODE_CMPNE, OPCODE_TYPE_VOID},
  25. {L"cmpa", OPCODE_CMPA, OPCODE_TYPE_VOID},
  26. {L"cmpae", OPCODE_CMPAE, OPCODE_TYPE_VOID},
  27. {L"cmpb", OPCODE_CMPB, OPCODE_TYPE_VOID},
  28. {L"cmpbe", OPCODE_CMPBE, OPCODE_TYPE_VOID},
  29. {L"jiz", OPCODE_JIZ, OPCODE_TYPE_PTR},
  30. {L"jnz", OPCODE_JNZ, OPCODE_TYPE_PTR},
  31. {L"jmp", OPCODE_JMP, OPCODE_TYPE_PTR},
  32. {L"incs", OPCODE_INCS, OPCODE_TYPE_VOID},
  33. {L"decs", OPCODE_DECS, OPCODE_TYPE_VOID},
  34. {L"incp", OPCODE_INCP, OPCODE_TYPE_VOID},
  35. {L"decp", OPCODE_DECP, OPCODE_TYPE_VOID},
  36. {L"add", OPCODE_ADD, OPCODE_TYPE_VOID},
  37. {L"sub", OPCODE_SUB, OPCODE_TYPE_VOID},
  38. {L"mul", OPCODE_MUL, OPCODE_TYPE_VOID},
  39. {L"div", OPCODE_DIV, OPCODE_TYPE_VOID},
  40. {L"mod", OPCODE_MOD, OPCODE_TYPE_VOID},
  41. {L"neg", OPCODE_NEG, OPCODE_TYPE_VOID},
  42. {L"shl", OPCODE_SHL, OPCODE_TYPE_VOID},
  43. {L"shr", OPCODE_SHR, OPCODE_TYPE_VOID},
  44. {L"bnot", OPCODE_BNOT, OPCODE_TYPE_VOID},
  45. {L"bxor", OPCODE_XOR, OPCODE_TYPE_VOID},
  46. {L"band", OPCODE_AND, OPCODE_TYPE_VOID},
  47. {L"bor", OPCODE_OR, OPCODE_TYPE_VOID},
  48. {L"not", OPCODE_NOT, OPCODE_TYPE_VOID},
  49. {L"and", OPCODE_LAND, OPCODE_TYPE_VOID},
  50. {L"or", OPCODE_LOR, OPCODE_TYPE_VOID},
  51. {L"del", OPCODE_DELETE, OPCODE_TYPE_VOID},
  52. {L"new", OPCODE_NEW, OPCODE_TYPE_CLASSID},
  53. {L"cmpl", OPCODE_CMPLT, OPCODE_TYPE_VOID},
  54. };
  55. int MakiDisassembler::optable[256];
  56. int MakiDisassembler::optableready = 0;
  57. MakiDisassembler::MakiDisassembler(int _vcpuid) {
  58. if (!optableready) {
  59. MEMSET(optable, 0, sizeof(optable));
  60. for (int i=0;i<sizeof(_optable)/sizeof(opentry);i++) {
  61. opentry e = _optable[i];
  62. optable[e.opval] = i;
  63. }
  64. optableready = 1;
  65. }
  66. vcpuid = _vcpuid;
  67. disassemble();
  68. }
  69. MakiDisassembler::~MakiDisassembler() {
  70. lines.deleteAll();
  71. }
  72. int MakiDisassembler::getVCPUId() {
  73. return vcpuid;
  74. }
  75. int MakiDisassembler::getNumLines() {
  76. return lines.getNumItems();
  77. }
  78. SourceCodeLine *MakiDisassembler::enumLine(int n) {
  79. return lines.enumItem(n);
  80. }
  81. int MakiDisassembler::findLine(int pointer) {
  82. int i;
  83. for (i=0;i<lines.getNumItems();i++) {
  84. SourceCodeLine *l = lines.enumItem(i);
  85. int ip = l->getPointer();
  86. int il = l->getLength();
  87. if (pointer >= ip && pointer < ip+il) {
  88. return i;
  89. }
  90. }
  91. return -1;
  92. }
  93. void MakiDisassembler::disassemble() {
  94. int size;
  95. const char *codeblock = VCPU::getCodeBlock(vcpuid, &size);
  96. if (codeblock != NULL) {
  97. const char *p = codeblock;
  98. unsigned char opcode = OPCODE_NOP;
  99. while (p < codeblock+size) {
  100. const char *start_of_instruction = p;
  101. opcode = *p;
  102. p+=sizeof(opcode);
  103. StringW inst;
  104. int a = optable[opcode];
  105. int id;
  106. int size = 0;
  107. inst = _optable[a].opname;
  108. switch (_optable[a].type) {
  109. case OPCODE_TYPE_VOID:
  110. size = 1;
  111. break;
  112. case OPCODE_TYPE_VAR:
  113. id = *(int *)p; p+=sizeof(int);
  114. inst += StringPrintfW(L" var %08X", id);
  115. size = 5;
  116. break;
  117. case OPCODE_TYPE_PTR:
  118. id = *(int *)p; p+=sizeof(int);
  119. inst += StringPrintfW(L" %08X", id+(p-codeblock));
  120. size = 5;
  121. break;
  122. case OPCODE_TYPE_DLF: {
  123. id = *(int *)p; p+=sizeof(int);
  124. int np = *(int *)p;
  125. if ((np & 0xFFFF0000) == 0xFFFF0000) {
  126. p+=sizeof(int);
  127. np &= 0xFFFF;
  128. } else
  129. np = -1;
  130. int i = VCPU::dlfBase(vcpuid)+id;
  131. if (i != -1) {
  132. VCPUdlfEntry *e = VCPU::DLFentryTable.enumItem(i);
  133. if (e != NULL) {
  134. if (np != -1) inst += StringPrintfW(L"(%d)", np);
  135. inst += L" ";
  136. inst += e->functionName;
  137. }
  138. }
  139. size = 5 + ((np == -1) ? 0 : 4);
  140. break;
  141. }
  142. case OPCODE_TYPE_NDLF: {
  143. id = *(int *)p; p+=sizeof(int);
  144. int np = *p; p++;
  145. int i = VCPU::dlfBase(vcpuid)+id;
  146. if (i != -1) {
  147. VCPUdlfEntry *e = VCPU::DLFentryTable.enumItem(i);
  148. if (e != NULL) {
  149. inst += StringPrintfW(L"(%d) ", np);
  150. inst += e->functionName;
  151. }
  152. }
  153. size = 6;
  154. break;
  155. }
  156. case OPCODE_TYPE_CLASSID: {
  157. id = *(int *)p; p+=sizeof(int);
  158. const wchar_t *cn = WASABI_API_MAKI->vcpu_getClassName(vcpuid, id);
  159. inst += L" ";
  160. inst += cn;
  161. size = 5;
  162. break;
  163. }
  164. case OPCODE_TYPE_DISCARD:
  165. id = *(int *)p; p+=sizeof(int);
  166. size = 5;
  167. break;
  168. }
  169. SourceCodeLineI *scl = new SourceCodeLineI();
  170. scl->setLine(inst),
  171. scl->setPointer(start_of_instruction-codeblock);
  172. scl->setLength(size);
  173. lines.addItem(scl);
  174. }
  175. }
  176. }