1 /*************************************************************************************************** 2 3 Zyan Disassembler Library (Zydis) 4 5 Original Author : Mappa 6 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in all 15 * copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 25 ***************************************************************************************************/ 26 27 #ifndef ZYDIS_INTERNAL_ENCODERDATA_H 28 #define ZYDIS_INTERNAL_ENCODERDATA_H 29 30 #include <Zycore/Defines.h> 31 #include <Zydis/Mnemonic.h> 32 #include <Zydis/SharedTypes.h> 33 34 /** 35 * Used in encoder's table to represent standard ISA sizes in form of bit flags. 36 */ 37 typedef enum ZydisWidthFlag_ 38 { 39 ZYDIS_WIDTH_INVALID = 0x00, 40 ZYDIS_WIDTH_16 = 0x01, 41 ZYDIS_WIDTH_32 = 0x02, 42 ZYDIS_WIDTH_64 = 0x04, 43 44 /** 45 * Maximum value of this enum. 46 */ 47 ZYDIS_WIDTH_MAX_VALUE = (ZYDIS_WIDTH_64 | (ZYDIS_WIDTH_64 - 1)), 48 /** 49 * The minimum number of bits required to represent all values of this enum. 50 */ 51 ZYDIS_WIDTH_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_WIDTH_MAX_VALUE) 52 } ZydisWidthFlag; 53 54 /** 55 * Used in encoder's table to represent mandatory instruction prefix. Using this enum instead of 56 * actual prefix value saves space. 57 */ 58 typedef enum ZydisMandatoryPrefix_ 59 { 60 ZYDIS_MANDATORY_PREFIX_NONE, 61 ZYDIS_MANDATORY_PREFIX_66, 62 ZYDIS_MANDATORY_PREFIX_F2, 63 ZYDIS_MANDATORY_PREFIX_F3, 64 65 /** 66 * Maximum value of this enum. 67 */ 68 ZYDIS_MANDATORY_PREFIX_MAX_VALUE = ZYDIS_MANDATORY_PREFIX_F3, 69 /** 70 * The minimum number of bits required to represent all values of this enum. 71 */ 72 ZYDIS_MANDATORY_PREFIX_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_MANDATORY_PREFIX_MAX_VALUE) 73 } ZydisMandatoryPrefix; 74 75 /** 76 * Used in encoder's table to represent vector size supported by instruction definition. 77 */ 78 typedef enum ZydisVectorLength_ 79 { 80 ZYDIS_VECTOR_LENGTH_INVALID, 81 ZYDIS_VECTOR_LENGTH_128, 82 ZYDIS_VECTOR_LENGTH_256, 83 ZYDIS_VECTOR_LENGTH_512, 84 85 /** 86 * Maximum value of this enum. 87 */ 88 ZYDIS_VECTOR_LENGTH_MAX_VALUE = ZYDIS_VECTOR_LENGTH_512, 89 /** 90 * The minimum number of bits required to represent all values of this enum. 91 */ 92 ZYDIS_VECTOR_LENGTH_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_VECTOR_LENGTH_MAX_VALUE) 93 } ZydisVectorLength; 94 95 /** 96 * Used in encoder's table to represent hint type supported by instruction definition. 97 */ 98 typedef enum ZydisSizeHint_ 99 { 100 ZYDIS_SIZE_HINT_NONE, 101 ZYDIS_SIZE_HINT_ASZ, 102 ZYDIS_SIZE_HINT_OSZ, 103 104 /** 105 * Maximum value of this enum. 106 */ 107 ZYDIS_SIZE_HINT_MAX_VALUE = ZYDIS_SIZE_HINT_OSZ, 108 /** 109 * The minimum number of bits required to represent all values of this enum. 110 */ 111 ZYDIS_SIZE_HINT_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_SIZE_HINT_MAX_VALUE) 112 } ZydisSizeHint; 113 114 /** 115 * Used in encoder's primary lookup table which allows to access a set of instruction definitions 116 * for specified mnemonic in constant time. 117 */ 118 typedef struct ZydisEncoderLookupEntry_ 119 { 120 /** 121 * Index to main array of `ZydisEncodableInstruction`. 122 */ 123 ZyanU16 encoder_reference; 124 /** 125 * The number of entries. 126 */ 127 ZyanU8 instruction_count; 128 } ZydisEncoderLookupEntry; 129 130 #pragma pack(push, 1) 131 132 /** 133 * This structure is encoder's internal representation of encodable instruction definition. 134 */ 135 typedef struct ZydisEncodableInstruction_ 136 { 137 /** 138 * Index to one of decoder's instruction definition arrays. 139 */ 140 ZyanU16 instruction_reference; 141 /** 142 * Compressed information about operand count and types. Operand count is stored in lowest bits. 143 * Types of subsequent operands are stored in higher bits. 144 */ 145 ZyanU16 operand_mask; 146 /** 147 * The instruction-opcode. 148 */ 149 ZyanU8 opcode; 150 /** 151 * The mandatory ModR/M value. 152 */ 153 ZyanU8 modrm; 154 /** 155 * The instruction-encoding. 156 */ 157 ZyanU8 encoding ZYAN_BITFIELD(ZYDIS_INSTRUCTION_ENCODING_REQUIRED_BITS); 158 /** 159 * The opcode map. 160 */ 161 ZyanU8 opcode_map ZYAN_BITFIELD(ZYDIS_OPCODE_MAP_REQUIRED_BITS); 162 /** 163 * The combination of allowed processor modes. 164 */ 165 ZyanU8 modes ZYAN_BITFIELD(ZYDIS_WIDTH_REQUIRED_BITS); 166 /** 167 * The combination of allowed address sizes. 168 */ 169 ZyanU8 address_sizes ZYAN_BITFIELD(ZYDIS_WIDTH_REQUIRED_BITS); 170 /** 171 * The combination of allowed operand sizes. 172 */ 173 ZyanU8 operand_sizes ZYAN_BITFIELD(ZYDIS_WIDTH_REQUIRED_BITS); 174 /** 175 * The mandatory prefix. 176 */ 177 ZyanU8 mandatory_prefix ZYAN_BITFIELD(ZYDIS_MANDATORY_PREFIX_REQUIRED_BITS); 178 /** 179 * True if `REX.W` is required for this definition. 180 */ 181 ZyanU8 rex_w ZYAN_BITFIELD(1); 182 /** 183 * The vector length. 184 */ 185 ZyanU8 vector_length ZYAN_BITFIELD(ZYDIS_MANDATORY_PREFIX_REQUIRED_BITS); 186 /** 187 * The accepted sizing hint. 188 */ 189 ZyanU8 accepts_hint ZYAN_BITFIELD(ZYDIS_SIZE_HINT_REQUIRED_BITS); 190 /** 191 * Indicates that next instruction definition can be safely used instead of current one. This 192 * is used with some `VEX` instructions to take advantage of 2-byte `VEX` prefix when possible. 193 * 2-byte `VEX` allows to use high registers only when operand is encoded in `modrm_reg` 194 * (high bit in `REX.R`). Encoder uses swappable definitions to take advantage of this 195 * optimization opportunity. 196 * 197 * Second use of this field is to handle special case for `mov` instruction. This particular 198 * conflict is described in detail inside `ZydisHandleSwappableDefinition`. 199 */ 200 ZyanU8 swappable ZYAN_BITFIELD(1); 201 } ZydisEncodableInstruction; 202 203 #pragma pack(pop) 204 205 /** 206 * Contains information used by instruction size prediction algorithm inside 207 * `ZydisEncoderEncodeInstructionAbsolute`. 208 */ 209 typedef struct ZydisEncoderRelInfo_ 210 { 211 /** 212 * Sizes of instruction variants. First index is effective address size. Second index is 213 * desired immediate size (8, 16 and 32 bits respectively). 214 */ 215 ZyanU8 size[3][3]; 216 /** 217 * See `ZydisSizeHint`. 218 */ 219 ZyanU8 accepts_scaling_hints; 220 /** 221 * True if instruction accepts branch hint prefixes. 222 */ 223 ZyanBool accepts_branch_hints; 224 /** 225 * True if instruction accepts bound (`BND`) prefix. 226 */ 227 ZyanBool accepts_bound; 228 } ZydisEncoderRelInfo; 229 230 /** 231 * Fetches array of `ZydisEncodableInstruction` structures and its size for given instruction 232 * mnemonic. 233 * 234 * @param mnemonic Instruction mnemonic. 235 * @param instruction This variable will receive a pointer to the array of 236 * `ZydisEncodableInstruction` structures. 237 * 238 * @return Entry count (0 if function failed). 239 */ 240 ZyanU8 ZydisGetEncodableInstructions(ZydisMnemonic mnemonic, 241 const ZydisEncodableInstruction **instruction); 242 243 /** 244 * Fetches `ZydisEncoderRelInfo` record for given instruction mnemonic. 245 * 246 * @param mnemonic Instruction mnemonic. 247 * 248 * @return Pointer to `ZydisEncoderRelInfo` structure or `ZYAN_NULL` if instruction doesn't have 249 * relative operands. 250 */ 251 const ZydisEncoderRelInfo *ZydisGetRelInfo(ZydisMnemonic mnemonic); 252 253 #endif /* ZYDIS_INTERNAL_ENCODERDATA_H */ 254