DBGCCmdHlp.cpp revision 10bea85296ddd1bd4ed6fca7f9bdf386d071ffb6
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * DBGC - Debugger Console, Command Helpers.
506df97a8c78dacfe69bc4d3ee5d3de832d0f19avboxsync * Copyright (C) 2006-2011 Oracle Corporation
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * available from http://www.virtualbox.org. This file is free software;
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * you can redistribute it and/or modify it under the terms of the GNU
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * General Public License (GPL) as published by the Free Software
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
6ec4e1827eab6a424d672ef0e5a17b065e52db20vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync/*******************************************************************************
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync* Header Files *
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync*******************************************************************************/
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Command helper for writing text to the debug console.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns VBox status.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pCmdHlp Pointer to the command callback structure.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pvBuf What to write.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param cbBuf Number of bytes to write.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pcbWritten Where to store the number of bytes actually written.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * If NULL the entire buffer must be successfully written.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic DECLCALLBACK(int) dbgcHlpWrite(PDBGCCMDHLP pCmdHlp, const void *pvBuf, size_t cbBuf, size_t *pcbWritten)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return pDbgc->pBack->pfnWrite(pDbgc->pBack, pvBuf, cbBuf, pcbWritten);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Command helper for writing formatted text to the debug console.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns VBox status.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pCmdHlp Pointer to the command callback structure.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pcb Where to store the number of bytes written.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pszFormat The format string.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * This is using the log formatter, so it's format extensions can be used.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param ... Arguments specified in the format string.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic DECLCALLBACK(int) dbgcHlpPrintf(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, ...)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Do the formatting and output.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync int rc = pCmdHlp->pfnPrintfV(pCmdHlp, pcbWritten, pszFormat, args);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Callback to format non-standard format specifiers.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns The number of bytes formatted.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pvArg Formatter argument.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pfnOutput Pointer to output function.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pvArgOutput Argument for the output function.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param ppszFormat Pointer to the format string pointer. Advance this till the char
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * after the format specifier.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pArgs Pointer to the argument list. Use this to fetch the arguments.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param cchWidth Format Width. -1 if not specified.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param cchPrecision Format Precision. -1 if not specified.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param fFlags Flags (RTSTR_NTFS_*).
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param chArgSize The argument size specifier, 'l' or 'L'.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic DECLCALLBACK(size_t) dbgcStringFormatter(void *pvArg, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync const char **ppszFormat, va_list *pArgs, int cchWidth,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync NOREF(cchWidth); NOREF(cchPrecision); NOREF(fFlags); NOREF(chArgSize); NOREF(pvArg);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Print variable without range.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * The argument is a const pointer to the variable.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%%%RGv", pVar->u.GCFlat);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%04x:%08x", pVar->u.GCFar.sel, pVar->u.GCFar.off);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%%%%%RGp", pVar->u.GCPhys);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%%#%RHv", (uintptr_t)pVar->u.pvHCFlat);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "#%%%%%RHp", pVar->u.HCPhys);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return pfnOutput(pvArgOutput, pVar->u.pszString, (size_t)pVar->u64Range);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%llx", pVar->u.u64Number);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Print variable with range.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * The argument is a const pointer to the variable.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTStrPrintf(szRange, sizeof(szRange), " L %llx", pVar->u64Range);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTStrPrintf(szRange, sizeof(szRange), " LB %llx", pVar->u64Range);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%%%RGv%s", pVar->u.GCFlat, szRange);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%04x:%08x%s", pVar->u.GCFar.sel, pVar->u.GCFar.off, szRange);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%%%%%RGp%s", pVar->u.GCPhys, szRange);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%%#%RHv%s", (uintptr_t)pVar->u.pvHCFlat, szRange);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "#%%%%%RHp%s", pVar->u.HCPhys, szRange);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return pfnOutput(pvArgOutput, pVar->u.pszString, (size_t)pVar->u64Range);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%llx%s", pVar->u.u64Number, szRange);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync AssertMsgFailed(("Invalid format type '%s'!\n", **ppszFormat));
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Output callback.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns number of bytes written.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pvArg User argument.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pachChars Pointer to an array of utf-8 characters.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param cbChars Number of bytes in the character array pointed to by pachChars.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic DECLCALLBACK(size_t) dbgcFormatOutput(void *pvArg, const char *pachChars, size_t cbChars)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync int rc = pDbgc->pBack->pfnWrite(pDbgc->pBack, pachChars, cbChars, NULL);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Command helper for writing formatted text to the debug console.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns VBox status.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pCmdHlp Pointer to the command callback structure.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pcbWritten Where to store the number of bytes written.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pszFormat The format string.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * This is using the log formatter, so it's format extensions can be used.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param args Arguments specified in the format string.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic DECLCALLBACK(int) dbgcHlpPrintfV(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, va_list args)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Do the formatting and output.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync size_t cb = RTStrFormatV(dbgcFormatOutput, pDbgc, dbgcStringFormatter, pDbgc, pszFormat, args);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Reports an error from a DBGF call.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns VBox status code appropriate to return from a command.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pCmdHlp Pointer to command helpers.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param rc The VBox status code returned by a DBGF call.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pszFormat Format string for additional messages. Can be NULL.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param ... Format arguments, optional.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic DECLCALLBACK(int) dbgcHlpVBoxErrorV(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, va_list args)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: %Rrc: %s", rc, pszFormat ? " " : "\n");
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync rc = pCmdHlp->pfnPrintfV(pCmdHlp, NULL, pszFormat, args);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Reports an error from a DBGF call.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns VBox status code appropriate to return from a command.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pCmdHlp Pointer to command helpers.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param rc The VBox status code returned by a DBGF call.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pszFormat Format string for additional messages. Can be NULL.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param ... Format arguments, optional.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic DECLCALLBACK(int) dbgcHlpVBoxError(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, ...)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync int rcRet = pCmdHlp->pfnVBoxErrorV(pCmdHlp, rc, pszFormat, args);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Command helper for reading memory specified by a DBGC variable.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns VBox status code appropriate to return from a command.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pCmdHlp Pointer to the command callback structure.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pVM VM handle if GC or physical HC address.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pvBuffer Where to store the read data.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param cbRead Number of bytes to read.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pVarPointer DBGC variable specifying where to start reading.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pcbRead Where to store the number of bytes actually read.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * This optional, but it's useful when read GC virtual memory where a
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * page in the requested range might not be present.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * If not specified not-present failure or end of a HC physical page
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * will cause failure.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic DECLCALLBACK(int) dbgcHlpMemRead(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Dummy check.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Convert Far addresses getting size and the correct base address.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Getting and checking the size is what makes this messy and slow.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Use DBGFR3AddrFromSelOff for the conversion. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, Var.u.GCFar.sel, Var.u.GCFar.off);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* don't bother with flat selectors (for now). */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync rc = DBGFR3SelQueryInfo(pDbgc->pVM, pDbgc->idCpu, Address.Sel,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGFSELQI_FLAGS_DT_GUEST | DBGFSELQI_FLAGS_DT_ADJ_64BIT_MODE, &SelInfo);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync cb = (SelInfo.u.Raw.Gen.u1Granularity ? UINT32_C(0xffffffff) : UINT32_C(0xffff)) - Address.off;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Copy page by page.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Calc read size.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync case DBGCVAR_TYPE_GC_FLAT: cb = RT_MIN(cb, PAGE_SIZE - (Var.u.GCFlat & PAGE_OFFSET_MASK)); break;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync case DBGCVAR_TYPE_GC_PHYS: cb = RT_MIN(cb, PAGE_SIZE - (Var.u.GCPhys & PAGE_OFFSET_MASK)); break;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync case DBGCVAR_TYPE_HC_FLAT: cb = RT_MIN(cb, PAGE_SIZE - ((uintptr_t)Var.u.pvHCFlat & PAGE_OFFSET_MASK)); break;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync case DBGCVAR_TYPE_HC_PHYS: cb = RT_MIN(cb, PAGE_SIZE - ((size_t)Var.u.HCPhys & PAGE_OFFSET_MASK)); break; /* size_t: MSC has braindead loss of data warnings! */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync default: break;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Perform read.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** @todo protect this!!! */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Check for failure.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync rc = DBGCCmdHlpEval(pCmdHlp, &Var, "%DV + %d", &Var, cb);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Command helper for writing memory specified by a DBGC variable.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns VBox status code appropriate to return from a command.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pCmdHlp Pointer to the command callback structure.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pVM VM handle if GC or physical HC address.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pvBuffer What to write.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param cbWrite Number of bytes to write.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pVarPointer DBGC variable specifying where to start reading.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pcbWritten Where to store the number of bytes written.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * This is optional. If NULL be aware that some of the buffer
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * might have been written to the specified address.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic DECLCALLBACK(int) dbgcHlpMemWrite(PDBGCCMDHLP pCmdHlp, PVM pVM, const void *pvBuffer, size_t cbWrite, PCDBGCVAR pVarPointer, size_t *pcbWritten)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Dummy check.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Convert Far addresses getting size and the correct base address.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Getting and checking the size is what makes this messy and slow.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Use DBGFR3AddrFromSelOff for the conversion. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, Var.u.GCFar.sel, Var.u.GCFar.off);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* don't bother with flat selectors (for now). */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync rc = DBGFR3SelQueryInfo(pDbgc->pVM, pDbgc->idCpu, Address.Sel,
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync DBGFSELQI_FLAGS_DT_GUEST | DBGFSELQI_FLAGS_DT_ADJ_64BIT_MODE, &SelInfo);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync cb = (SelInfo.u.Raw.Gen.u1Granularity ? UINT32_C(0xffffffff) : UINT32_C(0xffff)) - Address.off;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* fall thru */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Copy HC memory page by page.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* convert to flat address */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* calc size. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync cbChunk -= (uintptr_t)Var.u.pvHCFlat & PAGE_OFFSET_MASK;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** @todo protect this!!! */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* advance */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync Var.u.pvHCFlat = (uint8_t *)Var.u.pvHCFlat + cbChunk;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Executes one command expression.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * (Hopefully the parser and functions are fully reentrant.)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns VBox status code appropriate to return from a command.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pCmdHlp Pointer to the command callback structure.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pszExpr The expression. Format string with the format DBGC extensions.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param ... Format arguments.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic DECLCALLBACK(int) dbgcHlpExec(PDBGCCMDHLP pCmdHlp, const char *pszExpr, ...)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Save the scratch state. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Format the expression.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync size_t cbScratch = sizeof(pDbgc->achScratch) - (pDbgc->pszScratch - &pDbgc->achScratch[0]);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync size_t cb = RTStrPrintfExV(dbgcStringFormatter, pDbgc, pDbgc->pszScratch, cbScratch, pszExpr, args);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Execute the command.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * We save and restore the arg index and scratch buffer pointer.
506df97a8c78dacfe69bc4d3ee5d3de832d0f19avboxsync int rc = dbgcEvalCommand(pDbgc, pszScratch, cb, false /* fNoExecute */);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* Restore the scratch state. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @copydoc DBGCCMDHLP::pfnEvalV
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic DECLCALLBACK(int) dbgcHlpEvalV(PDBGCCMDHLP pCmdHlp, PDBGCVAR pResult, const char *pszExpr, va_list va)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Format the expression.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync size_t cb = RTStrPrintfExV(dbgcStringFormatter, pDbgc, szExprFormatted, sizeof(szExprFormatted), pszExpr, va);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /* ignore overflows. */
10bea85296ddd1bd4ed6fca7f9bdf386d071ffb6vboxsync return dbgcEvalSub(pDbgc, &szExprFormatted[0], cb, DBGCVAR_CAT_ANY, pResult);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @copydoc DBGCCMDHLP::pfnFailV
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic DECLCALLBACK(int) dbgcHlpFailV(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, const char *pszFormat, va_list va)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Do the formatting and output.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTStrFormat(dbgcFormatOutput, pDbgc, dbgcStringFormatter, pDbgc, "%s: error: ", pCmd->pszCmd);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync RTStrFormatV(dbgcFormatOutput, pDbgc, dbgcStringFormatter, pDbgc, pszFormat, va);
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Converts a DBGC variable to a DBGF address structure.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns VBox status code.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pCmdHlp Pointer to the command callback structure.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pVar The variable to convert.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pAddress The target address.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic DECLCALLBACK(int) dbgcHlpVarToDbgfAddr(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PDBGFADDRESS pAddress)
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync * Converts a DBGC variable to a number.
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync * @returns VBox status code.
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync * @param pCmdHlp Pointer to the command callback structure.
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync * @param pVar The variable to convert.
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync * @param pu64Number Where to store the number value.
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsyncstatic DECLCALLBACK(int) dbgcHlpVarToNumber(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t *pu64Number)
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync return VERR_PARSE_INCORRECT_ARG_TYPE; /** @todo better error code! */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Converts a DBGC variable to a boolean.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @returns VBox status code.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pCmdHlp Pointer to the command callback structure.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pVar The variable to convert.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pf Where to store the boolean.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsyncstatic DECLCALLBACK(int) dbgcHlpVarToBool(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, bool *pf)
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync /** @todo add strcasecmp / stricmp wrappers to iprt/string.h. */
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync return VERR_PARSE_INCORRECT_ARG_TYPE; /** @todo better error code! */
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync * @interface_method_impl{DBGCCMDHLP,pfnVarGetRange}
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsyncstatic DECLCALLBACK(int) dbgcHlpVarGetRange(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t cbElement, uint64_t cbDefault,
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync/** @todo implement this properly, strings/symbols are not resolved now. */
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync * @interface_method_impl{DBGCCMDHLP,pfnVarConvert}
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsyncstatic DECLCALLBACK(int) dbgcHlpVarConvert(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pInVar, DBGCVARTYPE enmToType, bool fConvSyms,
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync DBGCVAR const InVar = *pInVar; /* if pInVar == pResult */
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync PCDBGCVAR pArg = &InVar; /* lazy bird, clean up later */
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync DBGFR3AddrFromFlat(pDbgc->pVM, &Address, pArg->u.GCFlat),
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pVM, pDbgc->idCpu,
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync DBGFR3AddrFromFlat(pDbgc->pVM, &Address, pArg->u.GCFlat),
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync false /*fReadOnly */,
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync rc = DBGFR3AddrToHostPhys(pDbgc->pVM, pDbgc->idCpu,
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync DBGFR3AddrFromFlat(pDbgc->pVM, &Address, pArg->u.GCFlat),
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync rc = DBGFR3AddrToPhys(pDbgc->pVM, pDbgc->idCpu, &Address, &pResult->u.GCPhys);
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pVM, pDbgc->idCpu, &Address,
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync rc = DBGFR3AddrToHostPhys(pDbgc->pVM, pDbgc->idCpu, &Address, &pResult->u.GCPhys);
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync //rc = MMR3PhysGCPhys2GCVirtEx(pDbgc->pVM, pResult->u.GCPhys, ..., &pResult->u.GCFlat); - yea, sure.
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pVM, pDbgc->idCpu,
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync DBGFR3AddrFromPhys(pDbgc->pVM, &Address, pArg->u.GCPhys),
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync false /*fReadOnly */,
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync rc = DBGFR3AddrToHostPhys(pDbgc->pVM, pDbgc->idCpu,
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync DBGFR3AddrFromPhys(pDbgc->pVM, &Address, pArg->u.GCPhys),
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync rc = PGMR3DbgR3Ptr2GCPhys(pDbgc->pVM, pArg->u.pvHCFlat, &pResult->u.GCPhys);
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync /** @todo more memory types! */
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync rc = PGMR3DbgR3Ptr2HCPhys(pDbgc->pVM, pArg->u.pvHCFlat, &pResult->u.HCPhys);
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync /** @todo more memory types! */
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync pResult->u.u64Number = (uintptr_t)InVar.u.pvHCFlat;
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync rc = PGMR3DbgHCPhys2GCPhys(pDbgc->pVM, pArg->u.HCPhys, &pResult->u.GCPhys);
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync pResult->u.pvHCFlat = (void *)(uintptr_t)InVar.u.u64Number;
1cc76c220eb8fe406bb98b7d95861e5dc6bda516vboxsync rc = dbgcSymbolGet(pDbgc, InVar.u.pszString, enmToType, pResult);
dec9772aebc272b06ae34a7f3da31f3e716eb1dcvboxsync AssertMsgFailed(("f=%d t=%d\n", InVar.enmType, enmToType));
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync * Info helper callback wrapper - print formatted string.
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync * @param pHlp Pointer to this structure.
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync * @param pszFormat The format string.
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync * @param ... Arguments.
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsyncstatic DECLCALLBACK(void) dbgcHlpGetDbgfOutputHlp_Printf(PCDBGFINFOHLP pHlp, const char *pszFormat, ...)
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync PDBGC pDbgc = RT_FROM_MEMBER(pHlp, DBGC, DbgfOutputHlp);
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync pDbgc->CmdHlp.pfnPrintfV(&pDbgc->CmdHlp, NULL, pszFormat, va);
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync * Info helper callback wrapper - print formatted string.
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync * @param pHlp Pointer to this structure.
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync * @param pszFormat The format string.
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync * @param args Argument list.
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsyncstatic DECLCALLBACK(void) dbgcHlpGetDbgfOutputHlp_PrintfV(PCDBGFINFOHLP pHlp, const char *pszFormat, va_list args)
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync PDBGC pDbgc = RT_FROM_MEMBER(pHlp, DBGC, DbgfOutputHlp);
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync pDbgc->CmdHlp.pfnPrintfV(&pDbgc->CmdHlp, NULL, pszFormat, args);
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync * @interface_method_impl{DBGCCMDHLP,pfnGetDbgfOutputHlp}
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsyncstatic DECLCALLBACK(PCDBGFINFOHLP) dbgcHlpGetDbgfOutputHlp(PDBGCCMDHLP pCmdHlp)
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync /* Lazy init */
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync pDbgc->DbgfOutputHlp.pfnPrintf = dbgcHlpGetDbgfOutputHlp_Printf;
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync pDbgc->DbgfOutputHlp.pfnPrintfV = dbgcHlpGetDbgfOutputHlp_PrintfV;
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * Initializes the Command Helpers for a DBGC instance.
a33af978add1a03aab11b2895f441af5cb2a11a6vboxsync * @param pDbgc Pointer to the DBGC instance.
75f41c9995e4a8d9ed39651503f229147318dbd2vboxsync pDbgc->CmdHlp.pfnVarToDbgfAddr = dbgcHlpVarToDbgfAddr;