/src/zydis/src/DecoderData.c
Line | Count | Source (jump to first uncovered line) |
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/DecoderData.h> |
28 | | |
29 | | /* ============================================================================================== */ |
30 | | /* Data tables */ |
31 | | /* ============================================================================================== */ |
32 | | |
33 | | /* ---------------------------------------------------------------------------------------------- */ |
34 | | /* Physical instruction encodings */ |
35 | | /* ---------------------------------------------------------------------------------------------- */ |
36 | | |
37 | | #include <Generated/InstructionEncodings.inc> |
38 | | |
39 | | /* ---------------------------------------------------------------------------------------------- */ |
40 | | /* Decoder tree */ |
41 | | /* ---------------------------------------------------------------------------------------------- */ |
42 | | |
43 | | #define ZYDIS_INVALID \ |
44 | | { ZYDIS_NODETYPE_INVALID, 0x00000000 } |
45 | | #define ZYDIS_FILTER(type, id) \ |
46 | | { type, id } |
47 | | #define ZYDIS_DEFINITION(encoding_id, id) \ |
48 | | { ZYDIS_NODETYPE_DEFINITION_MASK | encoding_id, id } |
49 | | |
50 | | #include <Generated/DecoderTables.inc> |
51 | | |
52 | | #undef ZYDIS_INVALID |
53 | | #undef ZYDIS_FILTER |
54 | | #undef ZYDIS_DEFINITION |
55 | | |
56 | | /* ---------------------------------------------------------------------------------------------- */ |
57 | | |
58 | | /* ============================================================================================== */ |
59 | | /* Functions */ |
60 | | /* ============================================================================================== */ |
61 | | |
62 | | /* ---------------------------------------------------------------------------------------------- */ |
63 | | /* Decoder tree */ |
64 | | /* ---------------------------------------------------------------------------------------------- */ |
65 | | |
66 | | const ZydisDecoderTreeNode zydis_decoder_tree_root = { ZYDIS_NODETYPE_FILTER_OPCODE, 0x0000 }; |
67 | | |
68 | | const ZydisDecoderTreeNode* ZydisDecoderTreeGetChildNode(const ZydisDecoderTreeNode* parent, |
69 | | ZyanU16 index) |
70 | 0 | { |
71 | 0 | switch (parent->type) |
72 | 0 | { |
73 | 0 | case ZYDIS_NODETYPE_FILTER_XOP: |
74 | 0 | ZYAN_ASSERT(index < 13); |
75 | 0 | return &FILTERS_XOP[parent->value][index]; |
76 | 0 | case ZYDIS_NODETYPE_FILTER_VEX: |
77 | 0 | ZYAN_ASSERT(index < 17); |
78 | 0 | return &FILTERS_VEX[parent->value][index]; |
79 | 0 | case ZYDIS_NODETYPE_FILTER_EMVEX: |
80 | 0 | ZYAN_ASSERT(index < 49); |
81 | 0 | return &FILTERS_EMVEX[parent->value][index]; |
82 | 0 | case ZYDIS_NODETYPE_FILTER_REX2: |
83 | 0 | ZYAN_ASSERT(index < 3); |
84 | 0 | return &FILTERS_REX2[parent->value][index]; |
85 | 0 | case ZYDIS_NODETYPE_FILTER_OPCODE: |
86 | 0 | ZYAN_ASSERT(index < 256); |
87 | 0 | return &FILTERS_OPCODE[parent->value][index]; |
88 | 0 | case ZYDIS_NODETYPE_FILTER_MODE: |
89 | 0 | ZYAN_ASSERT(index < 4); |
90 | 0 | return &FILTERS_MODE[parent->value][index]; |
91 | 0 | case ZYDIS_NODETYPE_FILTER_MODE_COMPACT: |
92 | 0 | ZYAN_ASSERT(index < 3); |
93 | 0 | return &FILTERS_MODE_COMPACT[parent->value][index]; |
94 | 0 | case ZYDIS_NODETYPE_FILTER_MODRM_MOD: |
95 | 0 | ZYAN_ASSERT(index < 4); |
96 | 0 | return &FILTERS_MODRM_MOD[parent->value][index]; |
97 | 0 | case ZYDIS_NODETYPE_FILTER_MODRM_MOD_COMPACT: |
98 | 0 | ZYAN_ASSERT(index < 2); |
99 | 0 | return &FILTERS_MODRM_MOD_COMPACT[parent->value][index]; |
100 | 0 | case ZYDIS_NODETYPE_FILTER_MODRM_REG: |
101 | 0 | ZYAN_ASSERT(index < 8); |
102 | 0 | return &FILTERS_MODRM_REG[parent->value][index]; |
103 | 0 | case ZYDIS_NODETYPE_FILTER_MODRM_RM: |
104 | 0 | ZYAN_ASSERT(index < 8); |
105 | 0 | return &FILTERS_MODRM_RM[parent->value][index]; |
106 | 0 | case ZYDIS_NODETYPE_FILTER_PREFIX_GROUP1: |
107 | 0 | ZYAN_ASSERT(index < 2); |
108 | 0 | return &FILTERS_PREFIX_GROUP1[parent->value][index]; |
109 | 0 | case ZYDIS_NODETYPE_FILTER_MANDATORY_PREFIX: |
110 | 0 | ZYAN_ASSERT(index < 5); |
111 | 0 | return &FILTERS_MANDATORY_PREFIX[parent->value][index]; |
112 | 0 | case ZYDIS_NODETYPE_FILTER_OPERAND_SIZE: |
113 | 0 | ZYAN_ASSERT(index < 3); |
114 | 0 | return &FILTERS_OPERAND_SIZE[parent->value][index]; |
115 | 0 | case ZYDIS_NODETYPE_FILTER_ADDRESS_SIZE: |
116 | 0 | ZYAN_ASSERT(index < 3); |
117 | 0 | return &FILTERS_ADDRESS_SIZE[parent->value][index]; |
118 | 0 | case ZYDIS_NODETYPE_FILTER_VECTOR_LENGTH: |
119 | 0 | ZYAN_ASSERT(index < 3); |
120 | 0 | return &FILTERS_VECTOR_LENGTH[parent->value][index]; |
121 | 0 | case ZYDIS_NODETYPE_FILTER_REX_W: |
122 | 0 | ZYAN_ASSERT(index < 2); |
123 | 0 | return &FILTERS_REX_W[parent->value][index]; |
124 | 0 | case ZYDIS_NODETYPE_FILTER_REX_B: |
125 | 0 | ZYAN_ASSERT(index < 2); |
126 | 0 | return &FILTERS_REX_B[parent->value][index]; |
127 | 0 | #ifndef ZYDIS_DISABLE_AVX512 |
128 | 0 | case ZYDIS_NODETYPE_FILTER_EVEX_B: |
129 | 0 | ZYAN_ASSERT(index < 2); |
130 | 0 | return &FILTERS_EVEX_B[parent->value][index]; |
131 | 0 | #endif |
132 | 0 | #ifndef ZYDIS_DISABLE_KNC |
133 | 0 | case ZYDIS_NODETYPE_FILTER_MVEX_E: |
134 | 0 | ZYAN_ASSERT(index < 2); |
135 | 0 | return &FILTERS_MVEX_E[parent->value][index]; |
136 | 0 | #endif |
137 | 0 | case ZYDIS_NODETYPE_FILTER_MODE_AMD: |
138 | 0 | ZYAN_ASSERT(index < 2); |
139 | 0 | return &FILTERS_MODE_AMD[parent->value][index]; |
140 | 0 | case ZYDIS_NODETYPE_FILTER_MODE_KNC: |
141 | 0 | ZYAN_ASSERT(index < 2); |
142 | 0 | return &FILTERS_MODE_KNC[parent->value][index]; |
143 | 0 | case ZYDIS_NODETYPE_FILTER_MODE_MPX: |
144 | 0 | ZYAN_ASSERT(index < 2); |
145 | 0 | return &FILTERS_MODE_MPX[parent->value][index]; |
146 | 0 | case ZYDIS_NODETYPE_FILTER_MODE_CET: |
147 | 0 | ZYAN_ASSERT(index < 2); |
148 | 0 | return &FILTERS_MODE_CET[parent->value][index]; |
149 | 0 | case ZYDIS_NODETYPE_FILTER_MODE_LZCNT: |
150 | 0 | ZYAN_ASSERT(index < 2); |
151 | 0 | return &FILTERS_MODE_LZCNT[parent->value][index]; |
152 | 0 | case ZYDIS_NODETYPE_FILTER_MODE_TZCNT: |
153 | 0 | ZYAN_ASSERT(index < 2); |
154 | 0 | return &FILTERS_MODE_TZCNT[parent->value][index]; |
155 | 0 | case ZYDIS_NODETYPE_FILTER_MODE_WBNOINVD: |
156 | 0 | ZYAN_ASSERT(index < 2); |
157 | 0 | return &FILTERS_MODE_WBNOINVD[parent->value][index]; |
158 | 0 | case ZYDIS_NODETYPE_FILTER_MODE_CLDEMOTE: |
159 | 0 | ZYAN_ASSERT(index < 2); |
160 | 0 | return &FILTERS_MODE_CLDEMOTE[parent->value][index]; |
161 | 0 | case ZYDIS_NODETYPE_FILTER_MODE_IPREFETCH: |
162 | 0 | ZYAN_ASSERT(index < 2); |
163 | 0 | return &FILTERS_MODE_IPREFETCH[parent->value][index]; |
164 | 0 | case ZYDIS_NODETYPE_FILTER_MODE_UD0_COMPAT: |
165 | 0 | ZYAN_ASSERT(index < 2); |
166 | 0 | return &FILTERS_MODE_UD0_COMPAT[parent->value][index]; |
167 | 0 | case ZYDIS_NODETYPE_FILTER_EVEX_ND: |
168 | 0 | ZYAN_ASSERT(index < 2); |
169 | 0 | return &FILTERS_EVEX_ND[parent->value][index]; |
170 | 0 | case ZYDIS_NODETYPE_FILTER_EVEX_NF: |
171 | 0 | ZYAN_ASSERT(index < 2); |
172 | 0 | return &FILTERS_EVEX_NF[parent->value][index]; |
173 | 0 | case ZYDIS_NODETYPE_FILTER_EVEX_SCC: |
174 | 0 | ZYAN_ASSERT(index < 16); |
175 | 0 | return &FILTERS_EVEX_SCC[parent->value][index]; |
176 | 0 | case ZYDIS_NODETYPE_FILTER_REX2_PREFIX: |
177 | 0 | ZYAN_ASSERT(index < 2); |
178 | 0 | return &FILTERS_REX2_PREFIX[parent->value][index]; |
179 | 0 | case ZYDIS_NODETYPE_FILTER_EVEX_U: |
180 | 0 | ZYAN_ASSERT(index < 2); |
181 | 0 | return &FILTERS_EVEX_U[parent->value][index]; |
182 | 0 | default: |
183 | 0 | ZYAN_UNREACHABLE; |
184 | 0 | } |
185 | 0 | } |
186 | | |
187 | | void ZydisGetInstructionEncodingInfo(const ZydisDecoderTreeNode* node, |
188 | | const ZydisInstructionEncodingInfo** info) |
189 | 0 | { |
190 | 0 | ZYAN_ASSERT(node->type & ZYDIS_NODETYPE_DEFINITION_MASK); |
191 | 0 | const ZyanU8 class = (node->type) & 0x7F; |
192 | 0 | ZYAN_ASSERT(class < ZYAN_ARRAY_LENGTH(INSTR_ENCODINGS)); |
193 | 0 | *info = &INSTR_ENCODINGS[class]; |
194 | 0 | } |
195 | | |
196 | | /* ---------------------------------------------------------------------------------------------- */ |
197 | | |
198 | | /* ============================================================================================== */ |