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 
ZydisGetInstructionDefinition(ZydisInstructionEncoding encoding,ZyanU16 id,const ZydisInstructionDefinition ** definition)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
ZydisGetOperandDefinitions(const ZydisInstructionDefinition * definition,const ZydisOperandDefinition ** operand)111 ZyanU8 ZydisGetOperandDefinitions(const ZydisInstructionDefinition* definition,
112     const ZydisOperandDefinition** operand)
113 {
114     if (definition->operand_count == 0)
115     {
116         *operand = ZYAN_NULL;
117         return 0;
118     }
119     ZYAN_ASSERT(definition->operand_reference != 0xFFFF);
120     *operand = &OPERAND_DEFINITIONS[definition->operand_reference];
121     return definition->operand_count;
122 }
123 #endif
124 
125 /* ---------------------------------------------------------------------------------------------- */
126 /* Element info                                                                                   */
127 /* ---------------------------------------------------------------------------------------------- */
128 
129 #ifndef ZYDIS_MINIMAL_MODE
ZydisGetElementInfo(ZydisInternalElementType element,ZydisElementType * type,ZydisElementSize * size)130 void ZydisGetElementInfo(ZydisInternalElementType element, ZydisElementType* type,
131     ZydisElementSize* size)
132 {
133     static const struct
134     {
135         ZydisElementType type;
136         ZydisElementSize size;
137     } lookup[ZYDIS_IELEMENT_TYPE_MAX_VALUE + 1] =
138     {
139         { ZYDIS_ELEMENT_TYPE_INVALID  ,   0 },
140         { ZYDIS_ELEMENT_TYPE_INVALID  ,   0 },
141         { ZYDIS_ELEMENT_TYPE_STRUCT   ,   0 },
142         { ZYDIS_ELEMENT_TYPE_INT      ,   0 },
143         { ZYDIS_ELEMENT_TYPE_UINT     ,   0 },
144         { ZYDIS_ELEMENT_TYPE_INT      ,   1 },
145         { ZYDIS_ELEMENT_TYPE_INT      ,   8 },
146         { ZYDIS_ELEMENT_TYPE_INT      ,  16 },
147         { ZYDIS_ELEMENT_TYPE_INT      ,  32 },
148         { ZYDIS_ELEMENT_TYPE_INT      ,  64 },
149         { ZYDIS_ELEMENT_TYPE_UINT     ,   8 },
150         { ZYDIS_ELEMENT_TYPE_UINT     ,  16 },
151         { ZYDIS_ELEMENT_TYPE_UINT     ,  32 },
152         { ZYDIS_ELEMENT_TYPE_UINT     ,  64 },
153         { ZYDIS_ELEMENT_TYPE_UINT     , 128 },
154         { ZYDIS_ELEMENT_TYPE_UINT     , 256 },
155         { ZYDIS_ELEMENT_TYPE_FLOAT16  ,  16 },
156         { ZYDIS_ELEMENT_TYPE_FLOAT32  ,  32 },
157         { ZYDIS_ELEMENT_TYPE_FLOAT64  ,  64 },
158         { ZYDIS_ELEMENT_TYPE_FLOAT80  ,  80 },
159         { ZYDIS_ELEMENT_TYPE_LONGBCD  ,  80 },
160         { ZYDIS_ELEMENT_TYPE_CC       ,   3 },
161         { ZYDIS_ELEMENT_TYPE_CC       ,   5 }
162     };
163 
164     ZYAN_ASSERT(element < ZYAN_ARRAY_LENGTH(lookup));
165 
166     *type = lookup[element].type;
167     *size = lookup[element].size;
168 }
169 #endif
170 
171 /* ---------------------------------------------------------------------------------------------- */
172 /* Accessed CPU flags                                                                             */
173 /* ---------------------------------------------------------------------------------------------- */
174 
175 #ifndef ZYDIS_MINIMAL_MODE
ZydisGetAccessedFlags(const ZydisInstructionDefinition * definition,const ZydisAccessedFlags ** flags)176 ZyanBool ZydisGetAccessedFlags(const ZydisInstructionDefinition* definition,
177     const ZydisAccessedFlags** flags)
178 {
179     ZYAN_ASSERT(definition->flags_reference < ZYAN_ARRAY_LENGTH(ACCESSED_FLAGS));
180     *flags = &ACCESSED_FLAGS[definition->flags_reference];
181     return (definition->flags_reference != 0);
182 }
183 #endif
184 
185 /* ---------------------------------------------------------------------------------------------- */
186 
187 /* ============================================================================================== */
188