1 /*************************************************************************************************** 2 3 Zyan Disassembler Library (Zydis) 4 5 Original Author : Florian Bernd 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 #include <Zydis/Internal/SharedData.h> 28 29 /* ============================================================================================== */ 30 /* Data tables */ 31 /* ============================================================================================== */ 32 33 /* ---------------------------------------------------------------------------------------------- */ 34 /* Instruction definitions */ 35 /* ---------------------------------------------------------------------------------------------- */ 36 37 #ifdef ZYDIS_MINIMAL_MODE 38 # define ZYDIS_NOTMIN(x) 39 #else 40 # define ZYDIS_NOTMIN(x) , x 41 #endif 42 43 #include <Generated/InstructionDefinitions.inc> 44 45 #undef ZYDIS_NOTMIN 46 47 /* ---------------------------------------------------------------------------------------------- */ 48 /* Operand definitions */ 49 /* ---------------------------------------------------------------------------------------------- */ 50 51 #define ZYDIS_OPERAND_DEFINITION(type, encoding, access) \ 52 { type, encoding, access } 53 54 #include <Generated/OperandDefinitions.inc> 55 56 #undef ZYDIS_OPERAND_DEFINITION 57 58 /* ---------------------------------------------------------------------------------------------- */ 59 /* Accessed CPU flags */ 60 /* ---------------------------------------------------------------------------------------------- */ 61 62 #include <Generated/AccessedFlags.inc> 63 64 /* ---------------------------------------------------------------------------------------------- */ 65 66 /* ============================================================================================== */ 67 /* Functions */ 68 /* ============================================================================================== */ 69 70 /* ---------------------------------------------------------------------------------------------- */ 71 /* Instruction definition */ 72 /* ---------------------------------------------------------------------------------------------- */ 73 74 void ZydisGetInstructionDefinition(ZydisInstructionEncoding encoding, ZyanU16 id, 75 const ZydisInstructionDefinition** definition) 76 { 77 switch (encoding) 78 { 79 case ZYDIS_INSTRUCTION_ENCODING_LEGACY: 80 *definition = (ZydisInstructionDefinition*)&ISTR_DEFINITIONS_LEGACY[id]; 81 break; 82 case ZYDIS_INSTRUCTION_ENCODING_3DNOW: 83 *definition = (ZydisInstructionDefinition*)&ISTR_DEFINITIONS_3DNOW[id]; 84 break; 85 case ZYDIS_INSTRUCTION_ENCODING_XOP: 86 *definition = (ZydisInstructionDefinition*)&ISTR_DEFINITIONS_XOP[id]; 87 break; 88 case ZYDIS_INSTRUCTION_ENCODING_VEX: 89 *definition = (ZydisInstructionDefinition*)&ISTR_DEFINITIONS_VEX[id]; 90 break; 91 #ifndef ZYDIS_DISABLE_AVX512 92 case ZYDIS_INSTRUCTION_ENCODING_EVEX: 93 *definition = (ZydisInstructionDefinition*)&ISTR_DEFINITIONS_EVEX[id]; 94 break; 95 #endif 96 #ifndef ZYDIS_DISABLE_KNC 97 case ZYDIS_INSTRUCTION_ENCODING_MVEX: 98 *definition = (ZydisInstructionDefinition*)&ISTR_DEFINITIONS_MVEX[id]; 99 break; 100 #endif 101 default: 102 ZYAN_UNREACHABLE; 103 } 104 } 105 106 /* ---------------------------------------------------------------------------------------------- */ 107 /* Operand definition */ 108 /* ---------------------------------------------------------------------------------------------- */ 109 110 #ifndef ZYDIS_MINIMAL_MODE 111 const ZydisOperandDefinition* ZydisGetOperandDefinitions( 112 const ZydisInstructionDefinition* definition) 113 { 114 if (definition->operand_count == 0) 115 { 116 return ZYAN_NULL; 117 } 118 ZYAN_ASSERT(definition->operand_reference != 0xFFFF); 119 return &OPERAND_DEFINITIONS[definition->operand_reference]; 120 } 121 #endif 122 123 /* ---------------------------------------------------------------------------------------------- */ 124 /* Element info */ 125 /* ---------------------------------------------------------------------------------------------- */ 126 127 #ifndef ZYDIS_MINIMAL_MODE 128 void ZydisGetElementInfo(ZydisInternalElementType element, ZydisElementType* type, 129 ZydisElementSize* size) 130 { 131 static const struct 132 { 133 ZydisElementType type; 134 ZydisElementSize size; 135 } lookup[ZYDIS_IELEMENT_TYPE_MAX_VALUE + 1] = 136 { 137 { ZYDIS_ELEMENT_TYPE_INVALID , 0 }, 138 { ZYDIS_ELEMENT_TYPE_INVALID , 0 }, 139 { ZYDIS_ELEMENT_TYPE_STRUCT , 0 }, 140 { ZYDIS_ELEMENT_TYPE_INT , 0 }, 141 { ZYDIS_ELEMENT_TYPE_UINT , 0 }, 142 { ZYDIS_ELEMENT_TYPE_INT , 1 }, 143 { ZYDIS_ELEMENT_TYPE_INT , 8 }, 144 { ZYDIS_ELEMENT_TYPE_INT , 32 }, // TODO: Should indicate 4 INT8 elements 145 { ZYDIS_ELEMENT_TYPE_INT , 16 }, 146 { ZYDIS_ELEMENT_TYPE_INT , 32 }, // TODO: Should indicate 2 INT16 elements 147 { ZYDIS_ELEMENT_TYPE_INT , 32 }, 148 { ZYDIS_ELEMENT_TYPE_INT , 64 }, 149 { ZYDIS_ELEMENT_TYPE_UINT , 8 }, 150 { ZYDIS_ELEMENT_TYPE_UINT , 32 }, // TODO: Should indicate 4 UINT8 elements 151 { ZYDIS_ELEMENT_TYPE_UINT , 16 }, 152 { ZYDIS_ELEMENT_TYPE_UINT , 32 }, // TODO: Should indicate 2 UINT16 elements 153 { ZYDIS_ELEMENT_TYPE_UINT , 32 }, 154 { ZYDIS_ELEMENT_TYPE_UINT , 64 }, 155 { ZYDIS_ELEMENT_TYPE_UINT , 128 }, 156 { ZYDIS_ELEMENT_TYPE_UINT , 256 }, 157 { ZYDIS_ELEMENT_TYPE_FLOAT16 , 16 }, 158 { ZYDIS_ELEMENT_TYPE_FLOAT16 , 32 }, // TODO: Should indicate 2 FLOAT16 elements 159 { ZYDIS_ELEMENT_TYPE_FLOAT32 , 32 }, 160 { ZYDIS_ELEMENT_TYPE_FLOAT64 , 64 }, 161 { ZYDIS_ELEMENT_TYPE_BFLOAT16 , 32 }, // TODO: Should indicate 2 BFLOAT16 elements 162 { ZYDIS_ELEMENT_TYPE_FLOAT80 , 80 }, 163 { ZYDIS_ELEMENT_TYPE_LONGBCD , 80 }, 164 { ZYDIS_ELEMENT_TYPE_CC , 3 }, 165 { ZYDIS_ELEMENT_TYPE_CC , 5 } 166 }; 167 168 ZYAN_ASSERT((ZyanUSize)element < ZYAN_ARRAY_LENGTH(lookup)); 169 170 *type = lookup[element].type; 171 *size = lookup[element].size; 172 } 173 #endif 174 175 /* ---------------------------------------------------------------------------------------------- */ 176 /* Accessed CPU flags */ 177 /* ---------------------------------------------------------------------------------------------- */ 178 179 #ifndef ZYDIS_MINIMAL_MODE 180 ZyanBool ZydisGetAccessedFlags(const ZydisInstructionDefinition* definition, 181 const ZydisDefinitionAccessedFlags** flags) 182 { 183 ZYAN_ASSERT(definition->flags_reference < ZYAN_ARRAY_LENGTH(ACCESSED_FLAGS)); 184 *flags = &ACCESSED_FLAGS[definition->flags_reference]; 185 return (definition->flags_reference != 0); 186 } 187 #endif 188 189 /* ---------------------------------------------------------------------------------------------- */ 190 191 /* ============================================================================================== */ 192