| Index: src/third_party/libdisasm/ia32_invariant.c
|
| diff --git a/src/third_party/libdisasm/ia32_invariant.c b/src/third_party/libdisasm/ia32_invariant.c
|
| deleted file mode 100644
|
| index 68ec153d27dd6814a6570aec76c15fe786d1a890..0000000000000000000000000000000000000000
|
| --- a/src/third_party/libdisasm/ia32_invariant.c
|
| +++ /dev/null
|
| @@ -1,313 +0,0 @@
|
| -#include <stdlib.h>
|
| -#include <string.h>
|
| -
|
| -#include "ia32_invariant.h"
|
| -#include "ia32_insn.h"
|
| -#include "ia32_settings.h"
|
| -
|
| -extern ia32_table_desc_t *ia32_tables;
|
| -extern ia32_settings_t ia32_settings;
|
| -
|
| -extern size_t ia32_table_lookup( unsigned char *buf, size_t buf_len,
|
| - unsigned int table, ia32_insn_t **raw_insn,
|
| - unsigned int *prefixes );
|
| -
|
| -
|
| -/* -------------------------------- ModR/M, SIB */
|
| -/* Convenience flags */
|
| -#define MODRM_EA 1 /* ModR/M is an effective addr */
|
| -#define MODRM_reg 2 /* ModR/M is a register */
|
| -
|
| -/* ModR/M flags */
|
| -#define MODRM_RM_SIB 0x04 /* R/M == 100 */
|
| -#define MODRM_RM_NOREG 0x05 /* R/B == 101 */
|
| -/* if (MODRM.MOD_NODISP && MODRM.RM_NOREG) then just disp32 */
|
| -#define MODRM_MOD_NODISP 0x00 /* mod == 00 */
|
| -#define MODRM_MOD_DISP8 0x01 /* mod == 01 */
|
| -#define MODRM_MOD_DISP32 0x02 /* mod == 10 */
|
| -#define MODRM_MOD_NOEA 0x03 /* mod == 11 */
|
| -/* 16-bit modrm flags */
|
| -#define MOD16_MOD_NODISP 0
|
| -#define MOD16_MOD_DISP8 1
|
| -#define MOD16_MOD_DISP16 2
|
| -#define MOD16_MOD_REG 3
|
| -
|
| -#define MOD16_RM_BXSI 0
|
| -#define MOD16_RM_BXDI 1
|
| -#define MOD16_RM_BPSI 2
|
| -#define MOD16_RM_BPDI 3
|
| -#define MOD16_RM_SI 4
|
| -#define MOD16_RM_DI 5
|
| -#define MOD16_RM_BP 6
|
| -#define MOD16_RM_BX 7
|
| -
|
| -/* SIB flags */
|
| -#define SIB_INDEX_NONE 0x04
|
| -#define SIB_BASE_EBP 0x05
|
| -#define SIB_SCALE_NOBASE 0x00
|
| -
|
| -/* Convenience struct for modR/M bitfield */
|
| -struct modRM_byte {
|
| - unsigned int mod : 2;
|
| - unsigned int reg : 3;
|
| - unsigned int rm : 3;
|
| -};
|
| -
|
| -/* Convenience struct for SIB bitfield */
|
| -struct SIB_byte {
|
| - unsigned int scale : 2;
|
| - unsigned int index : 3;
|
| - unsigned int base : 3;
|
| -};
|
| -
|
| -#ifdef WIN32
|
| -static void byte_decode(unsigned char b, struct modRM_byte *modrm) {
|
| -#else
|
| -static inline void byte_decode(unsigned char b, struct modRM_byte *modrm) {
|
| -#endif
|
| - /* generic bitfield-packing routine */
|
| -
|
| - modrm->mod = b >> 6; /* top 2 bits */
|
| - modrm->reg = (b & 56) >> 3; /* middle 3 bits */
|
| - modrm->rm = b & 7; /* bottom 3 bits */
|
| -}
|
| -static int ia32_invariant_modrm( unsigned char *in, unsigned char *out,
|
| - unsigned int mode_16, x86_invariant_op_t *op) {
|
| - struct modRM_byte modrm;
|
| - struct SIB_byte sib;
|
| - unsigned char *c, *cin;
|
| - unsigned short *s;
|
| - unsigned int *i;
|
| - int size = 0; /* modrm byte is already counted */
|
| -
|
| -
|
| - byte_decode(*in, &modrm); /* get bitfields */
|
| -
|
| - out[0] = in[0]; /* save modrm byte */
|
| - cin = &in[1];
|
| - c = &out[1];
|
| - s = (unsigned short *)&out[1];
|
| - i = (unsigned int *)&out[1];
|
| -
|
| - op->type = op_expression;
|
| - op->flags |= op_pointer;
|
| - if ( ! mode_16 && modrm.rm == MODRM_RM_SIB &&
|
| - modrm.mod != MODRM_MOD_NOEA ) {
|
| - size ++;
|
| - byte_decode(*cin, (struct modRM_byte *)(void*)&sib);
|
| -
|
| - out[1] = in[1]; /* save sib byte */
|
| - cin = &in[2];
|
| - c = &out[2];
|
| - s = (unsigned short *)&out[2];
|
| - i = (unsigned int *)&out[2];
|
| -
|
| - if ( sib.base == SIB_BASE_EBP && ! modrm.mod ) {
|
| - /* disp 32 is variant! */
|
| - memset( i, X86_WILDCARD_BYTE, 4 );
|
| - size += 4;
|
| - }
|
| - }
|
| -
|
| - if (! modrm.mod && modrm.rm == 101) {
|
| - if ( mode_16 ) { /* straight RVA in disp */
|
| - memset( s, X86_WILDCARD_BYTE, 2 );
|
| - size += 2;
|
| - } else {
|
| - memset( i, X86_WILDCARD_BYTE, 2 );
|
| - size += 4;
|
| - }
|
| - } else if (modrm.mod && modrm.mod < 3) {
|
| - if (modrm.mod == MODRM_MOD_DISP8) { /* offset in disp */
|
| - *c = *cin;
|
| - size += 1;
|
| - } else if ( mode_16 ) {
|
| - *s = (* ((unsigned short *) cin));
|
| - size += 2;
|
| - } else {
|
| - *i = (*((unsigned int *) cin));
|
| - size += 4;
|
| - }
|
| - } else if ( modrm.mod == 3 ) {
|
| - op->type = op_register;
|
| - op->flags &= ~op_pointer;
|
| - }
|
| -
|
| - return (size);
|
| -}
|
| -
|
| -
|
| -static int ia32_decode_invariant( unsigned char *buf, size_t buf_len,
|
| - ia32_insn_t *t, unsigned char *out,
|
| - unsigned int prefixes, x86_invariant_t *inv) {
|
| -
|
| - unsigned int addr_size, op_size, mode_16;
|
| - unsigned int op_flags[3] = { t->dest_flag, t->src_flag, t->aux_flag };
|
| - int x, type, bytes = 0, size = 0, modrm = 0;
|
| -
|
| - /* set addressing mode */
|
| - if (ia32_settings.options & opt_16_bit) {
|
| - op_size = ( prefixes & PREFIX_OP_SIZE ) ? 4 : 2;
|
| - addr_size = ( prefixes & PREFIX_ADDR_SIZE ) ? 4 : 2;
|
| - mode_16 = ( prefixes & PREFIX_ADDR_SIZE ) ? 0 : 1;
|
| - } else {
|
| - op_size = ( prefixes & PREFIX_OP_SIZE ) ? 2 : 4;
|
| - addr_size = ( prefixes & PREFIX_ADDR_SIZE ) ? 2 : 4;
|
| - mode_16 = ( prefixes & PREFIX_ADDR_SIZE ) ? 1 : 0;
|
| - }
|
| -
|
| - for (x = 0; x < 3; x++) {
|
| - inv->operands[x].access = (enum x86_op_access)
|
| - OP_PERM(op_flags[x]);
|
| - inv->operands[x].flags = (enum x86_op_flags)
|
| - (OP_FLAGS(op_flags[x]) >> 12);
|
| -
|
| - switch (op_flags[x] & OPTYPE_MASK) {
|
| - case OPTYPE_c:
|
| - size = (op_size == 4) ? 2 : 1;
|
| - break;
|
| - case OPTYPE_a: case OPTYPE_v:
|
| - size = (op_size == 4) ? 4 : 2;
|
| - break;
|
| - case OPTYPE_p:
|
| - size = (op_size == 4) ? 6 : 4;
|
| - break;
|
| - case OPTYPE_b:
|
| - size = 1;
|
| - break;
|
| - case OPTYPE_w:
|
| - size = 2;
|
| - break;
|
| - case OPTYPE_d: case OPTYPE_fs: case OPTYPE_fd:
|
| - case OPTYPE_fe: case OPTYPE_fb: case OPTYPE_fv:
|
| - case OPTYPE_si: case OPTYPE_fx:
|
| - size = 4;
|
| - break;
|
| - case OPTYPE_s:
|
| - size = 6;
|
| - break;
|
| - case OPTYPE_q: case OPTYPE_pi:
|
| - size = 8;
|
| - break;
|
| - case OPTYPE_dq: case OPTYPE_ps: case OPTYPE_ss:
|
| - case OPTYPE_pd: case OPTYPE_sd:
|
| - size = 16;
|
| - break;
|
| - case OPTYPE_m:
|
| - size = (addr_size == 4) ? 4 : 2;
|
| - break;
|
| - default:
|
| - break;
|
| - }
|
| -
|
| - type = op_flags[x] & ADDRMETH_MASK;
|
| - switch (type) {
|
| - case ADDRMETH_E: case ADDRMETH_M: case ADDRMETH_Q:
|
| - case ADDRMETH_R: case ADDRMETH_W:
|
| - modrm = 1;
|
| - bytes += ia32_invariant_modrm( buf, out,
|
| - mode_16, &inv->operands[x]);
|
| - break;
|
| - case ADDRMETH_C: case ADDRMETH_D: case ADDRMETH_G:
|
| - case ADDRMETH_P: case ADDRMETH_S: case ADDRMETH_T:
|
| - case ADDRMETH_V:
|
| - inv->operands[x].type = op_register;
|
| - modrm = 1;
|
| - break;
|
| - case ADDRMETH_A: case ADDRMETH_O:
|
| - /* pad with xF4's */
|
| - memset( &out[bytes + modrm], X86_WILDCARD_BYTE,
|
| - size );
|
| - bytes += size;
|
| - inv->operands[x].type = op_offset;
|
| - if ( type == ADDRMETH_O ) {
|
| - inv->operands[x].flags |= op_signed |
|
| - op_pointer;
|
| - }
|
| - break;
|
| - case ADDRMETH_I: case ADDRMETH_J:
|
| - /* grab imm value */
|
| - if ((op_flags[x] & OPTYPE_MASK) == OPTYPE_v) {
|
| - /* assume this is an address */
|
| - memset( &out[bytes + modrm],
|
| - X86_WILDCARD_BYTE, size );
|
| - } else {
|
| - memcpy( &out[bytes + modrm],
|
| - &buf[bytes + modrm], size );
|
| - }
|
| -
|
| - bytes += size;
|
| - if ( type == ADDRMETH_J ) {
|
| - if ( size == 1 ) {
|
| - inv->operands[x].type =
|
| - op_relative_near;
|
| - } else {
|
| - inv->operands[x].type =
|
| - op_relative_far;
|
| - }
|
| - inv->operands[x].flags |= op_signed;
|
| - } else {
|
| - inv->operands[x].type = op_immediate;
|
| - }
|
| - break;
|
| - case ADDRMETH_F:
|
| - inv->operands[x].type = op_register;
|
| - break;
|
| - case ADDRMETH_X:
|
| - inv->operands[x].flags |= op_signed |
|
| - op_pointer | op_ds_seg | op_string;
|
| - break;
|
| - case ADDRMETH_Y:
|
| - inv->operands[x].flags |= op_signed |
|
| - op_pointer | op_es_seg | op_string;
|
| - break;
|
| - case ADDRMETH_RR:
|
| - inv->operands[x].type = op_register;
|
| - break;
|
| - case ADDRMETH_II:
|
| - inv->operands[x].type = op_immediate;
|
| - break;
|
| - default:
|
| - inv->operands[x].type = op_unused;
|
| - break;
|
| - }
|
| - }
|
| -
|
| - return (bytes + modrm);
|
| -}
|
| -
|
| -size_t ia32_disasm_invariant( unsigned char * buf, size_t buf_len,
|
| - x86_invariant_t *inv ) {
|
| - ia32_insn_t *raw_insn = NULL;
|
| - unsigned int prefixes;
|
| - unsigned int type;
|
| - size_t size;
|
| -
|
| - /* Perform recursive table lookup starting with main table (0) */
|
| - size = ia32_table_lookup( buf, buf_len, 0, &raw_insn, &prefixes );
|
| - if ( size == INVALID_INSN || size > buf_len ) {
|
| - /* TODO: set errno */
|
| - return 0;
|
| - }
|
| -
|
| - /* copy opcode bytes to buffer */
|
| - memcpy( inv->bytes, buf, size );
|
| -
|
| - /* set mnemonic type and group */
|
| - type = raw_insn->mnem_flag & ~INS_FLAG_MASK;
|
| - inv->group = (enum x86_insn_group) (INS_GROUP(type)) >> 12;
|
| - inv->type = (enum x86_insn_type) INS_TYPE(type);
|
| -
|
| - /* handle operands */
|
| - size += ia32_decode_invariant( buf + size, buf_len - size, raw_insn,
|
| - &buf[size - 1], prefixes, inv );
|
| -
|
| - inv->size = size;
|
| -
|
| - return size; /* return size of instruction in bytes */
|
| -}
|
| -
|
| -size_t ia32_disasm_size( unsigned char *buf, size_t buf_len ) {
|
| - x86_invariant_t inv = { {0} };
|
| - return( ia32_disasm_invariant( buf, buf_len, &inv ) );
|
| -}
|
|
|