Home | History | Annotate | Download | only in windows
      1 /* Copyright (c) 2007, Google Inc.
      2  * All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  *
     30  * ---
     31  * Author: Joi Sigurdsson
     32  *
     33  * Several simple types used by the disassembler and some of the patching
     34  * mechanisms.
     35  */
     36 
     37 #ifndef GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_TYPES_H_
     38 #define GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_TYPES_H_
     39 
     40 namespace sidestep {
     41 
     42 // Categories of instructions that we care about
     43 enum InstructionType {
     44   // This opcode is not used
     45   IT_UNUSED,
     46   // This disassembler does not recognize this opcode (error)
     47   IT_UNKNOWN,
     48   // This is not an instruction but a reference to another table
     49   IT_REFERENCE,
     50   // This byte is a prefix byte that we can ignore
     51   IT_PREFIX,
     52   // This is a prefix byte that switches to the nondefault address size
     53   IT_PREFIX_ADDRESS,
     54   // This is a prefix byte that switches to the nondefault operand size
     55   IT_PREFIX_OPERAND,
     56   // A jump or call instruction
     57   IT_JUMP,
     58   // A return instruction
     59   IT_RETURN,
     60   // Any other type of instruction (in this case we don't care what it is)
     61   IT_GENERIC,
     62 };
     63 
     64 // Lists IA-32 operand sizes in multiples of 8 bits
     65 enum OperandSize {
     66   OS_ZERO = 0,
     67   OS_BYTE = 1,
     68   OS_WORD = 2,
     69   OS_DOUBLE_WORD = 4,
     70   OS_QUAD_WORD = 8,
     71   OS_DOUBLE_QUAD_WORD = 16,
     72   OS_32_BIT_POINTER = 32/8,
     73   OS_48_BIT_POINTER = 48/8,
     74   OS_SINGLE_PRECISION_FLOATING = 32/8,
     75   OS_DOUBLE_PRECISION_FLOATING = 64/8,
     76   OS_DOUBLE_EXTENDED_PRECISION_FLOATING = 80/8,
     77   OS_128_BIT_PACKED_SINGLE_PRECISION_FLOATING = 128/8,
     78   OS_PSEUDO_DESCRIPTOR = 6
     79 };
     80 
     81 // Operand addressing methods from the IA-32 manual.  The enAmMask value
     82 // is a mask for the rest.  The other enumeration values are named for the
     83 // names given to the addressing methods in the manual, e.g. enAm_D is for
     84 // the D addressing method.
     85 //
     86 // The reason we use a full 4 bytes and a mask, is that we need to combine
     87 // these flags with the enOperandType to store the details
     88 // on the operand in a single integer.
     89 enum AddressingMethod {
     90   AM_NOT_USED = 0,        // This operand is not used for this instruction
     91   AM_MASK = 0x00FF0000,  // Mask for the rest of the values in this enumeration
     92   AM_A = 0x00010000,    // A addressing type
     93   AM_C = 0x00020000,    // C addressing type
     94   AM_D = 0x00030000,    // D addressing type
     95   AM_E = 0x00040000,    // E addressing type
     96   AM_F = 0x00050000,    // F addressing type
     97   AM_G = 0x00060000,    // G addressing type
     98   AM_I = 0x00070000,    // I addressing type
     99   AM_J = 0x00080000,    // J addressing type
    100   AM_M = 0x00090000,    // M addressing type
    101   AM_O = 0x000A0000,    // O addressing type
    102   AM_P = 0x000B0000,    // P addressing type
    103   AM_Q = 0x000C0000,    // Q addressing type
    104   AM_R = 0x000D0000,    // R addressing type
    105   AM_S = 0x000E0000,    // S addressing type
    106   AM_T = 0x000F0000,    // T addressing type
    107   AM_V = 0x00100000,    // V addressing type
    108   AM_W = 0x00110000,    // W addressing type
    109   AM_X = 0x00120000,    // X addressing type
    110   AM_Y = 0x00130000,    // Y addressing type
    111   AM_REGISTER = 0x00140000,  // Specific register is always used as this op
    112   AM_IMPLICIT = 0x00150000,  // An implicit, fixed value is used
    113 };
    114 
    115 // Operand types from the IA-32 manual. The enOtMask value is
    116 // a mask for the rest. The rest of the values are named for the
    117 // names given to these operand types in the manual, e.g. enOt_ps
    118 // is for the ps operand type in the manual.
    119 //
    120 // The reason we use a full 4 bytes and a mask, is that we need
    121 // to combine these flags with the enAddressingMethod to store the details
    122 // on the operand in a single integer.
    123 enum OperandType {
    124   OT_MASK = 0xFF000000,
    125   OT_A = 0x01000000,
    126   OT_B = 0x02000000,
    127   OT_C = 0x03000000,
    128   OT_D = 0x04000000,
    129   OT_DQ = 0x05000000,
    130   OT_P = 0x06000000,
    131   OT_PI = 0x07000000,
    132   OT_PS = 0x08000000,  // actually unsupported for (we don't know its size)
    133   OT_Q = 0x09000000,
    134   OT_S = 0x0A000000,
    135   OT_SS = 0x0B000000,
    136   OT_SI = 0x0C000000,
    137   OT_V = 0x0D000000,
    138   OT_W = 0x0E000000,
    139   OT_SD = 0x0F000000,  // scalar double-precision floating-point value
    140   OT_PD = 0x10000000,  // double-precision floating point
    141   // dummy "operand type" for address mode M - which doesn't specify
    142   // operand type
    143   OT_ADDRESS_MODE_M = 0x80000000
    144 };
    145 
    146 // Flag that indicates if an immediate operand is 64-bits.
    147 //
    148 // The Intel 64 and IA-32 Architecture Software Developer's Manual currently
    149 // defines MOV as the only instruction supporting a 64-bit immediate operand.
    150 enum ImmediateOperandSize {
    151   IOS_MASK = 0x0000F000,
    152   IOS_DEFAULT = 0x0,
    153   IOS_64 = 0x00001000
    154 };
    155 
    156 // Everything that's in an Opcode (see below) except the three
    157 // alternative opcode structs for different prefixes.
    158 struct SpecificOpcode {
    159   // Index to continuation table, or 0 if this is the last
    160   // byte in the opcode.
    161   int table_index_;
    162 
    163   // The opcode type
    164   InstructionType type_;
    165 
    166   // Description of the type of the dest, src and aux operands,
    167   // put together from enOperandType, enAddressingMethod and
    168   // enImmediateOperandSize flags.
    169   int flag_dest_;
    170   int flag_source_;
    171   int flag_aux_;
    172 
    173   // We indicate the mnemonic for debugging purposes
    174   const char* mnemonic_;
    175 };
    176 
    177 // The information we keep in our tables about each of the different
    178 // valid instructions recognized by the IA-32 architecture.
    179 struct Opcode {
    180   // Index to continuation table, or 0 if this is the last
    181   // byte in the opcode.
    182   int table_index_;
    183 
    184   // The opcode type
    185   InstructionType type_;
    186 
    187   // Description of the type of the dest, src and aux operands,
    188   // put together from an enOperandType flag and an enAddressingMethod
    189   // flag.
    190   int flag_dest_;
    191   int flag_source_;
    192   int flag_aux_;
    193 
    194   // We indicate the mnemonic for debugging purposes
    195   const char* mnemonic_;
    196 
    197   // Alternative opcode info if certain prefixes are specified.
    198   // In most cases, all of these are zeroed-out.  Only used if
    199   // bPrefixDependent is true.
    200   bool is_prefix_dependent_;
    201   SpecificOpcode opcode_if_f2_prefix_;
    202   SpecificOpcode opcode_if_f3_prefix_;
    203   SpecificOpcode opcode_if_66_prefix_;
    204 };
    205 
    206 // Information about each table entry.
    207 struct OpcodeTable {
    208   // Table of instruction entries
    209   const Opcode* table_;
    210   // How many bytes left to shift ModR/M byte <b>before</b> applying mask
    211   unsigned char shift_;
    212   // Mask to apply to byte being looked at before comparing to table
    213   unsigned char mask_;
    214   // Minimum/maximum indexes in table.
    215   unsigned char min_lim_;
    216   unsigned char max_lim_;
    217 };
    218 
    219 // Information about each entry in table used to decode ModR/M byte.
    220 struct ModrmEntry {
    221   // Is the operand encoded as bytes in the instruction (rather than
    222   // if it's e.g. a register in which case it's just encoded in the
    223   // ModR/M byte)
    224   bool is_encoded_in_instruction_;
    225 
    226   // Is there a SIB byte?  In this case we always need to decode it.
    227   bool use_sib_byte_;
    228 
    229   // What is the size of the operand (only important if it's encoded
    230   // in the instruction)?
    231   OperandSize operand_size_;
    232 };
    233 
    234 };  // namespace sidestep
    235 
    236 #endif  // GOOGLE_PERFTOOLS_MINI_DISASSEMBLER_TYPES_H_
    237