VirtualBox

source: vbox/trunk/include/VBox/dis-x86-amd64.h@ 103224

Last change on this file since 103224 was 101539, checked in by vboxsync, 12 months ago

DIS,VMM,DBGC,IPRT,++: Some disassembler tweaks and TB disassembly work. bugref:10371 bugref:9898

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.5 KB
Line 
1/** @file
2 * DIS - The VirtualBox Disassembler.
3 */
4
5/*
6 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
7 *
8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
14 * License.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
23 *
24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
28 * CDDL are applicable instead of those of the GPL.
29 *
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
34 */
35
36#ifndef VBOX_INCLUDED_dis_x86_amd64_h
37#define VBOX_INCLUDED_dis_x86_amd64_h
38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
41
42#include <VBox/types.h>
43#include <VBox/disopcode-x86-amd64.h>
44#include <iprt/assert.h>
45
46
47RT_C_DECLS_BEGIN
48
49/** @addtogroup grp_dis VBox Disassembler
50 * @{ */
51
52/** @name Prefix byte flags (DISSTATE::fPrefix).
53 * @{
54 */
55#define DISPREFIX_NONE UINT8_C(0x00)
56/** non-default address size. */
57#define DISPREFIX_ADDRSIZE UINT8_C(0x01)
58/** non-default operand size. */
59#define DISPREFIX_OPSIZE UINT8_C(0x02)
60/** lock prefix. */
61#define DISPREFIX_LOCK UINT8_C(0x04)
62/** segment prefix. */
63#define DISPREFIX_SEG UINT8_C(0x08)
64/** rep(e) prefix (not a prefix, but we'll treat is as one). */
65#define DISPREFIX_REP UINT8_C(0x10)
66/** rep(e) prefix (not a prefix, but we'll treat is as one). */
67#define DISPREFIX_REPNE UINT8_C(0x20)
68/** REX prefix (64 bits) */
69#define DISPREFIX_REX UINT8_C(0x40)
70/** @} */
71
72/** @name VEX.Lvvvv prefix destination register flag.
73 * @{
74 */
75#define VEX_LEN256 UINT8_C(0x01)
76#define VEXREG_IS256B(x) ((x) & VEX_LEN256)
77/* Convert second byte of VEX prefix to internal format */
78#define VEX_2B2INT(x) ((((x) >> 2) & 0x1f))
79#define VEX_HAS_REX_R(x) (!((x) & 0x80))
80
81#define DISPREFIX_VEX_FLAG_W UINT8_C(0x01)
82 /** @} */
83
84/** @name 64 bits prefix byte flags (DISSTATE::fRexPrefix).
85 * Requires VBox/disopcode.h.
86 * @{
87 */
88#define DISPREFIX_REX_OP_2_FLAGS(a) (a - OP_PARM_REX_START)
89/*#define DISPREFIX_REX_FLAGS DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX) - 0, which is no flag */
90#define DISPREFIX_REX_FLAGS_B DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_B)
91#define DISPREFIX_REX_FLAGS_X DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_X)
92#define DISPREFIX_REX_FLAGS_XB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_XB)
93#define DISPREFIX_REX_FLAGS_R DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_R)
94#define DISPREFIX_REX_FLAGS_RB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_RB)
95#define DISPREFIX_REX_FLAGS_RX DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_RX)
96#define DISPREFIX_REX_FLAGS_RXB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_RXB)
97#define DISPREFIX_REX_FLAGS_W DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_W)
98#define DISPREFIX_REX_FLAGS_WB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WB)
99#define DISPREFIX_REX_FLAGS_WX DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WX)
100#define DISPREFIX_REX_FLAGS_WXB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WXB)
101#define DISPREFIX_REX_FLAGS_WR DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WR)
102#define DISPREFIX_REX_FLAGS_WRB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WRB)
103#define DISPREFIX_REX_FLAGS_WRX DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WRX)
104#define DISPREFIX_REX_FLAGS_WRXB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WRXB)
105/** @} */
106AssertCompile(RT_IS_POWER_OF_TWO(DISPREFIX_REX_FLAGS_B));
107AssertCompile(RT_IS_POWER_OF_TWO(DISPREFIX_REX_FLAGS_X));
108AssertCompile(RT_IS_POWER_OF_TWO(DISPREFIX_REX_FLAGS_W));
109AssertCompile(RT_IS_POWER_OF_TWO(DISPREFIX_REX_FLAGS_R));
110
111
112/** @name 64-bit general register indexes.
113 * This matches the AMD64 register encoding. It is found used in
114 * DISOPPARAM::Base.idxGenReg and DISOPPARAM::Index.idxGenReg.
115 * @note Safe to assume same values as the 16-bit and 32-bit general registers.
116 * @{
117 */
118#define DISGREG_RAX UINT8_C(0)
119#define DISGREG_RCX UINT8_C(1)
120#define DISGREG_RDX UINT8_C(2)
121#define DISGREG_RBX UINT8_C(3)
122#define DISGREG_RSP UINT8_C(4)
123#define DISGREG_RBP UINT8_C(5)
124#define DISGREG_RSI UINT8_C(6)
125#define DISGREG_RDI UINT8_C(7)
126#define DISGREG_R8 UINT8_C(8)
127#define DISGREG_R9 UINT8_C(9)
128#define DISGREG_R10 UINT8_C(10)
129#define DISGREG_R11 UINT8_C(11)
130#define DISGREG_R12 UINT8_C(12)
131#define DISGREG_R13 UINT8_C(13)
132#define DISGREG_R14 UINT8_C(14)
133#define DISGREG_R15 UINT8_C(15)
134/** @} */
135
136/** @name 32-bit general register indexes.
137 * This matches the AMD64 register encoding. It is found used in
138 * DISOPPARAM::Base.idxGenReg and DISOPPARAM::Index.idxGenReg.
139 * @note Safe to assume same values as the 16-bit and 64-bit general registers.
140 * @{
141 */
142#define DISGREG_EAX UINT8_C(0)
143#define DISGREG_ECX UINT8_C(1)
144#define DISGREG_EDX UINT8_C(2)
145#define DISGREG_EBX UINT8_C(3)
146#define DISGREG_ESP UINT8_C(4)
147#define DISGREG_EBP UINT8_C(5)
148#define DISGREG_ESI UINT8_C(6)
149#define DISGREG_EDI UINT8_C(7)
150#define DISGREG_R8D UINT8_C(8)
151#define DISGREG_R9D UINT8_C(9)
152#define DISGREG_R10D UINT8_C(10)
153#define DISGREG_R11D UINT8_C(11)
154#define DISGREG_R12D UINT8_C(12)
155#define DISGREG_R13D UINT8_C(13)
156#define DISGREG_R14D UINT8_C(14)
157#define DISGREG_R15D UINT8_C(15)
158/** @} */
159
160/** @name 16-bit general register indexes.
161 * This matches the AMD64 register encoding. It is found used in
162 * DISOPPARAM::Base.idxGenReg and DISOPPARAM::Index.idxGenReg.
163 * @note Safe to assume same values as the 32-bit and 64-bit general registers.
164 * @{
165 */
166#define DISGREG_AX UINT8_C(0)
167#define DISGREG_CX UINT8_C(1)
168#define DISGREG_DX UINT8_C(2)
169#define DISGREG_BX UINT8_C(3)
170#define DISGREG_SP UINT8_C(4)
171#define DISGREG_BP UINT8_C(5)
172#define DISGREG_SI UINT8_C(6)
173#define DISGREG_DI UINT8_C(7)
174#define DISGREG_R8W UINT8_C(8)
175#define DISGREG_R9W UINT8_C(9)
176#define DISGREG_R10W UINT8_C(10)
177#define DISGREG_R11W UINT8_C(11)
178#define DISGREG_R12W UINT8_C(12)
179#define DISGREG_R13W UINT8_C(13)
180#define DISGREG_R14W UINT8_C(14)
181#define DISGREG_R15W UINT8_C(15)
182/** @} */
183
184/** @name 8-bit general register indexes.
185 * This mostly (?) matches the AMD64 register encoding. It is found used in
186 * DISOPPARAM::Base.idxGenReg and DISOPPARAM::Index.idxGenReg.
187 * @{
188 */
189#define DISGREG_AL UINT8_C(0)
190#define DISGREG_CL UINT8_C(1)
191#define DISGREG_DL UINT8_C(2)
192#define DISGREG_BL UINT8_C(3)
193#define DISGREG_AH UINT8_C(4)
194#define DISGREG_CH UINT8_C(5)
195#define DISGREG_DH UINT8_C(6)
196#define DISGREG_BH UINT8_C(7)
197#define DISGREG_R8B UINT8_C(8)
198#define DISGREG_R9B UINT8_C(9)
199#define DISGREG_R10B UINT8_C(10)
200#define DISGREG_R11B UINT8_C(11)
201#define DISGREG_R12B UINT8_C(12)
202#define DISGREG_R13B UINT8_C(13)
203#define DISGREG_R14B UINT8_C(14)
204#define DISGREG_R15B UINT8_C(15)
205#define DISGREG_SPL UINT8_C(16)
206#define DISGREG_BPL UINT8_C(17)
207#define DISGREG_SIL UINT8_C(18)
208#define DISGREG_DIL UINT8_C(19)
209/** @} */
210
211/** @name Segment registerindexes.
212 * This matches the AMD64 register encoding. It is found used in
213 * DISOPPARAM::Base.idxSegReg.
214 * @{
215 */
216typedef enum
217{
218 DISSELREG_ES = 0,
219 DISSELREG_CS = 1,
220 DISSELREG_SS = 2,
221 DISSELREG_DS = 3,
222 DISSELREG_FS = 4,
223 DISSELREG_GS = 5,
224 /** End of the valid register index values. */
225 DISSELREG_END,
226 /** The usual 32-bit paranoia. */
227 DIS_SEGREG_32BIT_HACK = 0x7fffffff
228} DISSELREG;
229/** @} */
230
231/** @name FPU register indexes.
232 * This matches the AMD64 register encoding. It is found used in
233 * DISOPPARAM::Base.idxFpuReg.
234 * @{
235 */
236#define DISFPREG_ST0 UINT8_C(0)
237#define DISFPREG_ST1 UINT8_C(1)
238#define DISFPREG_ST2 UINT8_C(2)
239#define DISFPREG_ST3 UINT8_C(3)
240#define DISFPREG_ST4 UINT8_C(4)
241#define DISFPREG_ST5 UINT8_C(5)
242#define DISFPREG_ST6 UINT8_C(6)
243#define DISFPREG_ST7 UINT8_C(7)
244/** @} */
245
246/** @name Control register indexes.
247 * This matches the AMD64 register encoding. It is found used in
248 * DISOPPARAM::Base.idxCtrlReg.
249 * @{
250 */
251#define DISCREG_CR0 UINT8_C(0)
252#define DISCREG_CR1 UINT8_C(1)
253#define DISCREG_CR2 UINT8_C(2)
254#define DISCREG_CR3 UINT8_C(3)
255#define DISCREG_CR4 UINT8_C(4)
256#define DISCREG_CR8 UINT8_C(8)
257/** @} */
258
259/** @name Debug register indexes.
260 * This matches the AMD64 register encoding. It is found used in
261 * DISOPPARAM::Base.idxDbgReg.
262 * @{
263 */
264#define DISDREG_DR0 UINT8_C(0)
265#define DISDREG_DR1 UINT8_C(1)
266#define DISDREG_DR2 UINT8_C(2)
267#define DISDREG_DR3 UINT8_C(3)
268#define DISDREG_DR4 UINT8_C(4)
269#define DISDREG_DR5 UINT8_C(5)
270#define DISDREG_DR6 UINT8_C(6)
271#define DISDREG_DR7 UINT8_C(7)
272/** @} */
273
274/** @name MMX register indexes.
275 * This matches the AMD64 register encoding. It is found used in
276 * DISOPPARAM::Base.idxMmxReg.
277 * @{
278 */
279#define DISMREG_MMX0 UINT8_C(0)
280#define DISMREG_MMX1 UINT8_C(1)
281#define DISMREG_MMX2 UINT8_C(2)
282#define DISMREG_MMX3 UINT8_C(3)
283#define DISMREG_MMX4 UINT8_C(4)
284#define DISMREG_MMX5 UINT8_C(5)
285#define DISMREG_MMX6 UINT8_C(6)
286#define DISMREG_MMX7 UINT8_C(7)
287/** @} */
288
289/** @name SSE register indexes.
290 * This matches the AMD64 register encoding. It is found used in
291 * DISOPPARAM::Base.idxXmmReg.
292 * @{
293 */
294#define DISXREG_XMM0 UINT8_C(0)
295#define DISXREG_XMM1 UINT8_C(1)
296#define DISXREG_XMM2 UINT8_C(2)
297#define DISXREG_XMM3 UINT8_C(3)
298#define DISXREG_XMM4 UINT8_C(4)
299#define DISXREG_XMM5 UINT8_C(5)
300#define DISXREG_XMM6 UINT8_C(6)
301#define DISXREG_XMM7 UINT8_C(7)
302/** @} */
303
304
305/**
306 * Opcode parameter (operand) details for x86/AMD64.
307 */
308typedef struct
309{
310 /** Disposition. */
311 union
312 {
313 /** 64-bit displacement, applicable if DISUSE_DISPLACEMENT64 is set in fUse. */
314 int64_t i64;
315 uint64_t u64;
316 /** 32-bit displacement, applicable if DISUSE_DISPLACEMENT32 or
317 * DISUSE_RIPDISPLACEMENT32 is set in fUse. */
318 int32_t i32;
319 uint32_t u32;
320 /** 16-bit displacement, applicable if DISUSE_DISPLACEMENT16 is set in fUse. */
321 int32_t i16;
322 uint32_t u16;
323 /** 8-bit displacement, applicable if DISUSE_DISPLACEMENT8 is set in fUse. */
324 int32_t i8;
325 uint32_t u8;
326 } uDisp;
327 /** The base register from ModR/M or SIB, applicable if DISUSE_BASE is
328 * set in fUse. */
329 union
330 {
331 /** General register index (DISGREG_XXX), applicable if DISUSE_REG_GEN8,
332 * DISUSE_REG_GEN16, DISUSE_REG_GEN32 or DISUSE_REG_GEN64 is set in fUse. */
333 uint8_t idxGenReg;
334 /** FPU stack register index (DISFPREG_XXX), applicable if DISUSE_REG_FP is
335 * set in fUse. 1:1 indexes. */
336 uint8_t idxFpuReg;
337 /** MMX register index (DISMREG_XXX), applicable if DISUSE_REG_MMX is
338 * set in fUse. 1:1 indexes. */
339 uint8_t idxMmxReg;
340 /** SSE register index (DISXREG_XXX), applicable if DISUSE_REG_XMM is
341 * set in fUse. 1:1 indexes. */
342 uint8_t idxXmmReg;
343 /** SSE2 register index (DISYREG_XXX), applicable if DISUSE_REG_YMM is
344 * set in fUse. 1:1 indexes. */
345 uint8_t idxYmmReg;
346 /** Segment register index (DISSELREG_XXX), applicable if DISUSE_REG_SEG is
347 * set in fUse. */
348 uint8_t idxSegReg;
349 /** Test register, TR0-TR7, present on early IA32 CPUs, applicable if
350 * DISUSE_REG_TEST is set in fUse. No index defines for these. */
351 uint8_t idxTestReg;
352 /** Control register index (DISCREG_XXX), applicable if DISUSE_REG_CR is
353 * set in fUse. 1:1 indexes. */
354 uint8_t idxCtrlReg;
355 /** Debug register index (DISDREG_XXX), applicable if DISUSE_REG_DBG is
356 * set in fUse. 1:1 indexes. */
357 uint8_t idxDbgReg;
358 } Base;
359 /** The SIB index register meaning, applicable if DISUSE_INDEX is
360 * set in fUse. */
361 union
362 {
363 /** General register index (DISGREG_XXX), applicable if DISUSE_REG_GEN8,
364 * DISUSE_REG_GEN16, DISUSE_REG_GEN32 or DISUSE_REG_GEN64 is set in fUse. */
365 uint8_t idxGenReg;
366 /** XMM register index (DISXREG_XXX), applicable if DISUSE_REG_XMM
367 * is set in fUse. */
368 uint8_t idxXmmReg;
369 /** YMM register index (DISXREG_XXX), applicable if DISUSE_REG_YMM
370 * is set in fUse. */
371 uint8_t idxYmmReg;
372 } Index;
373 /** 2, 4 or 8, if DISUSE_SCALE is set in fUse. */
374 uint8_t uScale;
375 /** Parameter size. */
376 uint8_t cb;
377 /** Copy of the corresponding DISOPCODE::fParam1 / DISOPCODE::fParam2 /
378 * DISOPCODE::fParam3. */
379 uint32_t fParam;
380} DIS_OP_PARAM_X86_T;
381AssertCompileSize(DIS_OP_PARAM_X86_T, 16);
382/** Pointer to opcode parameter. */
383typedef DIS_OP_PARAM_X86_T *PDIS_OP_PARAM_X86_T;
384/** Pointer to opcode parameter. */
385typedef const DIS_OP_PARAM_X86_T *PCDIS_OP_PARAM_X86_T;
386
387
388/** Parser callback.
389 * @remark no DECLCALLBACK() here because it's considered to be internal and
390 * there is no point in enforcing CDECL. */
391typedef size_t FNDISPARSEX86(size_t offInstr, PCDISOPCODE pOp, PDISSTATE pDis, PDISOPPARAM pParam);
392/** Pointer to a disassembler parser function. */
393typedef FNDISPARSEX86 *PFNDISPARSEX86;
394/** Pointer to a const disassembler parser function pointer. */
395typedef PFNDISPARSEX86 const *PCPFNDISPARSEX86;
396
397/**
398 * The x86/AMD64 specific disassembler state and result.
399 */
400typedef struct
401{
402 /** SIB fields. */
403 union
404 {
405 /** Bitfield view */
406 struct
407 {
408 uint8_t Base;
409 uint8_t Index;
410 uint8_t Scale;
411 } Bits;
412 } SIB;
413 /** ModRM fields. */
414 union
415 {
416 /** Bitfield view */
417 struct
418 {
419 uint8_t Rm;
420 uint8_t Reg;
421 uint8_t Mod;
422 } Bits;
423 } ModRM;
424 /** The addressing mode (DISCPUMODE). */
425 uint8_t uAddrMode;
426 /** The operand mode (DISCPUMODE). */
427 uint8_t uOpMode;
428 /** Per instruction prefix settings. */
429 uint8_t fPrefix;
430 /** REX prefix value (64 bits only). */
431 uint8_t fRexPrefix;
432 /** Segment prefix value (DISSELREG). */
433 uint8_t idxSegPrefix;
434 /** Last prefix byte (for SSE2 extension tables). */
435 uint8_t bLastPrefix;
436 /** Last significant opcode byte of instruction. */
437 uint8_t bOpCode;
438 /** The size of the prefix bytes. */
439 uint8_t cbPrefix;
440 /** VEX presence flag, destination register and size
441 * @todo r=bird: There is no VEX presence flage here, just ~vvvv and L. */
442 uint8_t bVexDestReg;
443 /** VEX.W flag */
444 uint8_t bVexWFlag;
445 /** Internal: instruction filter */
446 uint32_t fFilter;
447 /** SIB displacment. */
448 int32_t i32SibDisp;
449 /** Internal: pointer to disassembly function table */
450 PCPFNDISPARSEX86 pfnDisasmFnTable;
451#if ARCH_BITS == 32
452 uint32_t uPtrPadding1;
453#endif
454} DIS_STATE_X86_T;
455AssertCompileSize(DIS_STATE_X86_T, 32);
456
457
458
459DISDECL(bool) DISFormatYasmIsOddEncoding(PDISSTATE pDis);
460
461/** @} */
462
463RT_C_DECLS_END
464
465#endif /* !VBOX_INCLUDED_dis_x86_amd64_h */
466
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette