12b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#ifndef LIBDISASM_H
22b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define LIBDISASM_H
32b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
42b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#ifdef WIN32
52b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include <windows.h>
62b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#endif
72b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
82b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include <stdint.h>
92b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* 'NEW" types
112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * __________________________________________________________________________*/
122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#ifndef LIBDISASM_QWORD_H       /* do not interfere with qword.h */
132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        #define LIBDISASM_QWORD_H
142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        #ifdef _MSC_VER
152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                typedef __int64         qword_t;
162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        #else
172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                typedef int64_t         qword_t;
182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        #endif
192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#endif
202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include <sys/types.h>
222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#ifdef __cplusplus
242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgextern "C" {
252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#endif
262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* 'NEW" x86 API
282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * __________________________________________________________________________*/
292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* ========================================= Error Reporting */
322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* REPORT CODES
332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      These are passed to a reporter function passed at initialization.
342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      Each code determines the type of the argument passed to the reporter;
352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      this allows the report to recover from errors, or just log them.
362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org */
372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgenum x86_report_codes {
382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        report_disasm_bounds,   /* RVA OUT OF BOUNDS : The disassembler could
392b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                   not disassemble the supplied RVA as it is
402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                   out of the range of the buffer. The
412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                   application should store the address and
422b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                   attempt to determine what section of the
432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                   binary it is in, then disassemble the
442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                   address from the bytes in that section.
452b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                        data: uint32_t rva */
462b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        report_insn_bounds,     /* INSTRUCTION OUT OF BOUNDS: The disassembler
472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                   could not disassemble the instruction as
482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                   the instruction would require bytes beyond
492b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                   the end of the current buffer. This usually
502b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                   indicated garbage bytes at the end of a
512b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                   buffer, or an incorrectly-sized buffer.
522b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                        data: uint32_t rva */
532b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        report_invalid_insn,    /* INVALID INSTRUCTION: The disassembler could
542b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                   not disassemble the instruction as it has an
552b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                   invalid combination of opcodes and operands.
562b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                   This will stop automated disassembly; the
572b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                   application can restart the disassembly
582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                   after the invalid instruction.
592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                                        data: uint32_t rva */
602b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        report_unknown
612b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org};
622b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
632b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* 'arg' is optional arbitrary data provided by the code passing the
642b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *       callback -- for example, it could be 'this' or 'self' in OOP code.
652b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * 'code' is provided by libdisasm, it is one of the above
662b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * 'data' is provided by libdisasm and is context-specific, per the enums */
672b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgtypedef void (*DISASM_REPORTER)( enum x86_report_codes code,
682b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org				 void *data, void *arg );
692b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* x86_report_error : Call the register reporter to report an error */
722b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgvoid x86_report_error( enum x86_report_codes code, void *data );
732b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
742b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* ========================================= Libdisasm Management Routines */
752b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgenum x86_options {		/* these can be ORed together */
762b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        opt_none= 0,
772b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        opt_ignore_nulls=1,     /* ignore sequences of > 4 NULL bytes */
782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        opt_16_bit=2,           /* 16-bit/DOS disassembly */
792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        opt_att_mnemonics=4,    /* use AT&T syntax names for alternate opcode mnemonics */
802b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org};
812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
822b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* management routines */
832b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* 'arg' is caller-specific data which is passed as the first argument
842b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * to the reporter callback routine */
852b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgint x86_init( enum x86_options options, DISASM_REPORTER reporter, void *arg);
862b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgvoid x86_set_reporter( DISASM_REPORTER reporter, void *arg);
872b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgvoid x86_set_options( enum x86_options options );
882b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgenum x86_options x86_get_options( void );
892b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgint x86_cleanup(void);
902b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
912b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
922b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* ========================================= Instruction Representation */
932b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* these defines are only intended for use in the array decl's */
942b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define MAX_REGNAME 8
952b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
962b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define MAX_PREFIX_STR 32
972b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define MAX_MNEM_STR 16
982b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define MAX_INSN_SIZE 20        /* same as in i386.h */
992b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define MAX_OP_STRING 32        /* max possible operand size in string form */
1002b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define MAX_OP_RAW_STRING 64    /* max possible operand size in raw form */
1012b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define MAX_OP_XML_STRING 256   /* max possible operand size in xml form */
1022b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define MAX_NUM_OPERANDS 8	/* max # implicit and explicit operands */
1032b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* in these, the '2 *' is arbitrary: the max # of operands should require
1042b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * more space than the rest of the insn */
1052b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define MAX_INSN_STRING 512        /* 2 * 8 * MAX_OP_STRING */
1062b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define MAX_INSN_RAW_STRING 1024   /* 2 * 8 * MAX_OP_RAW_STRING */
1072b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define MAX_INSN_XML_STRING 4096   /* 2 * 8 * MAX_OP_XML_STRING */
1082b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
1092b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgenum x86_reg_type {     /* NOTE: these may be ORed together */
1102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_gen         = 0x00001,      /* general purpose */
1112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_in          = 0x00002,      /* incoming args, ala RISC */
1122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_out         = 0x00004,      /* args to calls, ala RISC */
1132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_local       = 0x00008,      /* local vars, ala RISC */
1142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_fpu         = 0x00010,      /* FPU data register */
1152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_seg         = 0x00020,      /* segment register */
1162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_simd        = 0x00040,      /* SIMD/MMX reg */
1172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_sys         = 0x00080,      /* restricted/system register */
1182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_sp          = 0x00100,      /* stack pointer */
1192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_fp          = 0x00200,      /* frame pointer */
1202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_pc          = 0x00400,      /* program counter */
1212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_retaddr     = 0x00800,      /* return addr for func */
1222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_cond        = 0x01000,      /* condition code / flags */
1232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_zero        = 0x02000,      /* zero register, ala RISC */
1242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_ret         = 0x04000,      /* return value */
1252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_src         = 0x10000,      /* array/rep source */
1262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_dest        = 0x20000,      /* array/rep destination */
1272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        reg_count       = 0x40000       /* array/rep/loop counter */
1282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org};
1292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
1302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* x86_reg_t : an X86 CPU register */
1312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgtypedef struct {
1322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        char name[MAX_REGNAME];
1332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        enum x86_reg_type type;         /* what register is used for */
1342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        unsigned int size;              /* size of register in bytes */
1352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        unsigned int id;                /* register ID #, for quick compares */
1362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	unsigned int alias;		/* ID of reg this is an alias for */
1372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	unsigned int shift;		/* amount to shift aliased reg by */
1382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} x86_reg_t;
1392b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
1402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* x86_ea_t : an X86 effective address (address expression) */
1412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgtypedef struct {
1422b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        unsigned int     scale;         /* scale factor */
1432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        x86_reg_t        index, base;   /* index, base registers */
1442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        int32_t          disp;          /* displacement */
1452b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        char             disp_sign;     /* is negative? 1/0 */
1462b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        char             disp_size;     /* 0, 1, 2, 4 */
1472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} x86_ea_t;
1482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
1492b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* x86_absolute_t : an X86 segment:offset address (descriptor) */
1502b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgtypedef struct {
1512b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	unsigned short	segment;	/* loaded directly into CS */
1522b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	union {
1532b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org		unsigned short	off16;	/* loaded directly into IP */
1542b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org		uint32_t		off32;	/* loaded directly into EIP */
1552b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	} offset;
1562b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} x86_absolute_t;
1572b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
1582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgenum x86_op_type {      /* mutually exclusive */
1592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_unused = 0,          /* empty/unused operand: should never occur */
1602b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_register = 1,        /* CPU register */
1612b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_immediate = 2,       /* Immediate Value */
1622b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_relative_near = 3,   /* Relative offset from IP */
1632b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_relative_far = 4,    /* Relative offset from IP */
1642b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_absolute = 5,        /* Absolute address (ptr16:32) */
1652b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_expression = 6,      /* Address expression (scale/index/base/disp) */
1662b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_offset = 7,          /* Offset from start of segment (m32) */
1672b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_unknown
1682b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org};
1692b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
1702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define x86_optype_is_address( optype ) \
1712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	( optype == op_absolute || optype == op_offset )
1722b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define x86_optype_is_relative( optype ) \
1732b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	( optype == op_relative_near || optype == op_relative_far )
1742b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define x86_optype_is_memory( optype ) \
1752b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	( optype > op_immediate && optype < op_unknown )
1762b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
1772b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgenum x86_op_datatype {          /* these use Intel's lame terminology */
1782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_byte = 1,            /* 1 byte integer */
1792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_word = 2,            /* 2 byte integer */
1802b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_dword = 3,           /* 4 byte integer */
1812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_qword = 4,           /* 8 byte integer */
1822b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_dqword = 5,          /* 16 byte integer */
1832b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_sreal = 6,           /* 4 byte real (single real) */
1842b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_dreal = 7,           /* 8 byte real (double real) */
1852b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_extreal = 8,         /* 10 byte real (extended real) */
1862b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_bcd = 9,             /* 10 byte binary-coded decimal */
1872b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_ssimd = 10,          /* 16 byte : 4 packed single FP (SIMD, MMX) */
1882b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_dsimd = 11,          /* 16 byte : 2 packed double FP (SIMD, MMX) */
1892b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_sssimd = 12,         /* 4 byte : scalar single FP (SIMD, MMX) */
1902b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_sdsimd = 13,         /* 8 byte : scalar double FP (SIMD, MMX) */
1912b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_descr32 = 14,	/* 6 byte Intel descriptor 2:4 */
1922b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_descr16 = 15,	/* 4 byte Intel descriptor 2:2 */
1932b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_pdescr32 = 16,	/* 6 byte Intel pseudo-descriptor 32:16 */
1942b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_pdescr16 = 17,	/* 6 byte Intel pseudo-descriptor 8:24:16 */
1952b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_bounds16 = 18,	/* signed 16:16 lower:upper bounds */
1962b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_bounds32 = 19,	/* signed 32:32 lower:upper bounds */
1972b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_fpuenv16 = 20,	/* 14 byte FPU control/environment data */
1982b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_fpuenv32 = 21,	/* 28 byte FPU control/environment data */
1992b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_fpustate16 = 22,	/* 94 byte FPU state (env & reg stack) */
2002b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_fpustate32 = 23,	/* 108 byte FPU state (env & reg stack) */
2012b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_fpregset = 24,	/* 512 bytes: register set */
2022b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_fpreg = 25,		/* FPU register */
2032b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org    op_none = 0xFF,     /* operand without a datatype (INVLPG) */
2042b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org};
2052b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
2062b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgenum x86_op_access {    /* ORed together */
2072b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_read = 1,
2082b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_write = 2,
2092b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_execute = 4
2102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org};
2112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
2122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgenum x86_op_flags {     /* ORed together, but segs are mutually exclusive */
2132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_signed = 1,          /* signed integer */
2142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_string = 2,          /* possible string or array */
2152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_constant = 4,        /* symbolic constant */
2162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_pointer = 8,         /* operand points to a memory address */
2172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_sysref = 0x010,	/* operand is a syscall number */
2182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_implied = 0x020,	/* operand is implicit in the insn */
2192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_hardcode = 0x40,	/* operand is hardcoded in insn definition */
2202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	/* NOTE: an 'implied' operand is one which can be considered a side
2212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	 * effect of the insn, e.g. %esp being modified by PUSH or POP. A
2222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	 * 'hard-coded' operand is one which is specified in the instruction
2232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	 * definition, e.g. %es:%edi in MOVSB or 1 in ROL Eb, 1. The difference
2242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	 * is that hard-coded operands are printed by disassemblers and are
2252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	 * required to re-assemble, while implicit operands are invisible. */
2262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_es_seg = 0x100,      /* ES segment override */
2272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_cs_seg = 0x200,      /* CS segment override */
2282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_ss_seg = 0x300,      /* SS segment override */
2292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_ds_seg = 0x400,      /* DS segment override */
2302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_fs_seg = 0x500,      /* FS segment override */
2312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        op_gs_seg = 0x600       /* GS segment override */
2322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org};
2332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
2342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* x86_op_t : an X86 instruction operand */
2352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgtypedef struct {
2362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        enum x86_op_type        type;           /* operand type */
2372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        enum x86_op_datatype    datatype;       /* operand size */
2382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        enum x86_op_access      access;         /* operand access [RWX] */
2392b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        enum x86_op_flags       flags;          /* misc flags */
2402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        union {
2412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org		/* sizeof will have to work on these union members! */
2422b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                /* immediate values */
2432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                char            sbyte;
2442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                short           sword;
2452b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                int32_t         sdword;
2462b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                qword_t         sqword;
2472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                unsigned char   byte;
2482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                unsigned short  word;
2492b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                uint32_t        dword;
2502b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                qword_t         qword;
2512b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                float           sreal;
2522b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                double          dreal;
2532b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                /* misc large/non-native types */
2542b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                unsigned char   extreal[10];
2552b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                unsigned char   bcd[10];
2562b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                qword_t         dqword[2];
2572b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                unsigned char   simd[16];
2582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                unsigned char   fpuenv[28];
2592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                /* offset from segment */
2602b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                uint32_t        offset;
2612b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                /* ID of CPU register */
2622b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                x86_reg_t       reg;
2632b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                /* offsets from current insn */
2642b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                char            relative_near;
2652b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                int32_t         relative_far;
2662b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org		/* segment:offset */
2672b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org		x86_absolute_t	absolute;
2682b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                /* effective address [expression] */
2692b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                x86_ea_t        expression;
2702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        } data;
2712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	/* this is needed to make formatting operands more sane */
2722b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	void * insn;		/* pointer to x86_insn_t owning operand */
2732b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} x86_op_t;
2742b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
2752b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* Linked list of x86_op_t; provided for manual traversal of the operand
2762b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * list in an insn. Users wishing to add operands to this list, e.g. to add
2772b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * implicit operands, should use x86_operand_new in x86_operand_list.h */
2782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgtypedef struct x86_operand_list {
2792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	x86_op_t op;
2802b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	struct x86_operand_list *next;
2812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} x86_oplist_t;
2822b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
2832b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgenum x86_insn_group {
2842b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	insn_none = 0,		/* invalid instruction */
2852b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_controlflow = 1,
2862b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_arithmetic = 2,
2872b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_logic = 3,
2882b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_stack = 4,
2892b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_comparison = 5,
2902b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_move = 6,
2912b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_string = 7,
2922b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_bit_manip = 8,
2932b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_flag_manip = 9,
2942b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_fpu = 10,
2952b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_interrupt = 13,
2962b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_system = 14,
2972b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_other = 15
2982b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org};
2992b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
3002b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgenum x86_insn_type {
3012b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	insn_invalid = 0,	/* invalid instruction */
3022b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        /* insn_controlflow */
3032b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_jmp = 0x1001,
3042b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_jcc = 0x1002,
3052b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_call = 0x1003,
3062b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_callcc = 0x1004,
3072b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_return = 0x1005,
3082b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        /* insn_arithmetic */
3092b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_add = 0x2001,
3102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_sub = 0x2002,
3112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_mul = 0x2003,
3122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_div = 0x2004,
3132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_inc = 0x2005,
3142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_dec = 0x2006,
3152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_shl = 0x2007,
3162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_shr = 0x2008,
3172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_rol = 0x2009,
3182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_ror = 0x200A,
3192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        /* insn_logic */
3202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_and = 0x3001,
3212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_or = 0x3002,
3222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_xor = 0x3003,
3232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_not = 0x3004,
3242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_neg = 0x3005,
3252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        /* insn_stack */
3262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_push = 0x4001,
3272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_pop = 0x4002,
3282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_pushregs = 0x4003,
3292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_popregs = 0x4004,
3302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_pushflags = 0x4005,
3312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_popflags = 0x4006,
3322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_enter = 0x4007,
3332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_leave = 0x4008,
3342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        /* insn_comparison */
3352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_test = 0x5001,
3362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_cmp = 0x5002,
3372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        /* insn_move */
3382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_mov = 0x6001,      /* move */
3392b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_movcc = 0x6002,    /* conditional move */
3402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_xchg = 0x6003,     /* exchange */
3412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_xchgcc = 0x6004,   /* conditional exchange */
3422b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        /* insn_string */
3432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_strcmp = 0x7001,
3442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_strload = 0x7002,
3452b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_strmov = 0x7003,
3462b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_strstore = 0x7004,
3472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_translate = 0x7005,        /* xlat */
3482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        /* insn_bit_manip */
3492b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_bittest = 0x8001,
3502b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_bitset = 0x8002,
3512b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_bitclear = 0x8003,
3522b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        /* insn_flag_manip */
3532b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_clear_carry = 0x9001,
3542b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_clear_zero = 0x9002,
3552b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_clear_oflow = 0x9003,
3562b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_clear_dir = 0x9004,
3572b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_clear_sign = 0x9005,
3582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_clear_parity = 0x9006,
3592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_set_carry = 0x9007,
3602b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_set_zero = 0x9008,
3612b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_set_oflow = 0x9009,
3622b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_set_dir = 0x900A,
3632b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_set_sign = 0x900B,
3642b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_set_parity = 0x900C,
3652b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_tog_carry = 0x9010,
3662b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_tog_zero = 0x9020,
3672b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_tog_oflow = 0x9030,
3682b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_tog_dir = 0x9040,
3692b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_tog_sign = 0x9050,
3702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_tog_parity = 0x9060,
3712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        /* insn_fpu */
3722b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_fmov = 0xA001,
3732b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_fmovcc = 0xA002,
3742b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_fneg = 0xA003,
3752b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_fabs = 0xA004,
3762b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_fadd = 0xA005,
3772b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_fsub = 0xA006,
3782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_fmul = 0xA007,
3792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_fdiv = 0xA008,
3802b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_fsqrt = 0xA009,
3812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_fcmp = 0xA00A,
3822b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_fcos = 0xA00C,
3832b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_fldpi = 0xA00D,
3842b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_fldz = 0xA00E,
3852b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_ftan = 0xA00F,
3862b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_fsine = 0xA010,
3872b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_fsys = 0xA020,
3882b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        /* insn_interrupt */
3892b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_int = 0xD001,
3902b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_intcc = 0xD002,    /* not present in x86 ISA */
3912b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_iret = 0xD003,
3922b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_bound = 0xD004,
3932b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_debug = 0xD005,
3942b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_trace = 0xD006,
3952b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_invalid_op = 0xD007,
3962b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_oflow = 0xD008,
3972b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        /* insn_system */
3982b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_halt = 0xE001,
3992b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_in = 0xE002,       /* input from port/bus */
4002b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_out = 0xE003,      /* output to port/bus */
4012b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_cpuid = 0xE004,
4022b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        /* insn_other */
4032b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_nop = 0xF001,
4042b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_bcdconv = 0xF002,  /* convert to or from BCD */
4052b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_szconv = 0xF003    /* change size of operand */
4062b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org};
4072b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
4082b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* These flags specify special characteristics of the instruction, such as
4092b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * whether the inatruction is privileged or whether it serializes the
4102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * pipeline.
4112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * NOTE : These may not be accurate for all instructions; updates to the
4122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * opcode tables have not been completed. */
4132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgenum x86_insn_note {
4142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	insn_note_ring0		= 1,	/* Only available in ring 0 */
4152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	insn_note_smm		= 2,	/* "" in System Management Mode */
4162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	insn_note_serial	= 4,	/* Serializing instruction */
4172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	insn_note_nonswap	= 8,	/* Does not swap arguments in att-style formatting */
4182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	insn_note_nosuffix  = 16,	/* Does not have size suffix in att-style formatting */
4192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org};
4202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
4212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* This specifies what effects the instruction has on the %eflags register */
4222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgenum x86_flag_status {
4232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_carry_set = 0x1,			/* CF */
4242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_zero_set = 0x2,			/* ZF */
4252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_oflow_set = 0x4,			/* OF */
4262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_dir_set = 0x8,			/* DF */
4272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_sign_set = 0x10,			/* SF */
4282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_parity_set = 0x20,			/* PF */
4292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_carry_or_zero_set = 0x40,
4302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_zero_set_or_sign_ne_oflow = 0x80,
4312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_carry_clear = 0x100,
4322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_zero_clear = 0x200,
4332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_oflow_clear = 0x400,
4342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_dir_clear = 0x800,
4352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_sign_clear = 0x1000,
4362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_parity_clear = 0x2000,
4372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_sign_eq_oflow = 0x4000,
4382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_sign_ne_oflow = 0x8000
4392b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org};
4402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
4412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* The CPU model in which the insturction first appeared; this can be used
4422b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * to mask out instructions appearing in earlier or later models or to
4432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * check the portability of a binary.
4442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * NOTE : These may not be accurate for all instructions; updates to the
4452b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * opcode tables have not been completed. */
4462b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgenum x86_insn_cpu {
4472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	cpu_8086 	= 1,	/* Intel */
4482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	cpu_80286	= 2,
4492b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	cpu_80386	= 3,
4502b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	cpu_80387	= 4,
4512b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	cpu_80486	= 5,
4522b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	cpu_pentium	= 6,
4532b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	cpu_pentiumpro	= 7,
4542b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	cpu_pentium2	= 8,
4552b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	cpu_pentium3	= 9,
4562b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	cpu_pentium4	= 10,
4572b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	cpu_k6		= 16,	/* AMD */
4582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	cpu_k7		= 32,
4592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	cpu_athlon	= 48
4602b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org};
4612b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
4622b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* CPU ISA subsets: These are derived from the Instruction Groups in
4632b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * Intel Vol 1 Chapter 5; they represent subsets of the IA32 ISA but
4642b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * do not reflect the 'type' of the instruction in the same way that
4652b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * x86_insn_group does. In short, these are AMD/Intel's somewhat useless
4662b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * designations.
4672b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * NOTE : These may not be accurate for all instructions; updates to the
4682b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * opcode tables have not been completed. */
4692b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgenum x86_insn_isa {
4702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	isa_gp		= 1,	/* general purpose */
4712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	isa_fp		= 2,	/* floating point */
4722b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	isa_fpumgt	= 3,	/* FPU/SIMD management */
4732b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	isa_mmx		= 4,	/* Intel MMX */
4742b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	isa_sse1	= 5,	/* Intel SSE SIMD */
4752b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	isa_sse2	= 6,	/* Intel SSE2 SIMD */
4762b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	isa_sse3	= 7,	/* Intel SSE3 SIMD */
4772b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	isa_3dnow	= 8,	/* AMD 3DNow! SIMD */
4782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	isa_sys		= 9	/* system instructions */
4792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org};
4802b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
4812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgenum x86_insn_prefix {
4822b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_no_prefix = 0,
4832b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_rep_zero = 1,	/* REPZ and REPE */
4842b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_rep_notzero = 2,	/* REPNZ and REPNZ */
4852b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        insn_lock = 4		/* LOCK: */
4862b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org};
4872b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
4882b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* TODO: maybe provide insn_new/free(), and have disasm return new insn_t */
4892b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* x86_insn_t : an X86 instruction */
4902b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgtypedef struct {
4912b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        /* information about the instruction */
4922b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        uint32_t addr;             /* load address */
4932b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        uint32_t offset;           /* offset into file/buffer */
4942b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        enum x86_insn_group group;      /* meta-type, e.g. INS_EXEC */
4952b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        enum x86_insn_type type;        /* type, e.g. INS_BRANCH */
4962b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	enum x86_insn_note note;	/* note, e.g. RING0 */
4972b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        unsigned char bytes[MAX_INSN_SIZE];
4982b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        unsigned char size;             /* size of insn in bytes */
4992b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	/* 16/32-bit mode settings */
5002b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	unsigned char addr_size;	/* default address size : 2 or 4 */
5012b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	unsigned char op_size;		/* default operand size : 2 or 4 */
5022b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	/* CPU/instruction set */
5032b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	enum x86_insn_cpu cpu;
5042b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	enum x86_insn_isa isa;
5052b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	/* flags */
5062b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        enum x86_flag_status flags_set; /* flags set or tested by insn */
5072b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        enum x86_flag_status flags_tested;
5082b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	/* stack */
5092b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	unsigned char stack_mod;	/* 0 or 1 : is the stack modified? */
5102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	int32_t stack_mod_val;		/* val stack is modified by if known */
5112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
5122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        /* the instruction proper */
5132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        enum x86_insn_prefix prefix;	/* prefixes ORed together */
5142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        char prefix_string[MAX_PREFIX_STR]; /* prefixes [might be truncated] */
5152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        char mnemonic[MAX_MNEM_STR];
5162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        x86_oplist_t *operands;		/* list of explicit/implicit operands */
5172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	size_t operand_count;		/* total number of operands */
5182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	size_t explicit_count;		/* number of explicit operands */
5192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        /* convenience fields for user */
5202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        void *block;                    /* code block containing this insn */
5212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        void *function;                 /* function containing this insn */
5222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        int tag;			/* tag the insn as seen/processed */
5232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} x86_insn_t;
5242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
5252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
5262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* returns 0 if an instruction is invalid, 1 if valid */
5272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgint x86_insn_is_valid( x86_insn_t *insn );
5282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
5292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* DISASSEMBLY ROUTINES
5302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      Canonical order of arguments is
5312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *        (buf, buf_len, buf_rva, offset, len, insn, func, arg, resolve_func)
5322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      ...but of course all of these are not used at the same time.
5332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org */
5342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
5352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
5362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* Function prototype for caller-supplied callback routine
5372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      These callbacks are intended to process 'insn' further, e.g. by
5382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      adding it to a linked list, database, etc */
5392b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgtypedef void (*DISASM_CALLBACK)( x86_insn_t *insn, void * arg );
5402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
5412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* Function prototype for caller-supplied address resolver.
5422b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      This routine is used to determine the rva to disassemble next, given
5432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      the 'dest' operand of a jump/call. This allows the caller to resolve
5442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      jump/call targets stored in a register or on the stack, and also allows
5452b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      the caller to prevent endless loops by checking if an address has
5462b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      already been disassembled. If an address cannot be resolved from the
5472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      operand, or if the address has already been disassembled, this routine
5482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      should return -1; in all other cases the RVA to be disassembled next
5492b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      should be returned. */
5502b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgtypedef int32_t (*DISASM_RESOLVER)( x86_op_t *op, x86_insn_t * current_insn,
5512b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org				 void *arg );
5522b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
5532b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
5542b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* x86_disasm: Disassemble a single instruction from a buffer of bytes.
5552b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *             Returns size of instruction in bytes.
5562b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *             Caller is responsible for calling x86_oplist_free() on
5572b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *             a reused "insn" to avoid leaking memory when calling this
5582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *             function repeatedly.
5592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      buf     : Buffer of bytes to disassemble
5602b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      buf_len : Length of the buffer
5612b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      buf_rva : Load address of the start of the buffer
5622b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      offset  : Offset in buffer to disassemble
5632b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      insn    : Structure to fill with disassembled instruction
5642b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org */
5652b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgunsigned int x86_disasm( unsigned char *buf, unsigned int buf_len,
5662b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                	 uint32_t buf_rva, unsigned int offset,
5672b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                	 x86_insn_t * insn );
5682b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
5692b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* x86_disasm_range: Sequential disassembly of a range of bytes in a buffer,
5702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *                   invoking a callback function each time an instruction
5712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *                   is successfully disassembled. The 'range' refers to the
5722b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *                   bytes between 'offset' and 'offset + len' in the buffer;
5732b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *                   'len' is assumed to be less than the length of the buffer.
5742b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *                   Returns number of instructions processed.
5752b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      buf     : Buffer of bytes to disassemble (e.g. .text section)
5762b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      buf_rva : Load address of buffer (e.g. ELF Virtual Address)
5772b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      offset  : Offset in buffer to start disassembly at
5782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      len     : Number of bytes to disassemble
5792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      func    : Callback function to invoke (may be NULL)
5802b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      arg     : Arbitrary data to pass to callback (may be NULL)
5812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org */
5822b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgunsigned int x86_disasm_range( unsigned char *buf, uint32_t buf_rva,
5832b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	                       unsigned int offset, unsigned int len,
5842b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	                       DISASM_CALLBACK func, void *arg );
5852b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
5862b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* x86_disasm_forward: Flow-of-execution disassembly of the bytes in a buffer,
5872b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *                     invoking a callback function each time an instruction
5882b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *                     is successfully disassembled.
5892b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      buf     : Buffer to disassemble (e.g. .text section)
5902b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      buf_len : Number of bytes in buffer
5912b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      buf_rva : Load address of buffer (e.g. ELF Virtual Address)
5922b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      offset  : Offset in buffer to start disassembly at (e.g. entry point)
5932b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      func    : Callback function to invoke (may be NULL)
5942b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      arg     : Arbitrary data to pass to callback (may be NULL)
5952b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      resolver: Caller-supplied address resolver. If no resolver is
5962b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *                supplied, a default internal one is used -- however the
5972b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *                internal resolver does NOT catch loops and could end up
5982b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *                disassembling forever..
5992b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      r_arg	: Arbitrary data to pass to resolver (may be NULL)
6002b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org */
6012b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgunsigned int x86_disasm_forward( unsigned char *buf, unsigned int buf_len,
6022b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	                         uint32_t buf_rva, unsigned int offset,
6032b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	                         DISASM_CALLBACK func, void *arg,
6042b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	                         DISASM_RESOLVER resolver, void *r_arg );
6052b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6062b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* Instruction operands: these are stored as a list of explicit and
6072b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * implicit operands. It is recommended that the 'foreach' routines
6082b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * be used to when examining operands for purposes of data flow analysis */
6092b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* Operand FOREACH callback: 'arg' is an abritrary parameter passed to the
6112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * foreach routine, 'insn' is the x86_insn_t whose operands are being
6122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * iterated over, and 'op' is the current x86_op_t */
6132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgtypedef void (*x86_operand_fn)(x86_op_t *op, x86_insn_t *insn, void *arg);
6142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* FOREACH types: these are used to limit the foreach results to
6162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * operands which match a certain "type" (implicit or explicit)
6172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * or which are accessed in certain ways (e.g. read or write). Note
6182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * that this operates on the operand list of single instruction, so
6192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * specifying the 'real' operand type (register, memory, etc) is not
6202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * useful. Note also that by definition Execute Access implies Read
6212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * Access and implies Not Write Access.
6222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * The "type" (implicit or explicit) and the access method can
6232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * be ORed together, e.g. op_wo | op_explicit */
6242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgenum x86_op_foreach_type {
6252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_any 	= 0,		/* ALL operands (explicit, implicit, rwx) */
6262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_dest = 1,		/* operands with Write access */
6272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_src 	= 2,		/* operands with Read access */
6282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_ro 	= 3,		/* operands with Read but not Write access */
6292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_wo 	= 4,		/* operands with Write but not Read access */
6302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_xo 	= 5,		/* operands with Execute access */
6312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_rw 	= 6,		/* operands with Read AND Write access */
6322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_implicit = 0x10,	/* operands that are implied by the opcode */
6332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	op_explicit = 0x20	/* operands that are not side-effects */
6342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org};
6352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* free the operand list associated with an instruction -- useful for
6382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * preventing memory leaks when free()ing an x86_insn_t */
6392b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgvoid x86_oplist_free( x86_insn_t *insn );
6402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* Operand foreach: invokes 'func' with 'insn' and 'arg' as arguments. The
6422b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * 'type' parameter is used to select only operands matching specific
6432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * criteria. */
6442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgint x86_operand_foreach( x86_insn_t *insn, x86_operand_fn func, void *arg,
6452b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	       	  	 enum x86_op_foreach_type type);
6462b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* convenience routine: returns count of operands matching 'type' */
6482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgsize_t x86_operand_count( x86_insn_t *insn, enum x86_op_foreach_type type );
6492b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6502b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* accessor functions for the operands */
6512b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgx86_op_t * x86_operand_1st( x86_insn_t *insn );
6522b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgx86_op_t * x86_operand_2nd( x86_insn_t *insn );
6532b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgx86_op_t * x86_operand_3rd( x86_insn_t *insn );
6542b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6552b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* these allow libdisasm 2.0 accessor functions to still be used */
6562b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define x86_get_dest_operand( insn ) x86_operand_1st( insn )
6572b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define x86_get_src_operand( insn ) x86_operand_2nd( insn )
6582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define x86_get_imm_operand( insn ) x86_operand_3rd( insn )
6592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6602b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* get size of operand data in bytes */
6612b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgunsigned int x86_operand_size( x86_op_t *op );
6622b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6632b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* Operand Convenience Routines: the following three routines are common
6642b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * operations on operands, intended to ease the burden of the programmer. */
6652b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6662b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* Get Address: return the value of an offset operand, or the offset of
6672b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * a segment:offset absolute address */
6682b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orguint32_t x86_get_address( x86_insn_t *insn );
6692b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* Get Relative Offset: return as a sign-extended int32_t the near or far
6712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * relative offset operand, or 0 if there is none. There can be only one
6722b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * relaive offset operand in an instruction. */
6732b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgint32_t x86_get_rel_offset( x86_insn_t *insn );
6742b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6752b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* Get Branch Target: return the x86_op_t containing the target of
6762b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * a jump or call operand, or NULL if there is no branch target.
6772b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * Internally, a 'branch target' is defined as any operand with
6782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * Execute Access set. There can be only one branch target per instruction. */
6792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgx86_op_t * x86_get_branch_target( x86_insn_t *insn );
6802b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* Get Immediate: return the x86_op_t containing the immediate operand
6822b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * for this instruction, or NULL if there is no immediate operand. There
6832b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * can be only one immediate operand per instruction */
6842b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgx86_op_t * x86_get_imm( x86_insn_t *insn );
6852b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6862b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* Get Raw Immediate Data: returns a pointer to the immediate data encoded
6872b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * in the instruction. This is useful for large data types [>32 bits] currently
6882b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * not supported by libdisasm, or for determining if the disassembler
6892b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * screwed up the conversion of the immediate data. Note that 'imm' in this
6902b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * context refers to immediate data encoded at the end of an instruction as
6912b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * detailed in the Intel Manual Vol II Chapter 2; it does not refer to the
6922b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * 'op_imm' operand (the third operand in instructions like 'mul' */
6932b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgunsigned char * x86_get_raw_imm( x86_insn_t *insn );
6942b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6952b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
6962b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* More accessor fuctions, this time for user-defined info... */
6972b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* set the address (usually RVA) of the insn */
6982b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgvoid x86_set_insn_addr( x86_insn_t *insn, uint32_t addr );
6992b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7002b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* set the offset (usually offset into file) of the insn */
7012b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgvoid x86_set_insn_offset( x86_insn_t *insn, unsigned int offset );
7022b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7032b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* set a pointer to the function owning the instruction. The
7042b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * type of 'func' is user-defined; libdisasm does not use the func field. */
7052b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgvoid x86_set_insn_function( x86_insn_t *insn, void * func );
7062b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7072b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* set a pointer to the block of code owning the instruction. The
7082b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * type of 'block' is user-defined; libdisasm does not use the block field. */
7092b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgvoid x86_set_insn_block( x86_insn_t *insn, void * block );
7102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* instruction tagging: these routines allow the programmer to mark
7122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * instructions as "seen" in a DFS, for example. libdisasm does not use
7132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * the tag field.*/
7142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* set insn->tag to 1 */
7152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgvoid x86_tag_insn( x86_insn_t *insn );
7162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* set insn->tag to 0 */
7172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgvoid x86_untag_insn( x86_insn_t *insn );
7182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* return insn->tag */
7192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgint x86_insn_is_tagged( x86_insn_t *insn );
7202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* Disassembly formats:
7232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      AT&T is standard AS/GAS-style: "mnemonic\tsrc, dest, imm"
7242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      Intel is standard MASM/NASM/TASM: "mnemonic\tdest,src, imm"
7252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      Native is tab-delimited: "RVA\tbytes\tmnemonic\tdest\tsrc\timm"
7262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      XML is your typical <insn> ... </insn>
7272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *      Raw is addr|offset|size|bytes|prefix... see libdisasm_formats.7
7282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org */
7292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgenum x86_asm_format {
7302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	unknown_syntax = 0,		/* never use! */
7312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	native_syntax, 			/* header: 35 bytes */
7322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	intel_syntax, 			/* header: 23 bytes */
7332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	att_syntax,  			/* header: 23 bytes */
7342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	xml_syntax,			/* header: 679 bytes */
7352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	raw_syntax			/* header: 172 bytes */
7362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org};
7372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* format (sprintf) an operand into 'buf' using specified syntax */
7392b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgint x86_format_operand(x86_op_t *op, char *buf, int len,
7402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                  enum x86_asm_format format);
7412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7422b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* format (sprintf) an instruction mnemonic into 'buf' using specified syntax */
7432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgint x86_format_mnemonic(x86_insn_t *insn, char *buf, int len,
7442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org                        enum x86_asm_format format);
7452b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7462b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* format (sprintf) an instruction into 'buf' using specified syntax;
7472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * this includes formatting all operands */
7482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgint x86_format_insn(x86_insn_t *insn, char *buf, int len, enum x86_asm_format);
7492b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7502b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* fill 'buf' with a description of the format's syntax */
7512b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgint x86_format_header( char *buf, int len, enum x86_asm_format format);
7522b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7532b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* Endianness of an x86 CPU : 0 is big, 1 is little; always returns 1 */
7542b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgunsigned int x86_endian(void);
7552b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7562b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* Default address and operand size in bytes */
7572b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgunsigned int x86_addr_size(void);
7582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgunsigned int x86_op_size(void);
7592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7602b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* Size of a machine word in bytes */
7612b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgunsigned int x86_word_size(void);
7622b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7632b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* maximum size of a code instruction */
7642b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define x86_max_inst_size(x) x86_max_insn_size(x)
7652b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgunsigned int x86_max_insn_size(void);
7662b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7672b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* register IDs of Stack, Frame, Instruction pointer and Flags register */
7682b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgunsigned int x86_sp_reg(void);
7692b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgunsigned int x86_fp_reg(void);
7702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgunsigned int x86_ip_reg(void);
7712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgunsigned int x86_flag_reg(void);
7722b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7732b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* fill 'reg' struct with details of register 'id' */
7742b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgvoid x86_reg_from_id( unsigned int id, x86_reg_t * reg );
7752b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7762b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* convenience macro demonstrating how to get an aliased register; proto is
7772b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *   void x86_get_aliased_reg( x86_reg_t *alias_reg, x86_reg_t *output_reg )
7782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * where 'alias_reg' is a reg operand and 'output_reg' is filled with the
7792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * register that the operand is an alias for */
7802b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define x86_get_aliased_reg( alias_reg, output_reg )			\
7812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	x86_reg_from_id( alias_reg->alias, output_reg )
7822b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7832b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
7842b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* ================================== Invariant Instruction Representation */
7852b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* Invariant instructions are used for generating binary signatures;
7862b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * the instruction is modified so that all variant bytes in an instruction
7872b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * are replaced with a wildcard byte.
7882b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *
7892b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * A 'variant byte' is one that is expected to be modified by either the
7902b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * static or the dynamic linker: for example, an address encoded in an
7912b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * instruction.
7922b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *
7932b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * By comparing the invariant representation of one instruction [or of a
7942b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * sequence of instructions] with the invariant representation of another,
7952b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * one determine whether the two invariant representations are from the same
7962b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * relocatable object [.o] file. Thus one can use binary signatures [which
7972b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * are just sequences of invariant instruction representations] to look for
7982b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * library routines which have been statically-linked into a binary.
7992b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org *
8002b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * The invariant routines are faster and smaller than the disassembly
8012b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * routines; they can be used to determine the size of an instruction
8022b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * without all of the overhead of a full instruction disassembly.
8032b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org */
8042b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
8052b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* This byte is used to replace variant bytes */
8062b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define X86_WILDCARD_BYTE 0xF4
8072b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
8082b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgtypedef struct {
8092b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        enum x86_op_type        type;           /* operand type */
8102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        enum x86_op_datatype    datatype;       /* operand size */
8112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        enum x86_op_access      access;         /* operand access [RWX] */
8122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        enum x86_op_flags       flags;          /* misc flags */
8132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} x86_invariant_op_t;
8142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
8152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgtypedef struct {
8162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	unsigned char bytes[64];	/* invariant representation */
8172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	unsigned int  size;		/* number of bytes in insn */
8182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        enum x86_insn_group group;      /* meta-type, e.g. INS_EXEC */
8192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org        enum x86_insn_type type;        /* type, e.g. INS_BRANCH */
8202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org	x86_invariant_op_t operands[3];	/* operands: dest, src, imm */
8212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} x86_invariant_t;
8222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
8232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
8242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* return a version of the instruction with the variant bytes masked out */
8252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgsize_t x86_invariant_disasm( unsigned char *buf, int buf_len,
8262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org			  x86_invariant_t *inv );
8272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* return the size in bytes of the intruction pointed to by 'buf';
8282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * this used x86_invariant_disasm since it faster than x86_disasm */
8292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgsize_t x86_size_disasm( unsigned char *buf, unsigned int buf_len );
8302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
8312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#ifdef __cplusplus
8322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org}
8332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#endif
8342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
8352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org
8362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#endif
837