VirtualBox

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

Last change on this file since 2135 was 1937, checked in by vboxsync, 18 years ago

Added DISFetchRegSegEx

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