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 11namespace sidestep { 12 13// Categories of instructions that we care about 14enum 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 36enum 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. 60enum 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. 94enum 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. 119struct 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. 140struct 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. 168struct 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. 181struct 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