Zydis 3.2.1.0
FormatterBase.h
Go to the documentation of this file.
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
32#ifndef ZYDIS_FORMATTER_BASE_H
33#define ZYDIS_FORMATTER_BASE_H
34
35#include <Zydis/Formatter.h>
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
42/* ============================================================================================== */
43/* Macros */
44/* ============================================================================================== */
45
46/* ---------------------------------------------------------------------------------------------- */
47/* String */
48/* ---------------------------------------------------------------------------------------------- */
49
59#define ZYDIS_STRING_APPEND_NUM_U(formatter, base, str, value, padding_length) \
60 switch (base) \
61 { \
62 case ZYDIS_NUMERIC_BASE_DEC: \
63 ZYAN_CHECK(ZydisStringAppendDecU(str, value, padding_length, \
64 (formatter)->number_format[base][0].string, \
65 (formatter)->number_format[base][1].string)); \
66 break; \
67 case ZYDIS_NUMERIC_BASE_HEX: \
68 ZYAN_CHECK(ZydisStringAppendHexU(str, value, padding_length, \
69 (formatter)->hex_uppercase, \
70 (formatter)->number_format[base][0].string, \
71 (formatter)->number_format[base][1].string)); \
72 break; \
73 default: \
74 return ZYAN_STATUS_INVALID_ARGUMENT; \
75 }
76
87#define ZYDIS_STRING_APPEND_NUM_S(formatter, base, str, value, padding_length, force_sign) \
88 switch (base) \
89 { \
90 case ZYDIS_NUMERIC_BASE_DEC: \
91 ZYAN_CHECK(ZydisStringAppendDecS(str, value, padding_length, force_sign, \
92 (formatter)->number_format[base][0].string, \
93 (formatter)->number_format[base][1].string)); \
94 break; \
95 case ZYDIS_NUMERIC_BASE_HEX: \
96 ZYAN_CHECK(ZydisStringAppendHexS(str, value, padding_length, \
97 (formatter)->hex_uppercase, force_sign, \
98 (formatter)->number_format[base][0].string, \
99 (formatter)->number_format[base][1].string)); \
100 break; \
101 default: \
102 return ZYAN_STATUS_INVALID_ARGUMENT; \
103 }
104
105/* ---------------------------------------------------------------------------------------------- */
106/* Buffer */
107/* ---------------------------------------------------------------------------------------------- */
108
119#define ZYDIS_BUFFER_APPEND_TOKEN(buffer, type) \
120 if ((buffer)->is_token_list) \
121 { \
122 ZYAN_CHECK(ZydisFormatterBufferAppend(buffer, type)); \
123 }
124
134#define ZYDIS_BUFFER_REMEMBER(buffer, state) \
135 if ((buffer)->is_token_list) \
136 { \
137 (state) = (ZyanUPointer)(buffer)->string.vector.data; \
138 } else \
139 { \
140 (state) = (ZyanUPointer)(buffer)->string.vector.size; \
141 }
142
149#define ZYDIS_BUFFER_APPEND(buffer, name) \
150 if ((buffer)->is_token_list) \
151 { \
152 ZYAN_CHECK(ZydisFormatterBufferAppendPredefined(buffer, TOK_ ## name)); \
153 } else \
154 { \
155 ZYAN_CHECK(ZydisStringAppendShort(&buffer->string, &STR_ ## name)); \
156 }
157
158// TODO: Implement `letter_case` for predefined tokens
159
167#define ZYDIS_BUFFER_APPEND_CASE(buffer, name, letter_case) \
168 if ((buffer)->is_token_list) \
169 { \
170 ZYAN_CHECK(ZydisFormatterBufferAppendPredefined(buffer, TOK_ ## name)); \
171 } else \
172 { \
173 ZYAN_CHECK(ZydisStringAppendShortCase(&buffer->string, &STR_ ## name, letter_case)); \
174 }
175
176/* ---------------------------------------------------------------------------------------------- */
177
178/* ============================================================================================== */
179/* Helper functions */
180/* ============================================================================================== */
181
182/* ---------------------------------------------------------------------------------------------- */
183/* Buffer */
184/* ---------------------------------------------------------------------------------------------- */
185
186// MSVC does not like the C99 flexible-array extension
187#ifdef ZYAN_MSVC
188# pragma warning(push)
189# pragma warning(disable:4200)
190#endif
191
192#pragma pack(push, 1)
193
195{
196 ZyanU8 size;
197 ZyanU8 next;
198 ZyanU8 data[];
200
201#pragma pack(pop)
202
203#ifdef ZYAN_MSVC
204# pragma warning(pop)
205#endif
206
219 const ZydisPredefinedToken* data)
220{
221 ZYAN_ASSERT(buffer);
222 ZYAN_ASSERT(data);
223
224 const ZyanUSize len = buffer->string.vector.size;
225 ZYAN_ASSERT((len > 0) && (len < 256));
226 if (buffer->capacity <= len + data->size)
227 {
228 return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE;
229 }
230
231 ZydisFormatterToken* const last = (ZydisFormatterToken*)buffer->string.vector.data - 1;
232 last->next = (ZyanU8)len;
233
234 ZYAN_MEMCPY((ZyanU8*)buffer->string.vector.data + len, &data->data[0], data->size);
235
236 const ZyanUSize delta = len + data->next;
237 buffer->capacity -= delta;
238 buffer->string.vector.data = (ZyanU8*)buffer->string.vector.data + delta;
239 buffer->string.vector.size = data->size - data->next;
240 buffer->string.vector.capacity = ZYAN_MIN(buffer->capacity, 255);
241
242 return ZYAN_STATUS_SUCCESS;
243}
244
245/* ---------------------------------------------------------------------------------------------- */
246/* General */
247/* ---------------------------------------------------------------------------------------------- */
248
263 ZydisFormatterContext* context, ZyanU8 memop_id);
264
265/* ---------------------------------------------------------------------------------------------- */
266
267/* ============================================================================================== */
268/* Formatter functions */
269/* ============================================================================================== */
270
271/* ---------------------------------------------------------------------------------------------- */
272/* Operands */
273/* ---------------------------------------------------------------------------------------------- */
274
275ZyanStatus ZydisFormatterBaseFormatOperandREG(const ZydisFormatter* formatter,
277
278ZyanStatus ZydisFormatterBaseFormatOperandPTR(const ZydisFormatter* formatter,
280
281ZyanStatus ZydisFormatterBaseFormatOperandIMM(const ZydisFormatter* formatter,
283
284/* ---------------------------------------------------------------------------------------------- */
285/* Elemental tokens */
286/* ---------------------------------------------------------------------------------------------- */
287
288ZyanStatus ZydisFormatterBasePrintAddressABS(const ZydisFormatter* formatter,
290
291ZyanStatus ZydisFormatterBasePrintAddressREL(const ZydisFormatter* formatter,
293
294ZyanStatus ZydisFormatterBasePrintIMM(const ZydisFormatter* formatter,
296
297/* ---------------------------------------------------------------------------------------------- */
298/* Optional tokens */
299/* ---------------------------------------------------------------------------------------------- */
300
301ZyanStatus ZydisFormatterBasePrintSegment(const ZydisFormatter* formatter,
303
304ZyanStatus ZydisFormatterBasePrintPrefixes(const ZydisFormatter* formatter,
306
307ZyanStatus ZydisFormatterBasePrintDecorator(const ZydisFormatter* formatter,
308 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context, ZydisDecorator decorator);
309
310/* ---------------------------------------------------------------------------------------------- */
311
312/* ============================================================================================== */
313
314#ifdef __cplusplus
315}
316#endif
317
318#endif // ZYDIS_FORMATTER_BASE_H
ZYAN_INLINE ZyanStatus ZydisFormatterBufferAppendPredefined(ZydisFormatterBuffer *buffer, const ZydisPredefinedToken *data)
Appends a predefined token-list to the buffer.
Definition: FormatterBase.h:218
ZyanU32 ZydisFormatterHelperGetExplicitSize(const ZydisFormatter *formatter, ZydisFormatterContext *context, ZyanU8 memop_id)
Returns the size to be used as explicit size suffix (AT&T) or explicit typecast (INTEL),...
Functions for formatting instructions to human-readable text.
enum ZydisDecorator_ ZydisDecorator
Defines the ZydisDecorator enum.
Provides some internal, more performant, but unsafe helper functions for the ZyanString data-type.
Defines the ZydisFormatterBuffer struct.
Definition: FormatterBuffer.h:168
ZyanString string
The ZyanString instance that refers to the literal value of the most recently added token.
Definition: FormatterBuffer.h:182
ZyanUSize capacity
The remaining capacity of the buffer.
Definition: FormatterBuffer.h:177
Defines the ZydisFormatterContext struct.
Definition: Formatter.h:639
Defines the ZydisFormatterToken struct.
Definition: FormatterBuffer.h:139
ZyanU8 next
An offset to the next token, or 0.
Definition: FormatterBuffer.h:147
Defines the ZydisFormatter struct.
Definition: Formatter.h:753
Definition: FormatterBase.h:195