dbg.h revision 10bea85296ddd1bd4ed6fca7f9bdf386d071ffb6
/** @file
* Debugger Interfaces. (VBoxDbg)
*
* This header covers all external interfaces of the Debugger module.
* However, it does not cover the DBGF interface since that part of the
* VMM. Use dbgf.h for that.
*/
/*
* Copyright (C) 2006-2007 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* 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_dbg_h
#define ___VBox_dbg_h
#include <VBox/cdefs.h>
#include <VBox/types.h>
#include <VBox/vmm/dbgf.h>
#include <iprt/stdarg.h>
#ifdef IN_RING3
# include <iprt/err.h>
#endif
RT_C_DECLS_BEGIN
/** @def VBOX_WITH_DEBUGGER
* The build is with debugger module. Test if this is defined before registering
* external debugger commands. This is normally defined in Config.kmk.
*/
#ifdef DOXYGEN_RUNNING
# define VBOX_WITH_DEBUGGER
#endif
/**
* DBGC variable category.
*
* Used to describe an argument to a command or function and a functions
* return value.
*/
typedef enum DBGCVARCAT
{
/** Any type is fine. */
DBGCVAR_CAT_ANY = 0,
/** Any kind of pointer or number. */
DBGCVAR_CAT_POINTER_NUMBER,
/** Any kind of pointer or number, no range. */
DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE,
/** Any kind of pointer. */
DBGCVAR_CAT_POINTER,
/** Any kind of pointer with no range option. */
DBGCVAR_CAT_POINTER_NO_RANGE,
/** GC pointer. */
DBGCVAR_CAT_GC_POINTER,
/** GC pointer with no range option. */
DBGCVAR_CAT_GC_POINTER_NO_RANGE,
/** Numeric argument. */
DBGCVAR_CAT_NUMBER,
/** Numeric argument with no range option. */
DBGCVAR_CAT_NUMBER_NO_RANGE,
/** String. */
DBGCVAR_CAT_STRING,
/** Symbol. */
DBGCVAR_CAT_SYMBOL,
/** Option. */
DBGCVAR_CAT_OPTION,
/** Option + string. */
DBGCVAR_CAT_OPTION_STRING,
/** Option + number. */
DBGCVAR_CAT_OPTION_NUMBER
} DBGCVARCAT;
/**
* DBGC variable type.
*/
typedef enum DBGCVARTYPE
{
/** unknown... */
DBGCVAR_TYPE_UNKNOWN = 0,
/** Flat GC pointer. */
DBGCVAR_TYPE_GC_FLAT,
/** Segmented GC pointer. */
DBGCVAR_TYPE_GC_FAR,
/** Physical GC pointer. */
DBGCVAR_TYPE_GC_PHYS,
/** Flat HC pointer. */
DBGCVAR_TYPE_HC_FLAT,
/** Physical HC pointer. */
DBGCVAR_TYPE_HC_PHYS,
/** String. */
DBGCVAR_TYPE_STRING,
/** Number. */
DBGCVAR_TYPE_NUMBER,
/** Symbol.
* @todo drop this */
DBGCVAR_TYPE_SYMBOL,
/** Special type used when querying symbols. */
DBGCVAR_TYPE_ANY
} DBGCVARTYPE;
/** @todo Rename to DBGCVAR_IS_xyz. */
/** Checks if the specified variable type is of a pointer persuasion. */
#define DBGCVAR_ISPOINTER(enmType) ((enmType) >= DBGCVAR_TYPE_GC_FLAT && enmType <= DBGCVAR_TYPE_HC_PHYS)
/** Checks if the specified variable type is of a pointer persuasion. */
#define DBGCVAR_IS_FAR_PTR(enmType) ((enmType) == DBGCVAR_TYPE_GC_FAR)
/** Checks if the specified variable type is of a pointer persuasion and of the guest context sort. */
#define DBGCVAR_ISGCPOINTER(enmType) ((enmType) >= DBGCVAR_TYPE_GC_FLAT && (enmType) <= DBGCVAR_TYPE_GC_PHYS)
/** Checks if the specified variable type is of a pointer persuasion and of the host context sort. */
#define DBGCVAR_ISHCPOINTER(enmType) ((enmType) >= DBGCVAR_TYPE_HC_FLAT && (enmType) <= DBGCVAR_TYPE_HC_PHYS)
/**
* DBGC variable range type.
*/
typedef enum DBGCVARRANGETYPE
{
/** No range appliable or no range specified. */
DBGCVAR_RANGE_NONE = 0,
/** Number of elements. */
DBGCVAR_RANGE_ELEMENTS,
/** Number of bytes. */
DBGCVAR_RANGE_BYTES
} DBGCVARRANGETYPE;
/**
* Variable descriptor.
*/
typedef struct DBGCVARDESC
{
/** The minimal number of times this argument may occur.
* Use 0 here to inidicate that the argument is optional. */
unsigned cTimesMin;
/** Maximum number of occurrences.
* Use ~0 here to indicate infinite. */
unsigned cTimesMax;
/** Argument category. */
DBGCVARCAT enmCategory;
/** Flags, DBGCVD_FLAGS_* */
unsigned fFlags;
/** Argument name. */
const char *pszName;
/** Argument name. */
const char *pszDescription;
} DBGCVARDESC;
/** Pointer to an argument descriptor. */
typedef DBGCVARDESC *PDBGCVARDESC;
/** Pointer to a const argument descriptor. */
typedef const DBGCVARDESC *PCDBGCVARDESC;
/** Variable descriptor flags.
* @{ */
/** Indicates that the variable depends on the previous being present. */
#define DBGCVD_FLAGS_DEP_PREV RT_BIT(1)
/** @} */
/**
* DBGC variable.
*/
typedef struct DBGCVAR
{
/** Pointer to the argument descriptor. */
PCDBGCVARDESC pDesc;
/** Pointer to the next argument. */
struct DBGCVAR *pNext;
/** Argument type. */
DBGCVARTYPE enmType;
/** Type specific. */
union
{
/** Flat GC Address. (DBGCVAR_TYPE_GC_FLAT) */
RTGCPTR GCFlat;
/** Far (16:32) GC Address. (DBGCVAR_TYPE_GC_FAR) */
RTFAR32 GCFar;
/** Physical GC Address. (DBGCVAR_TYPE_GC_PHYS) */
RTGCPHYS GCPhys;
/** Flat HC Address. (DBGCVAR_TYPE_HC_FLAT) */
void *pvHCFlat;
/** Physical GC Address. (DBGCVAR_TYPE_HC_PHYS) */
RTHCPHYS HCPhys;
/** String. (DBGCVAR_TYPE_STRING)
* The basic idea is the the this is a pointer to the expression we're
* parsing, so no messing with freeing. */
const char *pszString;
/** Number. (DBGCVAR_TYPE_NUMBER) */
uint64_t u64Number;
} u;
/** Range type. */
DBGCVARRANGETYPE enmRangeType;
/** Range. The use of the content depends on the enmRangeType. */
uint64_t u64Range;
} DBGCVAR;
/** Pointer to a command argument. */
typedef DBGCVAR *PDBGCVAR;
/** Pointer to a const command argument. */
typedef const DBGCVAR *PCDBGCVAR;
/**
* Macro for initializing a DBGC variable with defaults.
* The result is an unknown variable type without any range.
*/
#define DBGCVAR_INIT(pVar) \
do { \
(pVar)->pDesc = NULL;\
(pVar)->pNext = NULL; \
(pVar)->enmType = DBGCVAR_TYPE_UNKNOWN; \
(pVar)->u.u64Number = 0; \
(pVar)->enmRangeType = DBGCVAR_RANGE_NONE; \
(pVar)->u64Range = 0; \
} while (0)
/**
* Macro for initializing a DBGC variable with a HC physical address.
*/
#define DBGCVAR_INIT_HC_PHYS(pVar, Phys) \
do { \
DBGCVAR_INIT(pVar); \
(pVar)->enmType = DBGCVAR_TYPE_HC_PHYS; \
(pVar)->u.HCPhys = (Phys); \
} while (0)
/**
* Macro for initializing a DBGC variable with a HC flat address.
*/
#define DBGCVAR_INIT_HC_FLAT(pVar, Flat) \
do { \
DBGCVAR_INIT(pVar); \
(pVar)->enmType = DBGCVAR_TYPE_HC_FLAT; \
(pVar)->u.pvHCFlat = (Flat); \
} while (0)
/**
* Macro for initializing a DBGC variable with a GC physical address.
*/
#define DBGCVAR_INIT_GC_PHYS(pVar, Phys) \
do { \
DBGCVAR_INIT(pVar); \
(pVar)->enmType = DBGCVAR_TYPE_GC_PHYS; \
(pVar)->u.GCPhys = (Phys); \
} while (0)
/**
* Macro for initializing a DBGC variable with a GC flat address.
*/
#define DBGCVAR_INIT_GC_FLAT(pVar, Flat) \
do { \
DBGCVAR_INIT(pVar); \
(pVar)->enmType = DBGCVAR_TYPE_GC_FLAT; \
(pVar)->u.GCFlat = (Flat); \
} while (0)
/**
* Macro for initializing a DBGC variable with a GC far address.
*/
#define DBGCVAR_INIT_GC_FAR(pVar, _sel, _off) \
do { \
DBGCVAR_INIT(pVar); \
(pVar)->enmType = DBGCVAR_TYPE_GC_FAR; \
(pVar)->u.GCFar.sel = (_sel); \
(pVar)->u.GCFar.off = (_off); \
} while (0)
/**
* Macro for initializing a DBGC variable with a number.
*/
#define DBGCVAR_INIT_NUMBER(pVar, Value) \
do { \
DBGCVAR_INIT(pVar); \
(pVar)->enmType = DBGCVAR_TYPE_NUMBER; \
(pVar)->u.u64Number = (Value); \
} while (0)
/**
* Macro for initializing a DBGC variable with a string.
*/
#define DBGCVAR_INIT_STRING(pVar, a_pszString) \
do { \
DBGCVAR_INIT(pVar); \
(pVar)->enmType = DBGCVAR_TYPE_STRING; \
(pVar)->enmRangeType = DBGCVAR_RANGE_BYTES; \
(pVar)->u.pszString = (a_pszString); \
(pVar)->u64Range = strlen(a_pszString); \
} while (0)
/**
* Macro for setting the range of a DBGC variable.
* @param pVar The variable.
* @param _enmRangeType The range type.
* @param Value The range length value.
*/
#define DBGCVAR_SET_RANGE(pVar, _enmRangeType, Value) \
do { \
(pVar)->enmRangeType = (_enmRangeType); \
(pVar)->u64Range = (Value); \
} while (0)
/** Pointer to command descriptor. */
typedef struct DBGCCMD *PDBGCCMD;
/** Pointer to const command descriptor. */
typedef const struct DBGCCMD *PCDBGCCMD;
/** Pointer to helper functions for commands. */
typedef struct DBGCCMDHLP *PDBGCCMDHLP;
/**
* Command helper for writing text to the debug console.
*
* @returns VBox status.
* @param pCmdHlp Pointer to the command callback structure.
* @param pvBuf What to write.
* @param cbBuf Number of bytes to write.
* @param pcbWritten Where to store the number of bytes actually written.
* If NULL the entire buffer must be successfully written.
*/
typedef DECLCALLBACK(int) FNDBGCHLPWRITE(PDBGCCMDHLP pCmdHlp, const void *pvBuf, size_t cbBuf, size_t *pcbWritten);
/** Pointer to a FNDBGCHLPWRITE() function. */
typedef FNDBGCHLPWRITE *PFNDBGCHLPWRITE;
/**
* Command helper for writing formatted text to the debug console.
*
* @returns VBox status.
* @param pCmdHlp Pointer to the command callback structure.
* @param pcb Where to store the number of bytes written.
* @param pszFormat The format string.
* This is using the log formatter, so it's format extensions can be used.
* @param ... Arguments specified in the format string.
*/
typedef DECLCALLBACK(int) FNDBGCHLPPRINTF(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, ...);
/** Pointer to a FNDBGCHLPPRINTF() function. */
typedef FNDBGCHLPPRINTF *PFNDBGCHLPPRINTF;
/**
* Command helper for writing formatted text to the debug console.
*
* @returns VBox status.
* @param pCmdHlp Pointer to the command callback structure.
* @param pcb Where to store the number of bytes written.
* @param pszFormat The format string.
* This is using the log formatter, so it's format extensions can be used.
* @param args Arguments specified in the format string.
*/
typedef DECLCALLBACK(int) FNDBGCHLPPRINTFV(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, va_list args);
/** Pointer to a FNDBGCHLPPRINTFV() function. */
typedef FNDBGCHLPPRINTFV *PFNDBGCHLPPRINTFV;
/**
* Command helper for formatting and error message for a VBox status code.
*
* @returns VBox status code appropriate to return from a command.
* @param pCmdHlp Pointer to the command callback structure.
* @param rc The VBox status code.
* @param pszFormat Format string for additional messages. Can be NULL.
* @param ... Format arguments, optional.
*/
typedef DECLCALLBACK(int) FNDBGCHLPVBOXERROR(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, ...);
/** Pointer to a FNDBGCHLPVBOXERROR() function. */
typedef FNDBGCHLPVBOXERROR *PFNDBGCHLPVBOXERROR;
/**
* Command helper for formatting and error message for a VBox status code.
*
* @returns VBox status code appropriate to return from a command.
* @param pCmdHlp Pointer to the command callback structure.
* @param rc The VBox status code.
* @param pcb Where to store the number of bytes written.
* @param pszFormat Format string for additional messages. Can be NULL.
* @param args Format arguments, optional.
*/
typedef DECLCALLBACK(int) FNDBGCHLPVBOXERRORV(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, va_list args);
/** Pointer to a FNDBGCHLPVBOXERRORV() function. */
typedef FNDBGCHLPVBOXERRORV *PFNDBGCHLPVBOXERRORV;
/**
* Command helper for reading memory specified by a DBGC variable.
*
* @returns VBox status code appropriate to return from a command.
* @param pCmdHlp Pointer to the command callback structure.
* @param pVM VM handle if GC or physical HC address.
* @param pvBuffer Where to store the read data.
* @param cbRead Number of bytes to read.
* @param pVarPointer DBGC variable specifying where to start reading.
* @param pcbRead Where to store the number of bytes actually read.
* This optional, but it's useful when read GC virtual memory where a
* page in the requested range might not be present.
* If not specified not-present failure or end of a HC physical page
* will cause failure.
*/
typedef DECLCALLBACK(int) FNDBGCHLPMEMREAD(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead);
/** Pointer to a FNDBGCHLPMEMREAD() function. */
typedef FNDBGCHLPMEMREAD *PFNDBGCHLPMEMREAD;
/**
* Command helper for writing memory specified by a DBGC variable.
*
* @returns VBox status code appropriate to return from a command.
* @param pCmdHlp Pointer to the command callback structure.
* @param pVM VM handle if GC or physical HC address.
* @param pvBuffer What to write.
* @param cbWrite Number of bytes to write.
* @param pVarPointer DBGC variable specifying where to start reading.
* @param pcbWritten Where to store the number of bytes written.
* This is optional. If NULL be aware that some of the buffer
* might have been written to the specified address.
*/
typedef DECLCALLBACK(int) FNDBGCHLPMEMWRITE(PDBGCCMDHLP pCmdHlp, PVM pVM, const void *pvBuffer, size_t cbWrite, PCDBGCVAR pVarPointer, size_t *pcbWritten);
/** Pointer to a FNDBGCHLPMEMWRITE() function. */
typedef FNDBGCHLPMEMWRITE *PFNDBGCHLPMEMWRITE;
/**
* Executes command an expression.
* (Hopefully the parser and functions are fully reentrant.)
*
* @returns VBox status code appropriate to return from a command.
* @param pCmdHlp Pointer to the command callback structure.
* @param pszExpr The expression. Format string with the format DBGC extensions.
* @param ... Format arguments.
*/
typedef DECLCALLBACK(int) FNDBGCHLPEXEC(PDBGCCMDHLP pCmdHlp, const char *pszExpr, ...);
/** Pointer to a FNDBGCHLPEVAL() function. */
typedef FNDBGCHLPEXEC *PFNDBGCHLPEXEC;
/**
* Helper functions for commands.
*/
typedef struct DBGCCMDHLP
{
/** Pointer to a FNDBCHLPWRITE() function. */
PFNDBGCHLPWRITE pfnWrite;
/** Pointer to a FNDBGCHLPPRINTF() function. */
PFNDBGCHLPPRINTF pfnPrintf;
/** Pointer to a FNDBGCHLPPRINTFV() function. */
PFNDBGCHLPPRINTFV pfnPrintfV;
/** Pointer to a FNDBGCHLPVBOXERROR() function. */
PFNDBGCHLPVBOXERROR pfnVBoxError;
/** Pointer to a FNDBGCHLPVBOXERRORV() function. */
PFNDBGCHLPVBOXERRORV pfnVBoxErrorV;
/** Pointer to a FNDBGCHLPMEMREAD() function. */
PFNDBGCHLPMEMREAD pfnMemRead;
/** Pointer to a FNDBGCHLPMEMWRITE() function. */
PFNDBGCHLPMEMWRITE pfnMemWrite;
/** Pointer to a FNDBGCHLPEXEC() function. */
PFNDBGCHLPEXEC pfnExec;
/**
* Evaluates an expression.
* (Hopefully the parser and functions are fully reentrant.)
*
* @returns VBox status code appropriate to return from a command.
* @param pCmdHlp Pointer to the command callback structure.
* @param pResult Where to store the result.
* @param pszExpr The expression. Format string with the format DBGC extensions.
* @param va Format arguments.
*/
DECLCALLBACKMEMBER(int, pfnEvalV)(PDBGCCMDHLP pCmdHlp, PDBGCVAR pResult, const char *pszExpr, va_list va);
/**
* Print an error and fail the current command.
*
* @returns VBox status code to pass upwards.
*
* @param pCmdHlp Pointer to the command callback structure.
* @param pCmd The failing command.
* @param pszFormat The error message format string.
* @param va Format arguments.
*/
DECLCALLBACKMEMBER(int, pfnFailV)(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, const char *pszFormat, va_list va);
/**
* Converts a DBGC variable to a DBGF address structure.
*
* @returns VBox status code.
* @param pCmdHlp Pointer to the command callback structure.
* @param pVar The variable to convert.
* @param pAddress The target address.
*/
DECLCALLBACKMEMBER(int, pfnVarToDbgfAddr)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PDBGFADDRESS pAddress);
/**
* Converts a DBGC variable to a 64-bit number.
*
* @returns VBox status code.
* @param pCmdHlp Pointer to the command callback structure.
* @param pVar The variable to convert.
* @param pu64Number Where to store the number.
*/
DECLCALLBACKMEMBER(int, pfnVarToNumber)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t *pu64Number);
/**
* Converts a DBGC variable to a boolean.
*
* @returns VBox status code.
* @param pCmdHlp Pointer to the command callback structure.
* @param pVar The variable to convert.
* @param pf Where to store the boolean.
*/
DECLCALLBACKMEMBER(int, pfnVarToBool)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, bool *pf);
/**
* Get the range of a variable in bytes, resolving symbols if necessary.
*
* @returns VBox status code.
* @param pCmdHlp Pointer to the command callback structure.
* @param pVar The variable to convert.
* @param cbElement Conversion factor for element ranges.
* @param cbDefault The default range.
* @param pcbRange The length of the range.
*/
DECLCALLBACKMEMBER(int, pfnVarGetRange)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t cbElement, uint64_t cbDefault,
uint64_t *pcbRange);
/**
* Converts a variable to one with the specified type.
*
* This preserves the range.
*
* @returns VBox status code.
* @param pCmdHlp Pointer to the command callback structure.
* @param pVar The variable to convert.
* @param enmToType The target type.
* @param fConvSyms If @c true, then attempt to resolve symbols.
* @param pResult The output variable. Can be the same as @a pVar.
*/
DECLCALLBACKMEMBER(int, pfnVarConvert)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, DBGCVARTYPE enmToType, bool fConvSyms,
PDBGCVAR pResult);
/**
* Gets a DBGF output helper that directs the output to the debugger
* console.
*
* @returns Pointer to the helper structure.
* @param pCmdHlp Pointer to the command callback structure.
*/
DECLCALLBACKMEMBER(PCDBGFINFOHLP, pfnGetDbgfOutputHlp)(PDBGCCMDHLP pCmdHlp);
} DBGCCMDHLP;
#ifdef IN_RING3
/**
* Command helper for writing formatted text to the debug console.
*
* @returns VBox status.
* @param pCmdHlp Pointer to the command callback structure.
* @param pszFormat The format string.
* This is using the log formatter, so it's format extensions can be used.
* @param ... Arguments specified in the format string.
*/
DECLINLINE(int) DBGCCmdHlpPrintf(PDBGCCMDHLP pCmdHlp, const char *pszFormat, ...)
{
va_list va;
int rc;
va_start(va, pszFormat);
rc = pCmdHlp->pfnPrintfV(pCmdHlp, NULL, pszFormat, va);
va_end(va);
return rc;
}
/**
* @copydoc FNDBGCHLPVBOXERROR
*/
DECLINLINE(int) DBGCCmdHlpVBoxError(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, ...)
{
va_list va;
va_start(va, pszFormat);
rc = pCmdHlp->pfnVBoxErrorV(pCmdHlp, rc, pszFormat, va);
va_end(va);
return rc;
}
/**
* @copydoc FNDBGCHLPMEMREAD
*/
DECLINLINE(int) DBGCCmdHlpMemRead(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead)
{
return pCmdHlp->pfnMemRead(pCmdHlp, pVM, pvBuffer, cbRead, pVarPointer, pcbRead);
}
/**
* Evaluates an expression.
* (Hopefully the parser and functions are fully reentrant.)
*
* @returns VBox status code appropriate to return from a command.
* @param pCmdHlp Pointer to the command callback structure.
* @param pResult Where to store the result.
* @param pszExpr The expression. Format string with the format DBGC extensions.
* @param ... Format arguments.
*/
DECLINLINE(int) DBGCCmdHlpEval(PDBGCCMDHLP pCmdHlp, PDBGCVAR pResult, const char *pszExpr, ...)
{
va_list va;
int rc;
va_start(va, pszExpr);
rc = pCmdHlp->pfnEvalV(pCmdHlp, pResult, pszExpr, va);
va_end(va);
return rc;
}
/**
* Print an error and fail the current command.
*
* @returns VBox status code to pass upwards.
*
* @param pCmdHlp Pointer to the command callback structure.
* @param pCmd The failing command.
* @param pszFormat The error message format string.
* @param ... Format arguments.
*/
DECLINLINE(int) DBGCCmdHlpFail(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, const char *pszFormat, ...)
{
va_list va;
int rc;
va_start(va, pszFormat);
rc = pCmdHlp->pfnFailV(pCmdHlp, pCmd, pszFormat, va);
va_end(va);
return rc;
}
/**
* @copydoc DBGCCMDHLP::pfnVarToDbgfAddr
*/
DECLINLINE(int) DBGCCmdHlpVarToDbgfAddr(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PDBGFADDRESS pAddress)
{
return pCmdHlp->pfnVarToDbgfAddr(pCmdHlp, pVar, pAddress);
}
/**
* Converts an variable to a flat address.
*
* @returns VBox status code.
* @param pCmdHlp Pointer to the command callback structure.
* @param pVar The variable to convert.
* @param pFlatPtr Where to store the flat address.
*/
DECLINLINE(int) DBGCCmdHlpVarToFlatAddr(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PRTGCPTR pFlatPtr)
{
DBGFADDRESS Addr;
int rc = pCmdHlp->pfnVarToDbgfAddr(pCmdHlp, pVar, &Addr);
if (RT_SUCCESS(rc))
*pFlatPtr = Addr.FlatPtr;
return rc;
}
/**
* @copydoc DBGCCMDHLP::pfnVarToNumber
*/
DECLINLINE(int) DBGCCmdHlpVarToNumber(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t *pu64Number)
{
return pCmdHlp->pfnVarToNumber(pCmdHlp, pVar, pu64Number);
}
/**
* @copydoc DBGCCMDHLP::pfnVarToBool
*/
DECLINLINE(int) DBGCCmdHlpVarToBool(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, bool *pf)
{
return pCmdHlp->pfnVarToBool(pCmdHlp, pVar, pf);
}
/**
* @copydoc DBGCCMDHLP::pfnVarGetRange
*/
DECLINLINE(int) DBGCCmdHlpVarGetRange(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t cbElement, uint64_t cbDefault, uint64_t *pcbRange)
{
return pCmdHlp->pfnVarGetRange(pCmdHlp, pVar, cbElement, cbDefault, pcbRange);
}
/**
* @copydoc DBGCCMDHLP::pfnVarConvert
*/
DECLINLINE(int) DBGCCmdHlpConvert(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, DBGCVARTYPE enmToType, bool fConvSyms, PDBGCVAR pResult)
{
return pCmdHlp->pfnVarConvert(pCmdHlp, pVar, enmToType, fConvSyms, pResult);
}
/**
* @copydoc DBGCCMDHLP::pfnGetDbgfOutputHlp
*/
DECLINLINE(PCDBGFINFOHLP) DBGCCmdHlpGetDbgfOutputHlp(PDBGCCMDHLP pCmdHlp)
{
return pCmdHlp->pfnGetDbgfOutputHlp(pCmdHlp);
}
#endif /* IN_RING3 */
/**
* Command handler.
*
* The console will call the handler for a command once it's finished
* parsing the user input. The command handler function is responsible
* for executing the command itself.
*
* @returns VBox status.
* @param pCmd Pointer to the command descriptor (as registered).
* @param pCmdHlp Pointer to command helper functions.
* @param pVM Pointer to the current VM (if any).
* @param paArgs Pointer to (readonly) array of arguments.
* @param cArgs Number of arguments in the array.
* @param pResult Where to store the result. NULL if no result descriptor was specified.
*/
typedef DECLCALLBACK(int) FNDBGCCMD(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArgs, unsigned cArgs, PDBGCVAR pResult);
/** Pointer to a FNDBGCCMD() function. */
typedef FNDBGCCMD *PFNDBGCCMD;
/**
* DBGC command descriptor.
*
* If a pResultDesc is specified the command can be called and used
* as a function too. If it's a pure function, set fFlags to
* DBGCCMD_FLAGS_FUNCTION.
*/
typedef struct DBGCCMD
{
/** Command string. */
const char *pszCmd;
/** Minimum number of arguments. */
unsigned cArgsMin;
/** Max number of arguments. */
unsigned cArgsMax;
/** Argument descriptors (array). */
PCDBGCVARDESC paArgDescs;
/** Number of argument descriptors. */
unsigned cArgDescs;
/** Result descriptor. */
PCDBGCVARDESC pResultDesc;
/** flags. (reserved for now) */
unsigned fFlags;
/** Handler function. */
PFNDBGCCMD pfnHandler;
/** Command syntax. */
const char *pszSyntax;
/** Command description. */
const char *pszDescription;
} DBGCCMD;
/** DBGCCMD Flags.
* @{
*/
/** The description is of a pure function which cannot be invoked
* as a command from the commandline. */
#define DBGCCMD_FLAGS_FUNCTION 1
/** @} */
/** Pointer to a DBGC backend. */
typedef struct DBGCBACK *PDBGCBACK;
/**
* Checks if there is input.
*
* @returns true if there is input ready.
* @returns false if there not input ready.
* @param pBack Pointer to the backend structure supplied by
* the backend. The backend can use this to find
* it's instance data.
* @param cMillies Number of milliseconds to wait on input data.
*/
typedef DECLCALLBACK(bool) FNDBGCBACKINPUT(PDBGCBACK pBack, uint32_t cMillies);
/** Pointer to a FNDBGCBACKINPUT() callback. */
typedef FNDBGCBACKINPUT *PFNDBGCBACKINPUT;
/**
* Read input.
*
* @returns VBox status code.
* @param pBack Pointer to the backend structure supplied by
* the backend. The backend can use this to find
* it's instance data.
* @param pvBuf Where to put the bytes we read.
* @param cbBuf Maximum nymber of bytes to read.
* @param pcbRead Where to store the number of bytes actually read.
* If NULL the entire buffer must be filled for a
* successful return.
*/
typedef DECLCALLBACK(int) FNDBGCBACKREAD(PDBGCBACK pBack, void *pvBuf, size_t cbBuf, size_t *pcbRead);
/** Pointer to a FNDBGCBACKREAD() callback. */
typedef FNDBGCBACKREAD *PFNDBGCBACKREAD;
/**
* Write (output).
*
* @returns VBox status code.
* @param pBack Pointer to the backend structure supplied by
* the backend. The backend can use this to find
* it's instance data.
* @param pvBuf What to write.
* @param cbBuf Number of bytes to write.
* @param pcbWritten Where to store the number of bytes actually written.
* If NULL the entire buffer must be successfully written.
*/
typedef DECLCALLBACK(int) FNDBGCBACKWRITE(PDBGCBACK pBack, const void *pvBuf, size_t cbBuf, size_t *pcbWritten);
/** Pointer to a FNDBGCBACKWRITE() callback. */
typedef FNDBGCBACKWRITE *PFNDBGCBACKWRITE;
/**
* Ready / busy notification.
*
* @param pBack Pointer to the backend structure supplied by
* the backend. The backend can use this to find
* it's instance data.
* @param fReady Whether it's ready (true) or busy (false).
*/
typedef DECLCALLBACK(void) FNDBGCBACKSETREADY(PDBGCBACK pBack, bool fReady);
/** Pointer to a FNDBGCBACKSETREADY() callback. */
typedef FNDBGCBACKSETREADY *PFNDBGCBACKSETREADY;
/**
* The communication backend provides the console with a number of callbacks
* which can be used
*/
typedef struct DBGCBACK
{
/** Check for input. */
PFNDBGCBACKINPUT pfnInput;
/** Read input. */
PFNDBGCBACKREAD pfnRead;
/** Write output. */
PFNDBGCBACKWRITE pfnWrite;
/** Ready / busy notification. */
PFNDBGCBACKSETREADY pfnSetReady;
} DBGCBACK;
/**
* Make a console instance.
*
* This will not return until either an 'exit' command is issued or a error code
* indicating connection loss is encountered.
*
* @returns VINF_SUCCESS if console termination caused by the 'exit' command.
* @returns The VBox status code causing the console termination.
*
* @param pVM VM Handle.
* @param pBack Pointer to the backend structure. This must contain
* a full set of function pointers to service the console.
* @param fFlags Reserved, must be zero.
* @remark A forced termination of the console is easiest done by forcing the
* callbacks to return fatal failures.
*/
DBGDECL(int) DBGCCreate(PVM pVM, PDBGCBACK pBack, unsigned fFlags);
/**
* Register one or more external commands.
*
* @returns VBox status.
* @param paCommands Pointer to an array of command descriptors.
* The commands must be unique. It's not possible
* to register the same commands more than once.
* @param cCommands Number of commands.
*/
DBGDECL(int) DBGCRegisterCommands(PCDBGCCMD paCommands, unsigned cCommands);
/**
* Deregister one or more external commands previously registered by
* DBGCRegisterCommands().
*
* @returns VBox status.
* @param paCommands Pointer to an array of command descriptors
* as given to DBGCRegisterCommands().
* @param cCommands Number of commands.
*/
DBGDECL(int) DBGCDeregisterCommands(PCDBGCCMD paCommands, unsigned cCommands);
/**
* Spawns a new thread with a TCP based debugging console service.
*
* @returns VBox status.
* @param pVM VM handle.
* @param ppvData Where to store the pointer to instance data.
*/
DBGDECL(int) DBGCTcpCreate(PVM pVM, void **ppvUser);
/**
* Terminates any running TCP base debugger console service.
*
* @returns VBox status.
* @param pVM VM handle.
* @param pvData Instance data set by DBGCTcpCreate().
*/
DBGDECL(int) DBGCTcpTerminate(PVM pVM, void *pvData);
/** @defgroup grp_dbgc_plug_in The DBGC Plug-in Interface
* @{
*/
/** The plug-in module name prefix. */
#define DBGC_PLUG_IN_PREFIX "DBGCPlugIn"
/** The name of the plug-in entry point (FNDBGCPLUGIN) */
#define DBGC_PLUG_IN_ENTRYPOINT "DBGCPlugInEntry"
/**
* DBGC plug-in operations.
*/
typedef enum DBGCPLUGINOP
{
/** The usual invalid first value. */
DBGCPLUGINOP_INVALID,
/** Initialize the plug-in, register all the stuff.
* The plug-in will be unloaded on failure.
* uArg: The VirtualBox version (major+minor). */
DBGCPLUGINOP_INIT,
/** Terminate the plug-ing, deregister all the stuff.
* The plug-in will be unloaded after this call regardless of the return
* code. */
DBGCPLUGINOP_TERM,
/** The usual 32-bit hack. */
DBGCPLUGINOP_32BIT_HACK = 0x7fffffff
} DBGCPLUGINOP;
/**
* DBGC plug-in main entry point.
*
* @returns VBox status code.
*
* @param enmOperation The operation.
* @param pVM The VM handle. This may be NULL.
* @param uArg Extra argument.
*/
typedef DECLCALLBACK(int) FNDBGCPLUGIN(DBGCPLUGINOP enmOperation, PVM pVM, uintptr_t uArg);
/** Pointer to a FNDBGCPLUGIN. */
typedef FNDBGCPLUGIN *PFNDBGCPLUGIN;
/** @copydoc FNDBGCPLUGIN */
DECLEXPORT(int) DBGCPlugInEntry(DBGCPLUGINOP enmOperation, PVM pVM, uintptr_t uArg);
/** @} */
RT_C_DECLS_END
#endif