VirtualBox

source: vbox/trunk/include/VBox/dis.h@ 101540

Last change on this file since 101540 was 101540, checked in by vboxsync, 13 months ago

DIS,VMM,DBGC,IPRT,++: Some disassembler tweaks and TB disassembly work. [build fix, missing bits] bugref:10371 bugref:9898

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.9 KB
RevLine 
[1]1/** @file
2 * DIS - The VirtualBox Disassembler.
3 */
4
5/*
[98103]6 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
[1]7 *
[96407]8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
[5999]10 *
[96407]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 *
[5999]24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
[96407]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
[5999]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.
[96407]32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
[1]34 */
35
[76558]36#ifndef VBOX_INCLUDED_dis_h
37#define VBOX_INCLUDED_dis_h
[76507]38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
[1]41
42#include <VBox/types.h>
[99220]43#include <VBox/dis-x86-amd64.h>
[99241]44#if defined(VBOX_DIS_WITH_ARMV8)
45# include <VBox/dis-armv8.h>
46#endif
[41692]47#include <iprt/assert.h>
[1]48
49
[20374]50RT_C_DECLS_BEGIN
[1]51
[58111]52/** @defgroup grp_dis VBox Disassembler
[58110]53 * @{ */
[1]54
[99220]55/** @name Operand type (DISOPCODEX86::fOpType).
[1]56 * @{
57 */
[99220]58#define DISOPTYPE_INVALID RT_BIT_32(0)
59#define DISOPTYPE_HARMLESS RT_BIT_32(1)
60#define DISOPTYPE_CONTROLFLOW RT_BIT_32(2)
61#define DISOPTYPE_POTENTIALLY_DANGEROUS RT_BIT_32(3)
62#define DISOPTYPE_DANGEROUS RT_BIT_32(4)
63#define DISOPTYPE_PORTIO RT_BIT_32(5)
64#define DISOPTYPE_PRIVILEGED RT_BIT_32(6)
65#define DISOPTYPE_PRIVILEGED_NOTRAP RT_BIT_32(7)
66#define DISOPTYPE_UNCOND_CONTROLFLOW RT_BIT_32(8)
67#define DISOPTYPE_RELATIVE_CONTROLFLOW RT_BIT_32(9)
68#define DISOPTYPE_COND_CONTROLFLOW RT_BIT_32(10)
69#define DISOPTYPE_INTERRUPT RT_BIT_32(11)
70#define DISOPTYPE_ILLEGAL RT_BIT_32(12)
71#define DISOPTYPE_RRM_DANGEROUS RT_BIT_32(14) /**< Some additional dangerous ones when recompiling raw r0. */
72#define DISOPTYPE_RRM_DANGEROUS_16 RT_BIT_32(15) /**< Some additional dangerous ones when recompiling 16-bit raw r0. */
73#define DISOPTYPE_RRM_MASK (DISOPTYPE_RRM_DANGEROUS | DISOPTYPE_RRM_DANGEROUS_16)
74#define DISOPTYPE_INHIBIT_IRQS RT_BIT_32(16) /**< Will or can inhibit irqs (sti, pop ss, mov ss) */
[1]75
[99220]76#define DISOPTYPE_X86_PORTIO_READ RT_BIT_32(17)
77#define DISOPTYPE_X86_PORTIO_WRITE RT_BIT_32(18)
78#define DISOPTYPE_X86_INVALID_64 RT_BIT_32(19) /**< Invalid in 64 bits mode */
79#define DISOPTYPE_X86_ONLY_64 RT_BIT_32(20) /**< Only valid in 64 bits mode */
80#define DISOPTYPE_X86_DEFAULT_64_OP_SIZE RT_BIT_32(21) /**< Default 64 bits operand size */
81#define DISOPTYPE_X86_FORCED_64_OP_SIZE RT_BIT_32(22) /**< Forced 64 bits operand size; regardless of prefix bytes */
82#define DISOPTYPE_X86_REXB_EXTENDS_OPREG RT_BIT_32(23) /**< REX.B extends the register field in the opcode byte */
83#define DISOPTYPE_X86_MOD_FIXED_11 RT_BIT_32(24) /**< modrm.mod is always 11b */
84#define DISOPTYPE_X86_FORCED_32_OP_SIZE_X86 RT_BIT_32(25) /**< Forced 32 bits operand size; regardless of prefix bytes (only in 16 & 32 bits mode!) */
85#define DISOPTYPE_X86_AVX RT_BIT_32(28) /**< AVX,AVX2,++ instruction. Not implemented yet! */
86#define DISOPTYPE_X86_SSE RT_BIT_32(29) /**< SSE,SSE2,SSE3,SSE4,++ instruction. Not implemented yet! */
87#define DISOPTYPE_X86_MMX RT_BIT_32(30) /**< MMX,MMXExt,3DNow,++ instruction. Not implemented yet! */
88#define DISOPTYPE_X86_FPU RT_BIT_32(31) /**< FPU instruction. Not implemented yet! */
89#define DISOPTYPE_ALL UINT32_C(0xffffffff)
90/** @} */
[53172]91
[53094]92
[99220]93/**
94 * Opcode descriptor.
[7000]95 */
[99220]96#if !defined(DIS_CORE_ONLY) || defined(DOXYGEN_RUNNING)
97typedef struct DISOPCODE
98{
99# define DISOPCODE_FORMAT 0
100 /** Mnemonic and operand formatting. */
101 const char *pszOpcode;
102 /** Parameter \#1 parser index. */
103 uint8_t idxParse1;
104 /** Parameter \#2 parser index. */
105 uint8_t idxParse2;
106 /** Parameter \#3 parser index. */
107 uint8_t idxParse3;
108 /** Parameter \#4 parser index. */
109 uint8_t idxParse4;
[101539]110 /** The opcode identifier (enum OPCODESX86) - this is DIS specific.
111 * @see grp_dis_opcodes, VBox/disopcode-x86-amd64.h */
[99220]112 uint16_t uOpcode;
113 /** Parameter \#1 info, @see grp_dis_opparam. */
114 uint16_t fParam1;
115 /** Parameter \#2 info, @see grp_dis_opparam. */
116 uint16_t fParam2;
117 /** Parameter \#3 info, @see grp_dis_opparam. */
118 uint16_t fParam3;
119 /** Parameter \#4 info, @see grp_dis_opparam. */
120 uint16_t fParam4;
121 /** padding unused */
122 uint16_t uPadding;
123 /** Operand type flags, DISOPTYPE_XXX. */
124 uint32_t fOpType;
125} DISOPCODE;
126#else
127# pragma pack(1)
128typedef struct DISOPCODE
129{
130#if 1 /*!defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64) - probably not worth it for ~4K, costs 2-3% speed. */
131 /* 16 bytes (trick is to make sure the bitfields doesn't cross dwords): */
132# define DISOPCODE_FORMAT 16
133 uint32_t fOpType;
134 uint16_t uOpcode;
135 uint8_t idxParse1;
136 uint8_t idxParse2;
137 uint32_t fParam1 : 12; /* 1st dword: 12+12+8 = 0x20 (32) */
138 uint32_t fParam2 : 12;
139 uint32_t idxParse3 : 8;
140 uint32_t fParam3 : 12; /* 2nd dword: 12+12+8 = 0x20 (32) */
141 uint32_t fParam4 : 12;
142 uint32_t idxParse4 : 8;
143#else /* 15 bytes: */
144# define DISOPCODE_FORMAT 15
145 uint64_t uOpcode : 10; /* 1st qword: 10+12+12+12+6+6+6 = 0x40 (64) */
146 uint64_t idxParse1 : 6;
147 uint64_t idxParse2 : 6;
148 uint64_t idxParse3 : 6;
149 uint64_t fParam1 : 12;
150 uint64_t fParam2 : 12;
151 uint64_t fParam3 : 12;
152 uint32_t fOpType;
153 uint16_t fParam4;
154 uint8_t idxParse4;
155#endif
156} DISOPCODE;
157# pragma pack()
158AssertCompile(sizeof(DISOPCODE) == DISOPCODE_FORMAT);
159#endif
160AssertCompile(DISOPCODE_FORMAT != 15); /* Needs fixing before use as disopcode.h now has more than 1024 opcode values. */
[7000]161
[1]162
[41674]163/** @name Parameter usage flags.
[1]164 * @{
165 */
[41676]166#define DISUSE_BASE RT_BIT_64(0)
167#define DISUSE_INDEX RT_BIT_64(1)
168#define DISUSE_SCALE RT_BIT_64(2)
169#define DISUSE_REG_GEN8 RT_BIT_64(3)
170#define DISUSE_REG_GEN16 RT_BIT_64(4)
171#define DISUSE_REG_GEN32 RT_BIT_64(5)
172#define DISUSE_REG_GEN64 RT_BIT_64(6)
173#define DISUSE_REG_FP RT_BIT_64(7)
174#define DISUSE_REG_MMX RT_BIT_64(8)
175#define DISUSE_REG_XMM RT_BIT_64(9)
[53094]176#define DISUSE_REG_YMM RT_BIT_64(10)
177#define DISUSE_REG_CR RT_BIT_64(11)
178#define DISUSE_REG_DBG RT_BIT_64(12)
179#define DISUSE_REG_SEG RT_BIT_64(13)
180#define DISUSE_REG_TEST RT_BIT_64(14)
181#define DISUSE_DISPLACEMENT8 RT_BIT_64(15)
182#define DISUSE_DISPLACEMENT16 RT_BIT_64(16)
183#define DISUSE_DISPLACEMENT32 RT_BIT_64(17)
184#define DISUSE_DISPLACEMENT64 RT_BIT_64(18)
185#define DISUSE_RIPDISPLACEMENT32 RT_BIT_64(19)
186#define DISUSE_IMMEDIATE8 RT_BIT_64(20)
187#define DISUSE_IMMEDIATE8_REL RT_BIT_64(21)
188#define DISUSE_IMMEDIATE16 RT_BIT_64(22)
189#define DISUSE_IMMEDIATE16_REL RT_BIT_64(23)
190#define DISUSE_IMMEDIATE32 RT_BIT_64(24)
191#define DISUSE_IMMEDIATE32_REL RT_BIT_64(25)
192#define DISUSE_IMMEDIATE64 RT_BIT_64(26)
193#define DISUSE_IMMEDIATE64_REL RT_BIT_64(27)
194#define DISUSE_IMMEDIATE_ADDR_0_32 RT_BIT_64(28)
195#define DISUSE_IMMEDIATE_ADDR_16_32 RT_BIT_64(29)
196#define DISUSE_IMMEDIATE_ADDR_0_16 RT_BIT_64(30)
197#define DISUSE_IMMEDIATE_ADDR_16_16 RT_BIT_64(31)
[1]198/** DS:ESI */
[53094]199#define DISUSE_POINTER_DS_BASED RT_BIT_64(32)
[1]200/** ES:EDI */
[53094]201#define DISUSE_POINTER_ES_BASED RT_BIT_64(33)
202#define DISUSE_IMMEDIATE16_SX8 RT_BIT_64(34)
203#define DISUSE_IMMEDIATE32_SX8 RT_BIT_64(35)
[41676]204#define DISUSE_IMMEDIATE64_SX8 RT_BIT_64(36)
[1]205
[41676]206/** Mask of immediate use flags. */
207#define DISUSE_IMMEDIATE ( DISUSE_IMMEDIATE8 \
208 | DISUSE_IMMEDIATE16 \
209 | DISUSE_IMMEDIATE32 \
210 | DISUSE_IMMEDIATE64 \
211 | DISUSE_IMMEDIATE8_REL \
212 | DISUSE_IMMEDIATE16_REL \
213 | DISUSE_IMMEDIATE32_REL \
214 | DISUSE_IMMEDIATE64_REL \
215 | DISUSE_IMMEDIATE_ADDR_0_32 \
216 | DISUSE_IMMEDIATE_ADDR_16_32 \
217 | DISUSE_IMMEDIATE_ADDR_0_16 \
218 | DISUSE_IMMEDIATE_ADDR_16_16 \
219 | DISUSE_IMMEDIATE16_SX8 \
220 | DISUSE_IMMEDIATE32_SX8 \
221 | DISUSE_IMMEDIATE64_SX8)
222/** Check if the use flags indicates an effective address. */
223#define DISUSE_IS_EFFECTIVE_ADDR(a_fUseFlags) (!!( (a_fUseFlags) \
224 & ( DISUSE_BASE \
225 | DISUSE_INDEX \
226 | DISUSE_DISPLACEMENT32 \
227 | DISUSE_DISPLACEMENT64 \
228 | DISUSE_DISPLACEMENT16 \
229 | DISUSE_DISPLACEMENT8 \
230 | DISUSE_RIPDISPLACEMENT32) ))
[1]231/** @} */
232
[8142]233
[1]234/**
[41745]235 * Opcode parameter (operand) details.
[1]236 */
[41692]237typedef struct DISOPPARAM
[1]238{
[41678]239 /** A combination of DISUSE_XXX. */
[99220]240 uint64_t fUse;
[41744]241 /** Immediate value or address, applicable if any of the flags included in
[99220]242 * DISUSE_IMMEDIATE are set in fUse. */
243 uint64_t uValue;
244
245 /** Architecture specific parameter state. */
[101540]246 RT_GCC_EXTENSION union
[41662]247 {
[101539]248 /** x86/AMD64 specific state. */
249 DIS_OP_PARAM_X86_T x86;
[99241]250#if defined(VBOX_DIS_WITH_ARMV8)
251 /** ARMv8 specific state. */
[101539]252 DIS_OP_PARAM_ARMV8_T armv8;
[99241]253#endif
[101539]254 };
[41692]255} DISOPPARAM;
256AssertCompileSize(DISOPPARAM, 32);
[1]257/** Pointer to opcode parameter. */
[41730]258typedef const DISOPPARAM *PCDISOPPARAM;
[1]259
260
[41730]261/**
[41760]262 * Callback for reading instruction bytes.
[41658]263 *
[101539]264 * @returns VBox status code, bytes in DISSTATE::Instr::ab and byte count in
[41790]265 * DISSTATE::cbCachedInstr.
[41760]266 * @param pDis Pointer to the disassembler state. The user
[41790]267 * argument can be found in DISSTATE::pvUser if needed.
[41760]268 * @param offInstr The offset relative to the start of the instruction.
269 *
270 * To get the source address, add this to
[41790]271 * DISSTATE::uInstrAddr.
[41760]272 *
273 * To calculate the destination buffer address, use it
[101539]274 * as an index into DISSTATE::Instr::ab.
[41760]275 *
276 * @param cbMinRead The minimum number of bytes to read.
277 * @param cbMaxRead The maximum number of bytes that may be read.
[41658]278 */
[85121]279typedef DECLCALLBACKTYPE(int, FNDISREADBYTES,(PDISSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead));
[41658]280/** Pointer to a opcode byte reader. */
281typedef FNDISREADBYTES *PFNDISREADBYTES;
[1]282
283
[41730]284/**
285 * The diassembler state and result.
286 */
[41790]287typedef struct DISSTATE
[1]288{
[101539]289 /** The different instruction views.
290 * @sa cbCachedInstr, FNDISREADBYTES */
[8333]291 union
292 {
[101539]293 /** Byte (8-bit) view.
294 * This is the one referred to by FNDISREADBYTES and cbCached. */
295 uint8_t ab[16];
[99220]296 /** Single 16-bit view. */
297 uint16_t u16;
298 /** Single 32-bit view. */
299 uint32_t u32;
300 /** 16-bit view. */
[101539]301 uint16_t au16[8];
[99220]302 /** 32-bit view. */
[101539]303 uint32_t au32[4];
[99220]304 /** 64-bit view. */
[101539]305 uint64_t au64[2];
306 } Instr;
[99220]307
[1]308 /** Pointer to the current instruction. */
[99220]309 PCDISOPCODE pCurInstr;
[41692]310#if ARCH_BITS == 32
[99220]311 uint32_t uPtrPadding2;
[41658]312#endif
[41792]313
[99220]314 DISOPPARAM Param1;
315 DISOPPARAM Param2;
316 DISOPPARAM Param3;
317 DISOPPARAM Param4;
318
[101539]319 /** The number of valid bytes in DISSTATE::Instr. */
[99220]320 uint8_t cbCachedInstr;
321 /** The CPU mode (DISCPUMODE). */
322 uint8_t uCpuMode;
323 /** The instruction size. */
324 uint8_t cbInstr;
325 /** Unused bytes. */
326 uint8_t abUnused[1];
327
[41792]328 /** Return code set by a worker function like the opcode bytes readers. */
[99220]329 int32_t rc;
[41692]330 /** The address of the instruction. */
[99220]331 RTUINTPTR uInstrAddr;
[41658]332 /** Optional read function */
[99220]333 PFNDISREADBYTES pfnReadBytes;
[41692]334#if ARCH_BITS == 32
[99220]335 uint32_t uPadding3;
[41692]336#endif
[41731]337 /** User data supplied as an argument to the APIs. */
[101539]338 void *pvUser;
[41692]339#if ARCH_BITS == 32
[99220]340 uint32_t uPadding4;
[41692]341#endif
[99220]342
343 /** Architecture specific state. */
[101540]344 RT_GCC_EXTENSION union
[99220]345 {
[101539]346 /** x86/AMD64 specific state. */
347 DIS_STATE_X86_T x86;
[99241]348#if defined(VBOX_DIS_WITH_ARMV8)
349 /** ARMv8 specific state. */
[101539]350 DIS_STATE_ARMV8_T armv8;
[99241]351#endif
[101539]352 };
[41790]353} DISSTATE;
[101539]354AssertCompileMemberAlignment(DISSTATE, x86, 8);
[53094]355AssertCompileSize(DISSTATE, 0xd8);
[1]356
[20530]357
[1]358
[41669]359DISDECL(int) DISInstrToStr(void const *pvInstr, DISCPUMODE enmCpuMode,
[41790]360 PDISSTATE pDis, uint32_t *pcbInstr, char *pszOutput, size_t cbOutput);
[41671]361DISDECL(int) DISInstrToStrWithReader(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, PFNDISREADBYTES pfnReadBytes, void *pvUser,
[41790]362 PDISSTATE pDis, uint32_t *pcbInstr, char *pszOutput, size_t cbOutput);
[41671]363DISDECL(int) DISInstrToStrEx(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode,
364 PFNDISREADBYTES pfnReadBytes, void *pvUser, uint32_t uFilter,
[41790]365 PDISSTATE pDis, uint32_t *pcbInstr, char *pszOutput, size_t cbOutput);
[1]366
[41790]367DISDECL(int) DISInstr(void const *pvInstr, DISCPUMODE enmCpuMode, PDISSTATE pDis, uint32_t *pcbInstr);
[41674]368DISDECL(int) DISInstrWithReader(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, PFNDISREADBYTES pfnReadBytes, void *pvUser,
[41790]369 PDISSTATE pDis, uint32_t *pcbInstr);
[41886]370DISDECL(int) DISInstrEx(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, uint32_t uFilter,
371 PFNDISREADBYTES pfnReadBytes, void *pvUser,
372 PDISSTATE pDis, uint32_t *pcbInstr);
373DISDECL(int) DISInstrWithPrefetchedBytes(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, uint32_t fFilter,
374 void const *pvPrefetched, size_t cbPretched,
375 PFNDISREADBYTES pfnReadBytes, void *pvUser,
376 PDISSTATE pDis, uint32_t *pcbInstr);
[1]377
[93742]378DISDECL(uint8_t) DISGetParamSize(PCDISSTATE pDis, PCDISOPPARAM pParam);
[97211]379#if 0 /* unused */
[41790]380DISDECL(DISSELREG) DISDetectSegReg(PCDISSTATE pDis, PCDISOPPARAM pParam);
381DISDECL(uint8_t) DISQuerySegPrefixByte(PCDISSTATE pDis);
[97211]382#endif
[1]383
[97211]384#if 0 /* Needs refactoring if we want to use this again, CPUMCTXCORE is history. */
[41731]385/** @name Flags returned by DISQueryParamVal (DISQPVPARAMVAL::flags).
386 * @{
387 */
388#define DISQPV_FLAG_8 UINT8_C(0x01)
389#define DISQPV_FLAG_16 UINT8_C(0x02)
390#define DISQPV_FLAG_32 UINT8_C(0x04)
391#define DISQPV_FLAG_64 UINT8_C(0x08)
392#define DISQPV_FLAG_FARPTR16 UINT8_C(0x10)
393#define DISQPV_FLAG_FARPTR32 UINT8_C(0x20)
394/** @} */
395
396/** @name Types returned by DISQueryParamVal (DISQPVPARAMVAL::flags).
397 * @{ */
398#define DISQPV_TYPE_REGISTER UINT8_C(1)
399#define DISQPV_TYPE_ADDRESS UINT8_C(2)
400#define DISQPV_TYPE_IMMEDIATE UINT8_C(3)
401/** @} */
402
403typedef struct
404{
405 union
406 {
407 uint8_t val8;
408 uint16_t val16;
409 uint32_t val32;
410 uint64_t val64;
411
[93742]412 int8_t i8;
413 int16_t i16;
414 int32_t i32;
415 int64_t i64;
416
[41731]417 struct
418 {
419 uint16_t sel;
420 uint32_t offset;
421 } farptr;
422 } val;
423
424 uint8_t type;
425 uint8_t size;
426 uint8_t flags;
427} DISQPVPARAMVAL;
428/** Pointer to opcode parameter value. */
429typedef DISQPVPARAMVAL *PDISQPVPARAMVAL;
430
431/** Indicates which parameter DISQueryParamVal should operate on. */
432typedef enum DISQPVWHICH
433{
434 DISQPVWHICH_DST = 1,
435 DISQPVWHICH_SRC,
436 DISQPVWHAT_32_BIT_HACK = 0x7fffffff
437} DISQPVWHICH;
[41790]438DISDECL(int) DISQueryParamVal(PCPUMCTXCORE pCtx, PCDISSTATE pDis, PCDISOPPARAM pParam, PDISQPVPARAMVAL pParamVal, DISQPVWHICH parmtype);
439DISDECL(int) DISQueryParamRegPtr(PCPUMCTXCORE pCtx, PCDISSTATE pDis, PCDISOPPARAM pParam, void **ppReg, size_t *pcbSize);
[41731]440
[10016]441DISDECL(int) DISFetchReg8(PCCPUMCTXCORE pCtx, unsigned reg8, uint8_t *pVal);
442DISDECL(int) DISFetchReg16(PCCPUMCTXCORE pCtx, unsigned reg16, uint16_t *pVal);
443DISDECL(int) DISFetchReg32(PCCPUMCTXCORE pCtx, unsigned reg32, uint32_t *pVal);
444DISDECL(int) DISFetchReg64(PCCPUMCTXCORE pCtx, unsigned reg64, uint64_t *pVal);
[41727]445DISDECL(int) DISFetchRegSeg(PCCPUMCTXCORE pCtx, DISSELREG sel, RTSEL *pVal);
[8142]446DISDECL(int) DISWriteReg8(PCPUMCTXCORE pRegFrame, unsigned reg8, uint8_t val8);
447DISDECL(int) DISWriteReg16(PCPUMCTXCORE pRegFrame, unsigned reg32, uint16_t val16);
448DISDECL(int) DISWriteReg32(PCPUMCTXCORE pRegFrame, unsigned reg32, uint32_t val32);
449DISDECL(int) DISWriteReg64(PCPUMCTXCORE pRegFrame, unsigned reg64, uint64_t val64);
[41727]450DISDECL(int) DISWriteRegSeg(PCPUMCTXCORE pCtx, DISSELREG sel, RTSEL val);
[8142]451DISDECL(int) DISPtrReg8(PCPUMCTXCORE pCtx, unsigned reg8, uint8_t **ppReg);
452DISDECL(int) DISPtrReg16(PCPUMCTXCORE pCtx, unsigned reg16, uint16_t **ppReg);
453DISDECL(int) DISPtrReg32(PCPUMCTXCORE pCtx, unsigned reg32, uint32_t **ppReg);
454DISDECL(int) DISPtrReg64(PCPUMCTXCORE pCtx, unsigned reg64, uint64_t **ppReg);
[97211]455#endif /* obsolete */
[1]456
[9266]457
458/**
459 * Try resolve an address into a symbol name.
460 *
461 * For use with DISFormatYasmEx(), DISFormatMasmEx() and DISFormatGasEx().
462 *
463 * @returns VBox status code.
464 * @retval VINF_SUCCESS on success, pszBuf contains the full symbol name.
465 * @retval VINF_BUFFER_OVERFLOW if pszBuf is too small the symbol name. The
466 * content of pszBuf is truncated and zero terminated.
467 * @retval VERR_SYMBOL_NOT_FOUND if no matching symbol was found for the address.
468 *
[41790]469 * @param pDis Pointer to the disassembler CPU state.
[9266]470 * @param u32Sel The selector value. Use DIS_FMT_SEL_IS_REG, DIS_FMT_SEL_GET_VALUE,
471 * DIS_FMT_SEL_GET_REG to access this.
472 * @param uAddress The segment address.
473 * @param pszBuf Where to store the symbol name
474 * @param cchBuf The size of the buffer.
475 * @param poff If not a perfect match, then this is where the offset from the return
476 * symbol to the specified address is returned.
477 * @param pvUser The user argument.
478 */
[85121]479typedef DECLCALLBACKTYPE(int, FNDISGETSYMBOL,(PCDISSTATE pDis, uint32_t u32Sel, RTUINTPTR uAddress, char *pszBuf, size_t cchBuf,
480 RTINTPTR *poff, void *pvUser));
[9266]481/** Pointer to a FNDISGETSYMBOL(). */
482typedef FNDISGETSYMBOL *PFNDISGETSYMBOL;
483
484/**
485 * Checks if the FNDISGETSYMBOL argument u32Sel is a register or not.
486 */
487#define DIS_FMT_SEL_IS_REG(u32Sel) ( !!((u32Sel) & RT_BIT(31)) )
488
489/**
490 * Extracts the selector value from the FNDISGETSYMBOL argument u32Sel.
491 * @returns Selector value.
492 */
493#define DIS_FMT_SEL_GET_VALUE(u32Sel) ( (RTSEL)(u32Sel) )
494
495/**
496 * Extracts the register number from the FNDISGETSYMBOL argument u32Sel.
497 * @returns USE_REG_CS, USE_REG_SS, USE_REG_DS, USE_REG_ES, USE_REG_FS or USE_REG_FS.
498 */
499#define DIS_FMT_SEL_GET_REG(u32Sel) ( ((u32Sel) >> 16) & 0xf )
500
501/** @internal */
502#define DIS_FMT_SEL_FROM_REG(uReg) ( ((uReg) << 16) | RT_BIT(31) | 0xffff )
503/** @internal */
504#define DIS_FMT_SEL_FROM_VALUE(Sel) ( (Sel) & 0xffff )
505
506
507/** @name Flags for use with DISFormatYasmEx(), DISFormatMasmEx() and DISFormatGasEx().
508 * @{
509 */
510/** Put the address to the right. */
511#define DIS_FMT_FLAGS_ADDR_RIGHT RT_BIT_32(0)
512/** Put the address to the left. */
513#define DIS_FMT_FLAGS_ADDR_LEFT RT_BIT_32(1)
514/** Put the address in comments.
515 * For some assemblers this implies placing it to the right. */
516#define DIS_FMT_FLAGS_ADDR_COMMENT RT_BIT_32(2)
517/** Put the instruction bytes to the right of the disassembly. */
518#define DIS_FMT_FLAGS_BYTES_RIGHT RT_BIT_32(3)
519/** Put the instruction bytes to the left of the disassembly. */
520#define DIS_FMT_FLAGS_BYTES_LEFT RT_BIT_32(4)
521/** Put the instruction bytes in comments.
522 * For some assemblers this implies placing the bytes to the right. */
523#define DIS_FMT_FLAGS_BYTES_COMMENT RT_BIT_32(5)
524/** Put the bytes in square brackets. */
525#define DIS_FMT_FLAGS_BYTES_BRACKETS RT_BIT_32(6)
526/** Put spaces between the bytes. */
527#define DIS_FMT_FLAGS_BYTES_SPACED RT_BIT_32(7)
528/** Display the relative +/- offset of branch instructions that uses relative addresses,
529 * and put the target address in parenthesis. */
530#define DIS_FMT_FLAGS_RELATIVE_BRANCH RT_BIT_32(8)
[9271]531/** Strict assembly. The assembly should, when ever possible, make the
532 * assembler reproduce the exact same binary. (Refers to the yasm
533 * strict keyword.) */
534#define DIS_FMT_FLAGS_STRICT RT_BIT_32(9)
[9266]535/** Checks if the given flags are a valid combination. */
536#define DIS_FMT_FLAGS_IS_VALID(fFlags) \
[9271]537 ( !((fFlags) & ~UINT32_C(0x000003ff)) \
[9266]538 && ((fFlags) & (DIS_FMT_FLAGS_ADDR_RIGHT | DIS_FMT_FLAGS_ADDR_LEFT)) != (DIS_FMT_FLAGS_ADDR_RIGHT | DIS_FMT_FLAGS_ADDR_LEFT) \
539 && ( !((fFlags) & DIS_FMT_FLAGS_ADDR_COMMENT) \
540 || (fFlags & (DIS_FMT_FLAGS_ADDR_RIGHT | DIS_FMT_FLAGS_ADDR_LEFT)) ) \
541 && ((fFlags) & (DIS_FMT_FLAGS_BYTES_RIGHT | DIS_FMT_FLAGS_BYTES_LEFT)) != (DIS_FMT_FLAGS_BYTES_RIGHT | DIS_FMT_FLAGS_BYTES_LEFT) \
542 && ( !((fFlags) & (DIS_FMT_FLAGS_BYTES_COMMENT | DIS_FMT_FLAGS_BYTES_BRACKETS)) \
543 || (fFlags & (DIS_FMT_FLAGS_BYTES_RIGHT | DIS_FMT_FLAGS_BYTES_LEFT)) ) \
544 )
545/** @} */
546
[41790]547DISDECL(size_t) DISFormatYasm( PCDISSTATE pDis, char *pszBuf, size_t cchBuf);
548DISDECL(size_t) DISFormatYasmEx(PCDISSTATE pDis, char *pszBuf, size_t cchBuf, uint32_t fFlags, PFNDISGETSYMBOL pfnGetSymbol, void *pvUser);
549DISDECL(size_t) DISFormatMasm( PCDISSTATE pDis, char *pszBuf, size_t cchBuf);
550DISDECL(size_t) DISFormatMasmEx(PCDISSTATE pDis, char *pszBuf, size_t cchBuf, uint32_t fFlags, PFNDISGETSYMBOL pfnGetSymbol, void *pvUser);
551DISDECL(size_t) DISFormatGas( PCDISSTATE pDis, char *pszBuf, size_t cchBuf);
552DISDECL(size_t) DISFormatGasEx( PCDISSTATE pDis, char *pszBuf, size_t cchBuf, uint32_t fFlags, PFNDISGETSYMBOL pfnGetSymbol, void *pvUser);
[9266]553
[99319]554DISDECL(size_t) DISFormatArmV8( PCDISSTATE pDis, char *pszBuf, size_t cchBuf);
555DISDECL(size_t) DISFormatArmV8Ex(PCDISSTATE pDis, char *pszBuf, size_t cchBuf, uint32_t fFlags, PFNDISGETSYMBOL pfnGetSymbol, void *pvUser);
556
[41790]557/** @todo DISAnnotate(PCDISSTATE pDis, char *pszBuf, size_t cchBuf, register
558 * reader, memory reader); */
[9266]559
[58110]560/** @} */
[41501]561
[20374]562RT_C_DECLS_END
[1]563
[76585]564#endif /* !VBOX_INCLUDED_dis_h */
[1]565
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