Zydis: include/Zydis/Internal/FormatterBase.h Source File

Zydis v4.0.0

Loading...
Searching...
No Matches
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>
36#include <Zydis/Internal/String.h>
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
42/* ============================================================================================== */
43/* Macros */
44/* ============================================================================================== */
45
46/* ---------------------------------------------------------------------------------------------- */
47/* String */
48/* ---------------------------------------------------------------------------------------------- */
49
61#define ZYDIS_STRING_APPEND_NUM_U(formatter, base, str, value, padding_length, \
62 force_leading_number) \
63 switch (base) \
64 { \
65 case ZYDIS_NUMERIC_BASE_DEC: \
66 ZYAN_CHECK(ZydisStringAppendDecU(str, value, padding_length, \
67 (formatter)->number_format[base][0].string, \
68 (formatter)->number_format[base][1].string)); \
69 break; \
70 case ZYDIS_NUMERIC_BASE_HEX: \
71 ZYAN_CHECK(ZydisStringAppendHexU(str, value, padding_length, force_leading_number, \
72 (formatter)->hex_uppercase, \
73 (formatter)->number_format[base][0].string, \
74 (formatter)->number_format[base][1].string)); \
75 break; \
76 default: \
77 return ZYAN_STATUS_INVALID_ARGUMENT; \
78 }
79
92#define ZYDIS_STRING_APPEND_NUM_S(formatter, base, str, value, padding_length, \
93 force_leading_number, force_sign) \
94 switch (base) \
95 { \
96 case ZYDIS_NUMERIC_BASE_DEC: \
97 ZYAN_CHECK(ZydisStringAppendDecS(str, value, padding_length, force_sign, \
98 (formatter)->number_format[base][0].string, \
99 (formatter)->number_format[base][1].string)); \
100 break; \
101 case ZYDIS_NUMERIC_BASE_HEX: \
102 ZYAN_CHECK(ZydisStringAppendHexS(str, value, padding_length, force_leading_number, \
103 (formatter)->hex_uppercase, force_sign, \
104 (formatter)->number_format[base][0].string, \
105 (formatter)->number_format[base][1].string)); \
106 break; \
107 default: \
108 return ZYAN_STATUS_INVALID_ARGUMENT; \
109 }
110
111/* ---------------------------------------------------------------------------------------------- */
112/* Buffer */
113/* ---------------------------------------------------------------------------------------------- */
114
125#define ZYDIS_BUFFER_APPEND_TOKEN(buffer, type) \
126 if ((buffer)->is_token_list) \
127 { \
128 ZYAN_CHECK(ZydisFormatterBufferAppend(buffer, type)); \
129 }
130
140#define ZYDIS_BUFFER_REMEMBER(buffer, state) \
141 if ((buffer)->is_token_list) \
142 { \
143 (state) = (ZyanUPointer)(buffer)->string.vector.data; \
144 } else \
145 { \
146 (state) = (ZyanUPointer)(buffer)->string.vector.size; \
147 }
148
155#define ZYDIS_BUFFER_APPEND(buffer, name) \
156 if ((buffer)->is_token_list) \
157 { \
158 ZYAN_CHECK(ZydisFormatterBufferAppendPredefined(buffer, TOK_ ## name)); \
159 } else \
160 { \
161 ZYAN_CHECK(ZydisStringAppendShort(&buffer->string, &STR_ ## name)); \
162 }
163
164// TODO: Implement `letter_case` for predefined tokens
165
173#define ZYDIS_BUFFER_APPEND_CASE(buffer, name, letter_case) \
174 if ((buffer)->is_token_list) \
175 { \
176 ZYAN_CHECK(ZydisFormatterBufferAppendPredefined(buffer, TOK_ ## name)); \
177 } else \
178 { \
179 ZYAN_CHECK(ZydisStringAppendShortCase(&buffer->string, &STR_ ## name, letter_case)); \
180 }
181
182/* ---------------------------------------------------------------------------------------------- */
183
184/* ============================================================================================== */
185/* Helper functions */
186/* ============================================================================================== */
187
188/* ---------------------------------------------------------------------------------------------- */
189/* Buffer */
190/* ---------------------------------------------------------------------------------------------- */
191
192// MSVC does not like the C99 flexible-array extension
193#ifdef ZYAN_MSVC
194# pragma warning(push)
195# pragma warning(disable:4200)
196#endif
197
198#pragma pack(push, 1)
199
200 typedef struct ZydisPredefinedToken_
201{
202 ZyanU8 size;
203 ZyanU8 next;
204 ZyanU8 data[];
205} ZydisPredefinedToken;
206
207#pragma pack(pop)
208
209#ifdef ZYAN_MSVC
210# pragma warning(pop)
211#endif
212
224ZYAN_INLINE ZyanStatus ZydisFormatterBufferAppendPredefined(ZydisFormatterBuffer* buffer,
225 const ZydisPredefinedToken* data)
226{
227 ZYAN_ASSERT(buffer);
228 ZYAN_ASSERT(data);
229
230 const ZyanUSize len = buffer->string.vector.size;
231 ZYAN_ASSERT((len > 0) && (len < 256));
232 if (buffer->capacity <= len + data->size)
233 {
234 return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE;
235 }
236
237 ZydisFormatterToken* const last = (ZydisFormatterToken*)buffer->string.vector.data - 1;
238 last->next = (ZyanU8)len;
239
240 ZYAN_MEMCPY((ZyanU8*)buffer->string.vector.data + len, &data->data[0], data->size);
241
242 const ZyanUSize delta = len + data->next;
243 buffer->capacity -= delta;
244 buffer->string.vector.data = (ZyanU8*)buffer->string.vector.data + delta;
245 buffer->string.vector.size = data->size - data->next;
246 buffer->string.vector.capacity = ZYAN_MIN(buffer->capacity, 255);
247
248 return ZYAN_STATUS_SUCCESS;
249}
250
251/* ---------------------------------------------------------------------------------------------- */
252/* General */
253/* ---------------------------------------------------------------------------------------------- */
254
268ZyanU32 ZydisFormatterHelperGetExplicitSize(const ZydisFormatter* formatter,
269 ZydisFormatterContext* context, const ZydisDecodedOperand* operand);
270
271/* ---------------------------------------------------------------------------------------------- */
272
273/* ============================================================================================== */
274/* Formatter functions */
275/* ============================================================================================== */
276
277/* ---------------------------------------------------------------------------------------------- */
278/* Operands */
279/* ---------------------------------------------------------------------------------------------- */
280
281ZyanStatus ZydisFormatterBaseFormatOperandREG(const ZydisFormatter* formatter,
282 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context);
283
284ZyanStatus ZydisFormatterBaseFormatOperandPTR(const ZydisFormatter* formatter,
285 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context);
286
287ZyanStatus ZydisFormatterBaseFormatOperandIMM(const ZydisFormatter* formatter,
288 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context);
289
290/* ---------------------------------------------------------------------------------------------- */
291/* Elemental tokens */
292/* ---------------------------------------------------------------------------------------------- */
293
294ZyanStatus ZydisFormatterBasePrintAddressABS(const ZydisFormatter* formatter,
295 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context);
296
297ZyanStatus ZydisFormatterBasePrintAddressREL(const ZydisFormatter* formatter,
298 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context);
299
300ZyanStatus ZydisFormatterBasePrintIMM(const ZydisFormatter* formatter,
301 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context);
302
303/* ---------------------------------------------------------------------------------------------- */
304/* Optional tokens */
305/* ---------------------------------------------------------------------------------------------- */
306
307ZyanStatus ZydisFormatterBasePrintSegment(const ZydisFormatter* formatter,
308 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context);
309
310ZyanStatus ZydisFormatterBasePrintPrefixes(const ZydisFormatter* formatter,
311 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context);
312
313ZyanStatus ZydisFormatterBasePrintDecorator(const ZydisFormatter* formatter,
314 ZydisFormatterBuffer* buffer, ZydisFormatterContext* context, ZydisDecorator decorator);
315
316/* ---------------------------------------------------------------------------------------------- */
317
318/* ============================================================================================== */
319
320#ifdef __cplusplus
321}
322#endif
323
324#endif // ZYDIS_FORMATTER_BASE_H
ZydisFormatterBufferAppendPredefined
ZYAN_INLINE ZyanStatus ZydisFormatterBufferAppendPredefined(ZydisFormatterBuffer *buffer, const ZydisPredefinedToken *data)
Appends a predefined token-list to the buffer.
Definition: FormatterBase.h:224
ZydisFormatterHelperGetExplicitSize
ZyanU32 ZydisFormatterHelperGetExplicitSize(const ZydisFormatter *formatter, ZydisFormatterContext *context, const ZydisDecodedOperand *operand)
Returns the size to be used as explicit size suffix (AT&T) or explicit typecast (INTEL),...
Formatter.h
Functions for formatting instructions to human-readable text.
ZydisDecorator
enum ZydisDecorator_ ZydisDecorator
Enum of all decorator types.
String.h
Provides some internal, more performant, but unsafe helper functions for the ZyanString data-type.
ZydisDecodedOperand_
Defines the ZydisDecodedOperand struct.
Definition: DecoderTypes.h:200
ZydisFormatterBuffer_
Defines the ZydisFormatterBuffer struct.
Definition: FormatterBuffer.h:168
ZydisFormatterBuffer_::string
ZyanString string
The ZyanString instance that refers to the literal value of the most recently added token.
Definition: FormatterBuffer.h:182
ZydisFormatterBuffer_::capacity
ZyanUSize capacity
The remaining capacity of the buffer.
Definition: FormatterBuffer.h:177
ZydisFormatterContext_
Context structure that that is passed to all formatter.
Definition: Formatter.h:650
ZydisFormatterToken_
Defines the ZydisFormatterToken struct.
Definition: FormatterBuffer.h:139
ZydisFormatterToken_::next
ZyanU8 next
An offset to the next token, or 0.
Definition: FormatterBuffer.h:147
ZydisFormatter_
Context structure keeping track of internal state of the formatter.
Definition: Formatter.h:771
ZydisPredefinedToken_
Definition: FormatterBase.h:201