dbgf.h revision 761a066e976face73a49d0edb1daeedd16b4d70f
/** @file
* DBGF - Debugger Facility.
*/
/*
* Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
#ifndef ___VBox_vmm_dbgf_h
#define ___VBox_vmm_dbgf_h
/** @defgroup grp_dbgf The Debugger Facility API
* @{
*/
/** @addgroup grp_dbgf_rz The RZ DBGF API
* @ingroup grp_dbgf
* @{
*/
VMMRZ_INT_DECL(int) DBGFRZTrap01Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCUINTREG uDr6);
/** @} */
#endif
#ifdef IN_RING3
/**
* Mixed address.
*/
typedef struct DBGFADDRESS
{
/** The flat address. */
/** The selector offset address. */
/** The selector. DBGF_SEL_FLAT is a legal value. */
/** Flags describing further details about the address. */
} DBGFADDRESS;
/** Pointer to a mixed address. */
typedef DBGFADDRESS *PDBGFADDRESS;
/** Pointer to a const mixed address. */
typedef const DBGFADDRESS *PCDBGFADDRESS;
/** @name DBGFADDRESS Flags.
* @{ */
/** A 16:16 far address. */
#define DBGFADDRESS_FLAGS_FAR16 0
/** A 16:32 far address. */
#define DBGFADDRESS_FLAGS_FAR32 1
/** A 16:64 far address. */
#define DBGFADDRESS_FLAGS_FAR64 2
/** A flat address. */
#define DBGFADDRESS_FLAGS_FLAT 3
/** A physical address. */
#define DBGFADDRESS_FLAGS_PHYS 4
/** A physical address. */
#define DBGFADDRESS_FLAGS_RING0 5
/** The address type mask. */
#define DBGFADDRESS_FLAGS_TYPE_MASK 7
/** Set if the address is valid. */
/** The address is within the hypervisor memoary area (HMA).
* If not set, the address can be assumed to be a guest address. */
/** Checks if the mixed address is flat or not. */
#define DBGFADDRESS_IS_FLAT(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FLAT )
/** Checks if the mixed address is flat or not. */
#define DBGFADDRESS_IS_PHYS(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_PHYS )
/** Checks if the mixed address is far 16:16 or not. */
#define DBGFADDRESS_IS_FAR16(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FAR16 )
/** Checks if the mixed address is far 16:32 or not. */
#define DBGFADDRESS_IS_FAR32(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FAR32 )
/** Checks if the mixed address is far 16:64 or not. */
#define DBGFADDRESS_IS_FAR64(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FAR64 )
/** Checks if the mixed address is valid. */
/** Checks if the address is flagged as within the HMA. */
/** @} */
VMMR3DECL(int) DBGFR3AddrFromSelOff(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, RTSEL Sel, RTUINTPTR off);
VMMR3DECL(int) DBGFR3AddrFromSelInfoOff(PUVM pUVM, PDBGFADDRESS pAddress, PCDBGFSELINFO pSelInfo, RTUINTPTR off);
VMMR3DECL(int) DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTGCPHYS pGCPhys);
VMMR3DECL(int) DBGFR3AddrToHostPhys(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTHCPHYS pHCPhys);
VMMR3DECL(int) DBGFR3AddrToVolatileR3Ptr(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, bool fReadOnly, void **ppvR3Ptr);
#endif /* IN_RING3 */
/**
* VMM Debug Event Type.
*/
typedef enum DBGFEVENTTYPE
{
/** Halt completed.
* This notifies that a halt command have been successfully completed.
*/
DBGFEVENT_HALT_DONE = 0,
/** Detach completed.
* This notifies that the detach command have been successfully completed.
*/
/** The command from the debugger is not recognized.
* This means internal error or half implemented features.
*/
/** Fatal error.
* This notifies a fatal error in the VMM and that the debugger get's a
* chance to first hand information about the the problem.
*/
DBGFEVENT_FATAL_ERROR = 100,
/** Breakpoint Hit.
* This notifies that a breakpoint installed by the debugger was hit. The
* identifier of the breakpoint can be found in the DBGFEVENT::u::Bp::iBp member.
*/
/** Breakpoint Hit in the Hypervisor.
* This notifies that a breakpoint installed by the debugger was hit. The
* identifier of the breakpoint can be found in the DBGFEVENT::u::Bp::iBp member.
*/
/** Assertion in the Hypervisor (breakpoint instruction).
* This notifies that a breakpoint instruction was hit in the hypervisor context.
*/
/** Single Stepped.
* This notifies that a single step operation was completed.
*/
/** Single Stepped.
* This notifies that a hypervisor single step operation was completed.
*/
/** The developer have used the DBGFSTOP macro or the PDMDeviceDBGFSTOP function
* to bring up the debugger at a specific place.
*/
/** The VM is terminating.
* When this notification is received, the debugger thread should detach ASAP.
*/
/** The usual 32-bit hack. */
DBGFEVENT_32BIT_HACK = 0x7fffffff
/**
* The context of an event.
*/
typedef enum DBGFEVENTCTX
{
/** The usual invalid entry. */
DBGFEVENTCTX_INVALID = 0,
/** Raw mode. */
/** Recompiled mode. */
/** VMX / AVT mode. */
/** Hypervisor context. */
/** Other mode */
/** The usual 32-bit hack */
DBGFEVENTCTX_32BIT_HACK = 0x7fffffff
} DBGFEVENTCTX;
/**
* VMM Debug Event.
*/
typedef struct DBGFEVENT
{
/** Type. */
/** Context */
/** Type specific data. */
union
{
/** Fatal error details. */
struct
{
/** The GC return code. */
int rc;
} FatalError;
/** Source location. */
struct
{
/** File name. */
/** Function name. */
R3PTRTYPE(const char *) pszFunction;
/** Message. */
R3PTRTYPE(const char *) pszMessage;
/** Line number. */
unsigned uLine;
} Src;
/** Assertion messages. */
struct
{
/** The first message. */
/** The second message. */
} Assert;
/** Breakpoint. */
struct DBGFEVENTBP
{
/** The identifier of the breakpoint which was hit. */
} Bp;
/** Padding for ensuring that the structure is 8 byte aligned. */
} u;
} DBGFEVENT;
/** Pointer to VMM Debug Event. */
typedef DBGFEVENT *PDBGFEVENT;
/** Pointer to const VMM Debug Event. */
typedef const DBGFEVENT *PCDBGFEVENT;
#ifdef IN_RING3 /* The event API only works in ring-3. */
/** @def DBGFSTOP
* Stops the debugger raising a DBGFEVENT_DEVELOPER_STOP event.
*
* @returns VBox status code which must be propagated up to EM if not VINF_SUCCESS.
* @param pVM VM Handle.
*/
# ifdef VBOX_STRICT
# define DBGFSTOP(pVM) DBGFR3EventSrc(pVM, DBGFEVENT_DEV_STOP, __FILE__, __LINE__, __PRETTY_FUNCTION__, NULL)
# else
# endif
const char *pszFunction, const char *pszFormat, ...);
VMMR3DECL(int) DBGFR3EventSrcV(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine,
VMMR3_INT_DECL(int) DBGFR3EventAssertion(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszMsg1, const char *pszMsg2);
#endif /* IN_RING3 */
/** Breakpoint type. */
typedef enum DBGFBPTYPE
{
/** Free breakpoint entry. */
DBGFBPTYPE_FREE = 0,
/** Debug register. */
/** INT 3 instruction. */
/** Recompiler. */
/** ensure 32-bit size. */
DBGFBPTYPE_32BIT_HACK = 0x7fffffff
} DBGFBPTYPE;
/**
* A Breakpoint.
*/
typedef struct DBGFBP
{
/** The number of breakpoint hits. */
/** The hit number which starts to trigger the breakpoint. */
/** The hit number which stops triggering the breakpoint (disables it).
* Use ~(uint64_t)0 if it should never stop. */
/** The Flat GC address of the breakpoint.
* (PC register value if REM type?) */
/** The breakpoint id. */
/** The breakpoint status - enabled or disabled. */
bool fEnabled;
/** The breakpoint type. */
#if GC_ARCH_BITS == 64
#endif
/** Union of type specific data. */
union
{
/** Debug register data. */
struct DBGFBPREG
{
/** The debug register number. */
/** The access type (one of the X86_DR7_RW_* value). */
/** The access size. */
} Reg;
/** Recompiler breakpoint data. */
struct DBGFBPINT3
{
/** The byte value we replaced by the INT 3 instruction. */
} Int3;
/** Recompiler breakpoint data. */
struct DBGFBPREM
{
/** nothing yet */
} Rem;
/** Paddind to ensure that the size is identical on win32 and linux. */
} u;
} DBGFBP;
/** Pointer to a breakpoint. */
/** Pointer to a const breakpoint. */
#ifdef IN_RING3 /* The breakpoint management API is only available in ring-3. */
VMMR3DECL(int) DBGFR3BpSet(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp);
VMMR3DECL(int) DBGFR3BpSetReg(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable,
VMMR3DECL(int) DBGFR3BpSetREM(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp);
/**
* Breakpoint enumeration callback function.
*
* @returns VBox status code. Any failure will stop the enumeration.
* @param pUVM The user mode VM handle.
* @param pvUser The user argument.
* @param pBp Pointer to the breakpoint information. (readonly)
*/
/** Pointer to a breakpoint enumeration callback function. */
typedef FNDBGFBPENUM *PFNDBGFBPENUM;
#endif /* IN_RING3 */
#ifdef IN_RING3 /* The CPU mode API only works in ring-3. */
#endif
#ifdef IN_RING3 /* The info callbacks API only works in ring-3. */
/**
* Info helper callback structure.
*/
typedef struct DBGFINFOHLP
{
/**
* Print formatted string.
*
* @param pHlp Pointer to this structure.
* @param pszFormat The format string.
* @param ... Arguments.
*/
/**
* Print formatted string.
*
* @param pHlp Pointer to this structure.
* @param pszFormat The format string.
* @param args Argument list.
*/
} DBGFINFOHLP;
/**
* Info handler, device version.
*
* @param pDevIns The device instance which registered the info.
* @param pHlp Callback functions for doing output.
* @param pszArgs Argument string. Optional and specific to the handler.
*/
typedef DECLCALLBACK(void) FNDBGFHANDLERDEV(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
/** Pointer to a FNDBGFHANDLERDEV function. */
typedef FNDBGFHANDLERDEV *PFNDBGFHANDLERDEV;
/**
* Info handler, USB device version.
*
* @param pUsbIns The USB device instance which registered the info.
* @param pHlp Callback functions for doing output.
* @param pszArgs Argument string. Optional and specific to the handler.
*/
typedef DECLCALLBACK(void) FNDBGFHANDLERUSB(PPDMUSBINS pUsbIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
/** Pointer to a FNDBGFHANDLERUSB function. */
typedef FNDBGFHANDLERUSB *PFNDBGFHANDLERUSB;
/**
* Info handler, driver version.
*
* @param pDrvIns The driver instance which registered the info.
* @param pHlp Callback functions for doing output.
* @param pszArgs Argument string. Optional and specific to the handler.
*/
typedef DECLCALLBACK(void) FNDBGFHANDLERDRV(PPDMDRVINS pDrvIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
/** Pointer to a FNDBGFHANDLERDRV function. */
typedef FNDBGFHANDLERDRV *PFNDBGFHANDLERDRV;
/**
* Info handler, internal version.
*
* @param pVM The VM handle.
* @param pHlp Callback functions for doing output.
* @param pszArgs Argument string. Optional and specific to the handler.
*/
/** Pointer to a FNDBGFHANDLERINT function. */
typedef FNDBGFHANDLERINT *PFNDBGFHANDLERINT;
/**
* Info handler, external version.
*
* @param pvUser User argument.
* @param pHlp Callback functions for doing output.
* @param pszArgs Argument string. Optional and specific to the handler.
*/
/** Pointer to a FNDBGFHANDLEREXT function. */
typedef FNDBGFHANDLEREXT *PFNDBGFHANDLEREXT;
/** @name Flags for the info registration functions.
* @{ */
/** The handler must run on the EMT. */
#define DBGFINFO_FLAGS_RUN_ON_EMT RT_BIT(0)
/** @} */
VMMR3_INT_DECL(int) DBGFR3InfoRegisterDevice(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler, PPDMDEVINS pDevIns);
VMMR3_INT_DECL(int) DBGFR3InfoRegisterDriver(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDRV pfnHandler, PPDMDRVINS pDrvIns);
VMMR3_INT_DECL(int) DBGFR3InfoRegisterInternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler);
VMMR3_INT_DECL(int) DBGFR3InfoRegisterInternalEx(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler, uint32_t fFlags);
VMMR3DECL(int) DBGFR3InfoRegisterExternal(PUVM pUVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLEREXT pfnHandler, void *pvUser);
VMMR3DECL(int) DBGFR3InfoEx(PUVM pUVM, VMCPUID idCpu, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp);
/** @def DBGFR3InfoLog
* Display a piece of info writing to the log if enabled.
*
* @param a_pVM The shared VM handle.
* @param a_pszName The identifier of the info to display.
* @param a_pszArgs Arguments to the info handler.
*/
#ifdef LOG_ENABLED
do { \
if (LogIsEnabled()) \
} while (0)
#else
#endif
/**
* Enumeration callback for use with DBGFR3InfoEnum.
*
* @returns VBox status code.
* A status code indicating failure will end the enumeration
* and DBGFR3InfoEnum will return with that status code.
* @param pUVM The user mode VM handle.
* @param pszName Info identifier name.
* @param pszDesc The description.
*/
typedef DECLCALLBACK(int) FNDBGFINFOENUM(PUVM pUVM, const char *pszName, const char *pszDesc, void *pvUser);
/** Pointer to a FNDBGFINFOENUM function. */
typedef FNDBGFINFOENUM *PFNDBGFINFOENUM;
#endif /* IN_RING3 */
#ifdef IN_RING3 /* The log contrl API only works in ring-3. */
#endif /* IN_RING3 */
#ifdef IN_RING3 /* The debug information management APIs only works in ring-3. */
/** Max length (including '\\0') of a symbol name. */
#define DBGF_SYMBOL_NAME_LENGTH 512
/**
* Debug symbol.
*/
typedef struct DBGFSYMBOL
{
/** Symbol value (address). */
/** Symbol size. */
/** Symbol Flags. (reserved). */
/** Symbol name. */
char szName[DBGF_SYMBOL_NAME_LENGTH];
} DBGFSYMBOL;
/** Pointer to debug symbol. */
typedef DBGFSYMBOL *PDBGFSYMBOL;
/** Pointer to const debug symbol. */
typedef const DBGFSYMBOL *PCDBGFSYMBOL;
/**
* Debug line number information.
*/
typedef struct DBGFLINE
{
/** Address. */
/** Line number. */
/** Filename. */
char szFilename[260];
} DBGFLINE;
/** Pointer to debug line number. */
/** Pointer to const debug line number. */
typedef const DBGFLINE *PCDBGFLINE;
/** @name Address spaces aliases.
* @{ */
/** The guest global address space. */
/** The guest kernel address space.
* This is usually resolves to the same as DBGF_AS_GLOBAL. */
/** The physical address space. */
/** Raw-mode context. */
/** Ring-0 context. */
/** Raw-mode context and then global guest context.
* When used for looking up information, it works as if the call was first made
* with DBGF_AS_RC and then on failure with DBGF_AS_GLOBAL. When called for
* making address space changes, it works as if DBGF_AS_RC was used. */
/** The first special one. */
/** The last special one. */
#define DBGF_AS_LAST DBGF_AS_GLOBAL
#endif
/** The number of special address space handles. */
#define DBGF_AS_COUNT (6U)
#ifdef IN_RING3
/** Converts an alias handle to an array index. */
#define DBGF_AS_ALIAS_2_INDEX(hAlias) \
/** Predicat macro that check if the specified handle is an alias. */
#define DBGF_AS_IS_ALIAS(hAlias) \
/** Predicat macro that check if the specified alias is a fixed one or not. */
#define DBGF_AS_IS_FIXED_ALIAS(hAlias) \
/** @} */
VMMR3DECL(int) DBGFR3AsLoadImage(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags);
VMMR3DECL(int) DBGFR3AsLoadMap(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, RTGCUINTPTR uSubtrahend, uint32_t fFlags);
VMMR3DECL(int) DBGFR3AsLinkModule(PUVM pUVM, RTDBGAS hDbgAs, RTDBGMOD hMod, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags);
VMMR3DECL(int) DBGFR3AsSymbolByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
VMMR3DECL(PRTDBGSYMBOL) DBGFR3AsSymbolByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, PRTGCINTPTR poffDisp, PRTDBGMOD phMod);
VMMR3DECL(int) DBGFR3AsSymbolByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
/* The following are soon to be obsoleted: */
VMMR3DECL(int) DBGFR3ModuleLoad(PUVM pUVM, const char *pszFilename, RTGCUINTPTR AddressDelta, const char *pszName, RTGCUINTPTR ModuleAddress, unsigned cbImage);
VMMR3_INT_DECL(void) DBGFR3ModuleRelocate(PVM pVM, RTGCUINTPTR OldImageBase, RTGCUINTPTR NewImageBase, RTGCUINTPTR cbImage,
const char *pszFilename, const char *pszName);
VMMR3_INT_DECL(int) DBGFR3SymbolAdd(PVM pVM, RTGCUINTPTR ModuleAddress, RTGCUINTPTR SymbolAddress, RTUINT cbSymbol, const char *pszSymbol);
VMMR3_INT_DECL(int) DBGFR3SymbolByAddr(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement, PDBGFSYMBOL pSymbol);
VMMR3DECL(int) DBGFR3LineByAddr(PUVM pUVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement, PDBGFLINE pLine);
VMMR3DECL(PDBGFLINE) DBGFR3LineByAddrAlloc(PUVM pUVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement);
#endif /* IN_RING3 */
#ifdef IN_RING3 /* The stack API only works in ring-3. */
/**
* Return type.
*/
typedef enum DBGFRETRUNTYPE
{
/** The usual invalid 0 value. */
/** Near 16-bit return. */
/** Near 32-bit return. */
/** Near 64-bit return. */
/** Far 16:16 return. */
/** Far 16:32 return. */
/** Far 16:64 return. */
/** 16-bit iret return (e.g. real or 286 protect mode). */
/** 32-bit iret return. */
/** 32-bit iret return. */
/** 32-bit iret return to V86 mode. */
/** @todo 64-bit iret return. */
/** The end of the valid return types. */
/** The usual 32-bit blowup. */
DBGFRETURNTYPE_32BIT_HACK = 0x7fffffff
/**
* Figures the size of the return state on the stack.
*
* @returns number of bytes. 0 if invalid parameter.
* @param enmRetType The type of return.
*/
{
switch (enmRetType)
{
case DBGFRETURNTYPE_NEAR16: return 2;
case DBGFRETURNTYPE_NEAR32: return 4;
case DBGFRETURNTYPE_NEAR64: return 8;
case DBGFRETURNTYPE_FAR16: return 4;
case DBGFRETURNTYPE_FAR32: return 4;
case DBGFRETURNTYPE_FAR64: return 8;
case DBGFRETURNTYPE_IRET16: return 6;
case DBGFRETURNTYPE_IRET64:
default:
return 0;
}
}
/** Pointer to stack frame info. */
typedef struct DBGFSTACKFRAME *PDBGFSTACKFRAME;
/** Pointer to const stack frame info. */
typedef struct DBGFSTACKFRAME const *PCDBGFSTACKFRAME;
/**
* Info about a stack frame.
*/
typedef struct DBGFSTACKFRAME
{
/** Frame number. */
/** Frame flags. */
/** The frame address.
* The off member is [e|r]bp and the Sel member is ss. */
/** The stack address of the frame.
* The off member is [e|r]sp and the Sel member is ss. */
/** The program counter (PC) address of the frame.
* The off member is [e|r]ip and the Sel member is cs. */
/** Pointer to the symbol nearest the program counter (PC). NULL if not found. */
/** Pointer to the linnumber nearest the program counter (PC). NULL if not found. */
/** The return frame address.
* The off member is [e|r]bp and the Sel member is ss. */
/** The return stack address.
* The off member is [e|r]sp and the Sel member is ss. */
/** The way this frame returns to the next one. */
/** The program counter (PC) address which the frame returns to.
* The off member is [e|r]ip and the Sel member is cs. */
/** Pointer to the symbol nearest the return PC. NULL if not found. */
/** Pointer to the linnumber nearest the return PC. NULL if not found. */
/** 32-bytes of stack arguments. */
union
{
/** 64-bit view */
/** 32-bit view */
/** 16-bit view */
/** 8-bit view */
} Args;
/** Pointer to the next frame.
* Might not be used in some cases, so consider it internal. */
/** Pointer to the first frame.
* Might not be used in some cases, so consider it internal. */
/** @name DBGFSTACKFRAME Flags.
* @{ */
/** Set if the content of the frame is filled in by DBGFR3StackWalk() and can be used
* to construct the next frame. */
# define DBGFSTACKFRAME_FLAGS_ALL_VALID RT_BIT(0)
/** This is the last stack frame we can read.
* This flag is not set if the walk stop because of max dept or recursion. */
/** This is the last record because we detected a loop. */
/** This is the last record because we reached the maximum depth. */
/** 16-bit frame. */
/** 32-bit frame. */
/** 64-bit frame. */
/** @} */
/** @name DBGFCODETYPE
* @{ */
typedef enum DBGFCODETYPE
{
/** The usual invalid 0 value. */
DBGFCODETYPE_INVALID = 0,
/** Stack walk for guest code. */
/** Stack walk for hypervisor code. */
/** Stack walk for ring 0 code. */
/** The usual 32-bit blowup. */
DBGFCODETYPE_32BIT_HACK = 0x7fffffff
} DBGFCODETYPE;
/** @} */
VMMR3DECL(int) DBGFR3StackWalkBeginEx(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFADDRESS pAddrFrame,
#endif /* IN_RING3 */
#ifdef IN_RING3 /* The disassembly API only works in ring-3. */
/** Flags to pass to DBGFR3DisasInstrEx().
* @{ */
/** Disassemble the current guest instruction, with annotations. */
#define DBGF_DISAS_FLAGS_CURRENT_GUEST RT_BIT(0)
/** Disassemble the current hypervisor instruction, with annotations. */
/** No annotations for current context. */
/** No symbol lookup. */
/** No instruction bytes. */
/** No address in the output. */
/** Disassemble in the default mode of the specific context. */
/** Disassemble in 16-bit mode. */
/** Disassemble in 16-bit mode with real mode address translation. */
/** Disassemble in 32-bit mode. */
/** Disassemble in 64-bit mode. */
/** The disassembly mode mask. */
/** Mask containing the valid flags. */
/** @} */
/** Special flat selector. */
#define DBGF_SEL_FLAT 1
VMMR3DECL(int) DBGFR3DisasInstrEx(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, RTGCPTR GCPtr, uint32_t fFlags,
/** @def DBGFR3DisasInstrCurrentLog
* Disassembles the current guest context instruction and writes it to the log.
* All registers and data will be displayed. Addresses will be attempted resolved to symbols.
*/
#ifdef LOG_ENABLED
do { \
if (LogIsEnabled()) \
} while (0)
#else
#endif
VMMR3DECL(int) DBGFR3DisasInstrLogInternal(PVMCPU pVCpu, RTSEL Sel, RTGCPTR GCPtr, const char *pszPrefix);
/** @def DBGFR3DisasInstrLog
* Disassembles the specified guest context instruction and writes it to the log.
* Addresses will be attempted resolved to symbols.
* @thread Any EMT.
*/
# ifdef LOG_ENABLED
do { \
if (LogIsEnabled()) \
} while (0)
# else
# endif
#endif
#ifdef IN_RING3
VMMR3DECL(int) DBGFR3MemScan(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, RTGCUINTPTR uAlign,
VMMR3DECL(int) DBGFR3MemRead(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead);
VMMR3DECL(int) DBGFR3MemReadString(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, char *pszBuf, size_t cbBuf);
VMMR3DECL(int) DBGFR3MemWrite(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void const *pvBuf, size_t cbRead);
#endif
/** @name Flags for DBGFR3PagingDumpEx, PGMR3DumpHierarchyHCEx and
* PGMR3DumpHierarchyGCEx
* @{ */
/** The CR3 from the current CPU state. */
#define DBGFPGDMP_FLAGS_CURRENT_CR3 RT_BIT_32(0)
/** The current CPU paging mode (PSE, PAE, LM, EPT, NX). */
/** Whether PSE is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
* Same value as X86_CR4_PSE. */
/** Whether PAE is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
* Same value as X86_CR4_PAE. */
/** Whether LME is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
* Same value as MSR_K6_EFER_LME. */
/** Whether nested paging is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE). */
/** Whether extended nested page tables are enabled
* (!DBGFPGDMP_FLAGS_CURRENT_STATE). */
/** Whether no-execution is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
* Same value as MSR_K6_EFER_NXE. */
/** Whether to print the CR3. */
/** Whether to print the header. */
/** Whether to dump additional page information. */
/** Dump the shadow tables if set.
* Cannot be used together with DBGFPGDMP_FLAGS_GUEST. */
/** Dump the guest tables if set.
* Cannot be used together with DBGFPGDMP_FLAGS_SHADOW. */
/** Mask of valid bits. */
/** The mask of bits controlling the paging mode. */
/** @} */
VMMDECL(int) DBGFR3PagingDumpEx(PUVM pUVM, VMCPUID idCpu, uint32_t fFlags, uint64_t cr3, uint64_t u64FirstAddr,
/** @name DBGFR3SelQueryInfo flags.
* @{ */
/** Get the info from the guest descriptor table. */
#define DBGFSELQI_FLAGS_DT_GUEST UINT32_C(0)
/** Get the info from the shadow descriptor table.
* Only works in raw-mode. */
/** If currently executing in in 64-bit mode, blow up data selectors. */
/** @} */
VMMR3DECL(int) DBGFR3SelQueryInfo(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, uint32_t fFlags, PDBGFSELINFO pSelInfo);
/**
* Register identifiers.
*/
typedef enum DBGFREG
{
/* General purpose registers: */
DBGFREG_AL = 0,
/* Segments and other special registers: */
/* FPU: */
/* SSE: */
/** @todo add XMM aliases. */
/* System registers: */
/* MSRs: */
/** The number of registers to pass to DBGFR3RegQueryAll. */
/* Misc aliases that doesn't need be part of the 'all' query: */
/** The end of the registers. */
/** The usual 32-bit type hack. */
DBGFREG_32BIT_HACK = 0x7fffffff
} DBGFREG;
/** Pointer to a register identifier. */
/** Pointer to a const register identifier. */
/**
* Register value type.
*/
typedef enum DBGFREGVALTYPE
{
/** Unsigned 8-bit register value. */
/** Unsigned 16-bit register value. */
/** Unsigned 32-bit register value. */
/** Unsigned 64-bit register value. */
/** Unsigned 128-bit register value. */
/** Long double register value. */
/** Descriptor table register value. */
/** End of the valid register value types. */
/** The usual 32-bit type hack. */
DBGFREGVALTYPE_32BIT_HACK = 0x7fffffff
/** Pointer to a register value type. */
typedef DBGFREGVALTYPE *PDBGFREGVALTYPE;
/**
* A generic register value type.
*/
typedef union DBGFREGVAL
{
/** GDTR or LDTR (DBGFREGVALTYPE_DTR). */
struct
{
/** The table address. */
/** The table limit (length minus 1). */
} dtr;
RTUINT128U u;
} DBGFREGVAL;
/** Pointer to a generic register value type. */
typedef DBGFREGVAL *PDBGFREGVAL;
/** Pointer to a const generic register value type. */
typedef DBGFREGVAL const *PCDBGFREGVAL;
VMMDECL(ssize_t) DBGFR3RegFormatValue(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType, bool fSpecial);
VMMDECL(ssize_t) DBGFR3RegFormatValueEx(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType,
/**
* Register sub-field descriptor.
*/
typedef struct DBGFREGSUBFIELD
{
/** The name of the sub-field. NULL is used to terminate the array. */
const char *pszName;
/** The index of the first bit. Ignored if pfnGet is set. */
/** The number of bits. Mandatory. */
/** The shift count. Not applied when pfnGet is set, but used to
* calculate the minimum type. */
/** Sub-field flags, DBGFREGSUBFIELD_FLAGS_XXX. */
/** Getter (optional). */
DECLCALLBACKMEMBER(int, pfnGet)(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, PRTUINT128U puValue);
/** Setter (optional). */
DECLCALLBACKMEMBER(int, pfnSet)(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, RTUINT128U uValue, RTUINT128U fMask);
/** Pointer to a const register sub-field descriptor. */
typedef DBGFREGSUBFIELD const *PCDBGFREGSUBFIELD;
/** @name DBGFREGSUBFIELD_FLAGS_XXX
* @{ */
/** The sub-field is read-only. */
/** @} */
/** Macro for creating a read-write sub-field entry without getters. */
/** Macro for creating a read-write sub-field entry with getters. */
/** Macro for creating a terminator sub-field entry. */
#define DBGFREGSUBFIELD_TERMINATOR() \
/**
* Register alias descriptor.
*/
typedef struct DBGFREGALIAS
{
/** The alias name. NULL is used to terminate the array. */
const char *pszName;
/** Set to a valid type if the alias has a different type. */
} DBGFREGALIAS;
/** Pointer to a const register alias descriptor. */
typedef DBGFREGALIAS const *PCDBGFREGALIAS;
/**
* Register descriptor.
*/
typedef struct DBGFREGDESC
{
/** The normal register name. */
const char *pszName;
/** The register identifier if this is a CPU register. */
/** The default register type. */
/** Flags, see DBGFREG_FLAGS_XXX. */
/** The internal register indicator.
* For CPU registers this is the offset into the CPUMCTX structure,
* thuse the 'off' prefix. */
/** Getter. */
/** Setter. */
DECLCALLBACKMEMBER(int, pfnSet)(void *pvUser, struct DBGFREGDESC const *pDesc, PCDBGFREGVAL pValue, PCDBGFREGVAL pfMask);
/** Aliases (optional). */
/** Sub fields (optional). */
} DBGFREGDESC;
/** @name Macros for constructing DBGFREGDESC arrays.
* @{ */
{ a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, NULL /*paAlises*/, NULL /*paSubFields*/ }
{ a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, NULL /*paAlises*/, NULL /*paSubFields*/ }
{ a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, NULL /*paSubFields*/ }
{ a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, NULL /*paSubFields*/ }
{ a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, /*paAliases*/, a_paSubFields }
{ a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, /*paAliases*/, a_paSubFields }
#define DBGFREGDESC_RW_AS(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields) \
{ a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields }
#define DBGFREGDESC_RO_AS(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields) \
{ a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields }
#define DBGFREGDESC_TERMINATOR() \
/** @} */
/** @name DBGFREG_FLAGS_XXX
* @{ */
/** The register is read-only. */
#define DBGFREG_FLAGS_READ_ONLY RT_BIT_32(0)
/** @} */
/**
* Entry in a batch query or set operation.
*/
typedef struct DBGFREGENTRY
{
/** The register identifier. */
/** The size of the value in bytes. */
/** The register value. The valid view is indicated by enmType. */
} DBGFREGENTRY;
/** Pointer to a register entry in a batch operation. */
typedef DBGFREGENTRY *PDBGFREGENTRY;
/** Pointer to a const register entry in a batch operation. */
typedef DBGFREGENTRY const *PCDBGFREGENTRY;
/** Used with DBGFR3Reg* to indicate the hypervisor register set instead of the
* guest. */
VMMR3DECL(int) DBGFR3RegCpuQueryXdtr(PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64Base, uint16_t *pu16Limit);
#if 0
VMMR3DECL(int) DBGFR3RegCpuSetBatch( PUVM pUVM, VMCPUID idCpu, PCDBGFREGENTRY paRegs, size_t cRegs);
#endif
VMMR3_INT_DECL(int) DBGFR3RegRegisterCpu(PVM pVM, PVMCPU pVCpu, PCDBGFREGDESC paRegisters, bool fGuestRegs);
/**
* Entry in a named batch query or set operation.
*/
typedef struct DBGFREGENTRYNM
{
/** The register name. */
const char *pszName;
/** The size of the value in bytes. */
/** The register value. The valid view is indicated by enmType. */
/** Pointer to a named register entry in a batch operation. */
typedef DBGFREGENTRYNM *PDBGFREGENTRYNM;
/** Pointer to a const named register entry in a batch operation. */
typedef DBGFREGENTRYNM const *PCDBGFREGENTRYNM;
VMMR3DECL(int) DBGFR3RegNmQuery( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType);
VMMR3DECL(int) DBGFR3RegNmQueryU16( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint16_t *pu16);
VMMR3DECL(int) DBGFR3RegNmQueryU32( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint32_t *pu32);
VMMR3DECL(int) DBGFR3RegNmQueryU64( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64);
VMMR3DECL(int) DBGFR3RegNmQueryU128(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PRTUINT128U pu128);
/*VMMR3DECL(int) DBGFR3RegNmQueryLrd( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, long double *plrd);*/
VMMR3DECL(int) DBGFR3RegNmQueryXdtr(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64Base, uint16_t *pu16Limit);
VMMR3DECL(int) DBGFR3RegNmQueryBatch(PUVM pUVM,VMCPUID idDefCpu, PDBGFREGENTRYNM paRegs, size_t cRegs);
VMMR3DECL(int) DBGFR3RegNmSet( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType);
VMMR3DECL(int) DBGFR3RegNmSetU128( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, RTUINT128U u128);
VMMR3DECL(int) DBGFR3RegNmSetLrd( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, long double lrd);
VMMR3DECL(int) DBGFR3RegNmSetBatch( PUVM pUVM, VMCPUID idDefCpu, PCDBGFREGENTRYNM paRegs, size_t cRegs);
/** @todo add enumeration methods. */
VMMR3DECL(int) DBGFR3RegPrintf( PUVM pUVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, ...);
VMMR3DECL(int) DBGFR3RegPrintfV(PUVM pUVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, va_list va);
/**
* Guest OS digger interface identifier.
*
* This is for use together with PDBGFR3QueryInterface and is used to
* obtain access to optional interfaces.
*/
typedef enum DBGFOSINTERFACE
{
/** The usual invalid entry. */
/** Process info. */
/** Thread info. */
/** The end of the valid entries. */
/** The usual 32-bit type blowup. */
DBGFOSINTERFACE_32BIT_HACK = 0x7fffffff
/** Pointer to a Guest OS digger interface identifier. */
typedef DBGFOSINTERFACE *PDBGFOSINTERFACE;
/** Pointer to a const Guest OS digger interface identifier. */
typedef DBGFOSINTERFACE const *PCDBGFOSINTERFACE;
/**
* Guest OS Digger Registration Record.
*
* This is used with the DBGFR3OSRegister() API.
*/
typedef struct DBGFOSREG
{
/** Magic value (DBGFOSREG_MAGIC). */
/** Flags. Reserved. */
/** The size of the instance data. */
/** Operative System name. */
char szName[24];
/**
* Constructs the instance.
*
* @returns VBox status code.
* @param pUVM The user mode VM handle.
* @param pvData Pointer to the instance data.
*/
/**
* Destroys the instance.
*
* @param pUVM The user mode VM handle.
* @param pvData Pointer to the instance data.
*/
/**
* Probes the guest memory for OS finger prints.
*
* No setup or so is performed, it will be followed by a call to pfnInit
* or pfnRefresh that should take care of that.
*
* @returns true if is an OS handled by this module, otherwise false.
* @param pUVM The user mode VM handle.
* @param pvData Pointer to the instance data.
*/
/**
* Initializes a fresly detected guest, loading symbols and such useful stuff.
*
* This is called after pfnProbe.
*
* @returns VBox status code.
* @param pUVM The user mode VM handle.
* @param pvData Pointer to the instance data.
*/
/**
* Refreshes symbols and stuff following a redetection of the same OS.
*
* This is called after pfnProbe.
*
* @returns VBox status code.
* @param pUVM The user mode VM handle.
* @param pvData Pointer to the instance data.
*/
/**
* Terminates an OS when a new (or none) OS has been detected,
* and before destruction.
*
* This is called after pfnProbe and if needed before pfnDestruct.
*
* @param pUVM The user mode VM handle.
* @param pvData Pointer to the instance data.
*/
/**
* Queries the version of the running OS.
*
* This is only called after pfnInit().
*
* @returns VBox status code.
* @param pUVM The user mode VM handle.
* @param pvData Pointer to the instance data.
* @param pszVersion Where to store the version string.
* @param cchVersion The size of the version string buffer.
*/
DECLCALLBACKMEMBER(int, pfnQueryVersion)(PUVM pUVM, void *pvData, char *pszVersion, size_t cchVersion);
/**
* Queries the pointer to a interface.
*
* This is called after pfnProbe.
*
* @returns Pointer to the interface if available, NULL if not available.
* @param pUVM The user mode VM handle.
* @param pvData Pointer to the instance data.
* @param enmIf The interface identifier.
*/
/** Trailing magic (DBGFOSREG_MAGIC). */
} DBGFOSREG;
/** Pointer to a Guest OS digger registration record. */
typedef DBGFOSREG *PDBGFOSREG;
/** Pointer to a const Guest OS digger registration record. */
typedef DBGFOSREG const *PCDBGFOSREG;
/** Magic value for DBGFOSREG::u32Magic and DBGFOSREG::u32EndMagic. (Hitomi Kanehara) */
#define DBGFOSREG_MAGIC 0x19830808
VMMR3DECL(int) DBGFR3OSQueryNameAndVersion(PUVM pUVM, char *pszName, size_t cchName, char *pszVersion, size_t cchVersion);
/** @} */
#endif