Instruction.h 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Optional.h>
  8. #include <AK/StdLibExtras.h>
  9. #include <AK/String.h>
  10. #include <AK/Types.h>
  11. #include <stdio.h>
  12. namespace X86 {
  13. class Instruction;
  14. class Interpreter;
  15. typedef void (Interpreter::*InstructionHandler)(const Instruction&);
  16. class SymbolProvider {
  17. public:
  18. virtual String symbolicate(FlatPtr, u32* offset = nullptr) const = 0;
  19. protected:
  20. virtual ~SymbolProvider() = default;
  21. };
  22. template<typename T>
  23. struct TypeTrivia {
  24. static const size_t bits = sizeof(T) * 8;
  25. static const T sign_bit = 1 << (bits - 1);
  26. static const T mask = MakeUnsigned<T>(-1);
  27. };
  28. template<typename T, typename U>
  29. constexpr T sign_extended_to(U value)
  30. {
  31. if (!(value & TypeTrivia<U>::sign_bit))
  32. return value;
  33. return (TypeTrivia<T>::mask & ~TypeTrivia<U>::mask) | value;
  34. }
  35. enum IsLockPrefixAllowed {
  36. LockPrefixNotAllowed = 0,
  37. LockPrefixAllowed
  38. };
  39. enum InstructionFormat {
  40. InvalidFormat,
  41. MultibyteWithSlash,
  42. InstructionPrefix,
  43. __BeginFormatsWithRMByte,
  44. OP_RM16_reg16,
  45. OP_reg8_RM8,
  46. OP_reg16_RM16,
  47. OP_RM16_seg,
  48. OP_RM32_seg,
  49. OP_RM8_imm8,
  50. OP_RM16_imm16,
  51. OP_RM16_imm8,
  52. OP_RM32_imm8,
  53. OP_RM8,
  54. OP_RM16,
  55. OP_RM32,
  56. OP_FPU,
  57. OP_FPU_reg,
  58. OP_FPU_mem,
  59. OP_FPU_AX16,
  60. OP_FPU_RM16,
  61. OP_FPU_RM32,
  62. OP_FPU_RM64,
  63. OP_FPU_M80,
  64. OP_RM8_reg8,
  65. OP_RM32_reg32,
  66. OP_reg32_RM32,
  67. OP_RM32_imm32,
  68. OP_reg16_RM16_imm8,
  69. OP_reg32_RM32_imm8,
  70. OP_reg16_RM16_imm16,
  71. OP_reg32_RM32_imm32,
  72. OP_reg16_mem16,
  73. OP_reg32_mem32,
  74. OP_seg_RM16,
  75. OP_seg_RM32,
  76. OP_RM8_1,
  77. OP_RM16_1,
  78. OP_RM32_1,
  79. OP_FAR_mem16,
  80. OP_FAR_mem32,
  81. OP_RM8_CL,
  82. OP_RM16_CL,
  83. OP_RM32_CL,
  84. OP_reg32_CR,
  85. OP_CR_reg32,
  86. OP_reg32_DR,
  87. OP_DR_reg32,
  88. OP_reg16_RM8,
  89. OP_reg32_RM8,
  90. OP_reg32_RM16,
  91. OP_RM16_reg16_imm8,
  92. OP_RM32_reg32_imm8,
  93. OP_RM16_reg16_CL,
  94. OP_RM32_reg32_CL,
  95. OP_mm1_rm32,
  96. OP_rm32_mm2,
  97. OP_mm1_mm2m64,
  98. OP_mm1_mm2m32,
  99. OP_mm1_imm8,
  100. OP_mm1m64_mm2,
  101. __EndFormatsWithRMByte,
  102. OP_reg32_imm32,
  103. OP_AL_imm8,
  104. OP_AX_imm16,
  105. OP_EAX_imm32,
  106. OP_CS,
  107. OP_DS,
  108. OP_ES,
  109. OP_SS,
  110. OP_FS,
  111. OP_GS,
  112. OP,
  113. OP_reg16,
  114. OP_imm16,
  115. OP_relimm16,
  116. OP_relimm32,
  117. OP_imm8,
  118. OP_imm16_imm16,
  119. OP_imm16_imm32,
  120. OP_AX_reg16,
  121. OP_EAX_reg32,
  122. OP_AL_moff8,
  123. OP_AX_moff16,
  124. OP_EAX_moff32,
  125. OP_moff8_AL,
  126. OP_moff16_AX,
  127. OP_moff32_EAX,
  128. OP_reg8_imm8,
  129. OP_reg16_imm16,
  130. OP_3,
  131. OP_AX_imm8,
  132. OP_EAX_imm8,
  133. OP_short_imm8,
  134. OP_AL_DX,
  135. OP_AX_DX,
  136. OP_EAX_DX,
  137. OP_DX_AL,
  138. OP_DX_AX,
  139. OP_DX_EAX,
  140. OP_imm8_AL,
  141. OP_imm8_AX,
  142. OP_imm8_EAX,
  143. OP_reg8_CL,
  144. OP_reg32,
  145. OP_imm32,
  146. OP_imm16_imm8,
  147. OP_NEAR_imm,
  148. };
  149. static const unsigned CurrentAddressSize = 0xB33FBABE;
  150. struct InstructionDescriptor {
  151. InstructionHandler handler { nullptr };
  152. bool opcode_has_register_index { false };
  153. const char* mnemonic { nullptr };
  154. InstructionFormat format { InvalidFormat };
  155. bool has_rm { false };
  156. unsigned imm1_bytes { 0 };
  157. unsigned imm2_bytes { 0 };
  158. // Addressed by the 3 REG bits in the MOD-REG-R/M byte.
  159. // Some slash instructions have further subgroups when MOD is 11,
  160. // in that case the InstructionDescriptors in slashes have themselves
  161. // a non-null slashes member that's indexed by the three R/M bits.
  162. InstructionDescriptor* slashes { nullptr };
  163. unsigned imm1_bytes_for_address_size(bool a32)
  164. {
  165. if (imm1_bytes == CurrentAddressSize)
  166. return a32 ? 4 : 2;
  167. return imm1_bytes;
  168. }
  169. unsigned imm2_bytes_for_address_size(bool a32)
  170. {
  171. if (imm2_bytes == CurrentAddressSize)
  172. return a32 ? 4 : 2;
  173. return imm2_bytes;
  174. }
  175. IsLockPrefixAllowed lock_prefix_allowed { LockPrefixNotAllowed };
  176. };
  177. extern InstructionDescriptor s_table16[256];
  178. extern InstructionDescriptor s_table32[256];
  179. extern InstructionDescriptor s_0f_table16[256];
  180. extern InstructionDescriptor s_0f_table32[256];
  181. struct Prefix {
  182. enum Op {
  183. OperandSizeOverride = 0x66,
  184. AddressSizeOverride = 0x67,
  185. REP = 0xf3,
  186. REPZ = 0xf3,
  187. REPNZ = 0xf2,
  188. LOCK = 0xf0,
  189. };
  190. };
  191. enum class SegmentRegister {
  192. ES = 0,
  193. CS,
  194. SS,
  195. DS,
  196. FS,
  197. GS,
  198. SegR6,
  199. SegR7,
  200. };
  201. enum RegisterIndex8 {
  202. RegisterAL = 0,
  203. RegisterCL,
  204. RegisterDL,
  205. RegisterBL,
  206. RegisterAH,
  207. RegisterCH,
  208. RegisterDH,
  209. RegisterBH
  210. };
  211. enum RegisterIndex16 {
  212. RegisterAX = 0,
  213. RegisterCX,
  214. RegisterDX,
  215. RegisterBX,
  216. RegisterSP,
  217. RegisterBP,
  218. RegisterSI,
  219. RegisterDI
  220. };
  221. enum RegisterIndex32 {
  222. RegisterEAX = 0,
  223. RegisterECX,
  224. RegisterEDX,
  225. RegisterEBX,
  226. RegisterESP,
  227. RegisterEBP,
  228. RegisterESI,
  229. RegisterEDI
  230. };
  231. enum FpuRegisterIndex {
  232. ST0 = 0,
  233. ST1,
  234. ST2,
  235. ST3,
  236. ST4,
  237. ST5,
  238. ST6,
  239. ST7
  240. };
  241. enum MMXRegisterIndex {
  242. RegisterMM0 = 0,
  243. RegisterMM1,
  244. RegisterMM2,
  245. RegisterMM3,
  246. RegisterMM4,
  247. RegisterMM5,
  248. RegisterMM6,
  249. RegisterMM7
  250. };
  251. class LogicalAddress {
  252. public:
  253. LogicalAddress() = default;
  254. LogicalAddress(u16 selector, FlatPtr offset)
  255. : m_selector(selector)
  256. , m_offset(offset)
  257. {
  258. }
  259. u16 selector() const { return m_selector; }
  260. FlatPtr offset() const { return m_offset; }
  261. void set_selector(u16 selector) { m_selector = selector; }
  262. void set_offset(FlatPtr offset) { m_offset = offset; }
  263. private:
  264. u16 m_selector { 0 };
  265. FlatPtr m_offset { 0 };
  266. };
  267. class InstructionStream {
  268. public:
  269. virtual bool can_read() = 0;
  270. virtual u8 read8() = 0;
  271. virtual u16 read16() = 0;
  272. virtual u32 read32() = 0;
  273. virtual u64 read64() = 0;
  274. protected:
  275. virtual ~InstructionStream() = default;
  276. };
  277. class SimpleInstructionStream final : public InstructionStream {
  278. public:
  279. SimpleInstructionStream(const u8* data, size_t size)
  280. : m_data(data)
  281. , m_size(size)
  282. {
  283. }
  284. virtual bool can_read() override { return m_offset < m_size; }
  285. virtual u8 read8() override
  286. {
  287. if (!can_read())
  288. return 0;
  289. return m_data[m_offset++];
  290. }
  291. virtual u16 read16() override
  292. {
  293. u8 lsb = read8();
  294. u8 msb = read8();
  295. return ((u16)msb << 8) | (u16)lsb;
  296. }
  297. virtual u32 read32() override
  298. {
  299. u16 lsw = read16();
  300. u16 msw = read16();
  301. return ((u32)msw << 16) | (u32)lsw;
  302. }
  303. virtual u64 read64() override
  304. {
  305. u32 lsw = read32();
  306. u32 msw = read32();
  307. return ((u64)msw << 32) | (u64)lsw;
  308. }
  309. size_t offset() const { return m_offset; }
  310. private:
  311. const u8* m_data { nullptr };
  312. size_t m_offset { 0 };
  313. size_t m_size { 0 };
  314. };
  315. class MemoryOrRegisterReference {
  316. friend class Instruction;
  317. public:
  318. String to_string_o8(const Instruction&) const;
  319. String to_string_o16(const Instruction&) const;
  320. String to_string_o32(const Instruction&) const;
  321. String to_string_fpu_reg() const;
  322. String to_string_fpu_mem(const Instruction&) const;
  323. String to_string_fpu_ax16() const;
  324. String to_string_fpu16(const Instruction&) const;
  325. String to_string_fpu32(const Instruction&) const;
  326. String to_string_fpu64(const Instruction&) const;
  327. String to_string_fpu80(const Instruction&) const;
  328. String to_string_mm(const Instruction&) const;
  329. bool is_register() const { return m_register_index != 0x7f; }
  330. unsigned register_index() const { return m_register_index; }
  331. RegisterIndex32 reg32() const { return static_cast<RegisterIndex32>(register_index()); }
  332. RegisterIndex16 reg16() const { return static_cast<RegisterIndex16>(register_index()); }
  333. RegisterIndex8 reg8() const { return static_cast<RegisterIndex8>(register_index()); }
  334. FpuRegisterIndex reg_fpu() const { return static_cast<FpuRegisterIndex>(register_index()); }
  335. // helpers to get the parts by name as in the spec
  336. u8 mod() const { return m_rm_byte >> 6; }
  337. u8 reg() const { return m_rm_byte >> 3 & 0b111; }
  338. u8 rm() const { return m_rm_byte & 0b111; }
  339. template<typename CPU, typename T>
  340. void write8(CPU&, const Instruction&, T);
  341. template<typename CPU, typename T>
  342. void write16(CPU&, const Instruction&, T);
  343. template<typename CPU, typename T>
  344. void write32(CPU&, const Instruction&, T);
  345. template<typename CPU, typename T>
  346. void write64(CPU&, const Instruction&, T);
  347. template<typename CPU, typename T>
  348. void write128(CPU&, const Instruction&, T);
  349. template<typename CPU, typename T>
  350. void write256(CPU&, const Instruction&, T);
  351. template<typename CPU>
  352. typename CPU::ValueWithShadowType8 read8(CPU&, const Instruction&);
  353. template<typename CPU>
  354. typename CPU::ValueWithShadowType16 read16(CPU&, const Instruction&);
  355. template<typename CPU>
  356. typename CPU::ValueWithShadowType32 read32(CPU&, const Instruction&);
  357. template<typename CPU>
  358. typename CPU::ValueWithShadowType64 read64(CPU&, const Instruction&);
  359. template<typename CPU>
  360. typename CPU::ValueWithShadowType128 read128(CPU&, const Instruction&);
  361. template<typename CPU>
  362. typename CPU::ValueWithShadowType256 read256(CPU&, const Instruction&);
  363. template<typename CPU>
  364. LogicalAddress resolve(const CPU&, const Instruction&);
  365. private:
  366. MemoryOrRegisterReference() = default;
  367. String to_string(const Instruction&) const;
  368. String to_string_a16() const;
  369. String to_string_a32() const;
  370. template<typename InstructionStreamType>
  371. void decode(InstructionStreamType&, bool a32);
  372. template<typename InstructionStreamType>
  373. void decode16(InstructionStreamType&);
  374. template<typename InstructionStreamType>
  375. void decode32(InstructionStreamType&);
  376. template<typename CPU>
  377. LogicalAddress resolve16(const CPU&, Optional<SegmentRegister>);
  378. template<typename CPU>
  379. LogicalAddress resolve32(const CPU&, Optional<SegmentRegister>);
  380. template<typename CPU>
  381. u32 evaluate_sib(const CPU&, SegmentRegister& default_segment) const;
  382. union {
  383. u32 m_displacement32 { 0 };
  384. u16 m_displacement16;
  385. };
  386. u8 m_rm_byte { 0 };
  387. u8 m_sib { 0 };
  388. u8 m_displacement_bytes { 0 };
  389. u8 m_register_index : 7 { 0x7f };
  390. bool m_has_sib : 1 { false };
  391. };
  392. class Instruction {
  393. public:
  394. template<typename InstructionStreamType>
  395. static Instruction from_stream(InstructionStreamType&, bool o32, bool a32);
  396. ~Instruction() { }
  397. ALWAYS_INLINE MemoryOrRegisterReference& modrm() const { return m_modrm; }
  398. ALWAYS_INLINE InstructionHandler handler() const { return m_descriptor->handler; }
  399. bool has_segment_prefix() const { return m_segment_prefix != 0xff; }
  400. ALWAYS_INLINE Optional<SegmentRegister> segment_prefix() const
  401. {
  402. if (has_segment_prefix())
  403. return static_cast<SegmentRegister>(m_segment_prefix);
  404. return {};
  405. }
  406. bool has_address_size_override_prefix() const { return m_has_address_size_override_prefix; }
  407. bool has_operand_size_override_prefix() const { return m_has_operand_size_override_prefix; }
  408. bool has_lock_prefix() const { return m_has_lock_prefix; }
  409. bool has_rep_prefix() const { return m_rep_prefix; }
  410. u8 rep_prefix() const { return m_rep_prefix; }
  411. bool is_valid() const { return m_descriptor; }
  412. unsigned length() const;
  413. String mnemonic() const;
  414. u8 op() const { return m_op; }
  415. u8 modrm_byte() const { return m_modrm.m_rm_byte; }
  416. u8 slash() const { return (modrm_byte() >> 3) & 7; }
  417. u8 imm8() const { return m_imm1; }
  418. u16 imm16() const { return m_imm1; }
  419. u32 imm32() const { return m_imm1; }
  420. u8 imm8_1() const { return imm8(); }
  421. u8 imm8_2() const { return m_imm2; }
  422. u16 imm16_1() const { return imm16(); }
  423. u16 imm16_2() const { return m_imm2; }
  424. u32 imm32_1() const { return imm32(); }
  425. u32 imm32_2() const { return m_imm2; }
  426. u32 imm_address() const { return m_a32 ? imm32() : imm16(); }
  427. LogicalAddress imm_address16_16() const { return LogicalAddress(imm16_1(), imm16_2()); }
  428. LogicalAddress imm_address16_32() const { return LogicalAddress(imm16_1(), imm32_2()); }
  429. bool has_sub_op() const
  430. {
  431. return m_op == 0x0f;
  432. }
  433. unsigned register_index() const { return m_register_index; }
  434. RegisterIndex32 reg32() const { return static_cast<RegisterIndex32>(register_index()); }
  435. RegisterIndex16 reg16() const { return static_cast<RegisterIndex16>(register_index()); }
  436. RegisterIndex8 reg8() const { return static_cast<RegisterIndex8>(register_index()); }
  437. SegmentRegister segment_register() const { return static_cast<SegmentRegister>(register_index()); }
  438. u8 cc() const { return has_sub_op() ? m_sub_op & 0xf : m_op & 0xf; }
  439. bool a32() const { return m_a32; }
  440. String to_string(u32 origin, const SymbolProvider* = nullptr, bool x32 = true) const;
  441. private:
  442. template<typename InstructionStreamType>
  443. Instruction(InstructionStreamType&, bool o32, bool a32);
  444. void to_string_internal(StringBuilder&, u32 origin, const SymbolProvider*, bool x32) const;
  445. const char* reg8_name() const;
  446. const char* reg16_name() const;
  447. const char* reg32_name() const;
  448. InstructionDescriptor* m_descriptor { nullptr };
  449. mutable MemoryOrRegisterReference m_modrm;
  450. u32 m_imm1 { 0 };
  451. u32 m_imm2 { 0 };
  452. u8 m_segment_prefix { 0xff };
  453. u8 m_register_index { 0xff };
  454. u8 m_op { 0 };
  455. u8 m_sub_op { 0 };
  456. u8 m_extra_bytes { 0 };
  457. u8 m_rep_prefix { 0 };
  458. bool m_a32 : 1 { false };
  459. bool m_o32 : 1 { false };
  460. bool m_has_lock_prefix : 1 { false };
  461. bool m_has_operand_size_override_prefix : 1 { false };
  462. bool m_has_address_size_override_prefix : 1 { false };
  463. };
  464. template<typename CPU>
  465. ALWAYS_INLINE LogicalAddress MemoryOrRegisterReference::resolve16(const CPU& cpu, Optional<SegmentRegister> segment_prefix)
  466. {
  467. auto default_segment = SegmentRegister::DS;
  468. u16 offset = 0;
  469. switch (rm()) {
  470. case 0:
  471. offset = cpu.bx().value() + cpu.si().value() + m_displacement16;
  472. break;
  473. case 1:
  474. offset = cpu.bx().value() + cpu.di().value() + m_displacement16;
  475. break;
  476. case 2:
  477. default_segment = SegmentRegister::SS;
  478. offset = cpu.bp().value() + cpu.si().value() + m_displacement16;
  479. break;
  480. case 3:
  481. default_segment = SegmentRegister::SS;
  482. offset = cpu.bp().value() + cpu.di().value() + m_displacement16;
  483. break;
  484. case 4:
  485. offset = cpu.si().value() + m_displacement16;
  486. break;
  487. case 5:
  488. offset = cpu.di().value() + m_displacement16;
  489. break;
  490. case 6:
  491. if (mod() == 0)
  492. offset = m_displacement16;
  493. else {
  494. default_segment = SegmentRegister::SS;
  495. offset = cpu.bp().value() + m_displacement16;
  496. }
  497. break;
  498. default:
  499. offset = cpu.bx().value() + m_displacement16;
  500. break;
  501. }
  502. u16 segment = cpu.segment(segment_prefix.value_or(default_segment));
  503. return { segment, offset };
  504. }
  505. template<typename CPU>
  506. ALWAYS_INLINE LogicalAddress MemoryOrRegisterReference::resolve32(const CPU& cpu, Optional<SegmentRegister> segment_prefix)
  507. {
  508. auto default_segment = SegmentRegister::DS;
  509. u32 offset = 0;
  510. switch (rm()) {
  511. case 0 ... 3:
  512. case 6 ... 7:
  513. offset = cpu.const_gpr32((RegisterIndex32)(rm())).value() + m_displacement32;
  514. break;
  515. case 4:
  516. offset = evaluate_sib(cpu, default_segment);
  517. break;
  518. default: // 5
  519. if (mod() == 0) {
  520. offset = m_displacement32;
  521. break;
  522. } else {
  523. default_segment = SegmentRegister::SS;
  524. offset = cpu.ebp().value() + m_displacement32;
  525. break;
  526. }
  527. break;
  528. }
  529. u16 segment = cpu.segment(segment_prefix.value_or(default_segment));
  530. return { segment, offset };
  531. }
  532. template<typename CPU>
  533. ALWAYS_INLINE u32 MemoryOrRegisterReference::evaluate_sib(const CPU& cpu, SegmentRegister& default_segment) const
  534. {
  535. u32 scale_shift = m_sib >> 6;
  536. u32 index = 0;
  537. switch ((m_sib >> 3) & 0x07) {
  538. case 0 ... 3:
  539. case 5 ... 7:
  540. index = cpu.const_gpr32((RegisterIndex32)((m_sib >> 3) & 0x07)).value();
  541. break;
  542. case 4:
  543. index = 0;
  544. break;
  545. }
  546. u32 base = m_displacement32;
  547. switch (m_sib & 0x07) {
  548. case 0 ... 3:
  549. case 6 ... 7:
  550. base += cpu.const_gpr32((RegisterIndex32)(m_sib & 0x07)).value();
  551. break;
  552. case 4:
  553. default_segment = SegmentRegister::SS;
  554. base += cpu.esp().value();
  555. break;
  556. default: // 5
  557. switch (mod()) {
  558. case 0:
  559. break;
  560. case 1:
  561. case 2:
  562. default_segment = SegmentRegister::SS;
  563. base += cpu.ebp().value();
  564. break;
  565. default:
  566. VERIFY_NOT_REACHED();
  567. break;
  568. }
  569. break;
  570. }
  571. return (index << scale_shift) + base;
  572. }
  573. template<typename CPU, typename T>
  574. ALWAYS_INLINE void MemoryOrRegisterReference::write8(CPU& cpu, const Instruction& insn, T value)
  575. {
  576. if (is_register()) {
  577. cpu.gpr8(reg8()) = value;
  578. return;
  579. }
  580. auto address = resolve(cpu, insn);
  581. cpu.write_memory8(address, value);
  582. }
  583. template<typename CPU, typename T>
  584. ALWAYS_INLINE void MemoryOrRegisterReference::write16(CPU& cpu, const Instruction& insn, T value)
  585. {
  586. if (is_register()) {
  587. cpu.gpr16(reg16()) = value;
  588. return;
  589. }
  590. auto address = resolve(cpu, insn);
  591. cpu.write_memory16(address, value);
  592. }
  593. template<typename CPU, typename T>
  594. ALWAYS_INLINE void MemoryOrRegisterReference::write32(CPU& cpu, const Instruction& insn, T value)
  595. {
  596. if (is_register()) {
  597. cpu.gpr32(reg32()) = value;
  598. return;
  599. }
  600. auto address = resolve(cpu, insn);
  601. cpu.write_memory32(address, value);
  602. }
  603. template<typename CPU, typename T>
  604. ALWAYS_INLINE void MemoryOrRegisterReference::write64(CPU& cpu, const Instruction& insn, T value)
  605. {
  606. VERIFY(!is_register());
  607. auto address = resolve(cpu, insn);
  608. cpu.write_memory64(address, value);
  609. }
  610. template<typename CPU, typename T>
  611. ALWAYS_INLINE void MemoryOrRegisterReference::write128(CPU& cpu, const Instruction& insn, T value)
  612. {
  613. VERIFY(!is_register());
  614. auto address = resolve(cpu, insn);
  615. cpu.write_memory128(address, value);
  616. }
  617. template<typename CPU, typename T>
  618. ALWAYS_INLINE void MemoryOrRegisterReference::write256(CPU& cpu, const Instruction& insn, T value)
  619. {
  620. VERIFY(!is_register());
  621. auto address = resolve(cpu, insn);
  622. cpu.write_memory256(address, value);
  623. }
  624. template<typename CPU>
  625. ALWAYS_INLINE typename CPU::ValueWithShadowType8 MemoryOrRegisterReference::read8(CPU& cpu, const Instruction& insn)
  626. {
  627. if (is_register())
  628. return cpu.const_gpr8(reg8());
  629. auto address = resolve(cpu, insn);
  630. return cpu.read_memory8(address);
  631. }
  632. template<typename CPU>
  633. ALWAYS_INLINE typename CPU::ValueWithShadowType16 MemoryOrRegisterReference::read16(CPU& cpu, const Instruction& insn)
  634. {
  635. if (is_register())
  636. return cpu.const_gpr16(reg16());
  637. auto address = resolve(cpu, insn);
  638. return cpu.read_memory16(address);
  639. }
  640. template<typename CPU>
  641. ALWAYS_INLINE typename CPU::ValueWithShadowType32 MemoryOrRegisterReference::read32(CPU& cpu, const Instruction& insn)
  642. {
  643. if (is_register())
  644. return cpu.const_gpr32(reg32());
  645. auto address = resolve(cpu, insn);
  646. return cpu.read_memory32(address);
  647. }
  648. template<typename CPU>
  649. ALWAYS_INLINE typename CPU::ValueWithShadowType64 MemoryOrRegisterReference::read64(CPU& cpu, const Instruction& insn)
  650. {
  651. VERIFY(!is_register());
  652. auto address = resolve(cpu, insn);
  653. return cpu.read_memory64(address);
  654. }
  655. template<typename CPU>
  656. ALWAYS_INLINE typename CPU::ValueWithShadowType128 MemoryOrRegisterReference::read128(CPU& cpu, const Instruction& insn)
  657. {
  658. VERIFY(!is_register());
  659. auto address = resolve(cpu, insn);
  660. return cpu.read_memory128(address);
  661. }
  662. template<typename CPU>
  663. ALWAYS_INLINE typename CPU::ValueWithShadowType256 MemoryOrRegisterReference::read256(CPU& cpu, const Instruction& insn)
  664. {
  665. VERIFY(!is_register());
  666. auto address = resolve(cpu, insn);
  667. return cpu.read_memory256(address);
  668. }
  669. template<typename InstructionStreamType>
  670. ALWAYS_INLINE Instruction Instruction::from_stream(InstructionStreamType& stream, bool o32, bool a32)
  671. {
  672. return Instruction(stream, o32, a32);
  673. }
  674. ALWAYS_INLINE unsigned Instruction::length() const
  675. {
  676. unsigned len = 1;
  677. if (has_sub_op())
  678. ++len;
  679. if (m_descriptor->has_rm) {
  680. ++len;
  681. if (m_modrm.m_has_sib)
  682. ++len;
  683. len += m_modrm.m_displacement_bytes;
  684. }
  685. len += m_extra_bytes;
  686. return len;
  687. }
  688. ALWAYS_INLINE Optional<SegmentRegister> to_segment_prefix(u8 op)
  689. {
  690. switch (op) {
  691. case 0x26:
  692. return SegmentRegister::ES;
  693. case 0x2e:
  694. return SegmentRegister::CS;
  695. case 0x36:
  696. return SegmentRegister::SS;
  697. case 0x3e:
  698. return SegmentRegister::DS;
  699. case 0x64:
  700. return SegmentRegister::FS;
  701. case 0x65:
  702. return SegmentRegister::GS;
  703. default:
  704. return {};
  705. }
  706. }
  707. template<typename InstructionStreamType>
  708. ALWAYS_INLINE Instruction::Instruction(InstructionStreamType& stream, bool o32, bool a32)
  709. : m_a32(a32)
  710. , m_o32(o32)
  711. {
  712. u8 prefix_bytes = 0;
  713. for (;; ++prefix_bytes) {
  714. u8 opbyte = stream.read8();
  715. if (opbyte == Prefix::OperandSizeOverride) {
  716. m_o32 = !o32;
  717. m_has_operand_size_override_prefix = true;
  718. continue;
  719. }
  720. if (opbyte == Prefix::AddressSizeOverride) {
  721. m_a32 = !a32;
  722. m_has_address_size_override_prefix = true;
  723. continue;
  724. }
  725. if (opbyte == Prefix::REPZ || opbyte == Prefix::REPNZ) {
  726. m_rep_prefix = opbyte;
  727. continue;
  728. }
  729. if (opbyte == Prefix::LOCK) {
  730. m_has_lock_prefix = true;
  731. continue;
  732. }
  733. auto segment_prefix = to_segment_prefix(opbyte);
  734. if (segment_prefix.has_value()) {
  735. m_segment_prefix = (u8)segment_prefix.value();
  736. continue;
  737. }
  738. m_op = opbyte;
  739. break;
  740. }
  741. if (m_op == 0x0f) {
  742. m_sub_op = stream.read8();
  743. m_descriptor = m_o32 ? &s_0f_table32[m_sub_op] : &s_0f_table16[m_sub_op];
  744. } else {
  745. m_descriptor = m_o32 ? &s_table32[m_op] : &s_table16[m_op];
  746. }
  747. if (m_descriptor->has_rm) {
  748. // Consume ModR/M (may include SIB and displacement.)
  749. m_modrm.decode(stream, m_a32);
  750. m_register_index = m_modrm.reg();
  751. } else {
  752. if (has_sub_op())
  753. m_register_index = m_sub_op & 7;
  754. else
  755. m_register_index = m_op & 7;
  756. }
  757. bool has_slash = m_descriptor->format == MultibyteWithSlash;
  758. if (has_slash) {
  759. m_descriptor = &m_descriptor->slashes[slash()];
  760. if ((modrm_byte() & 0xc0) == 0xc0 && m_descriptor->slashes)
  761. m_descriptor = &m_descriptor->slashes[modrm_byte() & 7];
  762. }
  763. if (!m_descriptor->mnemonic) {
  764. if (has_sub_op()) {
  765. if (has_slash)
  766. warnln("Instruction {:02X} {:02X} /{} not understood", m_op, m_sub_op, slash());
  767. else
  768. warnln("Instruction {:02X} {:02X} not understood", m_op, m_sub_op);
  769. } else {
  770. if (has_slash)
  771. warnln("Instruction {:02X} /{} not understood", m_op, slash());
  772. else
  773. warnln("Instruction {:02X} not understood", m_op);
  774. }
  775. m_descriptor = nullptr;
  776. return;
  777. }
  778. auto imm1_bytes = m_descriptor->imm1_bytes_for_address_size(m_a32);
  779. auto imm2_bytes = m_descriptor->imm2_bytes_for_address_size(m_a32);
  780. // Consume immediates if present.
  781. switch (imm2_bytes) {
  782. case 1:
  783. m_imm2 = stream.read8();
  784. break;
  785. case 2:
  786. m_imm2 = stream.read16();
  787. break;
  788. case 4:
  789. m_imm2 = stream.read32();
  790. break;
  791. default:
  792. VERIFY(imm2_bytes == 0);
  793. break;
  794. }
  795. switch (imm1_bytes) {
  796. case 1:
  797. m_imm1 = stream.read8();
  798. break;
  799. case 2:
  800. m_imm1 = stream.read16();
  801. break;
  802. case 4:
  803. m_imm1 = stream.read32();
  804. break;
  805. default:
  806. VERIFY(imm1_bytes == 0);
  807. break;
  808. }
  809. m_extra_bytes = prefix_bytes + imm1_bytes + imm2_bytes;
  810. #ifdef DISALLOW_INVALID_LOCK_PREFIX
  811. if (m_has_lock_prefix && !m_descriptor->lock_prefix_allowed) {
  812. warnln("Instruction not allowed with LOCK prefix, this will raise #UD");
  813. m_descriptor = nullptr;
  814. }
  815. #endif
  816. }
  817. template<typename InstructionStreamType>
  818. ALWAYS_INLINE void MemoryOrRegisterReference::decode(InstructionStreamType& stream, bool a32)
  819. {
  820. m_rm_byte = stream.read8();
  821. if (a32) {
  822. decode32(stream);
  823. switch (m_displacement_bytes) {
  824. case 0:
  825. break;
  826. case 1:
  827. m_displacement32 = sign_extended_to<u32>(stream.read8());
  828. break;
  829. case 4:
  830. m_displacement32 = stream.read32();
  831. break;
  832. default:
  833. VERIFY_NOT_REACHED();
  834. break;
  835. }
  836. } else {
  837. decode16(stream);
  838. switch (m_displacement_bytes) {
  839. case 0:
  840. break;
  841. case 1:
  842. m_displacement16 = sign_extended_to<u16>(stream.read8());
  843. break;
  844. case 2:
  845. m_displacement16 = stream.read16();
  846. break;
  847. default:
  848. VERIFY_NOT_REACHED();
  849. break;
  850. }
  851. }
  852. }
  853. template<typename InstructionStreamType>
  854. ALWAYS_INLINE void MemoryOrRegisterReference::decode16(InstructionStreamType&)
  855. {
  856. switch (mod()) {
  857. case 0b00:
  858. if (rm() == 6)
  859. m_displacement_bytes = 2;
  860. else
  861. VERIFY(m_displacement_bytes == 0);
  862. break;
  863. case 0b01:
  864. m_displacement_bytes = 1;
  865. break;
  866. case 0b10:
  867. m_displacement_bytes = 2;
  868. break;
  869. case 0b11:
  870. m_register_index = rm();
  871. break;
  872. }
  873. }
  874. template<typename InstructionStreamType>
  875. ALWAYS_INLINE void MemoryOrRegisterReference::decode32(InstructionStreamType& stream)
  876. {
  877. switch (mod()) {
  878. case 0b00:
  879. if (rm() == 5)
  880. m_displacement_bytes = 4;
  881. break;
  882. case 0b01:
  883. m_displacement_bytes = 1;
  884. break;
  885. case 0b10:
  886. m_displacement_bytes = 4;
  887. break;
  888. case 0b11:
  889. m_register_index = rm();
  890. return;
  891. }
  892. m_has_sib = rm() == 4;
  893. if (m_has_sib) {
  894. m_sib = stream.read8();
  895. if ((m_sib & 0x07) == 5) {
  896. switch (mod()) {
  897. case 0b00:
  898. m_displacement_bytes = 4;
  899. break;
  900. case 0b01:
  901. m_displacement_bytes = 1;
  902. break;
  903. case 0b10:
  904. m_displacement_bytes = 4;
  905. break;
  906. default:
  907. VERIFY_NOT_REACHED();
  908. break;
  909. }
  910. }
  911. }
  912. }
  913. template<typename CPU>
  914. ALWAYS_INLINE LogicalAddress MemoryOrRegisterReference::resolve(const CPU& cpu, const Instruction& insn)
  915. {
  916. if (insn.a32())
  917. return resolve32(cpu, insn.segment_prefix());
  918. return resolve16(cpu, insn.segment_prefix());
  919. }
  920. }