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 40namespace sidestep { 41 42// Categories of instructions that we care about 43enum 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 65enum 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. 89enum 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. 123enum 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. 150enum 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. 158struct 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. 179struct 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. 207struct 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. 220struct 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