VirtualBox

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

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

Biggest check-in ever. New source code headers for all (C) innotek files.

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