Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/zydis/include/Zydis/Decoder.h
4216 views
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
/**
28
* @file
29
* Functions for decoding instructions.
30
*/
31
32
#ifndef ZYDIS_DECODER_H
33
#define ZYDIS_DECODER_H
34
35
#include <Zycore/Types.h>
36
#include <Zycore/Defines.h>
37
#include <Zydis/DecoderTypes.h>
38
#include <Zydis/Status.h>
39
40
#ifdef __cplusplus
41
extern "C" {
42
#endif
43
44
/* ============================================================================================== */
45
/* Enums and types */
46
/* ============================================================================================== */
47
48
/* ---------------------------------------------------------------------------------------------- */
49
/* Decoder mode */
50
/* ---------------------------------------------------------------------------------------------- */
51
52
/**
53
* Defines the `ZydisDecoderMode` enum.
54
*/
55
typedef enum ZydisDecoderMode_
56
{
57
/**
58
* Enables minimal instruction decoding without semantic analysis.
59
*
60
* This mode provides access to the mnemonic, the instruction-length, the effective
61
* operand-size, the effective address-width, some attributes (e.g. `ZYDIS_ATTRIB_IS_RELATIVE`)
62
* and all of the information in the `raw` field of the `ZydisDecodedInstruction` struct.
63
*
64
* Operands, most attributes and other specific information (like `AVX` info) are not
65
* accessible in this mode.
66
*
67
* This mode is NOT enabled by default.
68
*/
69
ZYDIS_DECODER_MODE_MINIMAL,
70
/**
71
* Enables the `AMD`-branch mode.
72
*
73
* Intel ignores the operand-size override-prefix (`0x66`) for all branches with 32-bit
74
* immediates and forces the operand-size of the instruction to 64-bit in 64-bit mode.
75
* In `AMD`-branch mode `0x66` is not ignored and changes the operand-size and the size of the
76
* immediate to 16-bit.
77
*
78
* This mode is NOT enabled by default.
79
*/
80
ZYDIS_DECODER_MODE_AMD_BRANCHES,
81
/**
82
* Enables `KNC` compatibility-mode.
83
*
84
* `KNC` and `KNL+` chips are sharing opcodes and encodings for some mask-related instructions.
85
* Enable this mode to use the old `KNC` specifications (different mnemonics, operands, ..).
86
*
87
* This mode is NOT enabled by default.
88
*/
89
ZYDIS_DECODER_MODE_KNC,
90
/**
91
* Enables the `MPX` mode.
92
*
93
* The `MPX` isa-extension reuses (overrides) some of the widenop instruction opcodes.
94
*
95
* This mode is enabled by default.
96
*/
97
ZYDIS_DECODER_MODE_MPX,
98
/**
99
* Enables the `CET` mode.
100
*
101
* The `CET` isa-extension reuses (overrides) some of the widenop instruction opcodes.
102
*
103
* This mode is enabled by default.
104
*/
105
ZYDIS_DECODER_MODE_CET,
106
/**
107
* Enables the `LZCNT` mode.
108
*
109
* The `LZCNT` isa-extension reuses (overrides) some of the widenop instruction opcodes.
110
*
111
* This mode is enabled by default.
112
*/
113
ZYDIS_DECODER_MODE_LZCNT,
114
/**
115
* Enables the `TZCNT` mode.
116
*
117
* The `TZCNT` isa-extension reuses (overrides) some of the widenop instruction opcodes.
118
*
119
* This mode is enabled by default.
120
*/
121
ZYDIS_DECODER_MODE_TZCNT,
122
/**
123
* Enables the `WBNOINVD` mode.
124
*
125
* The `WBINVD` instruction is interpreted as `WBNOINVD` on ICL chips, if a `F3` prefix is
126
* used.
127
*
128
* This mode is disabled by default.
129
*/
130
ZYDIS_DECODER_MODE_WBNOINVD,
131
/**
132
* Enables the `CLDEMOTE` mode.
133
*
134
* The `CLDEMOTE` isa-extension reuses (overrides) some of the widenop instruction opcodes.
135
*
136
* This mode is enabled by default.
137
*/
138
ZYDIS_DECODER_MODE_CLDEMOTE,
139
140
/**
141
* Maximum value of this enum.
142
*/
143
ZYDIS_DECODER_MODE_MAX_VALUE = ZYDIS_DECODER_MODE_CLDEMOTE,
144
/**
145
* The minimum number of bits required to represent all values of this enum.
146
*/
147
ZYDIS_DECODER_MODE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_DECODER_MODE_MAX_VALUE)
148
} ZydisDecoderMode;
149
150
/* ---------------------------------------------------------------------------------------------- */
151
/* Decoder struct */
152
/* ---------------------------------------------------------------------------------------------- */
153
154
/**
155
* Defines the `ZydisDecoder` struct.
156
*
157
* All fields in this struct should be considered as "private". Any changes may lead to unexpected
158
* behavior.
159
*/
160
typedef struct ZydisDecoder_
161
{
162
/**
163
* The machine mode.
164
*/
165
ZydisMachineMode machine_mode;
166
/**
167
* The stack width.
168
*/
169
ZydisStackWidth stack_width;
170
/**
171
* The decoder mode array.
172
*/
173
ZyanBool decoder_mode[ZYDIS_DECODER_MODE_MAX_VALUE + 1];
174
} ZydisDecoder;
175
176
/* ---------------------------------------------------------------------------------------------- */
177
178
/* ============================================================================================== */
179
/* Exported functions */
180
/* ============================================================================================== */
181
182
/**
183
* @addtogroup decoder Decoder
184
* Functions allowing decoding of instruction bytes to a machine interpretable struct.
185
* @{
186
*/
187
188
/**
189
* Initializes the given `ZydisDecoder` instance.
190
*
191
* @param decoder A pointer to the `ZydisDecoder` instance.
192
* @param machine_mode The machine mode.
193
* @param stack_width The stack width.
194
*
195
* @return A zyan status code.
196
*/
197
ZYDIS_EXPORT ZyanStatus ZydisDecoderInit(ZydisDecoder* decoder, ZydisMachineMode machine_mode,
198
ZydisStackWidth stack_width);
199
200
/**
201
* Enables or disables the specified decoder-mode.
202
*
203
* @param decoder A pointer to the `ZydisDecoder` instance.
204
* @param mode The decoder mode.
205
* @param enabled `ZYAN_TRUE` to enable, or `ZYAN_FALSE` to disable the specified decoder-mode.
206
*
207
* @return A zyan status code.
208
*/
209
ZYDIS_EXPORT ZyanStatus ZydisDecoderEnableMode(ZydisDecoder* decoder, ZydisDecoderMode mode,
210
ZyanBool enabled);
211
212
/**
213
* Decodes the instruction in the given input `buffer` and returns all details (e.g. operands).
214
*
215
* @param decoder A pointer to the `ZydisDecoder` instance.
216
* @param buffer A pointer to the input buffer.
217
* @param length The length of the input buffer. Note that this can be bigger than the
218
* actual size of the instruction -- you don't have to know the size up
219
* front. This length is merely used to prevent Zydis from doing
220
* out-of-bounds reads on your buffer.
221
* @param instruction A pointer to the `ZydisDecodedInstruction` struct receiving the details
222
* about the decoded instruction.
223
* @param operands A pointer to an array with `ZYDIS_MAX_OPERAND_COUNT` entries that
224
* receives the decoded operands. The number of operands decoded is
225
* determined by the `instruction.operand_count` field. Excess entries are
226
* zeroed.
227
*
228
* This is a convenience function that combines the following functions into one call:
229
*
230
* - `ZydisDecoderDecodeInstruction`
231
* - `ZydisDecoderDecodeOperands`
232
*
233
* Please refer to `ZydisDecoderDecodeInstruction` if operand decoding is not required or should
234
* be done separately (`ZydisDecoderDecodeOperands`).
235
*
236
* This function is not available in MINIMAL_MODE.
237
*
238
* @return A zyan status code.
239
*/
240
ZYDIS_EXPORT ZyanStatus ZydisDecoderDecodeFull(const ZydisDecoder* decoder,
241
const void* buffer, ZyanUSize length, ZydisDecodedInstruction* instruction,
242
ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT]);
243
244
/**
245
* Decodes the instruction in the given input `buffer`.
246
*
247
* @param decoder A pointer to the `ZydisDecoder` instance.
248
* @param context A pointer to a decoder context struct which is required for further
249
* decoding (e.g. operand decoding using `ZydisDecoderDecodeOperands`) or
250
* `ZYAN_NULL` if not needed.
251
* @param buffer A pointer to the input buffer.
252
* @param length The length of the input buffer. Note that this can be bigger than the
253
* actual size of the instruction -- you don't have to know the size up
254
* front. This length is merely used to prevent Zydis from doing
255
* out-of-bounds reads on your buffer.
256
* @param instruction A pointer to the `ZydisDecodedInstruction` struct, that receives the
257
* details about the decoded instruction.
258
*
259
* @return A zyan status code.
260
*/
261
ZYDIS_EXPORT ZyanStatus ZydisDecoderDecodeInstruction(const ZydisDecoder* decoder,
262
ZydisDecoderContext* context, const void* buffer, ZyanUSize length,
263
ZydisDecodedInstruction* instruction);
264
265
/**
266
* Decodes the instruction operands.
267
*
268
* @param decoder A pointer to the `ZydisDecoder` instance.
269
* @param context A pointer to the `ZydisDecoderContext` struct.
270
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
271
* @param operands The array that receives the decoded operands.
272
* Refer to `ZYDIS_MAX_OPERAND_COUNT` or `ZYDIS_MAX_OPERAND_COUNT_VISIBLE`
273
* when allocating space for the array to ensure that the buffer size is
274
* sufficient to always fit all instruction operands.
275
* Refer to `instruction.operand_count` or
276
* `instruction.operand_count_visible' when allocating space for the array
277
* to ensure that the buffer size is sufficient to fit all operands of
278
* the given instruction.
279
* @param operand_count The length of the `operands` array.
280
* This argument as well limits the maximum amount of operands to decode.
281
* If this value is `0`, no operands will be decoded and `ZYAN_NULL` will
282
* be accepted for the `operands` argument.
283
*
284
* This function fails, if `operand_count` is larger than the total number of operands for the
285
* given instruction (`instruction.operand_count`).
286
*
287
* This function is not available in MINIMAL_MODE.
288
*
289
* @return A zyan status code.
290
*/
291
ZYDIS_EXPORT ZyanStatus ZydisDecoderDecodeOperands(const ZydisDecoder* decoder,
292
const ZydisDecoderContext* context, const ZydisDecodedInstruction* instruction,
293
ZydisDecodedOperand* operands, ZyanU8 operand_count);
294
295
/** @} */
296
297
/* ============================================================================================== */
298
299
#ifdef __cplusplus
300
}
301
#endif
302
303
#endif /* ZYDIS_DECODER_H */
304
305