X64.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. #pragma once
  2. #pragma warning(disable:4141)
  3. #pragma warning(disable:4624)
  4. #pragma warning(disable:4996)
  5. #pragma warning(disable:4267)
  6. #pragma warning(disable:4244)
  7. #include "DebugCommon.h"
  8. #include "BeefySysLib/Common.h"
  9. #include <sstream>
  10. #include "llvm/MC/MCInst.h"
  11. #include "llvm/MC/MCInstPrinter.h"
  12. #include "llvm/Support/raw_ostream.h"
  13. #include "CPU.h"
  14. #include "Debugger.h"
  15. namespace llvm
  16. {
  17. class MCSubtargetInfo;
  18. class MCRegisterInfo;
  19. class MCDisassembler;
  20. class MCInst;
  21. class MCInstrInfo;
  22. class MCAsmInfo;
  23. class MCContext;
  24. class MCObjectFileInfo;
  25. }
  26. NS_BF_BEGIN
  27. class X64CPU;
  28. enum X64CPURegister
  29. {
  30. X64Reg_None = -1,
  31. // integer general registers (DO NOT REORDER THESE; must exactly match DbgModule X64 register mappings)
  32. X64Reg_RAX = 0,
  33. X64Reg_RDX,
  34. X64Reg_RCX,
  35. X64Reg_RBX,
  36. X64Reg_RSI,
  37. X64Reg_RDI,
  38. X64Reg_RBP,
  39. X64Reg_RSP,
  40. X64Reg_R8,
  41. X64Reg_R9,
  42. X64Reg_R10,
  43. X64Reg_R11,
  44. X64Reg_R12,
  45. X64Reg_R13,
  46. X64Reg_R14,
  47. X64Reg_R15,
  48. X64Reg_RIP,
  49. X64Reg_EFL,
  50. X64Reg_GS,
  51. X64Reg_EAX,
  52. X64Reg_EDX,
  53. X64Reg_ECX,
  54. X64Reg_EBX,
  55. X64Reg_ESI,
  56. X64Reg_EDI,
  57. X64Reg_R8D,
  58. X64Reg_R9D,
  59. X64Reg_R10D,
  60. X64Reg_R11D,
  61. X64Reg_R12D,
  62. X64Reg_R13D,
  63. X64Reg_R14D,
  64. X64Reg_R15D,
  65. X64Reg_AX,
  66. X64Reg_DX,
  67. X64Reg_CX,
  68. X64Reg_BX,
  69. X64Reg_SI,
  70. X64Reg_DI,
  71. X64Reg_R8W,
  72. X64Reg_R9W,
  73. X64Reg_R10W,
  74. X64Reg_R11W,
  75. X64Reg_R12W,
  76. X64Reg_R13W,
  77. X64Reg_R14W,
  78. X64Reg_R15W,
  79. X64Reg_AL,
  80. X64Reg_DL,
  81. X64Reg_CL,
  82. X64Reg_BL,
  83. X64Reg_AH,
  84. X64Reg_DH,
  85. X64Reg_CH,
  86. X64Reg_BH,
  87. X64Reg_SIL,
  88. X64Reg_DIL,
  89. X64Reg_R8B,
  90. X64Reg_R9B,
  91. X64Reg_R10B,
  92. X64Reg_R11B,
  93. X64Reg_R12B,
  94. X64Reg_R13B,
  95. X64Reg_R14B,
  96. X64Reg_R15B,
  97. // fpu registers (80-bit st(#) reg stack)
  98. X64Reg_FPST0,
  99. X64Reg_FPST1,
  100. X64Reg_FPST2,
  101. X64Reg_FPST3,
  102. X64Reg_FPST4,
  103. X64Reg_FPST5,
  104. X64Reg_FPST6,
  105. X64Reg_FPST7,
  106. // mmx registers (alias to the low 64 bits of the matching st(#) register)
  107. X64Reg_MM0,
  108. X64Reg_MM1,
  109. X64Reg_MM2,
  110. X64Reg_MM3,
  111. X64Reg_MM4,
  112. X64Reg_MM5,
  113. X64Reg_MM6,
  114. X64Reg_MM7,
  115. // XMM registers, using first element as a double
  116. X64Reg_XMM0_f64,
  117. X64Reg_XMM1_f64,
  118. X64Reg_XMM2_f64,
  119. X64Reg_XMM3_f64,
  120. X64Reg_XMM4_f64,
  121. X64Reg_XMM5_f64,
  122. X64Reg_XMM6_f64,
  123. X64Reg_XMM7_f64,
  124. X64Reg_XMM8_f64,
  125. X64Reg_XMM9_f64,
  126. X64Reg_XMM10_f64,
  127. X64Reg_XMM11_f64,
  128. X64Reg_XMM12_f64,
  129. X64Reg_XMM13_f64,
  130. X64Reg_XMM14_f64,
  131. X64Reg_XMM15_f64,
  132. // XMM registers, using first element as a float
  133. X64Reg_XMM0_f32,
  134. X64Reg_XMM1_f32,
  135. X64Reg_XMM2_f32,
  136. X64Reg_XMM3_f32,
  137. X64Reg_XMM4_f32,
  138. X64Reg_XMM5_f32,
  139. X64Reg_XMM6_f32,
  140. X64Reg_XMM7_f32,
  141. X64Reg_XMM8_f32,
  142. X64Reg_XMM9_f32,
  143. X64Reg_XMM10_f32,
  144. X64Reg_XMM11_f32,
  145. X64Reg_XMM12_f32,
  146. X64Reg_XMM13_f32,
  147. X64Reg_XMM14_f32,
  148. X64Reg_XMM15_f32,
  149. // xmm registers
  150. X64Reg_XMM00,
  151. X64Reg_XMM01,
  152. X64Reg_XMM02,
  153. X64Reg_XMM03,
  154. X64Reg_XMM10,
  155. X64Reg_XMM11,
  156. X64Reg_XMM12,
  157. X64Reg_XMM13,
  158. X64Reg_XMM20,
  159. X64Reg_XMM21,
  160. X64Reg_XMM22,
  161. X64Reg_XMM23,
  162. X64Reg_XMM30,
  163. X64Reg_XMM31,
  164. X64Reg_XMM32,
  165. X64Reg_XMM33,
  166. X64Reg_XMM40,
  167. X64Reg_XMM41,
  168. X64Reg_XMM42,
  169. X64Reg_XMM43,
  170. X64Reg_XMM50,
  171. X64Reg_XMM51,
  172. X64Reg_XMM52,
  173. X64Reg_XMM53,
  174. X64Reg_XMM60,
  175. X64Reg_XMM61,
  176. X64Reg_XMM62,
  177. X64Reg_XMM63,
  178. X64Reg_XMM70,
  179. X64Reg_XMM71,
  180. X64Reg_XMM72,
  181. X64Reg_XMM73,
  182. X64Reg_XMM80,
  183. X64Reg_XMM81,
  184. X64Reg_XMM82,
  185. X64Reg_XMM83,
  186. X64Reg_XMM90,
  187. X64Reg_XMM91,
  188. X64Reg_XMM92,
  189. X64Reg_XMM93,
  190. X64Reg_XMM10_0,
  191. X64Reg_XMM10_1,
  192. X64Reg_XMM10_2,
  193. X64Reg_XMM10_3,
  194. X64Reg_XMM11_0,
  195. X64Reg_XMM11_1,
  196. X64Reg_XMM11_2,
  197. X64Reg_XMM11_3,
  198. X64Reg_XMM12_0,
  199. X64Reg_XMM12_1,
  200. X64Reg_XMM12_2,
  201. X64Reg_XMM12_3,
  202. X64Reg_XMM13_0,
  203. X64Reg_XMM13_1,
  204. X64Reg_XMM13_2,
  205. X64Reg_XMM13_3,
  206. X64Reg_XMM14_0,
  207. X64Reg_XMM14_1,
  208. X64Reg_XMM14_2,
  209. X64Reg_XMM14_3,
  210. X64Reg_XMM15_0,
  211. X64Reg_XMM15_1,
  212. X64Reg_XMM15_2,
  213. X64Reg_XMM15_3,
  214. // 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)
  215. X64Reg_M128_XMM0,
  216. X64Reg_M128_XMM1,
  217. X64Reg_M128_XMM2,
  218. X64Reg_M128_XMM3,
  219. X64Reg_M128_XMM4,
  220. X64Reg_M128_XMM5,
  221. X64Reg_M128_XMM6,
  222. X64Reg_M128_XMM7,
  223. X64Reg_M128_XMM8,
  224. X64Reg_M128_XMM9,
  225. X64Reg_M128_XMM10,
  226. X64Reg_M128_XMM11,
  227. X64Reg_M128_XMM12,
  228. X64Reg_M128_XMM13,
  229. X64Reg_M128_XMM14,
  230. X64Reg_M128_XMM15,
  231. // flags boolean pseudo-registers (aliases to individual flags in EFL)
  232. X64Reg_FLAG_CF_CARRY,
  233. X64Reg_FLAG_PF_PARITY,
  234. X64Reg_FLAG_AF_ADJUST,
  235. X64Reg_FLAG_ZF_ZERO,
  236. X64Reg_FLAG_SF_SIGN,
  237. X64Reg_FLAG_IF_INTERRUPT,
  238. X64Reg_FLAG_DF_DIRECTION,
  239. X64Reg_FLAG_OF_OVERFLOW,
  240. // category macro-registers
  241. X64Reg_CAT_ALLREGS,
  242. X64Reg_CAT_IREGS,
  243. X64Reg_CAT_FPREGS,
  244. X64Reg_CAT_MMREGS,
  245. X64Reg_CAT_XMMREGS,
  246. X64Reg_CAT_FLAGS,
  247. X64Reg_COUNT,
  248. X64Reg_INTREG_FIRST = X64Reg_RAX,
  249. X64Reg_INTREG_LAST = X64Reg_GS,
  250. X64Reg_INTREG_COUNT = (X64Reg_INTREG_LAST - X64Reg_INTREG_FIRST) + 1,
  251. X64Reg_FPSTREG_FIRST = X64Reg_FPST0,
  252. X64Reg_FPSTREG_LAST = X64Reg_FPST7,
  253. X64Reg_FPSTREG_COUNT = (X64Reg_FPSTREG_LAST - X64Reg_FPSTREG_FIRST) + 1,
  254. X64Reg_MMREG_FIRST = X64Reg_MM0,
  255. X64Reg_MMREG_LAST = X64Reg_MM7,
  256. X64Reg_MMREG_COUNT = (X64Reg_MMREG_LAST - X64Reg_MMREG_FIRST) + 1,
  257. X64Reg_XMMREG_FIRST = X64Reg_XMM00,
  258. X64Reg_XMMREG_LAST = X64Reg_XMM15_3,
  259. X64Reg_XMMREG_SINGLE_COUNT = (X64Reg_XMMREG_LAST - X64Reg_XMMREG_FIRST) + 1,
  260. X64Reg_M128_XMMREG_FIRST = X64Reg_M128_XMM0,
  261. X64Reg_M128_XMMREG_LAST = X64Reg_M128_XMM15,
  262. X64Reg_M128_XMMREG_COUNT = (X64Reg_M128_XMMREG_LAST - X64Reg_M128_XMMREG_FIRST) + 1,
  263. X64Reg_FLAG_FIRST = X64Reg_FLAG_CF_CARRY,
  264. X64Reg_FLAG_LAST = X64Reg_FLAG_OF_OVERFLOW,
  265. X64Reg_FLAG_COUNT = (X64Reg_FLAG_LAST - X64Reg_FLAG_FIRST) + 1,
  266. X64Reg_CAT_FIRST = X64Reg_CAT_ALLREGS,
  267. X64Reg_CAT_LAST = X64Reg_CAT_FLAGS,
  268. X64Reg_CAT_COUNT = (X64Reg_CAT_LAST - X64Reg_CAT_FIRST) + 1,
  269. };
  270. #pragma pack(push, 1)
  271. class X64CPURegisters
  272. {
  273. public:
  274. static const int kNumIntRegs = 19;
  275. static const int kNumFpMmRegs = 8;
  276. static const int kNumXmmRegs = 16;
  277. struct IntRegs
  278. {
  279. int64 rax;
  280. int64 rdx;
  281. int64 rcx;
  282. int64 rbx;
  283. int64 rsi;
  284. int64 rdi;
  285. uint64 rbp;
  286. uint64 rsp;
  287. int64 r8;
  288. int64 r9;
  289. int64 r10;
  290. int64 r11;
  291. int64 r12;
  292. int64 r13;
  293. int64 r14;
  294. int64 r15;
  295. uint64 rip;
  296. int64 efl; // Really just int32
  297. int64 gs; // For TLS
  298. };
  299. struct Fp80Reg
  300. {
  301. uint8 fp80[10]; // 80-bit FP value, must be down-converted to use as a double
  302. };
  303. union FpMmReg
  304. {
  305. Fp80Reg fp;
  306. int64 mm;
  307. };
  308. struct XmmReg
  309. {
  310. float f[4];
  311. };
  312. struct XmmDReg
  313. {
  314. double d[2];
  315. };
  316. struct XmmI32Reg
  317. {
  318. int32 i[4];
  319. };
  320. struct XmmI64Reg
  321. {
  322. int64 i[2];
  323. };
  324. union
  325. {
  326. IntRegs mIntRegs;
  327. int64 mIntRegsArray[kNumIntRegs];
  328. };
  329. FpMmReg mFpMmRegsArray[kNumFpMmRegs];
  330. union
  331. {
  332. XmmReg mXmmRegsArray[kNumXmmRegs];
  333. XmmDReg mXmmDRegsArray[kNumXmmRegs];
  334. XmmI32Reg mXmmI32RegsARray[kNumXmmRegs];
  335. XmmI64Reg mXmmI64RegsARray[kNumXmmRegs];
  336. };
  337. X64CPURegisters()
  338. {
  339. memset(&mIntRegs, 0, sizeof(mIntRegs));
  340. memset(mFpMmRegsArray, 0, sizeof(mFpMmRegsArray));
  341. memset(mXmmRegsArray, 0, sizeof(mXmmRegsArray));
  342. }
  343. inline uint64 GetPC() { return mIntRegs.rip; }
  344. inline uint64* GetPCRegisterRef() { return &mIntRegs.rip; }
  345. inline uint64 GetSP() { return mIntRegs.rsp; }
  346. inline uint64* GetSPRegisterRef() { return &mIntRegs.rsp; }
  347. inline uint64 GetBP() { return mIntRegs.rbp; }
  348. inline uint64* GetBPRegisterRef() { return &mIntRegs.rbp; }
  349. inline XmmReg* GetXMMRegRef(int regNum)
  350. {
  351. return &mXmmRegsArray[regNum];
  352. }
  353. inline int64* GetExceptionRegisterRef(int regNum)
  354. {
  355. int regRemapping[] =
  356. { X64Reg_RAX,
  357. X64Reg_RCX,
  358. X64Reg_RDX,
  359. X64Reg_RBX,
  360. X64Reg_RSP,
  361. X64Reg_RBP,
  362. X64Reg_RSI,
  363. X64Reg_RDI,
  364. X64Reg_R8,
  365. X64Reg_R9,
  366. X64Reg_R10,
  367. X64Reg_R11,
  368. X64Reg_R12,
  369. X64Reg_R13,
  370. X64Reg_R14,
  371. X64Reg_R15,
  372. X64Reg_RIP,
  373. X64Reg_EFL };
  374. return &mIntRegsArray[regRemapping[regNum]];
  375. }
  376. static int GetFlagBitForRegister(int flagRegister)
  377. {
  378. int flagBit = -1;
  379. switch (flagRegister)
  380. {
  381. case X64Reg_FLAG_CF_CARRY: flagBit = 0; break;
  382. case X64Reg_FLAG_PF_PARITY: flagBit = 2; break;
  383. case X64Reg_FLAG_AF_ADJUST: flagBit = 4; break;
  384. case X64Reg_FLAG_ZF_ZERO: flagBit = 6; break;
  385. case X64Reg_FLAG_SF_SIGN: flagBit = 7; break;
  386. case X64Reg_FLAG_IF_INTERRUPT: flagBit = 9; break;
  387. case X64Reg_FLAG_DF_DIRECTION: flagBit = 10; break;
  388. case X64Reg_FLAG_OF_OVERFLOW: flagBit = 11; break;
  389. default: break;
  390. }
  391. return flagBit;
  392. }
  393. static int GetCompositeRegister(int regNum)
  394. {
  395. if ((regNum >= X64Reg_XMMREG_FIRST) && (regNum <= X64Reg_XMMREG_LAST))
  396. return X64Reg_M128_XMMREG_FIRST + ((regNum - X64Reg_XMM00) / 4);
  397. return regNum;
  398. }
  399. static const char* sCPURegisterNames[];
  400. static const char* GetRegisterName(int regNum)
  401. {
  402. return sCPURegisterNames[regNum + 1];
  403. }
  404. };
  405. #pragma pack(pop)
  406. class X64Instr
  407. {
  408. public:
  409. X64CPU* mX64;
  410. llvm::MCInst mMCInst;
  411. uint64 mAddress;
  412. int mSize;
  413. llvm::SmallVector<char, 64> mAnnotationStr;
  414. llvm::raw_svector_ostream mAnnotationStream;
  415. //static uint8 sRegForm[];
  416. X64Instr() :
  417. mAnnotationStream(mAnnotationStr)
  418. {
  419. mX64 = NULL;
  420. mAddress = 0;
  421. mSize = 0;
  422. }
  423. int GetLength();
  424. bool IsBranch();
  425. bool IsCall();
  426. bool IsRep(bool& isPrefixOnly);
  427. bool IsReturn();
  428. bool IsLoadAddress();
  429. bool GetIndexRegisterAndOffset(int* outRegister, int* outOffset); // IE: [ebp + 0x4]
  430. bool GetImmediate(uint64* outImm);
  431. int GetJmpState(int flags);
  432. void MarkRegsUsed(Array<RegForm>& regsUsed, bool overrideForm);
  433. uint64 GetTarget(Debugger* debugger = NULL, X64CPURegisters* registers = NULL);
  434. bool PartialSimulate(Debugger* debugger, X64CPURegisters* registers);
  435. };
  436. class X64CPU
  437. {
  438. public:
  439. typedef std::multimap<String, int> StringToOpcodeMap;
  440. llvm::MCContext* mMCContext;
  441. llvm::MCObjectFileInfo* mMCObjectFileInfo;
  442. llvm::MCSubtargetInfo* mSubtargetInfo;
  443. llvm::MCRegisterInfo* mRegisterInfo;
  444. llvm::MCAsmInfo* mAsmInfo;
  445. llvm::MCInstPrinter* mInstPrinter;
  446. llvm::MCDisassembler* mDisAsm;
  447. llvm::MCInstrInfo* mInstrInfo;
  448. String mWarningString;
  449. std::stringstream mWarningStream;
  450. String mCommentString;
  451. std::stringstream mCommentStream;
  452. StringToOpcodeMap mStringToOpcodeMap;
  453. public:
  454. X64CPU();
  455. ~X64CPU();
  456. bool Decode(uint64 address, DbgModuleMemoryCache* memoryCache, X64Instr* inst);
  457. bool Decode(uint64 baseAddress, const uint8* dataBase, int dataLength, const uint8* dataPtr, X64Instr* inst);
  458. uint64 DecodeThunk(uint64 address, DbgModuleMemoryCache* memoryCache);
  459. bool IsReturnInstruction(X64Instr* inst);
  460. String InstructionToString(X64Instr* inst, uint64 addr);
  461. void GetNextPC(uint64 baseAddress, const uint8* dataBase, int dataLength, const uint8* dataPtr, uint32* regs, uint64 nextPCs[2]);
  462. DbgBreakKind GetDbgBreakKind(uint64 address, DbgModuleMemoryCache* memoryCache, int64* regs, int64* outObjectPtr);
  463. int GetOpcodesForMnemonic(const StringImpl& mnemonic, Array<int>& outOpcodes);
  464. void GetClobbersForMnemonic(const StringImpl& mnemonic, int argCount, Array<int>& outImplicitClobberRegNums, int& outClobberArgCount, bool& outMayClobberMem);
  465. bool ParseInlineAsmInstructionLLVM(const StringImpl&asmInst, String& outError);
  466. };
  467. #ifdef BF_DBG_64
  468. #define CPURegisters X64CPURegisters
  469. #define CPU X64CPU
  470. typedef X64Instr CPUInst;
  471. #define DwarfReg_SP X64Reg_RSP
  472. #define CPUReg_CAT_ALLREGS X64Reg_CAT_ALLREGS
  473. #define CPUReg_CAT_IREGS X64Reg_CAT_IREGS
  474. #define CPUReg_CAT_FPREGS X64Reg_CAT_FPREGS
  475. #define CPUReg_CAT_MMREGS X64Reg_CAT_MMREGS
  476. #define CPUReg_CAT_XMMREGS X64Reg_CAT_XMMREGS
  477. #define CPUReg_CAT_FLAGS X64Reg_CAT_FLAGS
  478. #define CPUReg_FLAG_CF_CARRY X64Reg_FLAG_CF_CARRY
  479. #define CPUReg_FLAG_PF_PARITY X64Reg_FLAG_PF_PARITY
  480. #define CPUReg_FLAG_AF_ADJUST X64Reg_FLAG_AF_ADJUST
  481. #define CPUReg_FLAG_ZF_ZERO X64Reg_FLAG_ZF_ZERO
  482. #define CPUReg_FLAG_SF_SIGN X64Reg_FLAG_SF_SIGN
  483. #define CPUReg_FLAG_IF_INTERRUPT X64Reg_FLAG_IF_INTERRUPT
  484. #define CPUReg_FLAG_DF_DIRECTION X64Reg_FLAG_DF_DIRECTION
  485. #define CPUReg_FLAG_OF_OVERFLOW X64Reg_FLAG_OF_OVERFLOW
  486. #define CPUReg_XMMREG_FIRST X64Reg_XMMREG_FIRST
  487. #define CPUReg_XMMREG_LAST X64Reg_XMMREG_LAST
  488. #define CPUReg_M128_XMMREG_FIRST X64Reg_M128_XMMREG_FIRST
  489. #define CPUReg_M128_XMMREG_LAST X64Reg_M128_XMMREG_LAST
  490. #define CPUReg_MMREG_FIRST X64Reg_MMREG_FIRST
  491. #define CPUReg_FPSTREG_FIRST X64Reg_FPSTREG_FIRST
  492. #endif
  493. static_assert(X64Reg_FPSTREG_COUNT == X64Reg_MMREG_COUNT, "CPUReg register count mismatch"); // these alias to the same regs
  494. static_assert(sizeof(X64CPURegisters::IntRegs) == X64CPURegisters::kNumIntRegs*sizeof(int64), "X64CPURegisters size mismatch");
  495. static_assert(sizeof(X64CPURegisters) == (X64Reg_INTREG_COUNT*sizeof(int64) + X64Reg_MMREG_COUNT*sizeof(X64CPURegisters::FpMmReg) + (X64Reg_XMMREG_SINGLE_COUNT / 4)*sizeof(X64CPURegisters::XmmReg)), "X64CPURegisters size mismatch");
  496. static_assert(offsetof(X64CPURegisters, mIntRegs) == 0, "X64CPURegisters layout mismatch");
  497. static_assert(offsetof(X64CPURegisters::IntRegs, rax) == 0, "X64CPURegisters layout mismatch");
  498. NS_BF_END