VirtualBox

source: vbox/trunk/src/VBox/Disassembler/DisasmInternal.h

Last change on this file was 101539, checked in by vboxsync, 10 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: 7.5 KB
RevLine 
[41668]1/* $Id: DisasmInternal.h 101539 2023-10-22 02:43:09Z vboxsync $ */
[1]2/** @file
[41668]3 * VBox disassembler - Internal header.
[1]4 */
5
6/*
[98103]7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
[1]8 *
[96407]9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
[1]26 */
27
[76566]28#ifndef VBOX_INCLUDED_SRC_DisasmInternal_h
29#define VBOX_INCLUDED_SRC_DisasmInternal_h
[76516]30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
[1]33
34#include <VBox/types.h>
[99236]35#include <VBox/err.h>
[1]36#include <VBox/dis.h>
[99236]37#include <VBox/log.h>
[1]38
[99236]39#include <iprt/param.h>
[1]40
[99236]41
[41690]42/** @defgroup grp_dis_int Internals.
43 * @ingroup grp_dis
44 * @{
45 */
46
[101539]47/** This must be less or equal to DISSTATE::Instr.ab.
[99236]48 * See Vol3A/Table 6-2 and Vol3B/Section22.25 for instance. */
49#define DIS_MAX_INSTR_LENGTH 15
[1]50
[99236]51/** Whether we can do unaligned access. */
52#if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
53# define DIS_HOST_UNALIGNED_ACCESS_OK
[95167]54#endif
[1]55
56
[41690]57/** @def OP
[55033]58 * Wrapper which initializes an DISOPCODE.
[41690]59 * We must use this so that we can exclude unused fields in order
60 * to save precious bytes in the GC version.
61 *
62 * @internal
63 */
[92809]64#if DISOPCODE_FORMAT == 0
[41690]65# define OP(pszOpcode, idxParse1, idxParse2, idxParse3, opcode, param1, param2, param3, optype) \
[53094]66 { pszOpcode, idxParse1, idxParse2, idxParse3, 0, opcode, param1, param2, param3, 0, 0, optype }
67# define OPVEX(pszOpcode, idxParse1, idxParse2, idxParse3, idxParse4, opcode, param1, param2, param3, param4, optype) \
[99220]68 { pszOpcode, idxParse1, idxParse2, idxParse3, idxParse4, opcode, param1, param2, param3, param4, 0, optype | DISOPTYPE_X86_SSE }
[92809]69
70#elif DISOPCODE_FORMAT == 16
[92805]71# define OP(pszOpcode, idxParse1, idxParse2, idxParse3, opcode, param1, param2, param3, optype) \
[92809]72 { optype, opcode, idxParse1, idxParse2, param1, param2, idxParse3, param3, 0, 0 }
[92805]73# define OPVEX(pszOpcode, idxParse1, idxParse2, idxParse3, idxParse4, opcode, param1, param2, param3, param4, optype) \
[99220]74 { optype | DISOPTYPE_X86_SSE, opcode, idxParse1, idxParse2, param1, param2, idxParse3, param3, param4, idxParse4 }
[92809]75
76#elif DISOPCODE_FORMAT == 15
[41690]77# define OP(pszOpcode, idxParse1, idxParse2, idxParse3, opcode, param1, param2, param3, optype) \
[92809]78 { opcode, idxParse1, idxParse2, idxParse3, param1, param2, param3, optype, 0, 0 }
[53094]79# define OPVEX(pszOpcode, idxParse1, idxParse2, idxParse3, idxParse4, opcode, param1, param2, param3, param4, optype) \
[99220]80 { opcode, idxParse1, idxParse2, idxParse3, param1, param2, param3, optype | DISOPTYPE_X86_SSE, param4, idxParse4 }
[92809]81#else
82# error Unsupported DISOPCODE_FORMAT value
[41690]83#endif
84
85
[99236]86/* Common */
87DECLHIDDEN(void) disReadMore(PDISSTATE pDis, uint8_t offInstr, uint8_t cbMin);
88DECLHIDDEN(uint8_t) disReadByteSlow(PDISSTATE pDis, size_t offInstr);
89DECLHIDDEN(uint16_t) disReadWordSlow(PDISSTATE pDis, size_t offInstr);
90DECLHIDDEN(uint32_t) disReadDWordSlow(PDISSTATE pDis, size_t offInstr);
91DECLHIDDEN(uint64_t) disReadQWordSlow(PDISSTATE pDis, size_t offInstr);
92
93
94/**
95 * Read a byte (8-bit) instruction.
96 *
97 * @returns The requested byte.
98 * @param pDis The disassembler state.
99 * @param uAddress The address.
100 */
101DECL_FORCE_INLINE(uint8_t) disReadByte(PDISSTATE pDis, size_t offInstr)
102{
103 if (offInstr >= pDis->cbCachedInstr)
104 return disReadByteSlow(pDis, offInstr);
[101539]105 return pDis->Instr.ab[offInstr];
[99236]106}
107
108
109/**
110 * Read a word (16-bit) instruction.
111 *
112 * @returns The requested word.
113 * @param pDis The disassembler state.
114 * @param offInstr The offset of the qword relative to the
115 * instruction.
116 */
117DECL_FORCE_INLINE(uint16_t) disReadWord(PDISSTATE pDis, size_t offInstr)
118{
119 if (offInstr + 2 > pDis->cbCachedInstr)
120 return disReadWordSlow(pDis, offInstr);
121
122#ifdef DIS_HOST_UNALIGNED_ACCESS_OK
[101539]123 return *(uint16_t const *)&pDis->Instr.ab[offInstr];
[99236]124#else
[101539]125 return RT_MAKE_U16(pDis->Instr.ab[offInstr], pDis->Instr.ab[offInstr + 1]);
[99236]126#endif
127}
128
129
130/**
131 * Read a dword (32-bit) instruction.
132 *
133 * @returns The requested dword.
134 * @param pDis The disassembler state.
135 * @param offInstr The offset of the qword relative to the
136 * instruction.
137 */
138DECL_FORCE_INLINE(uint32_t) disReadDWord(PDISSTATE pDis, size_t offInstr)
139{
140 if (offInstr + 4 > pDis->cbCachedInstr)
141 return disReadDWordSlow(pDis, offInstr);
142
143#ifdef DIS_HOST_UNALIGNED_ACCESS_OK
[101539]144 return *(uint32_t const *)&pDis->Instr.ab[offInstr];
[99236]145#else
[101539]146 return RT_MAKE_U32_FROM_U8(pDis->Instr.ab[offInstr ], pDis->Instr.ab[offInstr + 1],
147 pDis->Instr.ab[offInstr + 2], pDis->Instr.ab[offInstr + 3]);
[99236]148#endif
149}
150
151
152/**
153 * Read a qword (64-bit) instruction.
154 *
155 * @returns The requested qword.
156 * @param pDis The disassembler state.
157 * @param uAddress The address.
158 */
159DECL_FORCE_INLINE(uint64_t) disReadQWord(PDISSTATE pDis, size_t offInstr)
160{
161 if (offInstr + 8 > pDis->cbCachedInstr)
162 return disReadQWordSlow(pDis, offInstr);
163
164#ifdef DIS_HOST_UNALIGNED_ACCESS_OK
[101539]165 return *(uint64_t const *)&pDis->Instr.ab[offInstr];
[99236]166#else
[101539]167 return RT_MAKE_U64_FROM_U8(pDis->Instr.ab[offInstr ], pDis->Instr.ab[offInstr + 1],
168 pDis->Instr.ab[offInstr + 2], pDis->Instr.ab[offInstr + 3],
169 pDis->Instr.ab[offInstr + 4], pDis->Instr.ab[offInstr + 5],
170 pDis->Instr.ab[offInstr + 6], pDis->Instr.ab[offInstr + 7]);
[99236]171#endif
172}
173
174
175/**
176 * Reads some bytes into the cache.
177 *
178 * While this will set DISSTATE::rc on failure, the caller should disregard
179 * this since that is what would happen if we didn't prefetch bytes prior to the
180 * instruction parsing.
181 *
182 * @param pDis The disassembler state.
183 */
184DECL_FORCE_INLINE(void) disPrefetchBytes(PDISSTATE pDis)
185{
186 /*
187 * Read some bytes into the cache. (If this fail we continue as nothing
188 * has gone wrong since this is what would happen if we didn't precharge
189 * the cache here.)
190 */
[101539]191 int rc = pDis->pfnReadBytes(pDis, 0, 1, sizeof(pDis->Instr.ab));
[99236]192 if (RT_SUCCESS(rc))
193 {
194 Assert(pDis->cbCachedInstr >= 1);
[101539]195 Assert(pDis->cbCachedInstr <= sizeof(pDis->Instr.ab));
[99236]196 }
197 else
198 {
199 Log(("Initial read failed with rc=%Rrc!!\n", rc));
200 pDis->rc = rc;
201 }
202}
203
204
[99239]205#if defined(VBOX_DIS_WITH_X86_AMD64)
[99236]206DECLHIDDEN(PCDISOPCODE) disInitializeStateX86(PDISSTATE pDis, DISCPUMODE enmCpuMode, uint32_t fFilter);
207DECLHIDDEN(int) disInstrWorkerX86(PDISSTATE pDis, PCDISOPCODE paOneByteMap, uint32_t *pcbInstr);
[99239]208#endif
[99241]209#if defined(VBOX_DIS_WITH_ARMV8)
210DECLHIDDEN(PCDISOPCODE) disInitializeStateArmV8(PDISSTATE pDis, DISCPUMODE enmCpuMode, uint32_t fFilter);
211DECLHIDDEN(int) disInstrWorkerArmV8(PDISSTATE pDis, PCDISOPCODE paOneByteMap, uint32_t *pcbInstr);
212#endif
[99236]213
[41790]214size_t disFormatBytes(PCDISSTATE pDis, char *pszDst, size_t cchDst, uint32_t fFlags);
[9266]215
[41690]216/** @} */
[76566]217#endif /* !VBOX_INCLUDED_SRC_DisasmInternal_h */
[1]218
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle
ContactPrivacy/Do Not Sell My InfoTerms of Use