VirtualBox

source: vbox/trunk/src/VBox/Disassembler/DisasmMisc.cpp@ 100594

Last change on this file since 100594 was 99220, checked in by vboxsync, 19 months ago

Disassember,*: Start separating the disassembler into a architecture specific and common part, bugref:10394

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
  • Property svn:sync_process set to export
File size: 5.6 KB
Line 
1/* $Id: DisasmMisc.cpp 99220 2023-03-30 12:40:46Z vboxsync $ */
2/** @file
3 * VBox disassembler- Misc Helpers.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
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
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#define LOG_GROUP LOG_GROUP_DIS
33#include <VBox/dis.h>
34#include <VBox/disopcode-x86-amd64.h>
35#include <iprt/errcore.h>
36#include <VBox/log.h>
37#include <VBox/vmm/cpum.h>
38#include <iprt/assert.h>
39#include <iprt/string.h>
40#include <iprt/stdarg.h>
41#include "DisasmInternal.h"
42
43
44DISDECL(uint8_t) DISGetParamSize(PCDISSTATE pDis, PCDISOPPARAM pParam)
45{
46 unsigned subtype = OP_PARM_VSUBTYPE(pParam->arch.x86.fParam);
47 switch (subtype)
48 {
49 case OP_PARM_v:
50 switch (pDis->arch.x86.uOpMode)
51 {
52 case DISCPUMODE_32BIT:
53 return 4;
54 case DISCPUMODE_64BIT:
55 return 8;
56 case DISCPUMODE_16BIT:
57 return 2;
58 default: AssertFailed(); /* make gcc happy */ return 4;
59 }
60 break;
61
62 case OP_PARM_b:
63 return 1;
64
65 case OP_PARM_w:
66 return 2;
67
68 case OP_PARM_d:
69 return 4;
70
71 case OP_PARM_q:
72 return 8;
73
74 case OP_PARM_dq:
75 return 16;
76
77 case OP_PARM_qq:
78 return 32;
79
80 case 0: /* nop, pause, lea, wrmsr, rdmsr, etc. Most of these due to DISOPPARAM::cb being initialized in the wrong place
81 (disParseInstruction) where it will be called on intermediate stuff like IDX_ParseTwoByteEsc. The parameter
82 parsers should do it instead, though I see the potential filtering issue. */
83 //Assert( pDis->pCurInstr
84 // && ( pDis->pCurInstr->uOpcode == OP_NOP
85 // || pDis->pCurInstr->uOpcode == OP_LEA ));
86 return 0;
87
88 case OP_PARM_p: /* far pointer */
89 if (pDis->arch.x86.uAddrMode == DISCPUMODE_32BIT)
90 return 6; /* 16:32 */
91 if (pDis->arch.x86.uAddrMode == DISCPUMODE_64BIT)
92 return 12; /* 16:64 */
93 return 4; /* 16:16 */
94
95 case OP_PARM_s: /* lgdt, sgdt, lidt, sidt */
96 return pDis->uCpuMode == DISCPUMODE_64BIT ? 2 + 8 : 2 + 4;
97
98 case OP_PARM_a:
99 return pDis->arch.x86.uOpMode == DISCPUMODE_16BIT ? 2 + 2 : 4 + 4;
100
101 case OP_PARM_pi:
102 return 8;
103
104 case OP_PARM_sd:
105 case OP_PARM_ss:
106 return 16;
107
108 case OP_PARM_x:
109 case OP_PARM_pd:
110 case OP_PARM_ps:
111 return VEXREG_IS256B(pDis->arch.x86.bVexDestReg) ? 32 : 16; //??
112
113 case OP_PARM_y:
114 return pDis->arch.x86.uOpMode == DISCPUMODE_64BIT ? 4 : 8; //??
115
116 case OP_PARM_z:
117 if (pParam->arch.x86.cb)
118 return pParam->arch.x86.cb;
119 return pDis->arch.x86.uOpMode == DISCPUMODE_16BIT ? 2 : 4; //??
120
121 default:
122 if (pParam->arch.x86.cb)
123 return pParam->arch.x86.cb;
124 /// @todo dangerous!!!
125 AssertMsgFailed(("subtype=%#x fParam=%#x fUse=%#RX64 op=%#x\n", subtype, pParam->arch.x86.fParam, pParam->fUse,
126 pDis->pCurInstr ? pDis->pCurInstr->uOpcode : 0));
127 return 4;
128 }
129}
130
131#if 0 /* currently unused */
132DISDECL(DISSELREG) DISDetectSegReg(PCDISSTATE pDis, PCDISOPPARAM pParam)
133{
134 if (pDis->arch.x86.fPrefix & DISPREFIX_SEG)
135 /* Use specified SEG: prefix. */
136 return (DISSELREG)pDis->arch.x86.idxSegPrefix;
137
138 /* Guess segment register by parameter type. */
139 if (pParam->fUse & (DISUSE_REG_GEN32|DISUSE_REG_GEN64|DISUSE_REG_GEN16))
140 {
141 AssertCompile(DISGREG_ESP == DISGREG_RSP);
142 AssertCompile(DISGREG_EBP == DISGREG_RBP);
143 AssertCompile(DISGREG_ESP == DISGREG_SP);
144 AssertCompile(DISGREG_EBP == DISGREG_BP);
145 if (pParam->arch.x86.Base.idxGenReg == DISGREG_ESP || pParam->arch.x86.Base.idxGenReg == DISGREG_EBP)
146 return DISSELREG_SS;
147 }
148 /* Default is use DS: for data access. */
149 return DISSELREG_DS;
150}
151
152
153DISDECL(uint8_t) DISQuerySegPrefixByte(PCDISSTATE pDis)
154{
155 Assert(pDis->arch.x86.fPrefix & DISPREFIX_SEG);
156 switch (pDis->arch.x86.idxSegPrefix)
157 {
158 case DISSELREG_ES:
159 return 0x26;
160 case DISSELREG_CS:
161 return 0x2E;
162 case DISSELREG_SS:
163 return 0x36;
164 case DISSELREG_DS:
165 return 0x3E;
166 case DISSELREG_FS:
167 return 0x64;
168 case DISSELREG_GS:
169 return 0x65;
170 default:
171 AssertFailed();
172 return 0;
173 }
174}
175#endif
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