X86.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. #pragma once
  2. #pragma warning(disable:4141)
  3. #pragma warning(disable:4146)
  4. #pragma warning(disable:4624)
  5. #pragma warning(disable:4996)
  6. #pragma warning(disable:4267)
  7. #pragma warning(disable:4244)
  8. #include "DebugCommon.h"
  9. #include "BeefySysLib/Common.h"
  10. #include <sstream>
  11. #include "llvm/MC/MCInst.h"
  12. #include "llvm/MC/MCInstPrinter.h"
  13. #include "llvm/Support/raw_ostream.h"
  14. #include "CPU.h"
  15. #include "Debugger.h"
  16. namespace llvm
  17. {
  18. class MCSubtargetInfo;
  19. class MCRegisterInfo;
  20. class MCDisassembler;
  21. class MCInst;
  22. class MCInstrInfo;
  23. class MCAsmInfo;
  24. class MCContext;
  25. class MCObjectFileInfo;
  26. }
  27. NS_BF_BEGIN
  28. class X86CPU;
  29. enum X86CPURegister
  30. {
  31. // integer general registers (DO NOT REORDER THESE; must exactly match DbgModule x86 register mappings)
  32. X86Reg_EAX = 0,
  33. X86Reg_ECX,
  34. X86Reg_EDX,
  35. X86Reg_EBX,
  36. X86Reg_ESP,
  37. X86Reg_EBP,
  38. X86Reg_ESI,
  39. X86Reg_EDI,
  40. X86Reg_EIP,
  41. X86Reg_EFL,
  42. // fpu registers (80-bit st(#) reg stack)
  43. X86Reg_FPST0,
  44. X86Reg_FPST1,
  45. X86Reg_FPST2,
  46. X86Reg_FPST3,
  47. X86Reg_FPST4,
  48. X86Reg_FPST5,
  49. X86Reg_FPST6,
  50. X86Reg_FPST7,
  51. // mmx registers (alias to the low 64 bits of the matching st(#) register)
  52. X86Reg_MM0,
  53. X86Reg_MM1,
  54. X86Reg_MM2,
  55. X86Reg_MM3,
  56. X86Reg_MM4,
  57. X86Reg_MM5,
  58. X86Reg_MM6,
  59. X86Reg_MM7,
  60. // xmm registers
  61. X86Reg_XMM00,
  62. X86Reg_XMM01,
  63. X86Reg_XMM02,
  64. X86Reg_XMM03,
  65. X86Reg_XMM10,
  66. X86Reg_XMM11,
  67. X86Reg_XMM12,
  68. X86Reg_XMM13,
  69. X86Reg_XMM20,
  70. X86Reg_XMM21,
  71. X86Reg_XMM22,
  72. X86Reg_XMM23,
  73. X86Reg_XMM30,
  74. X86Reg_XMM31,
  75. X86Reg_XMM32,
  76. X86Reg_XMM33,
  77. X86Reg_XMM40,
  78. X86Reg_XMM41,
  79. X86Reg_XMM42,
  80. X86Reg_XMM43,
  81. X86Reg_XMM50,
  82. X86Reg_XMM51,
  83. X86Reg_XMM52,
  84. X86Reg_XMM53,
  85. X86Reg_XMM60,
  86. X86Reg_XMM61,
  87. X86Reg_XMM62,
  88. X86Reg_XMM63,
  89. X86Reg_XMM70,
  90. X86Reg_XMM71,
  91. X86Reg_XMM72,
  92. X86Reg_XMM73,
  93. // xmm 128-bit macro-registers (no stored data with these, they're symbolic for use as higher-level constructs, aliases to the individual xmm regs above)
  94. X86Reg_M128_XMM0,
  95. X86Reg_M128_XMM1,
  96. X86Reg_M128_XMM2,
  97. X86Reg_M128_XMM3,
  98. X86Reg_M128_XMM4,
  99. X86Reg_M128_XMM5,
  100. X86Reg_M128_XMM6,
  101. X86Reg_M128_XMM7,
  102. // flags boolean pseudo-registers (aliases to individual flags in EFL)
  103. X86Reg_FLAG_CF_CARRY,
  104. X86Reg_FLAG_PF_PARITY,
  105. X86Reg_FLAG_AF_ADJUST,
  106. X86Reg_FLAG_ZF_ZERO,
  107. X86Reg_FLAG_SF_SIGN,
  108. X86Reg_FLAG_IF_INTERRUPT,
  109. X86Reg_FLAG_DF_DIRECTION,
  110. X86Reg_FLAG_OF_OVERFLOW,
  111. // category macro-registers
  112. X86Reg_CAT_ALLREGS,
  113. X86Reg_CAT_IREGS,
  114. X86Reg_CAT_FPREGS,
  115. X86Reg_CAT_MMREGS,
  116. X86Reg_CAT_XMMREGS,
  117. X86Reg_CAT_FLAGS,
  118. X86Reg_COUNT,
  119. X86Reg_INTREG_FIRST = X86Reg_EAX,
  120. X86Reg_INTREG_LAST = X86Reg_EFL,
  121. X86Reg_INTREG_COUNT = (X86Reg_INTREG_LAST - X86Reg_INTREG_FIRST) + 1,
  122. X86Reg_FPSTREG_FIRST = X86Reg_FPST0,
  123. X86Reg_FPSTREG_LAST = X86Reg_FPST7,
  124. X86Reg_FPSTREG_COUNT = (X86Reg_FPSTREG_LAST - X86Reg_FPSTREG_FIRST) + 1,
  125. X86Reg_MMREG_FIRST = X86Reg_MM0,
  126. X86Reg_MMREG_LAST = X86Reg_MM7,
  127. X86Reg_MMREG_COUNT = (X86Reg_MMREG_LAST - X86Reg_MMREG_FIRST) + 1,
  128. X86Reg_XMMREG_FIRST = X86Reg_XMM00,
  129. X86Reg_XMMREG_LAST = X86Reg_XMM73,
  130. X86Reg_XMMREG_SINGLE_COUNT = (X86Reg_XMMREG_LAST - X86Reg_XMMREG_FIRST) + 1,
  131. X86Reg_M128_XMMREG_FIRST = X86Reg_M128_XMM0,
  132. X86Reg_M128_XMMREG_LAST = X86Reg_M128_XMM7,
  133. X86Reg_M128_XMMREG_COUNT = (X86Reg_M128_XMMREG_LAST - X86Reg_M128_XMMREG_FIRST) + 1,
  134. X86Reg_FLAG_FIRST = X86Reg_FLAG_CF_CARRY,
  135. X86Reg_FLAG_LAST = X86Reg_FLAG_OF_OVERFLOW,
  136. X86Reg_FLAG_COUNT = (X86Reg_FLAG_LAST - X86Reg_FLAG_FIRST) + 1,
  137. X86Reg_CAT_FIRST = X86Reg_CAT_ALLREGS,
  138. X86Reg_CAT_LAST = X86Reg_CAT_FLAGS,
  139. X86Reg_CAT_COUNT = (X86Reg_CAT_LAST - X86Reg_CAT_FIRST) + 1,
  140. };
  141. #pragma pack(push, 1)
  142. class X86CPURegisters
  143. {
  144. public:
  145. static const int kNumIntRegs = 10;
  146. static const int kNumFpMmRegs = 8;
  147. static const int kNumXmmRegs = 8;
  148. struct IntRegs
  149. {
  150. int32 eax;
  151. int32 ecx;
  152. int32 edx;
  153. int32 ebx;
  154. uint32 esp;
  155. uint32 ebp;
  156. int32 esi;
  157. int32 edi;
  158. uint32 eip;
  159. int32 efl;
  160. };
  161. struct Fp80Reg
  162. {
  163. uint8 fp80[10]; // 80-bit FP value, must be down-converted to use as a double
  164. };
  165. union FpMmReg
  166. {
  167. Fp80Reg fp;
  168. int64 mm;
  169. };
  170. struct XmmReg
  171. {
  172. float f[4];
  173. };
  174. struct XmmDReg
  175. {
  176. double d[2];
  177. };
  178. struct XmmI32Reg
  179. {
  180. int32 i[4];
  181. };
  182. struct XmmI64Reg
  183. {
  184. int64 i[2];
  185. };
  186. union
  187. {
  188. IntRegs mIntRegs;
  189. int32 mIntRegsArray[kNumIntRegs];
  190. };
  191. FpMmReg mFpMmRegsArray[kNumFpMmRegs];
  192. union
  193. {
  194. XmmReg mXmmRegsArray[kNumXmmRegs];
  195. XmmDReg mXmmDRegsArray[kNumXmmRegs];
  196. XmmI32Reg mXmmI32RegsARray[kNumXmmRegs];
  197. XmmI64Reg mXmmI64RegsARray[kNumXmmRegs];
  198. };
  199. X86CPURegisters()
  200. {
  201. memset(&mIntRegs, 0, sizeof(mIntRegs));
  202. memset(mFpMmRegsArray, 0, sizeof(mFpMmRegsArray));
  203. memset(mXmmRegsArray, 0, sizeof(mXmmRegsArray));
  204. }
  205. inline uint32 GetPC() { return mIntRegs.eip; }
  206. inline uint32* GetPCRegisterRef() { return &mIntRegs.eip; }
  207. inline uint32 GetSP() { return mIntRegs.esp; }
  208. inline uint32* GetSPRegisterRef() { return &mIntRegs.esp; }
  209. inline uint32 GetBP() { return mIntRegs.ebp; }
  210. inline uint32* GetBPRegisterRef() { return &mIntRegs.ebp; }
  211. inline XmmReg* GetXMMRegRef(int regNum)
  212. {
  213. return &mXmmRegsArray[regNum];
  214. }
  215. inline int32* GetExceptionRegisterRef(int regNum)
  216. {
  217. return NULL;
  218. }
  219. static int GetFlagBitForRegister(int flagRegister)
  220. {
  221. int flagBit = -1;
  222. switch (flagRegister)
  223. {
  224. case X86Reg_FLAG_CF_CARRY: flagBit = 0; break;
  225. case X86Reg_FLAG_PF_PARITY: flagBit = 2; break;
  226. case X86Reg_FLAG_AF_ADJUST: flagBit = 4; break;
  227. case X86Reg_FLAG_ZF_ZERO: flagBit = 6; break;
  228. case X86Reg_FLAG_SF_SIGN: flagBit = 7; break;
  229. case X86Reg_FLAG_IF_INTERRUPT: flagBit = 9; break;
  230. case X86Reg_FLAG_DF_DIRECTION: flagBit = 10; break;
  231. case X86Reg_FLAG_OF_OVERFLOW: flagBit = 11; break;
  232. default: break;
  233. }
  234. return flagBit;
  235. }
  236. static int GetCompositeRegister(int regNum)
  237. {
  238. if ((regNum >= X86Reg_XMMREG_FIRST) && (regNum <= X86Reg_XMMREG_LAST))
  239. return X86Reg_M128_XMMREG_FIRST + ((regNum - X86Reg_XMM00) / 4);
  240. return regNum;
  241. }
  242. static const char* sCPURegisterNames[];
  243. static const char* GetRegisterName(int regNum)
  244. {
  245. return sCPURegisterNames[regNum];
  246. }
  247. };
  248. #pragma pack(pop)
  249. class X86Instr
  250. {
  251. public:
  252. X86CPU* mX86;
  253. llvm::MCInst mMCInst;
  254. uint32 mAddress;
  255. int mSize;
  256. llvm::SmallVector<char, 64> mAnnotationStr;
  257. llvm::raw_svector_ostream mAnnotationStream;
  258. static uint8 sRegForm[];
  259. X86Instr() :
  260. mAnnotationStream(mAnnotationStr)
  261. {
  262. mX86 = NULL;
  263. mAddress = 0;
  264. mSize = 0;
  265. }
  266. int GetLength();
  267. bool StackAdjust(uint32& adjust);
  268. bool IsBranch();
  269. bool IsCall();
  270. bool IsRep(bool& isPrefixOnly);
  271. bool IsReturn();
  272. bool IsLoadAddress();
  273. bool GetIndexRegisterAndOffset(int* outRegister, int* outOffset); // IE: [ebp + 0x4]
  274. bool GetImmediate(uint32* outImm);
  275. int GetJmpState(int flags);
  276. void MarkRegsUsed(Array<RegForm>& regsUsed, bool overrideForm);
  277. uint32 GetTarget(Debugger* debugger = NULL, X86CPURegisters* registers = NULL);
  278. bool PartialSimulate(Debugger* debugger, X86CPURegisters* registers);
  279. };
  280. class X86CPU
  281. {
  282. public:
  283. typedef std::multimap<String, int> StringToOpcodeMap;
  284. llvm::MCContext* mMCContext;
  285. llvm::MCObjectFileInfo* mMCObjectFileInfo;
  286. llvm::MCSubtargetInfo* mSubtargetInfo;
  287. llvm::MCRegisterInfo* mRegisterInfo;
  288. llvm::MCAsmInfo* mAsmInfo;
  289. llvm::MCInstPrinter* mInstPrinter;
  290. llvm::MCDisassembler* mDisAsm;
  291. llvm::MCInstrInfo* mInstrInfo;
  292. String mWarningString;
  293. std::stringstream mWarningStream;
  294. String mCommentString;
  295. std::stringstream mCommentStream;
  296. StringToOpcodeMap mStringToOpcodeMap;
  297. public:
  298. X86CPU();
  299. ~X86CPU();
  300. bool Decode(uint32 address, DbgModuleMemoryCache* memoryCache, X86Instr* inst);
  301. bool Decode(uint32 baseAddress, const uint8* dataBase, int dataLength, const uint8* dataPtr, X86Instr* inst);
  302. uint32 DecodeThunk(uint32 address, DbgModuleMemoryCache* memoryCache) { return 0; }
  303. bool IsReturnInstruction(X86Instr* inst);
  304. String InstructionToString(X86Instr* inst, uint32 addr);
  305. void GetNextPC(uint32 baseAddress, const uint8* dataBase, int dataLength, const uint8* dataPtr, uint32* regs, uint32 nextPCs[2]);
  306. DbgBreakKind GetDbgBreakKind(uint32 address, DbgModuleMemoryCache* memoryCache, int32* regs, int32* outObjectPtr);
  307. int GetOpcodesForMnemonic(const StringImpl& mnemonic, Array<int>& outOpcodes);
  308. void GetClobbersForMnemonic(const StringImpl& mnemonic, int argCount, Array<int>& outImplicitClobberRegNums, int& outClobberArgCount, bool& outMayClobberMem);
  309. bool ParseInlineAsmInstructionLLVM(const StringImpl&asmInst, String& outError);
  310. };
  311. #ifdef BF_DBG_32
  312. #define CPURegisters X86CPURegisters
  313. #define CPU X86CPU
  314. typedef X86Instr CPUInst;
  315. #define DwarfReg_SP X86Reg_ESP
  316. #define CPUReg_CAT_ALLREGS X86Reg_CAT_ALLREGS
  317. #define CPUReg_CAT_IREGS X86Reg_CAT_IREGS
  318. #define CPUReg_CAT_FPREGS X86Reg_CAT_FPREGS
  319. #define CPUReg_CAT_MMREGS X86Reg_CAT_MMREGS
  320. #define CPUReg_CAT_XMMREGS X86Reg_CAT_XMMREGS
  321. #define CPUReg_CAT_FLAGS X86Reg_CAT_FLAGS
  322. #define CPUReg_FLAG_CF_CARRY X86Reg_FLAG_CF_CARRY
  323. #define CPUReg_FLAG_PF_PARITY X86Reg_FLAG_PF_PARITY
  324. #define CPUReg_FLAG_AF_ADJUST X86Reg_FLAG_AF_ADJUST
  325. #define CPUReg_FLAG_ZF_ZERO X86Reg_FLAG_ZF_ZERO
  326. #define CPUReg_FLAG_SF_SIGN X86Reg_FLAG_SF_SIGN
  327. #define CPUReg_FLAG_IF_INTERRUPT X86Reg_FLAG_IF_INTERRUPT
  328. #define CPUReg_FLAG_DF_DIRECTION X86Reg_FLAG_DF_DIRECTION
  329. #define CPUReg_FLAG_OF_OVERFLOW X86Reg_FLAG_OF_OVERFLOW
  330. #define CPUReg_XMMREG_FIRST X86Reg_XMMREG_FIRST
  331. #define CPUReg_XMMREG_LAST X86Reg_XMMREG_LAST
  332. #define CPUReg_M128_XMMREG_FIRST X86Reg_M128_XMMREG_FIRST
  333. #define CPUReg_M128_XMMREG_LAST X86Reg_M128_XMMREG_LAST
  334. #define CPUReg_MMREG_FIRST X86Reg_MMREG_FIRST
  335. #define CPUReg_FPSTREG_FIRST X86Reg_FPSTREG_FIRST
  336. #endif
  337. static_assert(X86Reg_FPSTREG_COUNT == X86Reg_MMREG_COUNT, "CPUReg register count mismatch"); // these alias to the same regs
  338. static_assert(sizeof(X86CPURegisters::IntRegs) == X86CPURegisters::kNumIntRegs*sizeof(int32), "X86CPURegisters size mismatch");
  339. static_assert(sizeof(X86CPURegisters) == (X86Reg_INTREG_COUNT*sizeof(int32) + X86Reg_MMREG_COUNT*sizeof(X86CPURegisters::FpMmReg) + (X86Reg_XMMREG_SINGLE_COUNT / 4)*sizeof(X86CPURegisters::XmmReg)), "X86CPURegisters size mismatch");
  340. static_assert(offsetof(X86CPURegisters, mIntRegs) == 0, "X86CPURegisters layout mismatch");
  341. static_assert(offsetof(X86CPURegisters::IntRegs, eax) == 0, "X86CPURegisters layout mismatch");
  342. NS_BF_END