Home | History | Annotate | Download | only in sidestep
      1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 //
      5 // Several simple types used by the disassembler and some of the patching
      6 // mechanisms.
      7 
      8 #ifndef SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_TYPES_H__
      9 #define SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_TYPES_H__
     10 
     11 namespace sidestep {
     12 
     13 // Categories of instructions that we care about
     14 enum InstructionType {
     15   // This opcode is not used
     16   IT_UNUSED,
     17   // This disassembler does not recognize this opcode (error)
     18   IT_UNKNOWN,
     19   // This is not an instruction but a reference to another table
     20   IT_REFERENCE,
     21   // This byte is a prefix byte that we can ignore
     22   IT_PREFIX,
     23   // This is a prefix byte that switches to the nondefault address size
     24   IT_PREFIX_ADDRESS,
     25   // This is a prefix byte that switches to the nondefault operand size
     26   IT_PREFIX_OPERAND,
     27   // A jump or call instruction
     28   IT_JUMP,
     29   // A return instruction
     30   IT_RETURN,
     31   // Any other type of instruction (in this case we don't care what it is)
     32   IT_GENERIC,
     33 };
     34 
     35 // Lists IA-32 operand sizes in multiples of 8 bits
     36 enum OperandSize {
     37   OS_ZERO = 0,
     38   OS_BYTE = 1,
     39   OS_WORD = 2,
     40   OS_DOUBLE_WORD = 4,
     41   OS_QUAD_WORD = 8,
     42   OS_DOUBLE_QUAD_WORD = 16,
     43   OS_32_BIT_POINTER = 32/8,
     44   OS_48_BIT_POINTER = 48/8,
     45   OS_SINGLE_PRECISION_FLOATING = 32/8,
     46   OS_DOUBLE_PRECISION_FLOATING = 64/8,
     47   OS_DOUBLE_EXTENDED_PRECISION_FLOATING = 80/8,
     48   OS_128_BIT_PACKED_SINGLE_PRECISION_FLOATING = 128/8,
     49   OS_PSEUDO_DESCRIPTOR = 6
     50 };
     51 
     52 // Operand addressing methods from the IA-32 manual.  The enAmMask value
     53 // is a mask for the rest.  The other enumeration values are named for the
     54 // names given to the addressing methods in the manual, e.g. enAm_D is for
     55 // the D addressing method.
     56 //
     57 // The reason we use a full 4 bytes and a mask, is that we need to combine
     58 // these flags with the enOperandType to store the details
     59 // on the operand in a single integer.
     60 enum AddressingMethod {
     61   AM_NOT_USED = 0,        // This operand is not used for this instruction
     62   AM_MASK = 0x00FF0000,  // Mask for the rest of the values in this enumeration
     63   AM_A = 0x00010000,    // A addressing type
     64   AM_C = 0x00020000,    // C addressing type
     65   AM_D = 0x00030000,    // D addressing type
     66   AM_E = 0x00040000,    // E addressing type
     67   AM_F = 0x00050000,    // F addressing type
     68   AM_G = 0x00060000,    // G addressing type
     69   AM_I = 0x00070000,    // I addressing type
     70   AM_J = 0x00080000,    // J addressing type
     71   AM_M = 0x00090000,    // M addressing type
     72   AM_O = 0x000A0000,    // O addressing type
     73   AM_P = 0x000B0000,    // P addressing type
     74   AM_Q = 0x000C0000,    // Q addressing type
     75   AM_R = 0x000D0000,    // R addressing type
     76   AM_S = 0x000E0000,    // S addressing type
     77   AM_T = 0x000F0000,    // T addressing type
     78   AM_V = 0x00100000,    // V addressing type
     79   AM_W = 0x00110000,    // W addressing type
     80   AM_X = 0x00120000,    // X addressing type
     81   AM_Y = 0x00130000,    // Y addressing type
     82   AM_REGISTER = 0x00140000,  // Specific register is always used as this op
     83   AM_IMPLICIT = 0x00150000,  // An implicit, fixed value is used
     84 };
     85 
     86 // Operand types from the IA-32 manual. The enOtMask value is
     87 // a mask for the rest. The rest of the values are named for the
     88 // names given to these operand types in the manual, e.g. enOt_ps
     89 // is for the ps operand type in the manual.
     90 //
     91 // The reason we use a full 4 bytes and a mask, is that we need
     92 // to combine these flags with the enAddressingMethod to store the details
     93 // on the operand in a single integer.
     94 enum OperandType {
     95   OT_MASK = 0xFF000000,
     96   OT_A = 0x01000000,
     97   OT_B = 0x02000000,
     98   OT_C = 0x03000000,
     99   OT_D = 0x04000000,
    100   OT_DQ = 0x05000000,
    101   OT_P = 0x06000000,
    102   OT_PI = 0x07000000,
    103   OT_PS = 0x08000000,  // actually unsupported for (we don't know its size)
    104   OT_Q = 0x09000000,
    105   OT_S = 0x0A000000,
    106   OT_SS = 0x0B000000,
    107   OT_SI = 0x0C000000,
    108   OT_V = 0x0D000000,
    109   OT_W = 0x0E000000,
    110   OT_SD = 0x0F000000,  // scalar double-precision floating-point value
    111   OT_PD = 0x10000000,  // double-precision floating point
    112   // dummy "operand type" for address mode M - which doesn't specify
    113   // operand type
    114   OT_ADDRESS_MODE_M = 0x80000000
    115 };
    116 
    117 // Everything that's in an Opcode (see below) except the three
    118 // alternative opcode structs for different prefixes.
    119 struct SpecificOpcode {
    120   // Index to continuation table, or 0 if this is the last
    121   // byte in the opcode.
    122   int table_index_;
    123 
    124   // The opcode type
    125   InstructionType type_;
    126 
    127   // Description of the type of the dest, src and aux operands,
    128   // put together from an enOperandType flag and an enAddressingMethod
    129   // flag.
    130   int flag_dest_;
    131   int flag_source_;
    132   int flag_aux_;
    133 
    134   // We indicate the mnemonic for debugging purposes
    135   const char* mnemonic_;
    136 };
    137 
    138 // The information we keep in our tables about each of the different
    139 // valid instructions recognized by the IA-32 architecture.
    140 struct Opcode {
    141   // Index to continuation table, or 0 if this is the last
    142   // byte in the opcode.
    143   int table_index_;
    144 
    145   // The opcode type
    146   InstructionType type_;
    147 
    148   // Description of the type of the dest, src and aux operands,
    149   // put together from an enOperandType flag and an enAddressingMethod
    150   // flag.
    151   int flag_dest_;
    152   int flag_source_;
    153   int flag_aux_;
    154 
    155   // We indicate the mnemonic for debugging purposes
    156   const char* mnemonic_;
    157 
    158   // Alternative opcode info if certain prefixes are specified.
    159   // In most cases, all of these are zeroed-out.  Only used if
    160   // bPrefixDependent is true.
    161   bool is_prefix_dependent_;
    162   SpecificOpcode opcode_if_f2_prefix_;
    163   SpecificOpcode opcode_if_f3_prefix_;
    164   SpecificOpcode opcode_if_66_prefix_;
    165 };
    166 
    167 // Information about each table entry.
    168 struct OpcodeTable {
    169   // Table of instruction entries
    170   const Opcode* table_;
    171   // How many bytes left to shift ModR/M byte <b>before</b> applying mask
    172   unsigned char shift_;
    173   // Mask to apply to byte being looked at before comparing to table
    174   unsigned char mask_;
    175   // Minimum/maximum indexes in table.
    176   unsigned char min_lim_;
    177   unsigned char max_lim_;
    178 };
    179 
    180 // Information about each entry in table used to decode ModR/M byte.
    181 struct ModrmEntry {
    182   // Is the operand encoded as bytes in the instruction (rather than
    183   // if it's e.g. a register in which case it's just encoded in the
    184   // ModR/M byte)
    185   bool is_encoded_in_instruction_;
    186 
    187   // Is there a SIB byte?  In this case we always need to decode it.
    188   bool use_sib_byte_;
    189 
    190   // What is the size of the operand (only important if it's encoded
    191   // in the instruction)?
    192   OperandSize operand_size_;
    193 };
    194 
    195 };  // namespace sidestep
    196 
    197 #endif  // SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_TYPES_H__
    198