ia32_operand.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "libdis.h"
  5. #include "ia32_insn.h"
  6. #include "ia32_operand.h"
  7. #include "ia32_modrm.h"
  8. #include "ia32_reg.h"
  9. #include "x86_imm.h"
  10. #include "x86_operand_list.h"
  11. /* apply segment override to memory operand in insn */
  12. static void apply_seg( x86_op_t *op, unsigned int prefixes ) {
  13. if (! prefixes ) return;
  14. /* apply overrides from prefix */
  15. switch ( prefixes & PREFIX_REG_MASK ) {
  16. /* NOTE: that op->flags for segment override are not a bitfield */
  17. case PREFIX_CS:
  18. op->flags.op_seg = x86_op_flags::op_cs_seg>>8; break;
  19. case PREFIX_SS:
  20. op->flags.op_seg = x86_op_flags::op_ss_seg>>8; break;
  21. case PREFIX_DS:
  22. op->flags.op_seg = x86_op_flags::op_ds_seg>>8; break;
  23. case PREFIX_ES:
  24. op->flags.op_seg = x86_op_flags::op_es_seg>>8; break;
  25. case PREFIX_FS:
  26. op->flags.op_seg = x86_op_flags::op_fs_seg>>8; break;
  27. case PREFIX_GS:
  28. op->flags.op_seg = x86_op_flags::op_gs_seg>>8; break;
  29. }
  30. return;
  31. }
  32. size_t Ia32_Decoder::decode_operand_value( unsigned char *buf, size_t buf_len,
  33. x86_op_t *op,
  34. unsigned int addr_meth, size_t op_size,
  35. unsigned int op_value, unsigned char modrm,
  36. size_t gen_regs ) {
  37. size_t size = 0;
  38. /* ++ Do Operand Addressing Method / Decode operand ++ */
  39. switch (addr_meth) {
  40. /* This sets the operand Size based on the Intel Opcode Map
  41. * (Vol 2, Appendix A). Letter encodings are from section
  42. * A.1.1, 'Codes for Addressing Method' */
  43. /* ---------------------- Addressing Method -------------- */
  44. /* Note that decoding mod ModR/M operand adjusts the size of
  45. * the instruction, but decoding the reg operand does not.
  46. * This should not cause any problems, as every 'reg' operand
  47. * has an associated 'mod' operand.
  48. * Goddamn-Intel-Note:
  49. * Some Intel addressing methods [M, R] specify that modR/M
  50. * byte may only refer to a memory address/may only refer to
  51. * a register -- however Intel provides no clues on what to do
  52. * if, say, the modR/M for an M opcode decodes to a register
  53. * rather than a memory address ... returning 0 is out of the
  54. * question, as this would be an Immediate or a RelOffset, so
  55. * instead these modR/Ms are decoded with total disregard to
  56. * the M, R constraints. */
  57. /* MODRM -- mod operand. sets size to at least 1! */
  58. case ADDRMETH_E: /* ModR/M present, Gen reg or memory */
  59. size = ia32_modrm_decode( buf, buf_len, op, gen_regs );
  60. break;
  61. case ADDRMETH_M: /* ModR/M only refers to memory */
  62. size = ia32_modrm_decode( buf, buf_len, op, gen_regs );
  63. break;
  64. case ADDRMETH_Q: /* ModR/M present, MMX or Memory */
  65. size = ia32_modrm_decode( buf, buf_len, op, REG_MMX_OFFSET );
  66. break;
  67. case ADDRMETH_R: /* ModR/M mod == gen reg */
  68. size = ia32_modrm_decode( buf, buf_len, op, gen_regs );
  69. break;
  70. case ADDRMETH_W: /* ModR/M present, mem or SIMD reg */
  71. size = ia32_modrm_decode( buf, buf_len, op, REG_SIMD_OFFSET );
  72. break;
  73. /* MODRM -- reg operand. does not effect size! */
  74. case ADDRMETH_C: /* ModR/M reg == control reg */
  75. ia32_reg_decode( modrm, op, REG_CTRL_OFFSET );
  76. break;
  77. case ADDRMETH_D: /* ModR/M reg == debug reg */
  78. ia32_reg_decode( modrm, op, REG_DEBUG_OFFSET );
  79. break;
  80. case ADDRMETH_G: /* ModR/M reg == gen-purpose reg */
  81. ia32_reg_decode( modrm, op, gen_regs );
  82. break;
  83. case ADDRMETH_P: /* ModR/M reg == qword MMX reg */
  84. ia32_reg_decode( modrm, op, REG_MMX_OFFSET );
  85. break;
  86. case ADDRMETH_S: /* ModR/M reg == segment reg */
  87. ia32_reg_decode( modrm, op, REG_SEG_OFFSET );
  88. break;
  89. case ADDRMETH_T: /* ModR/M reg == test reg */
  90. ia32_reg_decode( modrm, op, REG_TEST_OFFSET );
  91. break;
  92. case ADDRMETH_V: /* ModR/M reg == SIMD reg */
  93. ia32_reg_decode( modrm, op, REG_SIMD_OFFSET );
  94. break;
  95. /* No MODRM : note these set operand type explicitly */
  96. case ADDRMETH_A: /* No modR/M -- direct addr */
  97. op->type = op_absolute;
  98. //according to Intel Manuals, offset goes first
  99. /* segment:offset address used in far calls */
  100. if ( m_decoded->addr_size == 4 ) {
  101. x86_imm_sized( buf, buf_len, &op->data.absolute.offset.off32, 4 );
  102. size = 4;
  103. } else {
  104. x86_imm_sized( buf, buf_len, &op->data.absolute.offset.off16, 2 );
  105. size = 2;
  106. }
  107. x86_imm_sized( buf+size, buf_len-size, &op->data.absolute.segment, 2 );
  108. size+=2;
  109. break;
  110. case ADDRMETH_I: /* Immediate val */
  111. op->type = op_immediate;
  112. /* if it ever becomes legal to have imm as dest and
  113. * there is a src ModR/M operand, we are screwed! */
  114. if ( op->flags.op_signed ) {
  115. x86_imm_signsized(buf, buf_len, &op->data.byte,
  116. op_size);
  117. } else {
  118. x86_imm_sized(buf, buf_len, &op->data.byte,
  119. op_size);
  120. }
  121. size = op_size;
  122. break;
  123. case ADDRMETH_J: /* Rel offset to add to IP [jmp] */
  124. /* this fills op->data.near_offset or
  125. op->data.far_offset depending on the size of
  126. the operand */
  127. op->flags.op_signed = true;
  128. switch(op_size)
  129. {
  130. case 1:
  131. /* one-byte near offset */
  132. op->type = op_relative_near;
  133. size = x86_imm_signsized(buf, buf_len, &op->data.relative_near, 1);
  134. break;
  135. case 2:
  136. /* far offset...is this truly signed? */
  137. op->type = op_relative_far;
  138. int16_t offset_val; // easier upcast to int32_t
  139. size = x86_imm_signsized(buf, buf_len, &offset_val, 2 );
  140. op->data.relative_far=offset_val;
  141. break;
  142. default:
  143. assert(false);
  144. size=0;
  145. }
  146. break;
  147. case ADDRMETH_O: /* No ModR/M; op is word/dword offset */
  148. /* NOTE: these are actually RVAs not offsets to seg!! */
  149. /* note bene: 'O' ADDR_METH uses addr_size to
  150. determine operand size */
  151. op->type = op_offset;
  152. op->flags.op_pointer=true;
  153. x86_imm_sized( buf, buf_len, &op->data.offset, m_decoded->addr_size );
  154. size = m_decoded->addr_size;
  155. break;
  156. /* Hard-coded: these are specified in the insn definition */
  157. case ADDRMETH_F: /* EFLAGS register */
  158. op->type = op_register;
  159. op->flags.op_hardcode=true;
  160. ia32_handle_register( &op->data.reg, REG_FLAGS_INDEX );
  161. break;
  162. case ADDRMETH_X: /* Memory addressed by DS:SI [string] */
  163. op->type = op_expression;
  164. op->flags.op_hardcode = true;
  165. op->flags.op_seg = x86_op_flags::op_ds_seg>>8;
  166. op->flags.op_pointer = true;
  167. op->flags.op_string = true;
  168. ia32_handle_register( &op->data.expression.base,
  169. gen_regs + 6 );
  170. break;
  171. case ADDRMETH_Y: /* Memory addressed by ES:DI [string] */
  172. op->type = op_expression;
  173. op->flags.op_hardcode = true;
  174. op->flags.op_seg = x86_op_flags::op_es_seg>>8;
  175. op->flags.op_pointer = true;
  176. op->flags.op_string = true;
  177. ia32_handle_register( &op->data.expression.base,
  178. gen_regs + 7 );
  179. break;
  180. case ADDRMETH_RR: /* Gen Register hard-coded in opcode */
  181. op->type = op_register;
  182. op->flags.op_hardcode = true;
  183. ia32_handle_register( &op->data.reg,
  184. op_value + gen_regs );
  185. break;
  186. case ADDRMETH_RS: /* Seg Register hard-coded in opcode */
  187. op->type = op_register;
  188. op->flags.op_hardcode = true;
  189. ia32_handle_register( &op->data.reg, op_value + REG_SEG_OFFSET );
  190. break;
  191. case ADDRMETH_RF: /* FPU Register hard-coded in opcode */
  192. op->type = op_register;
  193. op->flags.op_hardcode = true;
  194. ia32_handle_register( &op->data.reg,
  195. op_value + REG_FPU_OFFSET );
  196. break;
  197. case ADDRMETH_RT: /* TST Register hard-coded in opcode */
  198. op->type = op_register;
  199. op->flags.op_hardcode = true;
  200. ia32_handle_register( &op->data.reg,
  201. op_value + REG_TEST_OFFSET );
  202. break;
  203. case ADDRMETH_II: /* Immediate hard-coded in opcode */
  204. op->type = op_immediate;
  205. op->data.dword = op_value;
  206. op->flags.op_hardcode = true;
  207. break;
  208. case 0: /* Operand is not used */
  209. default:
  210. /* ignore -- operand not used in this insn */
  211. op->type = op_unused; /* this shouldn't happen! */
  212. break;
  213. }
  214. return size;
  215. }
  216. size_t Ia32_Decoder::decode_operand_size( unsigned int op_type, x86_op_t *op ) {
  217. size_t size;
  218. /* ++ Do Operand Type ++ */
  219. switch (op_type) {
  220. /* This sets the operand Size based on the Intel Opcode Map
  221. * (Vol 2, Appendix A). Letter encodings are from section
  222. * A.1.2, 'Codes for Operand Type' */
  223. /* NOTE: in this routines, 'size' refers to the size
  224. * of the operand in the raw (encoded) instruction;
  225. * 'datatype' stores the actual size and datatype
  226. * of the operand */
  227. /* ------------------------ Operand Type ----------------- */
  228. case OPTYPE_c: /* byte or word [op size attr] */
  229. size = (m_decoded->op_size == 4) ? 2 : 1;
  230. op->datatype = (size == 4) ? op_word : op_byte;
  231. break;
  232. case OPTYPE_a: /* 2 word or 2 dword [op size attr] */
  233. /* pointer to a 16:16 or 32:32 BOUNDS operand */
  234. size = (m_decoded->op_size == 4) ? 8 : 4;
  235. op->datatype = (size == 4) ? op_bounds32 : op_bounds16;
  236. break;
  237. case OPTYPE_v: /* word or dword [op size attr] */
  238. size = (m_decoded->op_size == 4) ? 4 : 2;
  239. op->datatype = (size == 4) ? op_dword : op_word;
  240. break;
  241. case OPTYPE_p: /* 32/48-bit ptr [op size attr] */
  242. /* technically these flags are not accurate: the
  243. * value s a 16:16 pointer or a 16:32 pointer, where
  244. * the first '16' is a segment */
  245. size = (m_decoded->addr_size == 4) ? 6 : 4;
  246. op->datatype = (size == 6) ? op_descr32 : op_descr16;
  247. break;
  248. case OPTYPE_b: /* byte, ignore op-size */
  249. size = 1;
  250. op->datatype = op_byte;
  251. break;
  252. case OPTYPE_w: /* word, ignore op-size */
  253. size = 2;
  254. op->datatype = op_word;
  255. break;
  256. case OPTYPE_d: /* dword , ignore op-size */
  257. size = 4;
  258. op->datatype = op_dword;
  259. break;
  260. case OPTYPE_s: /* 6-byte psuedo-descriptor */
  261. /* ptr to 6-byte value which is 32:16 in 32-bit
  262. * mode, or 8:24:16 in 16-bit mode. The high byte
  263. * is ignored in 16-bit mode. */
  264. size = 6;
  265. op->datatype = (m_decoded->addr_size == 4) ?
  266. op_pdescr32 : op_pdescr16;
  267. break;
  268. case OPTYPE_q: /* qword, ignore op-size */
  269. size = 8;
  270. op->datatype = op_qword;
  271. break;
  272. case OPTYPE_dq: /* d-qword, ignore op-size */
  273. size = 16;
  274. op->datatype = op_dqword;
  275. break;
  276. case OPTYPE_ps: /* 128-bit FP data */
  277. size = 16;
  278. /* really this is 4 packed SP FP values */
  279. op->datatype = op_ssimd;
  280. break;
  281. case OPTYPE_pd: /* 128-bit FP data */
  282. size = 16;
  283. /* really this is 2 packed DP FP values */
  284. op->datatype = op_dsimd;
  285. break;
  286. case OPTYPE_ss: /* Scalar elem of 128-bit FP data */
  287. size = 16;
  288. /* this only looks at the low dword (4 bytes)
  289. * of the xmmm register passed as a param.
  290. * This is a 16-byte register where only 4 bytes
  291. * are used in the insn. Painful, ain't it? */
  292. op->datatype = op_sssimd;
  293. break;
  294. case OPTYPE_sd: /* Scalar elem of 128-bit FP data */
  295. size = 16;
  296. /* this only looks at the low qword (8 bytes)
  297. * of the xmmm register passed as a param.
  298. * This is a 16-byte register where only 8 bytes
  299. * are used in the insn. Painful, again... */
  300. op->datatype = op_sdsimd;
  301. break;
  302. case OPTYPE_pi: /* qword mmx register */
  303. size = 8;
  304. op->datatype = op_qword;
  305. break;
  306. case OPTYPE_si: /* dword integer register */
  307. size = 4;
  308. op->datatype = op_dword;
  309. break;
  310. case OPTYPE_fs: /* single-real */
  311. size = 4;
  312. op->datatype = op_sreal;
  313. break;
  314. case OPTYPE_fd: /* double real */
  315. size = 8;
  316. op->datatype = op_dreal;
  317. break;
  318. case OPTYPE_fe: /* extended real */
  319. size = 10;
  320. op->datatype = op_extreal;
  321. break;
  322. case OPTYPE_fb: /* packed BCD */
  323. size = 10;
  324. op->datatype = op_bcd;
  325. break;
  326. case OPTYPE_fv: /* pointer to FPU env: 14 or 28-bytes */
  327. size = (m_decoded->addr_size == 4)? 28 : 14;
  328. op->datatype = (size == 28)? op_fpuenv32: op_fpuenv16;
  329. break;
  330. case OPTYPE_ft: /* pointer to FPU env: 94 or 108 bytes */
  331. size = (m_decoded->addr_size == 4)? 108 : 94;
  332. op->datatype = (size == 108)?
  333. op_fpustate32: op_fpustate16;
  334. break;
  335. case OPTYPE_fx: /* 512-byte register stack */
  336. size = 512;
  337. op->datatype = op_fpregset;
  338. break;
  339. case OPTYPE_fp: /* floating point register */
  340. size = 10; /* double extended precision */
  341. op->datatype = op_fpreg;
  342. break;
  343. case OPTYPE_m: /* fake operand type used for "lea Gv, M" */
  344. size = m_decoded->addr_size;
  345. op->datatype = (size == 4) ? op_dword : op_word;
  346. break;
  347. case OPTYPE_none: /* handle weird instructions that have no encoding but use a dword datatype, like invlpg */
  348. size = 0;
  349. op->datatype = op_none;
  350. break;
  351. case 0:
  352. default:
  353. size = m_decoded->op_size;
  354. op->datatype = (size == 4) ? op_dword : op_word;
  355. break;
  356. }
  357. return size;
  358. }
  359. size_t Ia32_Decoder::ia32_decode_operand( unsigned char *buf, size_t buf_len,
  360. unsigned int raw_op,
  361. unsigned int raw_flags, unsigned int prefixes,
  362. unsigned char modrm ) {
  363. unsigned int addr_meth, op_type, op_size, gen_regs;
  364. x86_op_t *op;
  365. size_t size;
  366. /* ++ Yank optype and addr mode out of operand flags */
  367. addr_meth = raw_flags & ADDRMETH_MASK;
  368. op_type = raw_flags & OPTYPE_MASK;
  369. if ( raw_flags == ARG_NONE ) {
  370. /* operand is not used in this instruction */
  371. return 0;
  372. }
  373. /* allocate a new operand */
  374. op = m_decoded->x86_operand_new();
  375. /* ++ Copy flags from opcode table to x86_insn_t */
  376. op->access = (enum x86_op_access) OP_PERM(raw_flags);
  377. op->flags.whole = (OP_FLAGS(raw_flags) >> 12);
  378. /* Get size (for decoding) and datatype of operand */
  379. op_size = decode_operand_size(op_type, op);
  380. /* override default register set based on Operand Type */
  381. /* this allows mixing of 8, 16, and 32 bit regs in insn */
  382. if (op_size == 1) {
  383. gen_regs = REG_BYTE_OFFSET;
  384. } else if (op_size == 2) {
  385. gen_regs = REG_WORD_OFFSET;
  386. } else {
  387. gen_regs = REG_DWORD_OFFSET;
  388. }
  389. size = decode_operand_value( buf, buf_len, op, addr_meth,
  390. op_size, raw_op, modrm, gen_regs );
  391. /* if operand is an address, apply any segment override prefixes */
  392. if ( op->type == op_expression || op->type == op_offset ) {
  393. apply_seg(op, prefixes);
  394. }
  395. return size; /* return number of bytes in instruction */
  396. }