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