/src/zydis/src/FormatterBase.c
Line | Count | Source |
1 | | /*************************************************************************************************** |
2 | | |
3 | | Zyan Disassembler Library (Zydis) |
4 | | |
5 | | Original Author : Florian Bernd, Joel Hoener |
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/FormatterBase.h> |
28 | | #include <Zydis/Utils.h> |
29 | | |
30 | | /* ============================================================================================== */ |
31 | | /* Constants */ |
32 | | /* ============================================================================================== */ |
33 | | |
34 | | #include <Generated/FormatterStrings.inc> |
35 | | |
36 | | static const ZydisShortString* const STR_PREF_REX[16] = |
37 | | { |
38 | | &STR_PREF_REX_40, |
39 | | &STR_PREF_REX_41, |
40 | | &STR_PREF_REX_42, |
41 | | &STR_PREF_REX_43, |
42 | | &STR_PREF_REX_44, |
43 | | &STR_PREF_REX_45, |
44 | | &STR_PREF_REX_46, |
45 | | &STR_PREF_REX_47, |
46 | | &STR_PREF_REX_48, |
47 | | &STR_PREF_REX_49, |
48 | | &STR_PREF_REX_4A, |
49 | | &STR_PREF_REX_4B, |
50 | | &STR_PREF_REX_4C, |
51 | | &STR_PREF_REX_4D, |
52 | | &STR_PREF_REX_4E, |
53 | | &STR_PREF_REX_4F |
54 | | }; |
55 | | |
56 | | static const ZydisPredefinedToken* const TOK_PREF_REX[16] = |
57 | | { |
58 | | (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_40, |
59 | | (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_41, |
60 | | (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_42, |
61 | | (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_43, |
62 | | (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_44, |
63 | | (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_45, |
64 | | (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_46, |
65 | | (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_47, |
66 | | (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_48, |
67 | | (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_49, |
68 | | (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_4A, |
69 | | (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_4B, |
70 | | (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_4C, |
71 | | (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_4D, |
72 | | (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_4E, |
73 | | (const ZydisPredefinedToken* const)&TOK_DATA_PREF_REX_4F |
74 | | }; |
75 | | |
76 | | /* ============================================================================================== */ |
77 | | /* Helper functions */ |
78 | | /* ============================================================================================== */ |
79 | | |
80 | | ZyanU32 ZydisFormatterHelperGetExplicitSize(const ZydisFormatter* formatter, |
81 | | ZydisFormatterContext* context, const ZydisDecodedOperand* operand) |
82 | 3.57k | { |
83 | 3.57k | ZYAN_ASSERT(formatter); |
84 | 3.57k | ZYAN_ASSERT(context); |
85 | 3.57k | ZYAN_ASSERT(operand); |
86 | | |
87 | 3.57k | ZYAN_ASSERT(operand->type == ZYDIS_OPERAND_TYPE_MEMORY); |
88 | 3.57k | ZYAN_ASSERT((operand->mem.type == ZYDIS_MEMOP_TYPE_MEM) || |
89 | 3.57k | (operand->mem.type == ZYDIS_MEMOP_TYPE_AGEN) || |
90 | 3.57k | (operand->mem.type == ZYDIS_MEMOP_TYPE_VSIB)); |
91 | | |
92 | 3.57k | if (formatter->force_memory_size) |
93 | 2.85k | { |
94 | 2.85k | return operand->size; |
95 | 2.85k | } |
96 | 725 | else if (operand->mem.type == ZYDIS_MEMOP_TYPE_AGEN) |
97 | 13 | { |
98 | 13 | return 0; |
99 | 13 | } |
100 | | |
101 | 712 | if (!context->operands) |
102 | 193 | { |
103 | | // Single operand formatting. We can not derive the explicit size by using the other |
104 | | // operands. |
105 | 193 | return 0; |
106 | 193 | } |
107 | | |
108 | 519 | switch (operand->id) |
109 | 519 | { |
110 | 374 | case 0: |
111 | 374 | if (context->instruction->operand_count_visible < 2) |
112 | 77 | { |
113 | 77 | return 0; |
114 | 77 | } |
115 | 297 | if ((context->operands[1].type == ZYDIS_OPERAND_TYPE_UNUSED) || |
116 | 297 | (context->operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)) |
117 | 39 | { |
118 | 39 | return context->operands[0].size; |
119 | 39 | } |
120 | 258 | if (context->operands[0].size != context->operands[1].size) |
121 | 7 | { |
122 | 7 | return context->operands[0].size; |
123 | 7 | } |
124 | 251 | if ((context->operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER) && |
125 | 251 | (context->operands[1].visibility == ZYDIS_OPERAND_VISIBILITY_IMPLICIT) && |
126 | 47 | (context->operands[1].reg.value == ZYDIS_REGISTER_CL)) |
127 | 11 | { |
128 | 11 | return context->operands[0].size; |
129 | 11 | } |
130 | 240 | break; |
131 | 240 | case 1: |
132 | 122 | case 2: |
133 | 122 | if (context->operands[operand->id - 1].size != |
134 | 122 | context->operands[operand->id].size) |
135 | 39 | { |
136 | 39 | return context->operands[operand->id].size; |
137 | 39 | } |
138 | 83 | break; |
139 | 83 | default: |
140 | 23 | break; |
141 | 519 | } |
142 | | |
143 | 346 | return 0; |
144 | 519 | } |
145 | | |
146 | | /* ============================================================================================== */ |
147 | | /* Formatter functions */ |
148 | | /* ============================================================================================== */ |
149 | | |
150 | | /* ---------------------------------------------------------------------------------------------- */ |
151 | | /* Operands */ |
152 | | /* ---------------------------------------------------------------------------------------------- */ |
153 | | |
154 | | ZyanStatus ZydisFormatterBaseFormatOperandREG(const ZydisFormatter* formatter, |
155 | | ZydisFormatterBuffer* buffer, ZydisFormatterContext* context) |
156 | 4.55k | { |
157 | 4.55k | ZYAN_ASSERT(formatter); |
158 | 4.55k | ZYAN_ASSERT(buffer); |
159 | 4.55k | ZYAN_ASSERT(context); |
160 | | |
161 | 4.55k | return formatter->func_print_register(formatter, buffer, context, context->operand->reg.value); |
162 | 4.55k | } |
163 | | |
164 | | ZyanStatus ZydisFormatterBaseFormatOperandPTR(const ZydisFormatter* formatter, |
165 | | ZydisFormatterBuffer* buffer, ZydisFormatterContext* context) |
166 | 143 | { |
167 | 143 | ZYAN_ASSERT(formatter); |
168 | 143 | ZYAN_ASSERT(buffer); |
169 | 143 | ZYAN_ASSERT(context); |
170 | | |
171 | 143 | ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_IMMEDIATE); |
172 | 140 | ZYDIS_STRING_APPEND_NUM_U(formatter, formatter->addr_base, &buffer->string, |
173 | 140 | context->operand->ptr.segment, 4, formatter->hex_force_leading_number); |
174 | 109 | ZYDIS_BUFFER_APPEND(buffer, DELIM_SEGMENT); |
175 | | |
176 | 104 | ZyanU8 padding; |
177 | 104 | switch (context->instruction->operand_width) |
178 | 104 | { |
179 | 94 | case 16: |
180 | 94 | padding = 4; |
181 | 94 | break; |
182 | 10 | case 32: |
183 | 10 | padding = 8; |
184 | 10 | break; |
185 | 0 | default: |
186 | 0 | return ZYAN_STATUS_INVALID_ARGUMENT; |
187 | 104 | } |
188 | | |
189 | 104 | ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_IMMEDIATE); |
190 | 99 | ZYDIS_STRING_APPEND_NUM_U(formatter, formatter->addr_base, &buffer->string, |
191 | 99 | context->operand->ptr.offset , padding, formatter->hex_force_leading_number); |
192 | | |
193 | 65 | return ZYAN_STATUS_SUCCESS; |
194 | 99 | } |
195 | | |
196 | | ZyanStatus ZydisFormatterBaseFormatOperandIMM(const ZydisFormatter* formatter, |
197 | | ZydisFormatterBuffer* buffer, ZydisFormatterContext* context) |
198 | 2.81k | { |
199 | 2.81k | ZYAN_ASSERT(formatter); |
200 | 2.81k | ZYAN_ASSERT(buffer); |
201 | 2.81k | ZYAN_ASSERT(context); |
202 | | |
203 | | // The immediate operand contains an address |
204 | 2.81k | if (context->operand->imm.is_address) |
205 | 1.84k | { |
206 | 1.84k | const ZyanBool absolute = !context->operand->imm.is_relative || |
207 | 1.82k | (!formatter->force_relative_branches && |
208 | 1.08k | (context->runtime_address != ZYDIS_RUNTIME_ADDRESS_NONE)); |
209 | 1.84k | if (absolute) |
210 | 1.07k | { |
211 | 1.07k | return formatter->func_print_address_abs(formatter, buffer, context); |
212 | 1.07k | } |
213 | 768 | return formatter->func_print_address_rel(formatter, buffer, context); |
214 | 1.84k | } |
215 | | |
216 | | // The immediate operand contains an actual ordinal value |
217 | 969 | return formatter->func_print_imm(formatter, buffer, context); |
218 | 2.81k | } |
219 | | |
220 | | /* ---------------------------------------------------------------------------------------------- */ |
221 | | /* Elemental tokens */ |
222 | | /* ---------------------------------------------------------------------------------------------- */ |
223 | | |
224 | | ZyanStatus ZydisFormatterBasePrintAddressABS(const ZydisFormatter* formatter, |
225 | | ZydisFormatterBuffer* buffer, ZydisFormatterContext* context) |
226 | 1.03k | { |
227 | 1.03k | ZYAN_ASSERT(formatter); |
228 | 1.03k | ZYAN_ASSERT(buffer); |
229 | 1.03k | ZYAN_ASSERT(context); |
230 | | |
231 | 1.03k | ZyanU64 address; |
232 | 1.03k | ZYAN_CHECK(ZydisCalcAbsoluteAddress(context->instruction, context->operand, |
233 | 1.03k | context->runtime_address, &address)); |
234 | 1.03k | ZyanU8 padding = (formatter->addr_padding_absolute == |
235 | 1.03k | ZYDIS_PADDING_AUTO) ? 0 : (ZyanU8)formatter->addr_padding_absolute; |
236 | 1.03k | if ((formatter->addr_padding_absolute == ZYDIS_PADDING_AUTO) && |
237 | 276 | (formatter->addr_base == ZYDIS_NUMERIC_BASE_HEX)) |
238 | 220 | { |
239 | 220 | switch (context->instruction->address_width) |
240 | 220 | { |
241 | 28 | case 16: |
242 | 28 | padding = 4; |
243 | 28 | address = (ZyanU16)address; |
244 | 28 | break; |
245 | 80 | case 32: |
246 | 80 | padding = 8; |
247 | 80 | address = (ZyanU32)address; |
248 | 80 | break; |
249 | 112 | case 64: |
250 | 112 | padding = 16; |
251 | 112 | break; |
252 | 0 | default: |
253 | 0 | return ZYAN_STATUS_INVALID_ARGUMENT; |
254 | 220 | } |
255 | 220 | } |
256 | | |
257 | 1.03k | ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_ADDRESS_ABS); |
258 | 1.01k | ZYDIS_STRING_APPEND_NUM_U(formatter, formatter->addr_base, &buffer->string, address, padding, |
259 | 1.01k | formatter->hex_force_leading_number); |
260 | | |
261 | 647 | return ZYAN_STATUS_SUCCESS; |
262 | 1.01k | } |
263 | | |
264 | | ZyanStatus ZydisFormatterBasePrintAddressREL(const ZydisFormatter* formatter, |
265 | | ZydisFormatterBuffer* buffer, ZydisFormatterContext* context) |
266 | 530 | { |
267 | 530 | ZYAN_ASSERT(formatter); |
268 | 530 | ZYAN_ASSERT(buffer); |
269 | 530 | ZYAN_ASSERT(context); |
270 | | |
271 | 530 | ZyanU64 address; |
272 | 530 | ZYAN_CHECK(ZydisCalcAbsoluteAddress(context->instruction, context->operand, 0, &address)); |
273 | | |
274 | 530 | ZyanU8 padding = (formatter->addr_padding_relative == |
275 | 530 | ZYDIS_PADDING_AUTO) ? 0 : (ZyanU8)formatter->addr_padding_relative; |
276 | 530 | if ((formatter->addr_padding_relative == ZYDIS_PADDING_AUTO) && |
277 | 137 | (formatter->addr_base == ZYDIS_NUMERIC_BASE_HEX)) |
278 | 107 | { |
279 | 107 | switch (context->instruction->address_width) |
280 | 107 | { |
281 | 36 | case 16: |
282 | 36 | padding = 4; |
283 | 36 | address = (ZyanU16)address; |
284 | 36 | break; |
285 | 41 | case 32: |
286 | 41 | padding = 8; |
287 | 41 | address = (ZyanU32)address; |
288 | 41 | break; |
289 | 30 | case 64: |
290 | 30 | padding = 16; |
291 | 30 | break; |
292 | 0 | default: |
293 | 0 | return ZYAN_STATUS_INVALID_ARGUMENT; |
294 | 107 | } |
295 | 107 | } |
296 | | |
297 | 530 | ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_ADDRESS_REL); |
298 | 526 | switch (formatter->addr_signedness) |
299 | 526 | { |
300 | 345 | case ZYDIS_SIGNEDNESS_AUTO: |
301 | 400 | case ZYDIS_SIGNEDNESS_SIGNED: |
302 | 400 | ZYDIS_STRING_APPEND_NUM_S(formatter, formatter->addr_base, &buffer->string, address, |
303 | 400 | padding, formatter->hex_force_leading_number, ZYAN_TRUE); |
304 | 226 | break; |
305 | 126 | case ZYDIS_SIGNEDNESS_UNSIGNED: |
306 | 126 | ZYAN_CHECK(ZydisStringAppendShort(&buffer->string, &STR_ADD)); |
307 | 118 | ZYDIS_STRING_APPEND_NUM_U(formatter, formatter->addr_base, &buffer->string, address, |
308 | 118 | padding, formatter->hex_force_leading_number); |
309 | 70 | break; |
310 | 0 | default: |
311 | 0 | return ZYAN_STATUS_INVALID_ARGUMENT; |
312 | 526 | } |
313 | | |
314 | 296 | return ZYAN_STATUS_SUCCESS; |
315 | 526 | } |
316 | | |
317 | | ZyanStatus ZydisFormatterBasePrintIMM(const ZydisFormatter* formatter, |
318 | | ZydisFormatterBuffer* buffer, ZydisFormatterContext* context) |
319 | 954 | { |
320 | 954 | ZYAN_ASSERT(formatter); |
321 | 954 | ZYAN_ASSERT(buffer); |
322 | 954 | ZYAN_ASSERT(context); |
323 | | |
324 | 954 | ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_IMMEDIATE); |
325 | | |
326 | 948 | const ZyanBool is_signed = |
327 | 948 | (formatter->imm_signedness == ZYDIS_SIGNEDNESS_SIGNED) || |
328 | 839 | (formatter->imm_signedness == ZYDIS_SIGNEDNESS_AUTO && (context->operand->imm.is_signed)); |
329 | 948 | if (is_signed && (context->operand->imm.value.s < 0)) |
330 | 517 | { |
331 | 517 | ZYDIS_STRING_APPEND_NUM_S(formatter, formatter->imm_base, &buffer->string, |
332 | 517 | context->operand->imm.value.s, formatter->imm_padding, |
333 | 517 | formatter->hex_force_leading_number, ZYAN_FALSE); |
334 | 373 | return ZYAN_STATUS_SUCCESS; |
335 | 517 | } |
336 | 431 | ZyanU64 value; |
337 | 431 | ZyanU8 padding = (formatter->imm_padding == |
338 | 431 | ZYDIS_PADDING_AUTO) ? 0 : (ZyanU8)formatter->imm_padding; |
339 | 431 | switch (context->instruction->operand_width) |
340 | 431 | { |
341 | 153 | case 8: |
342 | 153 | if (formatter->imm_padding == ZYDIS_PADDING_AUTO) |
343 | 27 | { |
344 | 27 | padding = 2; |
345 | 27 | } |
346 | 153 | value = (ZyanU8 )context->operand->imm.value.u; |
347 | 153 | break; |
348 | 90 | case 16: |
349 | 90 | if (formatter->imm_padding == ZYDIS_PADDING_AUTO) |
350 | 25 | { |
351 | 25 | padding = 4; |
352 | 25 | } |
353 | 90 | value = (ZyanU16)context->operand->imm.value.u; |
354 | 90 | break; |
355 | 142 | case 32: |
356 | 142 | if (formatter->imm_padding == ZYDIS_PADDING_AUTO) |
357 | 14 | { |
358 | 14 | padding = 8; |
359 | 14 | } |
360 | 142 | value = (ZyanU32)context->operand->imm.value.u; |
361 | 142 | break; |
362 | 46 | case 64: |
363 | 46 | if (formatter->imm_padding == ZYDIS_PADDING_AUTO) |
364 | 20 | { |
365 | 20 | padding = 16; |
366 | 20 | } |
367 | 46 | value = (ZyanU64)context->operand->imm.value.u; |
368 | 46 | break; |
369 | 0 | default: |
370 | 0 | return ZYAN_STATUS_INVALID_ARGUMENT; |
371 | 431 | } |
372 | 431 | ZYDIS_STRING_APPEND_NUM_U(formatter, formatter->imm_base, &buffer->string, value, padding, |
373 | 431 | formatter->hex_force_leading_number); |
374 | | |
375 | 335 | return ZYAN_STATUS_SUCCESS; |
376 | 431 | } |
377 | | |
378 | | /* ---------------------------------------------------------------------------------------------- */ |
379 | | /* Optional tokens */ |
380 | | /* ---------------------------------------------------------------------------------------------- */ |
381 | | |
382 | | ZyanStatus ZydisFormatterBasePrintSegment(const ZydisFormatter* formatter, |
383 | | ZydisFormatterBuffer* buffer, ZydisFormatterContext* context) |
384 | 4.27k | { |
385 | 4.27k | ZYAN_ASSERT(formatter); |
386 | 4.27k | ZYAN_ASSERT(buffer); |
387 | 4.27k | ZYAN_ASSERT(context); |
388 | | |
389 | 4.27k | ZyanBool printed_segment = ZYAN_FALSE; |
390 | 4.27k | switch (context->operand->mem.segment) |
391 | 4.27k | { |
392 | 14 | case ZYDIS_REGISTER_ES: |
393 | 26 | case ZYDIS_REGISTER_CS: |
394 | 46 | case ZYDIS_REGISTER_FS: |
395 | 62 | case ZYDIS_REGISTER_GS: |
396 | 62 | ZYAN_CHECK(formatter->func_print_register(formatter, buffer, context, |
397 | 62 | context->operand->mem.segment)); |
398 | 49 | printed_segment = ZYAN_TRUE; |
399 | 49 | break; |
400 | 474 | case ZYDIS_REGISTER_SS: |
401 | 474 | if ((formatter->force_memory_segment) || |
402 | 171 | (context->instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_SS)) |
403 | 313 | { |
404 | 313 | ZYAN_CHECK(formatter->func_print_register(formatter, buffer, context, |
405 | 313 | context->operand->mem.segment)); |
406 | 296 | printed_segment = ZYAN_TRUE; |
407 | 296 | } |
408 | 457 | break; |
409 | 3.73k | case ZYDIS_REGISTER_DS: |
410 | 3.73k | if ((formatter->force_memory_segment) || |
411 | 1.02k | (context->instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_DS)) |
412 | 2.71k | { |
413 | 2.71k | ZYAN_CHECK(formatter->func_print_register(formatter, buffer, context, |
414 | 2.71k | context->operand->mem.segment)); |
415 | 2.63k | printed_segment = ZYAN_TRUE; |
416 | 2.63k | } |
417 | 3.65k | break; |
418 | 3.65k | default: |
419 | 0 | break; |
420 | 4.27k | } |
421 | 4.15k | if (printed_segment) |
422 | 2.98k | { |
423 | 2.98k | ZYDIS_BUFFER_APPEND(buffer, DELIM_SEGMENT); |
424 | 2.91k | } |
425 | | |
426 | 4.08k | return ZYAN_STATUS_SUCCESS; |
427 | 4.15k | } |
428 | | |
429 | | ZyanStatus ZydisFormatterBasePrintPrefixes(const ZydisFormatter* formatter, |
430 | | ZydisFormatterBuffer* buffer, ZydisFormatterContext* context) |
431 | 5.80k | { |
432 | 5.80k | ZYAN_ASSERT(formatter); |
433 | 5.80k | ZYAN_ASSERT(buffer); |
434 | 5.80k | ZYAN_ASSERT(context); |
435 | | |
436 | 5.80k | if (formatter->detailed_prefixes) |
437 | 3.77k | { |
438 | 5.36k | for (ZyanU8 i = 0; i < context->instruction->raw.prefix_count; ++i) |
439 | 1.65k | { |
440 | 1.65k | const ZyanU8 value = context->instruction->raw.prefixes[i].value; |
441 | 1.65k | switch (context->instruction->raw.prefixes[i].type) |
442 | 1.65k | { |
443 | 1.16k | case ZYDIS_PREFIX_TYPE_IGNORED: |
444 | 1.19k | case ZYDIS_PREFIX_TYPE_MANDATORY: |
445 | 1.19k | { |
446 | 1.19k | if ((value & 0xF0) == 0x40) |
447 | 435 | { |
448 | 435 | if (buffer->is_token_list) |
449 | 216 | { |
450 | | // TODO: Case |
451 | 216 | ZYAN_CHECK(ZydisFormatterBufferAppendPredefined(buffer, |
452 | 216 | TOK_PREF_REX[value & 0x0F])); |
453 | 216 | } else |
454 | 219 | { |
455 | 219 | ZYAN_CHECK(ZydisStringAppendShortCase(&buffer->string, |
456 | 219 | STR_PREF_REX[value & 0x0F], formatter->case_prefixes)); |
457 | 219 | } |
458 | 435 | } else |
459 | 755 | { |
460 | 755 | switch (value) |
461 | 755 | { |
462 | 102 | case 0xF0: |
463 | 102 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_LOCK, formatter->case_prefixes); |
464 | 98 | break; |
465 | 81 | case 0x2E: |
466 | 81 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_CS, formatter->case_prefixes); |
467 | 77 | break; |
468 | 61 | case 0x36: |
469 | 61 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_SS, formatter->case_prefixes); |
470 | 56 | break; |
471 | 43 | case 0x3E: |
472 | 43 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_DS, formatter->case_prefixes); |
473 | 40 | break; |
474 | 96 | case 0x26: |
475 | 96 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_ES, formatter->case_prefixes); |
476 | 89 | break; |
477 | 78 | case 0x64: |
478 | 78 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_FS, formatter->case_prefixes); |
479 | 73 | break; |
480 | 62 | case 0x65: |
481 | 62 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_SEG_GS, formatter->case_prefixes); |
482 | 57 | break; |
483 | 232 | default: |
484 | 232 | ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_PREFIX); |
485 | 229 | ZYAN_CHECK(ZydisStringAppendHexU(&buffer->string, value, 0, |
486 | 229 | formatter->hex_force_leading_number, formatter->hex_uppercase, |
487 | 229 | ZYAN_NULL, ZYAN_NULL)); |
488 | 224 | ZYDIS_BUFFER_APPEND_TOKEN(buffer, ZYDIS_TOKEN_WHITESPACE); |
489 | 221 | ZYAN_CHECK(ZydisStringAppendShort(&buffer->string, &STR_WHITESPACE)); |
490 | 214 | break; |
491 | 755 | } |
492 | 755 | } |
493 | 1.13k | break; |
494 | 1.19k | } |
495 | 1.13k | case ZYDIS_PREFIX_TYPE_EFFECTIVE: |
496 | 469 | switch (value) |
497 | 469 | { |
498 | 76 | case 0xF0: |
499 | 76 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_LOCK, formatter->case_prefixes); |
500 | 69 | break; |
501 | 72 | case 0xF2: |
502 | 72 | if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_XACQUIRE) |
503 | 29 | { |
504 | 29 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_XACQUIRE, formatter->case_prefixes); |
505 | 26 | } |
506 | 69 | if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_REPNE) |
507 | 0 | { |
508 | 0 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_REPNE, formatter->case_prefixes); |
509 | 0 | } |
510 | | |
511 | 69 | if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_BND) |
512 | 43 | { |
513 | 43 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_BND, formatter->case_prefixes); |
514 | 37 | } |
515 | 63 | break; |
516 | 63 | case 0xF3: |
517 | 35 | if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_XRELEASE) |
518 | 35 | { |
519 | 35 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_XRELEASE, formatter->case_prefixes); |
520 | 32 | } |
521 | 32 | if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_REP) |
522 | 0 | { |
523 | 0 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_REP, formatter->case_prefixes); |
524 | 0 | } |
525 | 32 | if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_REPE) |
526 | 0 | { |
527 | 0 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_REPE, formatter->case_prefixes); |
528 | 0 | } |
529 | 32 | break; |
530 | 286 | default: |
531 | 286 | break; |
532 | 469 | } |
533 | 450 | break; |
534 | 450 | default: |
535 | 0 | return ZYAN_STATUS_INVALID_ARGUMENT; |
536 | 1.65k | } |
537 | 1.65k | } |
538 | 3.70k | return ZYAN_STATUS_SUCCESS; |
539 | 3.77k | } |
540 | | |
541 | 2.02k | if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_XACQUIRE) |
542 | 31 | { |
543 | 31 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_XACQUIRE, formatter->case_prefixes); |
544 | 28 | } |
545 | 2.02k | if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_XRELEASE) |
546 | 25 | { |
547 | 25 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_XRELEASE, formatter->case_prefixes); |
548 | 21 | } |
549 | | |
550 | 2.02k | if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_LOCK) |
551 | 40 | { |
552 | 40 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_LOCK, formatter->case_prefixes); |
553 | 35 | } |
554 | | |
555 | 2.01k | if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_BND) |
556 | 31 | { |
557 | 31 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_BND, formatter->case_prefixes); |
558 | 29 | } |
559 | | |
560 | 2.01k | if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_NOTRACK) |
561 | 36 | { |
562 | 36 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_NOTRACK, formatter->case_prefixes); |
563 | 31 | } |
564 | | |
565 | 2.00k | if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_REP) |
566 | 34 | { |
567 | 34 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_REP, formatter->case_prefixes); |
568 | 31 | return ZYAN_STATUS_SUCCESS; |
569 | 34 | } |
570 | 1.97k | if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_REPE) |
571 | 8 | { |
572 | 8 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_REPE, formatter->case_prefixes); |
573 | 4 | return ZYAN_STATUS_SUCCESS; |
574 | 8 | } |
575 | 1.96k | if (context->instruction->attributes & ZYDIS_ATTRIB_HAS_REPNE) |
576 | 5 | { |
577 | 5 | ZYDIS_BUFFER_APPEND_CASE(buffer, PREF_REPNE, formatter->case_prefixes); |
578 | 3 | return ZYAN_STATUS_SUCCESS; |
579 | 5 | } |
580 | | |
581 | 1.96k | return ZYAN_STATUS_SUCCESS; |
582 | 1.96k | } |
583 | | |
584 | | ZyanStatus ZydisFormatterBasePrintDecorator(const ZydisFormatter* formatter, |
585 | | ZydisFormatterBuffer* buffer, ZydisFormatterContext* context, ZydisDecorator decorator) |
586 | 6.12k | { |
587 | 6.12k | ZYAN_ASSERT(formatter); |
588 | 6.12k | ZYAN_ASSERT(buffer); |
589 | 6.12k | ZYAN_ASSERT(context); |
590 | | |
591 | | #if defined(ZYDIS_DISABLE_AVX512) && defined(ZYDIS_DISABLE_KNC) |
592 | | ZYAN_UNUSED(formatter); |
593 | | ZYAN_UNUSED(buffer); |
594 | | ZYAN_UNUSED(context); |
595 | | #endif |
596 | | |
597 | 6.12k | switch (decorator) |
598 | 6.12k | { |
599 | 254 | case ZYDIS_DECORATOR_MASK: |
600 | 254 | { |
601 | 254 | #if !defined(ZYDIS_DISABLE_AVX512) || !defined(ZYDIS_DISABLE_KNC) |
602 | 254 | if (context->instruction->avx.mask.reg != ZYDIS_REGISTER_K0) |
603 | 228 | { |
604 | 228 | if (buffer->is_token_list) |
605 | 94 | { |
606 | 94 | ZYDIS_BUFFER_APPEND(buffer, DECO_BEGIN); |
607 | 85 | ZYAN_CHECK(formatter->func_print_register(formatter, buffer, context, |
608 | 85 | context->instruction->avx.mask.reg)); |
609 | 74 | ZYDIS_BUFFER_APPEND(buffer, DECO_END); |
610 | 68 | } else |
611 | 134 | { |
612 | 134 | ZYAN_CHECK(ZydisStringAppendShort(&buffer->string, &STR_DECO_BEGIN)); |
613 | 129 | ZYAN_CHECK(formatter->func_print_register(formatter, buffer, context, |
614 | 129 | context->instruction->avx.mask.reg)); |
615 | 119 | ZYAN_CHECK(ZydisStringAppendShort(&buffer->string, &STR_DECO_END)); |
616 | 119 | } |
617 | | |
618 | | // Only print the zeroing decorator, if the instruction is not a "zeroing masking only" |
619 | | // instruction (e.g. `vcmpsd`) |
620 | 184 | if ((context->instruction->avx.mask.mode == ZYDIS_MASK_MODE_ZEROING || |
621 | 140 | context->instruction->avx.mask.mode == ZYDIS_MASK_MODE_CONTROL_ZEROING) && |
622 | 47 | (context->instruction->raw.evex.z)) |
623 | 42 | { |
624 | 42 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_ZERO, formatter->case_decorators); |
625 | 37 | } |
626 | 184 | } |
627 | 205 | #endif |
628 | 205 | break; |
629 | 254 | } |
630 | 241 | case ZYDIS_DECORATOR_BC: |
631 | 241 | #if !defined(ZYDIS_DISABLE_AVX512) |
632 | 241 | if (!context->instruction->avx.broadcast.is_static) |
633 | 219 | { |
634 | 219 | switch (context->instruction->avx.broadcast.mode) |
635 | 219 | { |
636 | 152 | case ZYDIS_BROADCAST_MODE_NONE: |
637 | 152 | break; |
638 | 9 | case ZYDIS_BROADCAST_MODE_1_TO_2: |
639 | 9 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO2, formatter->case_decorators); |
640 | 7 | break; |
641 | 6 | case ZYDIS_BROADCAST_MODE_1_TO_4: |
642 | 6 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO4, formatter->case_decorators); |
643 | 4 | break; |
644 | 19 | case ZYDIS_BROADCAST_MODE_1_TO_8: |
645 | 19 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO8, formatter->case_decorators); |
646 | 12 | break; |
647 | 11 | case ZYDIS_BROADCAST_MODE_1_TO_16: |
648 | 11 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO16, formatter->case_decorators); |
649 | 7 | break; |
650 | 7 | case ZYDIS_BROADCAST_MODE_1_TO_32: |
651 | 7 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO32, formatter->case_decorators); |
652 | 5 | break; |
653 | 0 | case ZYDIS_BROADCAST_MODE_1_TO_64: |
654 | 0 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_1TO64, formatter->case_decorators); |
655 | 0 | break; |
656 | 8 | case ZYDIS_BROADCAST_MODE_4_TO_8: |
657 | 8 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_4TO8, formatter->case_decorators); |
658 | 6 | break; |
659 | 7 | case ZYDIS_BROADCAST_MODE_4_TO_16: |
660 | 7 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_4TO16, formatter->case_decorators); |
661 | 5 | break; |
662 | 0 | case ZYDIS_BROADCAST_MODE_8_TO_16: |
663 | 0 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_8TO16, formatter->case_decorators); |
664 | 0 | break; |
665 | 0 | default: |
666 | 0 | return ZYAN_STATUS_INVALID_ARGUMENT; |
667 | 219 | } |
668 | 219 | } |
669 | 220 | #endif |
670 | 220 | break; |
671 | 220 | case ZYDIS_DECORATOR_RC: |
672 | 171 | #if !defined(ZYDIS_DISABLE_AVX512) |
673 | 171 | if (context->instruction->avx.has_sae) |
674 | 36 | { |
675 | 36 | switch (context->instruction->avx.rounding.mode) |
676 | 36 | { |
677 | 7 | case ZYDIS_ROUNDING_MODE_NONE: |
678 | 7 | break; |
679 | 6 | case ZYDIS_ROUNDING_MODE_RN: |
680 | 6 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RN_SAE, formatter->case_decorators); |
681 | 3 | break; |
682 | 8 | case ZYDIS_ROUNDING_MODE_RD: |
683 | 8 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RD_SAE, formatter->case_decorators); |
684 | 5 | break; |
685 | 10 | case ZYDIS_ROUNDING_MODE_RU: |
686 | 10 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RU_SAE, formatter->case_decorators); |
687 | 7 | break; |
688 | 5 | case ZYDIS_ROUNDING_MODE_RZ: |
689 | 5 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RZ_SAE, formatter->case_decorators); |
690 | 3 | break; |
691 | 0 | default: |
692 | 0 | return ZYAN_STATUS_INVALID_ARGUMENT; |
693 | 36 | } |
694 | 36 | } else |
695 | 135 | { |
696 | 135 | switch (context->instruction->avx.rounding.mode) |
697 | 135 | { |
698 | 115 | case ZYDIS_ROUNDING_MODE_NONE: |
699 | 115 | break; |
700 | 5 | case ZYDIS_ROUNDING_MODE_RN: |
701 | 5 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RN, formatter->case_decorators); |
702 | 3 | break; |
703 | 5 | case ZYDIS_ROUNDING_MODE_RD: |
704 | 5 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RD, formatter->case_decorators); |
705 | 3 | break; |
706 | 5 | case ZYDIS_ROUNDING_MODE_RU: |
707 | 5 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RU, formatter->case_decorators); |
708 | 3 | break; |
709 | 5 | case ZYDIS_ROUNDING_MODE_RZ: |
710 | 5 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_RZ, formatter->case_decorators); |
711 | 3 | break; |
712 | 0 | default: |
713 | 0 | return ZYAN_STATUS_INVALID_ARGUMENT; |
714 | 135 | } |
715 | 135 | } |
716 | 152 | #endif |
717 | 152 | break; |
718 | 152 | case ZYDIS_DECORATOR_SAE: |
719 | 152 | #if !defined(ZYDIS_DISABLE_AVX512) |
720 | 152 | if (context->instruction->avx.has_sae && !context->instruction->avx.rounding.mode) |
721 | 7 | { |
722 | 7 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_SAE, formatter->case_decorators); |
723 | 5 | } |
724 | 150 | #endif |
725 | 150 | break; |
726 | 150 | case ZYDIS_DECORATOR_SWIZZLE: |
727 | 102 | #if !defined(ZYDIS_DISABLE_KNC) |
728 | 102 | switch (context->instruction->avx.swizzle.mode) |
729 | 102 | { |
730 | 57 | case ZYDIS_SWIZZLE_MODE_NONE: |
731 | 60 | case ZYDIS_SWIZZLE_MODE_DCBA: |
732 | | // Nothing to do here |
733 | 60 | break; |
734 | 5 | case ZYDIS_SWIZZLE_MODE_CDAB: |
735 | 5 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_CDAB, formatter->case_decorators); |
736 | 3 | break; |
737 | 7 | case ZYDIS_SWIZZLE_MODE_BADC: |
738 | 7 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_BADC, formatter->case_decorators); |
739 | 5 | break; |
740 | 5 | case ZYDIS_SWIZZLE_MODE_DACB: |
741 | 5 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DACB, formatter->case_decorators); |
742 | 3 | break; |
743 | 5 | case ZYDIS_SWIZZLE_MODE_AAAA: |
744 | 5 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_AAAA, formatter->case_decorators); |
745 | 3 | break; |
746 | 7 | case ZYDIS_SWIZZLE_MODE_BBBB: |
747 | 7 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_BBBB, formatter->case_decorators); |
748 | 4 | break; |
749 | 7 | case ZYDIS_SWIZZLE_MODE_CCCC: |
750 | 7 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_CCCC, formatter->case_decorators); |
751 | 4 | break; |
752 | 6 | case ZYDIS_SWIZZLE_MODE_DDDD: |
753 | 6 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DDDD, formatter->case_decorators); |
754 | 4 | break; |
755 | 0 | default: |
756 | 0 | return ZYAN_STATUS_INVALID_ARGUMENT; |
757 | 102 | } |
758 | 86 | #endif |
759 | 86 | break; |
760 | 94 | case ZYDIS_DECORATOR_CONVERSION: |
761 | 94 | #if !defined(ZYDIS_DISABLE_KNC) |
762 | 94 | switch (context->instruction->avx.conversion.mode) |
763 | 94 | { |
764 | 41 | case ZYDIS_CONVERSION_MODE_NONE: |
765 | 41 | break; |
766 | 11 | case ZYDIS_CONVERSION_MODE_FLOAT16: |
767 | 11 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_FLOAT16, formatter->case_decorators); |
768 | 7 | break; |
769 | 9 | case ZYDIS_CONVERSION_MODE_SINT8: |
770 | 9 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_SINT8, formatter->case_decorators); |
771 | 6 | break; |
772 | 11 | case ZYDIS_CONVERSION_MODE_UINT8: |
773 | 11 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_UINT8, formatter->case_decorators); |
774 | 9 | break; |
775 | 11 | case ZYDIS_CONVERSION_MODE_SINT16: |
776 | 11 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_SINT16, formatter->case_decorators); |
777 | 6 | break; |
778 | 11 | case ZYDIS_CONVERSION_MODE_UINT16: |
779 | 11 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_UINT16, formatter->case_decorators); |
780 | 8 | break; |
781 | 0 | default: |
782 | 0 | return ZYAN_STATUS_INVALID_ARGUMENT; |
783 | 94 | } |
784 | 77 | #endif |
785 | 77 | break; |
786 | 77 | case ZYDIS_DECORATOR_EH: |
787 | 77 | #if !defined(ZYDIS_DISABLE_KNC) |
788 | 77 | if (context->instruction->avx.has_eviction_hint) |
789 | 46 | { |
790 | 46 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_EH, formatter->case_decorators); |
791 | 40 | } |
792 | 71 | #endif |
793 | 71 | break; |
794 | 2.64k | case ZYDIS_DECORATOR_APX_NF: |
795 | 2.64k | #if !defined(ZYDIS_DISABLE_AVX512) |
796 | 2.64k | if (context->instruction->apx.has_nf) |
797 | 29 | { |
798 | 29 | ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_NF, formatter->case_decorators); |
799 | 26 | } |
800 | 2.64k | #endif |
801 | 2.64k | break; |
802 | 2.64k | case ZYDIS_DECORATOR_APX_DFV: |
803 | 2.39k | #if !defined(ZYDIS_DISABLE_AVX512) |
804 | 2.39k | if (context->instruction->apx.scc != ZYDIS_SCC_NONE) |
805 | 89 | { |
806 | 89 | switch (context->instruction->apx.default_flags) |
807 | 89 | { |
808 | 4 | case 0x0: ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DFV_0, formatter->case_decorators); break; |
809 | 6 | case 0x1: ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DFV_1, formatter->case_decorators); break; |
810 | 8 | case 0x2: ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DFV_2, formatter->case_decorators); break; |
811 | 4 | case 0x3: ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DFV_3, formatter->case_decorators); break; |
812 | 5 | case 0x4: ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DFV_4, formatter->case_decorators); break; |
813 | 6 | case 0x5: ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DFV_5, formatter->case_decorators); break; |
814 | 6 | case 0x6: ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DFV_6, formatter->case_decorators); break; |
815 | 5 | case 0x7: ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DFV_7, formatter->case_decorators); break; |
816 | 7 | case 0x8: ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DFV_8, formatter->case_decorators); break; |
817 | 6 | case 0x9: ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DFV_9, formatter->case_decorators); break; |
818 | 6 | case 0xA: ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DFV_A, formatter->case_decorators); break; |
819 | 4 | case 0xB: ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DFV_B, formatter->case_decorators); break; |
820 | 8 | case 0xC: ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DFV_C, formatter->case_decorators); break; |
821 | 4 | case 0xD: ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DFV_D, formatter->case_decorators); break; |
822 | 4 | case 0xE: ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DFV_E, formatter->case_decorators); break; |
823 | 6 | case 0xF: ZYDIS_BUFFER_APPEND_CASE(buffer, DECO_DFV_F, formatter->case_decorators); break; |
824 | 0 | default: |
825 | 0 | return ZYAN_STATUS_INVALID_ARGUMENT; |
826 | 89 | } |
827 | 89 | } |
828 | 2.34k | #endif |
829 | 2.34k | break; |
830 | 2.34k | default: |
831 | 0 | return ZYAN_STATUS_INVALID_ARGUMENT; |
832 | 6.12k | } |
833 | | |
834 | 5.95k | return ZYAN_STATUS_SUCCESS; |
835 | 6.12k | } |
836 | | |
837 | | /* ---------------------------------------------------------------------------------------------- */ |
838 | | |
839 | | /* ============================================================================================== */ |