ia32_insn.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <cassert>
  5. #include "qword.h"
  6. #include "ia32_insn.h"
  7. #include "ia32_opcode_tables.h"
  8. #include "ia32_reg.h"
  9. #include "ia32_operand.h"
  10. #include "ia32_implicit.h"
  11. #include "ia32_settings.h"
  12. #include "libdis.h"
  13. extern ia32_table_desc_t ia32_tables[];
  14. extern ia32_settings_t ia32_settings;
  15. #define IS_SP( op ) (op->type == op_register && \
  16. (op->data.reg.id == REG_ESP_INDEX || \
  17. op->data.reg.alias == REG_ESP_INDEX) )
  18. #define IS_IMM( op ) (op->type == op_immediate )
  19. #ifdef WIN32
  20. # define INLINE
  21. #else
  22. # define INLINE inline
  23. #endif
  24. /* for calculating stack modification based on an operand */
  25. INLINE int32_t x86_op_t::long_from_operand() {
  26. if (! IS_IMM(this) ) {
  27. return 0L;
  28. }
  29. switch ( datatype ) {
  30. case op_byte:
  31. return (int32_t) data.sbyte;
  32. case op_word:
  33. return (int32_t) data.sword;
  34. case op_qword:
  35. return (int32_t) data.sqword;
  36. case op_dword:
  37. return data.sdword;
  38. default:
  39. /* these are not used in stack insn */
  40. break;
  41. }
  42. return 0L;
  43. }
  44. /* determine what this insn does to the stack */
  45. void Ia32_Decoder::ia32_stack_mod() {
  46. x86_op_t *dest, *src = NULL;
  47. assert(this);
  48. if (! m_decoded->operands ) {
  49. return;
  50. }
  51. dest = &m_decoded->operands->op;
  52. if ( dest ) {
  53. src = &m_decoded->operands->next->op;
  54. }
  55. m_decoded->stack_mod = 0;
  56. m_decoded->stack_mod_val = 0;
  57. switch ( m_decoded->type ) {
  58. case insn_call:
  59. case insn_callcc:
  60. m_decoded->stack_mod = 1;
  61. m_decoded->stack_mod_val = m_decoded->addr_size * -1;
  62. break;
  63. case insn_push:
  64. m_decoded->stack_mod = 1;
  65. m_decoded->stack_mod_val = m_decoded->addr_size * -1;
  66. break;
  67. case insn_return:
  68. m_decoded->stack_mod = 1;
  69. m_decoded->stack_mod_val = m_decoded->addr_size;
  70. case insn_int: case insn_intcc:
  71. case insn_iret:
  72. break;
  73. case insn_pop:
  74. m_decoded->stack_mod = 1;
  75. if (! IS_SP( dest ) ) {
  76. m_decoded->stack_mod_val = m_decoded->op_size;
  77. } /* else we don't know the stack change in a pop esp */
  78. break;
  79. case insn_enter:
  80. m_decoded->stack_mod = 1;
  81. m_decoded->stack_mod_val = 0; /* TODO : FIX */
  82. break;
  83. case insn_leave:
  84. m_decoded->stack_mod = 1;
  85. m_decoded->stack_mod_val = 0; /* TODO : FIX */
  86. break;
  87. case insn_pushregs:
  88. m_decoded->stack_mod = 1;
  89. m_decoded->stack_mod_val = 0; /* TODO : FIX */
  90. break;
  91. case insn_popregs:
  92. m_decoded->stack_mod = 1;
  93. m_decoded->stack_mod_val = 0; /* TODO : FIX */
  94. break;
  95. case insn_pushflags:
  96. m_decoded->stack_mod = 1;
  97. m_decoded->stack_mod_val = 0; /* TODO : FIX */
  98. break;
  99. case insn_popflags:
  100. m_decoded->stack_mod = 1;
  101. m_decoded->stack_mod_val = 0; /* TODO : FIX */
  102. break;
  103. case insn_add:
  104. if ( IS_SP( dest ) ) {
  105. m_decoded->stack_mod = 1;
  106. m_decoded->stack_mod_val = src->long_from_operand();
  107. }
  108. break;
  109. case insn_sub:
  110. if ( IS_SP( dest ) ) {
  111. m_decoded->stack_mod = 1;
  112. m_decoded->stack_mod_val = src->long_from_operand();
  113. m_decoded->stack_mod_val *= -1;
  114. }
  115. break;
  116. case insn_inc:
  117. if ( IS_SP( dest ) ) {
  118. m_decoded->stack_mod = 1;
  119. m_decoded->stack_mod_val = 1;
  120. }
  121. break;
  122. case insn_dec:
  123. if ( IS_SP( dest ) ) {
  124. m_decoded->stack_mod = 1;
  125. m_decoded->stack_mod_val = 1;
  126. }
  127. break;
  128. case insn_mov: case insn_movcc:
  129. case insn_xchg: case insn_xchgcc:
  130. case insn_mul: case insn_div:
  131. case insn_shl: case insn_shr:
  132. case insn_rol: case insn_ror:
  133. case insn_and: case insn_or:
  134. case insn_not: case insn_neg:
  135. case insn_xor:
  136. if ( IS_SP( dest ) ) {
  137. m_decoded->stack_mod = 1;
  138. }
  139. break;
  140. default:
  141. break;
  142. }
  143. if (! strcmp("enter", m_decoded->mnemonic) ) {
  144. m_decoded->stack_mod = 1;
  145. } else if (! strcmp("leave", m_decoded->mnemonic) ) {
  146. m_decoded->stack_mod = 1;
  147. }
  148. /* for mov, etc we return 0 -- unknown stack mod */
  149. return;
  150. }
  151. /* get the cpu details for this insn from cpu flags int */
  152. void Ia32_Decoder::ia32_handle_cpu( unsigned int cpu ) {
  153. cpu = (enum x86_insn_cpu) CPU_MODEL(cpu);
  154. m_decoded->isa = (enum x86_insn_isa) ((ISA_SUBSET(cpu)) >> 16);
  155. return;
  156. }
  157. /* handle mnemonic type and group */
  158. void Ia32_Decoder::ia32_handle_mnemtype(unsigned int mnemtype) {
  159. unsigned int type = mnemtype & ~INS_FLAG_MASK;
  160. m_decoded->group = (enum x86_insn_t::x86_insn_group) ((INS_GROUP(type)) >> 12);
  161. m_decoded->type = (enum x86_insn_type) INS_TYPE(type);
  162. return;
  163. }
  164. void Ia32_Decoder::ia32_handle_notes(unsigned int notes) {
  165. m_decoded->note = (enum x86_insn_note) notes;
  166. return;
  167. }
  168. void Ia32_Decoder::ia32_handle_eflags( unsigned int eflags) {
  169. unsigned int flags;
  170. /* handle flags effected */
  171. flags = INS_FLAGS_TEST(eflags);
  172. /* handle weird OR cases */
  173. /* these are either JLE (ZF | SF<>OF) or JBE (CF | ZF) */
  174. if (flags & INS_TEST_OR) {
  175. flags &= ~INS_TEST_OR;
  176. if ( flags & INS_TEST_ZERO ) {
  177. flags &= ~INS_TEST_ZERO;
  178. if ( flags & INS_TEST_CARRY ) {
  179. flags &= ~INS_TEST_CARRY ;
  180. flags |= (int)insn_carry_or_zero_set;
  181. } else if ( flags & INS_TEST_SFNEOF ) {
  182. flags &= ~INS_TEST_SFNEOF;
  183. flags |= (int)insn_zero_set_or_sign_ne_oflow;
  184. }
  185. }
  186. }
  187. m_decoded->flags_tested = (enum x86_flag_status) flags;
  188. m_decoded->flags_set = (enum x86_flag_status) (INS_FLAGS_SET(eflags) >> 16);
  189. return;
  190. }
  191. void Ia32_Decoder::ia32_handle_prefix( unsigned int prefixes ) {
  192. m_decoded->prefix = (enum x86_insn_prefix) (prefixes & PREFIX_MASK); // >> 20;
  193. if (! (m_decoded->prefix & PREFIX_PRINT_MASK) ) {
  194. /* no printable prefixes */
  195. m_decoded->prefix = insn_no_prefix;
  196. }
  197. /* concat all prefix strings */
  198. if ( (unsigned int)m_decoded->prefix & PREFIX_LOCK ) {
  199. strncat(m_decoded->prefix_string, "lock ", 32 -
  200. strlen(m_decoded->prefix_string));
  201. }
  202. if ( (unsigned int)m_decoded->prefix & PREFIX_REPNZ ) {
  203. strncat(m_decoded->prefix_string, "repnz ", 32 -
  204. strlen(m_decoded->prefix_string));
  205. } else if ( (unsigned int)m_decoded->prefix & PREFIX_REPZ ) {
  206. strncat(m_decoded->prefix_string, "repz ", 32 -
  207. strlen(m_decoded->prefix_string));
  208. }
  209. return;
  210. }
  211. static void reg_32_to_16( x86_op_t *op, x86_insn_t *insn, void *arg ) {
  212. /* if this is a 32-bit register and it is a general register ... */
  213. if ( op->type == op_register && op->data.reg.size == 4 &&
  214. (op->data.reg.type & reg_gen) ) {
  215. /* WORD registers are 8 indices off from DWORD registers */
  216. ia32_handle_register( &(op->data.reg),
  217. op->data.reg.id + 8 );
  218. }
  219. }
  220. void Ia32_Decoder::handle_insn_metadata( ia32_insn_t *raw_insn ) {
  221. ia32_handle_mnemtype( raw_insn->mnem_flag );
  222. ia32_handle_notes( raw_insn->notes );
  223. ia32_handle_eflags( raw_insn->flags_effected );
  224. ia32_handle_cpu(raw_insn->cpu );
  225. ia32_stack_mod();
  226. }
  227. size_t Ia32_Decoder::ia32_decode_insn( unsigned char *buf, size_t buf_len,
  228. ia32_insn_t *raw_insn, unsigned int prefixes ) {
  229. size_t size, op_size;
  230. unsigned char modrm;
  231. /* this should never happen, but just in case... */
  232. if ( raw_insn->mnem_flag == INS_INVALID ) {
  233. return 0;
  234. }
  235. if (ia32_settings.options & opt_16_bit) {
  236. op_size = ( prefixes & PREFIX_OP_SIZE ) ? 4 : 2;
  237. m_decoded->addr_size = ( prefixes & PREFIX_ADDR_SIZE ) ? 4 : 2;
  238. } else {
  239. op_size = ( prefixes & PREFIX_OP_SIZE ) ? 2 : 4;
  240. m_decoded->addr_size = ( prefixes & PREFIX_ADDR_SIZE ) ? 2 : 4;
  241. }
  242. /* ++++ 1. Copy mnemonic and mnemonic-flags to CODE struct */
  243. if ((ia32_settings.options & opt_att_mnemonics) && raw_insn->mnemonic_att[0]) {
  244. strncpy( m_decoded->mnemonic, raw_insn->mnemonic_att, 16 );
  245. }
  246. else {
  247. strncpy( m_decoded->mnemonic, raw_insn->mnemonic, 16 );
  248. }
  249. ia32_handle_prefix( prefixes );
  250. handle_insn_metadata( raw_insn );
  251. /* prefetch the next byte in case it is a modr/m byte -- saves
  252. * worrying about whether the 'mod/rm' operand or the 'reg' operand
  253. * occurs first */
  254. modrm = GET_BYTE( buf, buf_len );
  255. /* ++++ 2. Decode Explicit Operands */
  256. /* Intel uses up to 3 explicit operands in its instructions;
  257. * the first is 'dest', the second is 'src', and the third
  258. * is an additional source value (usually an immediate value,
  259. * e.g. in the MUL instructions). These three explicit operands
  260. * are encoded in the opcode tables, even if they are not used
  261. * by the instruction. Additional implicit operands are stored
  262. * in a supplemental table and are handled later. */
  263. op_size = ia32_decode_operand( buf, buf_len, raw_insn->dest,
  264. raw_insn->dest_flag, prefixes, modrm );
  265. /* advance buffer, increase size if necessary */
  266. buf += op_size;
  267. buf_len -= op_size;
  268. size = op_size;
  269. op_size = ia32_decode_operand( buf, buf_len, raw_insn->src,
  270. raw_insn->src_flag, prefixes, modrm );
  271. buf += op_size;
  272. buf_len -= op_size;
  273. size += op_size;
  274. op_size = ia32_decode_operand( buf, buf_len, raw_insn->aux,
  275. raw_insn->aux_flag, prefixes, modrm );
  276. size += op_size;
  277. /* ++++ 3. Decode Implicit Operands */
  278. /* apply implicit operands */
  279. ia32_insn_implicit_ops( raw_insn->implicit_ops );
  280. /* we have one small inelegant hack here, to deal with
  281. * the two prefixes that have implicit operands. If Intel
  282. * adds more, we'll change the algorithm to suit :) */
  283. if ( (prefixes & PREFIX_REPZ) || (prefixes & PREFIX_REPNZ) ) {
  284. ia32_insn_implicit_ops( IDX_IMPLICIT_REP );
  285. }
  286. /* 16-bit hack: foreach operand, if 32-bit reg, make 16-bit reg */
  287. //TODO: find a better way to handle this
  288. if ( op_size == 2 ) {
  289. m_decoded->x86_operand_foreach( reg_32_to_16, NULL, op_any );
  290. }
  291. return size;
  292. }
  293. /* convenience routine */
  294. #define USES_MOD_RM(flag) \
  295. (flag == ADDRMETH_E || flag == ADDRMETH_M || flag == ADDRMETH_Q || \
  296. flag == ADDRMETH_W || flag == ADDRMETH_R)
  297. static int uses_modrm_flag( unsigned int flag ) {
  298. unsigned int meth;
  299. if ( flag == ARG_NONE ) {
  300. return 0;
  301. }
  302. meth = (flag & ADDRMETH_MASK);
  303. if ( USES_MOD_RM(meth) ) {
  304. return 1;
  305. }
  306. return 0;
  307. }
  308. /* This routine performs the actual byte-by-byte opcode table lookup.
  309. * Originally it was pretty simple: get a byte, adjust it to a proper
  310. * index into the table, then check the table row at that index to
  311. * determine what to do next. But is anything that simple with Intel?
  312. * This is now a huge, convoluted mess, mostly of bitter comments. */
  313. /* buf: pointer to next byte to read from stream
  314. * buf_len: length of buf
  315. * table: index of table to use for lookups
  316. * raw_insn: output pointer that receives opcode definition
  317. * prefixes: output integer that is encoded with prefixes in insn
  318. * returns : number of bytes consumed from stream during lookup */
  319. size_t ia32_table_lookup( unsigned char *buf, size_t buf_len,
  320. unsigned int table, ia32_insn_t **raw_insn,
  321. unsigned int *prefixes ) {
  322. unsigned char *next, op = buf[0]; /* byte value -- 'opcode' */
  323. size_t size = 1, sub_size = 0, next_len;
  324. ia32_table_desc_t *table_desc;
  325. unsigned int subtable, prefix = 0, recurse_table = 0;
  326. table_desc = &ia32_tables[table];
  327. op = GET_BYTE( buf, buf_len );
  328. if ( table_desc->type == tbl_fpu && op > table_desc->maxlim) {
  329. /* one of the fucking FPU tables out of the 00-BH range */
  330. /* OK,. this is a bit of a hack -- the proper way would
  331. * have been to use subtables in the 00-BF FPU opcode tables,
  332. * but that is rather wasteful of space... */
  333. table_desc = &ia32_tables[table +1];
  334. }
  335. /* PERFORM TABLE LOOKUP */
  336. /* ModR/M trick: shift extension bits into lowest bits of byte */
  337. /* Note: non-ModR/M tables have a shift value of 0 */
  338. op >>= table_desc->shift;
  339. /* ModR/M trick: mask out high bits to turn extension into an index */
  340. /* Note: non-ModR/M tables have a mask value of 0xFF */
  341. op &= table_desc->mask;
  342. /* Sparse table trick: check that byte is <= max value */
  343. /* Note: full (256-entry) tables have a maxlim of 155 */
  344. if ( op > table_desc->maxlim ) {
  345. /* this is a partial table, truncated at the tail,
  346. and op is out of range! */
  347. return INVALID_INSN;
  348. }
  349. /* Sparse table trick: check that byte is >= min value */
  350. /* Note: full (256-entry) tables have a minlim of 0 */
  351. if ( table_desc->minlim > op ) {
  352. /* this is a partial table, truncated at the head,
  353. and op is out of range! */
  354. return INVALID_INSN;
  355. }
  356. /* adjust op to be an offset from table index 0 */
  357. op -= table_desc->minlim;
  358. /* Yay! 'op' is now fully adjusted to be an index into 'table' */
  359. *raw_insn = &(table_desc->table[op]);
  360. //printf("BYTE %X TABLE %d OP %X\n", buf[0], table, op );
  361. if ( (*raw_insn)->mnem_flag & INS_FLAG_PREFIX ) {
  362. prefix = (*raw_insn)->mnem_flag & PREFIX_MASK;
  363. }
  364. /* handle escape to a multibyte/coproc/extension/etc table */
  365. /* NOTE: if insn is a prefix and has a subtable, then we
  366. * only recurse if this is the first prefix byte --
  367. * that is, if *prefixes is 0.
  368. * NOTE also that suffix tables are handled later */
  369. subtable = (*raw_insn)->table;
  370. if ( subtable && ia32_tables[subtable].type != tbl_suffix &&
  371. (! prefix || ! *prefixes) ) {
  372. if ( ia32_tables[subtable].type == tbl_ext_ext ||
  373. ia32_tables[subtable].type == tbl_fpu_ext ) {
  374. /* opcode extension: reuse current byte in buffer */
  375. next = buf;
  376. next_len = buf_len;
  377. } else {
  378. /* "normal" opcode: advance to next byte in buffer */
  379. if ( buf_len > 1 ) {
  380. next = &buf[1];
  381. next_len = buf_len - 1;
  382. }
  383. else {
  384. // buffer is truncated
  385. return INVALID_INSN;
  386. }
  387. }
  388. /* we encountered a multibyte opcode: recurse using the
  389. * table specified in the opcode definition */
  390. sub_size = ia32_table_lookup( next, next_len, subtable,
  391. raw_insn, prefixes );
  392. /* SSE/prefix hack: if the original opcode def was a
  393. * prefix that specified a subtable, and the subtable
  394. * lookup returned a valid insn, then we have encountered
  395. * an SSE opcode definition; otherwise, we pretend we
  396. * never did the subtable lookup, and deal with the
  397. * prefix normally later */
  398. if ( prefix && ( sub_size == INVALID_INSN ||
  399. INS_TYPE((*raw_insn)->mnem_flag) == INS_INVALID ) ) {
  400. /* this is a prefix, not an SSE insn :
  401. * lookup next byte in main table,
  402. * subsize will be reset during the
  403. * main table lookup */
  404. recurse_table = 1;
  405. } else {
  406. /* this is either a subtable (two-byte) insn
  407. * or an invalid insn: either way, set prefix
  408. * to NULL and end the opcode lookup */
  409. prefix = 0;
  410. // short-circuit lookup on invalid insn
  411. if (sub_size == INVALID_INSN) return INVALID_INSN;
  412. }
  413. } else if ( prefix ) {
  414. recurse_table = 1;
  415. }
  416. /* by default, we assume that we have the opcode definition,
  417. * and there is no need to recurse on the same table, but
  418. * if we do then a prefix was encountered... */
  419. if ( recurse_table ) {
  420. /* this must have been a prefix: use the same table for
  421. * lookup of the next byte */
  422. sub_size = ia32_table_lookup( &buf[1], buf_len - 1, table,
  423. raw_insn, prefixes );
  424. // short-circuit lookup on invalid insn
  425. if (sub_size == INVALID_INSN) return INVALID_INSN;
  426. /* a bit of a hack for branch hints */
  427. if ( prefix & BRANCH_HINT_MASK ) {
  428. if ( INS_GROUP((*raw_insn)->mnem_flag) == INS_EXEC ) {
  429. /* segment override prefixes are invalid for
  430. * all branch instructions, so delete them */
  431. prefix &= ~PREFIX_REG_MASK;
  432. } else {
  433. prefix &= ~BRANCH_HINT_MASK;
  434. }
  435. }
  436. /* apply prefix to instruction */
  437. /* TODO: implement something enforcing prefix groups */
  438. (*prefixes) |= prefix;
  439. }
  440. /* if this lookup was in a ModR/M table, then an opcode byte is
  441. * NOT consumed: subtract accordingly. NOTE that if none of the
  442. * operands used the ModR/M, then we need to consume the byte
  443. * here, but ONLY in the 'top-level' opcode extension table */
  444. if ( table_desc->type == tbl_ext_ext ) {
  445. /* extensions-to-extensions never consume a byte */
  446. --size;
  447. } else if ( (table_desc->type == tbl_extension ||
  448. table_desc->type == tbl_fpu ||
  449. table_desc->type == tbl_fpu_ext ) &&
  450. /* extensions that have an operand encoded in ModR/M
  451. * never consume a byte */
  452. (uses_modrm_flag((*raw_insn)->dest_flag) ||
  453. uses_modrm_flag((*raw_insn)->src_flag) ) ) {
  454. --size;
  455. }
  456. size += sub_size;
  457. return size;
  458. }
  459. size_t Ia32_Decoder::handle_insn_suffix( unsigned char *buf, size_t buf_len,
  460. ia32_insn_t *raw_insn ) {
  461. ia32_table_desc_t *table_desc;
  462. ia32_insn_t *sfx_insn;
  463. size_t size;
  464. unsigned int prefixes = 0;
  465. table_desc = &ia32_tables[raw_insn->table];
  466. size = ia32_table_lookup( buf, buf_len, raw_insn->table, &sfx_insn,
  467. &prefixes );
  468. if (size == INVALID_INSN || sfx_insn->mnem_flag == INS_INVALID ) {
  469. return 0;
  470. }
  471. strncpy( m_decoded->mnemonic, sfx_insn->mnemonic, 16 );
  472. handle_insn_metadata( sfx_insn );
  473. return 1;
  474. }
  475. /* invalid instructions are handled by returning 0 [error] from the
  476. * function, setting the size of the insn to 1 byte, and copying
  477. * the byte at the start of the invalid insn into the x86_insn_t.
  478. * if the caller is saving the x86_insn_t for invalid instructions,
  479. * instead of discarding them, this will maintain a consistent
  480. * address space in the x86_insn_ts */
  481. /* this function is called by the controlling disassembler, so its name and
  482. * calling convention cannot be changed */
  483. /* buf points to the loc of the current opcode (start of the
  484. * instruction) in the instruction stream. The instruction
  485. * stream is assumed to be a buffer of bytes read directly
  486. * from the file for the purpose of disassembly; a mem-mapped
  487. * file is ideal for * this.
  488. * insn points to a code structure to be filled by instr_decode
  489. * returns the size of the decoded instruction in bytes */
  490. size_t Ia32_Decoder::ia32_disasm_addr( unsigned char * buf, size_t buf_len) {
  491. ia32_insn_t *raw_insn = NULL;
  492. unsigned int prefixes = 0;
  493. size_t _size, sfx_size;
  494. assert(m_decoded);
  495. if ( (ia32_settings.options & opt_ignore_nulls) && buf_len > 3 &&
  496. !buf[0] && !buf[1] && !buf[2] && !buf[3]) {
  497. /* IF IGNORE_NULLS is set AND
  498. * first 4 bytes in the intruction stream are NULL
  499. * THEN return 0 (END_OF_DISASSEMBLY) */
  500. /* TODO: set errno */
  501. m_decoded->make_invalid(buf);
  502. return 0; /* 4 00 bytes in a row? This isn't code! */
  503. }
  504. /* Perform recursive table lookup starting with main table (0) */
  505. _size = ia32_table_lookup(buf, buf_len, idx_Main, &raw_insn, &prefixes);
  506. if ( _size == INVALID_INSN || _size > buf_len || raw_insn->mnem_flag == INS_INVALID ) {
  507. m_decoded->make_invalid( buf );
  508. /* TODO: set errno */
  509. return 0;
  510. }
  511. /* We now have the opcode itself figured out: we can decode
  512. * the rest of the instruction. */
  513. _size += ia32_decode_insn( &buf[_size], buf_len - _size, raw_insn, prefixes );
  514. if ( raw_insn->mnem_flag & INS_FLAG_SUFFIX ) {
  515. /* AMD 3DNow! suffix -- get proper operand type here */
  516. sfx_size = handle_insn_suffix( &buf[_size], buf_len - _size,
  517. raw_insn);
  518. if (! sfx_size ) {
  519. /* TODO: set errno */
  520. m_decoded->make_invalid( buf );
  521. return 0;
  522. }
  523. _size += sfx_size;
  524. }
  525. if (! _size ) {
  526. /* invalid insn */
  527. m_decoded->make_invalid( buf );
  528. return 0;
  529. }
  530. m_decoded->size = _size;
  531. return _size; /* return size of instruction in bytes */
  532. }