VirtualBox

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

Last change on this file since 3257 was 3205, checked in by vboxsync, 17 years ago

Added OPTYPE_PORTIO_READ & OPTYPE_PORTIO_WRITE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.4 KB
Line 
1/** @file
2 * DIS - The VirtualBox Disassembler.
3 */
4
5/*
6 * Copyright (C) 2006-2007 innotek GmbH
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License as published by the Free Software Foundation,
12 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
13 * distribution. VirtualBox OSE is distributed in the hope that it will
14 * be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * If you received this file as part of a commercial VirtualBox
17 * distribution, then only the terms of your commercial VirtualBox
18 * license agreement apply instead of the previous paragraph.
19 */
20
21#ifndef __VBox_disasm_h__
22#define __VBox_disasm_h__
23
24#include <VBox/cdefs.h>
25#include <VBox/types.h>
26#include <VBox/cpum.h>
27#include <VBox/disopcode.h>
28
29#if defined(__L4ENV__) || defined(IN_RING0)
30#include <setjmp.h>
31#endif
32
33__BEGIN_DECLS
34
35
36/** CPU mode flags (DISCPUSTATE::mode).
37 * @{
38 */
39#define CPUMODE_16BIT 1
40#define CPUMODE_32BIT 2
41/** @} */
42
43/** Prefix byte flags
44 * @{
45 */
46#define PREFIX_NONE 0
47/** non-default address size. */
48#define PREFIX_ADDRSIZE 1
49/** non-default operand size. */
50#define PREFIX_OPSIZE 2
51/** lock prefix. */
52#define PREFIX_LOCK 4
53/** segment prefix. */
54#define PREFIX_SEG 8
55/** rep(e) prefix (not a prefix, but we'll treat is as one). */
56#define PREFIX_REP 16
57/** rep(e) prefix (not a prefix, but we'll treat is as one). */
58#define PREFIX_REPNE 32
59/** @} */
60
61/**
62 * Operand type.
63 */
64#define OPTYPE_INVALID BIT(0)
65#define OPTYPE_HARMLESS BIT(1)
66#define OPTYPE_CONTROLFLOW BIT(2)
67#define OPTYPE_POTENTIALLY_DANGEROUS BIT(3)
68#define OPTYPE_DANGEROUS BIT(4)
69#define OPTYPE_PORTIO BIT(5)
70#define OPTYPE_PRIVILEGED BIT(6)
71#define OPTYPE_PRIVILEGED_NOTRAP BIT(7)
72#define OPTYPE_UNCOND_CONTROLFLOW BIT(8)
73#define OPTYPE_RELATIVE_CONTROLFLOW BIT(9)
74#define OPTYPE_COND_CONTROLFLOW BIT(10)
75#define OPTYPE_INTERRUPT BIT(11)
76#define OPTYPE_ILLEGAL BIT(12)
77#define OPTYPE_RRM_DANGEROUS BIT(14) /**< Some additional dangerouse ones when recompiling raw r0. */
78#define OPTYPE_RRM_DANGEROUS_16 BIT(15) /**< Some additional dangerouse ones when recompiling 16-bit raw r0. */
79#define OPTYPE_RRM_MASK (OPTYPE_RRM_DANGEROUS | OPTYPE_RRM_DANGEROUS_16)
80#define OPTYPE_INHIBIT_IRQS BIT(16) /**< Will or can inhibit irqs (sti, pop ss, mov ss) */
81#define OPTYPE_PORTIO_READ BIT(17)
82#define OPTYPE_PORTIO_WRITE BIT(18)
83#define OPTYPE_ALL (0xffffffff)
84
85/** Parameter usage flags.
86 * @{
87 */
88#define USE_BASE BIT(0)
89#define USE_INDEX BIT(1)
90#define USE_SCALE BIT(2)
91#define USE_REG_GEN8 BIT(3)
92#define USE_REG_GEN16 BIT(4)
93#define USE_REG_GEN32 BIT(5)
94#define USE_REG_FP BIT(6)
95#define USE_REG_MMX BIT(7)
96#define USE_REG_XMM BIT(8)
97#define USE_REG_CR BIT(9)
98#define USE_REG_DBG BIT(10)
99#define USE_REG_SEG BIT(11)
100#define USE_REG_TEST BIT(12)
101#define USE_DISPLACEMENT8 BIT(13)
102#define USE_DISPLACEMENT16 BIT(14)
103#define USE_DISPLACEMENT32 BIT(15)
104#define USE_IMMEDIATE8 BIT(16)
105#define USE_IMMEDIATE8_REL BIT(17)
106#define USE_IMMEDIATE16 BIT(18)
107#define USE_IMMEDIATE16_REL BIT(19)
108#define USE_IMMEDIATE32 BIT(20)
109#define USE_IMMEDIATE32_REL BIT(21)
110#define USE_IMMEDIATE64 BIT(22)
111#define USE_IMMEDIATE_ADDR_0_32 BIT(23)
112#define USE_IMMEDIATE_ADDR_16_32 BIT(24)
113#define USE_IMMEDIATE_ADDR_0_16 BIT(25)
114#define USE_IMMEDIATE_ADDR_16_16 BIT(26)
115/** DS:ESI */
116#define USE_POINTER_DS_BASED BIT(27)
117/** ES:EDI */
118#define USE_POINTER_ES_BASED BIT(28)
119#define USE_IMMEDIATE16_SX8 BIT(29)
120#define USE_IMMEDIATE32_SX8 BIT(30)
121
122#define USE_IMMEDIATE (USE_IMMEDIATE8|USE_IMMEDIATE16|USE_IMMEDIATE32|USE_IMMEDIATE64|USE_IMMEDIATE8_REL|USE_IMMEDIATE16_REL|USE_IMMEDIATE32_REL|USE_IMMEDIATE_ADDR_0_32|USE_IMMEDIATE_ADDR_16_32|USE_IMMEDIATE_ADDR_0_16|USE_IMMEDIATE_ADDR_16_16|USE_IMMEDIATE16_SX8|USE_IMMEDIATE32_SX8)
123
124/** @} */
125
126/** index in {"EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI"}
127 * @{
128 */
129#define USE_REG_EAX 0
130#define USE_REG_ECX 1
131#define USE_REG_EDX 2
132#define USE_REG_EBX 3
133#define USE_REG_ESP 4
134#define USE_REG_EBP 5
135#define USE_REG_ESI 6
136#define USE_REG_EDI 7
137/** @} */
138/** index in {"AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI"}
139 * @{
140 */
141#define USE_REG_AX 0
142#define USE_REG_CX 1
143#define USE_REG_DX 2
144#define USE_REG_BX 3
145#define USE_REG_SP 4
146#define USE_REG_BP 5
147#define USE_REG_SI 6
148#define USE_REG_DI 7
149/** @} */
150
151/** index in {"AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH"}
152 * @{
153 */
154#define USE_REG_AL 0
155#define USE_REG_CL 1
156#define USE_REG_DL 2
157#define USE_REG_BL 3
158#define USE_REG_AH 4
159#define USE_REG_CH 5
160#define USE_REG_DH 6
161#define USE_REG_BH 7
162/** @} */
163
164/** index in {ES, CS, SS, DS, FS, GS}
165 * @{
166 */
167#define USE_REG_ES 0
168#define USE_REG_CS 1
169#define USE_REG_SS 2
170#define USE_REG_DS 3
171#define USE_REG_FS 4
172#define USE_REG_GS 5
173/** @} */
174
175#define USE_REG_FP0 0
176#define USE_REG_FP1 1
177#define USE_REG_FP2 2
178#define USE_REG_FP3 3
179#define USE_REG_FP4 4
180#define USE_REG_FP5 5
181#define USE_REG_FP6 6
182#define USE_REG_FP7 7
183
184#define USE_REG_CR0 0
185#define USE_REG_CR1 1
186#define USE_REG_CR2 2
187#define USE_REG_CR3 3
188#define USE_REG_CR4 4
189
190#define USE_REG_DR0 0
191#define USE_REG_DR1 1
192#define USE_REG_DR2 2
193#define USE_REG_DR3 3
194#define USE_REG_DR4 4
195#define USE_REG_DR5 5
196#define USE_REG_DR6 6
197#define USE_REG_DR7 7
198
199#define USE_REG_MMX0 0
200#define USE_REG_MMX1 1
201#define USE_REG_MMX2 2
202#define USE_REG_MMX3 3
203#define USE_REG_MMX4 4
204#define USE_REG_MMX5 5
205#define USE_REG_MMX6 6
206#define USE_REG_MMX7 7
207
208#define USE_REG_XMM0 0
209#define USE_REG_XMM1 1
210#define USE_REG_XMM2 2
211#define USE_REG_XMM3 3
212#define USE_REG_XMM4 4
213#define USE_REG_XMM5 5
214#define USE_REG_XMM6 6
215#define USE_REG_XMM7 7
216
217/** Used by DISQueryParamVal & EMIQueryParamVal
218 * @{
219 */
220#define PARAM_VAL8 BIT(0)
221#define PARAM_VAL16 BIT(1)
222#define PARAM_VAL32 BIT(2)
223#define PARAM_VAL64 BIT(3)
224#define PARAM_VALFARPTR16 BIT(4)
225#define PARAM_VALFARPTR32 BIT(5)
226
227#define PARMTYPE_REGISTER 1
228#define PARMTYPE_ADDRESS 2
229#define PARMTYPE_IMMEDIATE 3
230
231typedef struct
232{
233 uint32_t type;
234 uint32_t flags;
235 uint32_t size;
236
237 union
238 {
239 uint8_t val8;
240 uint16_t val16;
241 uint32_t val32;
242 uint64_t val64;
243
244 struct
245 {
246 uint16_t sel;
247 uint32_t offset;
248 } farptr;
249 } val;
250
251} OP_PARAMVAL;
252/** Pointer to opcode parameter value. */
253typedef OP_PARAMVAL *POP_PARAMVAL;
254
255typedef enum
256{
257 PARAM_DEST,
258 PARAM_SOURCE
259} PARAM_TYPE;
260
261/** @} */
262
263/**
264 * Operand Parameter.
265 */
266typedef struct _OP_PARAMETER
267{
268 int param;
269 uint64_t parval;
270 char szParam[32];
271
272 int32_t disp8, disp16, disp32;
273
274 uint32_t flags;
275
276 uint32_t size;
277
278 union
279 {
280 uint32_t reg_gen8;
281 uint32_t reg_gen16;
282 uint32_t reg_gen32;
283 /** ST(0) - ST(7) */
284 uint32_t reg_fp;
285 /** MMX0 - MMX7 */
286 uint32_t reg_mmx;
287 /** XMM0 - XMM7 */
288 uint32_t reg_xmm;
289 /** {ES, CS, SS, DS, FS, GS} */
290 uint32_t reg_seg;
291 /** TR0-TR7 (?) */
292 uint32_t reg_test;
293 /** CR0-CR4 */
294 uint32_t reg_ctrl;
295 /** DR0-DR7 */
296 uint32_t reg_dbg;
297 } base;
298 union
299 {
300 uint32_t reg_gen;
301 } index;
302
303 /** 2, 4 or 8. */
304 uint32_t scale;
305
306} OP_PARAMETER;
307/** Pointer to opcode parameter. */
308typedef OP_PARAMETER *POP_PARAMETER;
309/** Pointer to opcode parameter. */
310typedef const OP_PARAMETER *PCOP_PARAMETER;
311
312
313struct _OPCODE;
314/** Pointer to opcode. */
315typedef struct _OPCODE *POPCODE;
316/** Pointer to const opcode. */
317typedef const struct _OPCODE *PCOPCODE;
318
319typedef DECLCALLBACK(int32_t) FN_DIS_READBYTES(RTUINTPTR pSrc, uint8_t *pDest, uint32_t size, RTUINTPTR dwUserdata);
320typedef FN_DIS_READBYTES *PFN_DIS_READBYTES;
321
322/* forward decl */
323struct _DISCPUSTATE;
324/** Pointer to the disassembler CPU state. */
325typedef struct _DISCPUSTATE *PDISCPUSTATE;
326
327/** Parser callback.
328 * @remark no DECLCALLBACK() here because it's considered to be internal (really, I'm too lazy to update all the functions). */
329typedef int FNDISPARSE(RTUINTPTR pu8CodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu);
330typedef FNDISPARSE *PFNDISPARSE;
331
332typedef struct _DISCPUSTATE
333{
334 /* Global setting */
335 uint32_t mode;
336
337 /* Per instruction prefix settings */
338 uint32_t prefix;
339 /** segment prefix value. */
340 uint32_t prefix_seg;
341 /** addressing mode (16 or 32 bits). (CPUMODE_*) */
342 uint32_t addrmode;
343 /** operand mode (16 or 32 bits). (CPUMODE_*) */
344 uint32_t opmode;
345
346 OP_PARAMETER param1;
347 OP_PARAMETER param2;
348 OP_PARAMETER param3;
349
350 /** ModRM byte. */
351 uint32_t ModRM;
352 /** scalar, index, base byte. */
353 uint32_t SIB;
354
355 int32_t disp;
356
357 /** First opcode byte of instruction. */
358 uint8_t opcode;
359 /** Last prefix byte (for SSE2 extension tables) */
360 uint8_t lastprefix;
361 RTUINTPTR opaddr;
362 uint32_t opsize;
363#ifndef DIS_CORE_ONLY
364 /** Opcode format string for current instruction. */
365 const char *pszOpcode;
366#endif
367
368 /** Internal: pointer to disassembly function table */
369 PFNDISPARSE *pfnDisasmFnTable;
370 /** Internal: instruction filter */
371 uint32_t uFilter;
372
373 /** Pointer to the current instruction. */
374 PCOPCODE pCurInstr;
375
376 RTUINTPTR dwUserData[3];
377
378 /** Optional read function */
379 PFN_DIS_READBYTES pfnReadBytes;
380#ifdef __L4ENV__
381 jmp_buf *pJumpBuffer;
382#endif /* __L4ENV__ */
383} DISCPUSTATE;
384
385/** Opcode. */
386#pragma pack(4)
387typedef struct _OPCODE
388{
389#ifndef DIS_CORE_ONLY
390 const char *pszOpcode;
391#endif
392 uint8_t idxParse1;
393 uint8_t idxParse2;
394 uint8_t idxParse3;
395 uint16_t opcode;
396 uint16_t param1;
397 uint16_t param2;
398 uint16_t param3;
399
400 uint32_t optype;
401} OPCODE;
402#pragma pack()
403
404
405/**
406 * Disassembles a code block.
407 *
408 * @returns Success indicator.
409 * @param pCpu Pointer to cpu structure which have DISCPUSTATE::mode
410 * set correctly.
411 * @param pvCodeBlock Pointer to the strunction to disassemble.
412 * @param cbMax Maximum number of bytes to disassemble.
413 * @param pcbSize Where to store the size of the instruction.
414 * NULL is allowed.
415 *
416 *
417 * @todo Define output callback.
418 * @todo Using signed integers as sizes is a bit odd. There are still
419 * some GCC warnings about mixing signed and unsigend integers.
420 * @todo Need to extend this interface to include a code address so we
421 * can dissassemble GC code. Perhaps a new function is better...
422 * @remark cbMax isn't respected as a boundry. DISInstr() will read beyond cbMax.
423 * This means *pcbSize >= cbMax sometimes.
424 */
425DISDECL(bool) DISBlock(PDISCPUSTATE pCpu, RTUINTPTR pvCodeBlock, int32_t cbMax, uint32_t *pSize);
426
427/**
428 * Disassembles one instruction
429 *
430 * @returns Success indicator.
431 * @param pCpu Pointer to cpu structure which have DISCPUSTATE::mode
432 * set correctly.
433 * @param pu8Instruction Pointer to the instrunction to disassemble.
434 * @param u32EipOffset Offset to add to instruction address to get the real virtual address
435 * @param pcbSize Where to store the size of the instruction.
436 * NULL is allowed.
437 * @param pszOutput Storage for disassembled instruction
438 *
439 * @todo Define output callback.
440 */
441DISDECL(bool) DISInstr(PDISCPUSTATE pCpu, RTUINTPTR pu8Instruction, uint32_t u32EipOffset, uint32_t *pcbSize, char *pszOutput);
442
443/**
444 * Disassembles one instruction
445 *
446 * @returns Success indicator.
447 * @param pCpu Pointer to cpu structure which have DISCPUSTATE::mode
448 * set correctly.
449 * @param pu8Instruction Pointer to the strunction to disassemble.
450 * @param u32EipOffset Offset to add to instruction address to get the real virtual address
451 * @param pcbSize Where to store the size of the instruction.
452 * NULL is allowed.
453 * @param pszOutput Storage for disassembled instruction
454 * @param uFilter Instruction type filter
455 *
456 * @todo Define output callback.
457 */
458DISDECL(bool) DISInstrEx(PDISCPUSTATE pCpu, RTUINTPTR pu8Instruction, uint32_t u32EipOffset, uint32_t *pcbSize,
459 char *pszOutput, uint32_t uFilter);
460
461/**
462 * Parses one instruction.
463 * The result is found in pCpu.
464 *
465 * @returns Success indicator.
466 * @param pCpu Pointer to cpu structure which has DISCPUSTATE::mode set correctly.
467 * @param InstructionAddr Pointer to the instruction to parse.
468 * @param pcbInstruction Where to store the size of the instruction.
469 * NULL is allowed.
470 */
471DISDECL(bool) DISCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction);
472
473/**
474 * Parses one guest instruction.
475 * * The result is found in pCpu and pcbInstruction.
476 *
477 * @returns VBox status code.
478 * @param InstructionAddr Address of the instruction to decode. What this means
479 * is left to the pfnReadBytes function.
480 * @param CpuMode The CPU mode. CPUMODE_32BIT, CPUMODE_16BIT, or CPUMODE_64BIT.
481 * @param pfnReadBytes Callback for reading instruction bytes.
482 * @param pvUser User argument for the instruction reader. (Ends up in dwUserData[0].)
483 * @param pCpu Pointer to cpu structure. Will be initialized.
484 * @param pcbInstruction Where to store the size of the instruction.
485 * NULL is allowed.
486 */
487DISDECL(int) DISCoreOneEx(RTUINTPTR InstructionAddr, unsigned CpuMode, PFN_DIS_READBYTES pfnReadBytes, void *pvUser,
488 PDISCPUSTATE pCpu, unsigned *pcbInstruction);
489
490DISDECL(int) DISGetParamSize(PDISCPUSTATE pCpu, POP_PARAMETER pParam);
491DISDECL(int) DISDetectSegReg(PDISCPUSTATE pCpu, POP_PARAMETER pParam);
492DISDECL(uint8_t) DISQuerySegPrefixByte(PDISCPUSTATE pCpu);
493
494/**
495 * Returns the value of the parameter in pParam
496 *
497 * @returns VBox error code
498 * @param pCtx Exception structure pointer
499 * @param pCpu Pointer to cpu structure which have DISCPUSTATE::mode
500 * set correctly.
501 * @param pParam Pointer to the parameter to parse
502 * @param pParamVal Pointer to parameter value (OUT)
503 * @param parmtype Parameter type
504 *
505 * @note Currently doesn't handle FPU/XMM/MMX/3DNow! parameters correctly!!
506 *
507 */
508DISDECL(int) DISQueryParamVal(PCPUMCTXCORE pCtx, PDISCPUSTATE pCpu, POP_PARAMETER pParam, POP_PARAMVAL pParamVal, PARAM_TYPE parmtype);
509
510DISDECL(int) DISFetchReg8(PCPUMCTXCORE pCtx, uint32_t reg8, uint8_t *pVal);
511DISDECL(int) DISFetchReg16(PCPUMCTXCORE pCtx, uint32_t reg16, uint16_t *pVal);
512DISDECL(int) DISFetchReg32(PCPUMCTXCORE pCtx, uint32_t reg32, uint32_t *pVal);
513DISDECL(int) DISFetchRegSeg(PCPUMCTXCORE pCtx, uint32_t sel, RTSEL *pVal);
514DISDECL(int) DISFetchRegSegEx(PCPUMCTXCORE pCtx, uint32_t sel, RTSEL *pVal, CPUMSELREGHID **ppSelHidReg);
515DISDECL(int) DISWriteReg8(PCPUMCTXCORE pRegFrame, uint32_t reg8, uint8_t val8);
516DISDECL(int) DISWriteReg16(PCPUMCTXCORE pRegFrame, uint32_t reg32, uint16_t val16);
517DISDECL(int) DISWriteReg32(PCPUMCTXCORE pRegFrame, uint32_t reg32, uint32_t val32);
518DISDECL(int) DISWriteRegSeg(PCPUMCTXCORE pCtx, uint32_t sel, RTSEL val);
519
520__END_DECLS
521
522#endif
523
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