VBoxTpG.cpp revision 81614fc60e096e714022d10d38b70a36b9b21d48
a89ad754cce3cfc8aee71760e10217b54020360dTripp * VBox Build Tool - VBox Tracepoint Generator.
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * Copyright (C) 2012 Oracle Corporation
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * This file is part of VirtualBox Open Source Edition (OSE), as
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * available from http://www.virtualbox.org. This file is free software;
828c58761d90445b8b9d20a82d85dc1479317f71Tripp * you can redistribute it and/or modify it under the terms of the GNU
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * General Public License (GPL) as published by the Free Software
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Foundation, in version 2 as it comes in the "COPYING" file of the
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp/*******************************************************************************
828c58761d90445b8b9d20a82d85dc1479317f71Tripp* Header Files *
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp*******************************************************************************/
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp/*******************************************************************************
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp* Structures and Typedefs *
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp*******************************************************************************/
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripptypedef struct VTGATTRS
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripptypedef struct VTGARG
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp const char *pszType;
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripptypedef struct VTGPROBE
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripptypedef struct VTGPROVIDER
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp const char *pszName;
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * A string table string.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripptypedef struct VTGSTRING
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp /** The string space core. */
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp /** The string table offset. */
9eaaa502227248d304ac9170902697d02158c1d9Tripp /** The actual string. */
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp/*******************************************************************************
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp* Global Variables *
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp*******************************************************************************/
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp/** The string space organizing the string table strings. Each node is a VTGSTRING. */
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp/** Used by the string table enumerator to set VTGSTRING::offStrTab. */
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp/** List of providers created by the parser. */
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp/** The number of type errors. */
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp/** @name Options
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic bool g_fApplyCpp = false;
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic const char g_szAssemblerOsDef[] = "RT_OS_DARWIN";
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic const char g_szAssemblerOsDef[] = "RT_OS_WINDOWS";
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic const char g_szAssemblerOsDef[] = "RT_OS_FREEBSD";
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic const char g_szAssemblerOsDef[] = "RT_OS_NETBSD";
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic const char g_szAssemblerOsDef[] = "RT_OS_OPENBSD";
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic const char g_szAssemblerOsDef[] = "RT_OS_LINUX";
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic const char g_szAssemblerOsDef[] = "RT_OS_SOLARIS";
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic const char *g_pszAssemblerFmtVal = RT_CONCAT(g_szAssemblerFmtVal, ARCH_BITS);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic const char *g_pszAssemblerIncVal = __FILE__ "/../../../include/";
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic unsigned g_cAssemblerOptions = 0;
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic const char *g_pszProbeFnName = "SUPR0TracerFireProbe";
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic bool g_fProbeFnImported = true;
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic bool g_fPic = false;
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Inserts a string into the string table, reusing any matching existing string
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * if possible.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @returns Read only string.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @param pch The string to insert (need not be terminated).
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @param cch The length of the string.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic const char *strtabInsertN(const char *pch, size_t cch)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp PVTGSTRING pStr = (PVTGSTRING)RTStrSpaceGetN(&g_StrSpace, pch, cch);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Create a new entry.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp pStr = (PVTGSTRING)RTMemAlloc(RT_OFFSETOF(VTGSTRING, szString[cch + 1]));
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp bool fRc = RTStrSpaceInsert(&g_StrSpace, &pStr->Core);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Retrieves the string table offset of the given string table string.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @returns String table offset.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @param pszStrTabString The string table string.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic uint32_t strtabGetOff(const char *pszStrTabString)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp PVTGSTRING pStr = RT_FROM_MEMBER(pszStrTabString, VTGSTRING, szString[0]);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Invokes the assembler.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @returns Exit code.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @param pszOutput The output file.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @param pszTempAsm The source file.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic RTEXITCODE generateInvokeAssembler(const char *pszOutput, const char *pszTempAsm)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp unsigned iArg = 0;
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp if (!strcmp(g_pszAssemblerFmtVal, "macho32") || !strcmp(g_pszAssemblerFmtVal, "macho64"))
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp else if (!strcmp(g_pszAssemblerFmtVal, "obj") || !strcmp(g_pszAssemblerFmtVal, "omf"))
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp return RTMsgErrorExit(RTEXITCODE_FAILURE, "Unknown assembler format '%s'", g_pszAssemblerFmtVal);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp for (unsigned i = 0; i < g_cAssemblerOptions; i++)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp RTMsgInfo("Starting assmbler '%s' with arguments:\n", g_pszAssembler);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp for (unsigned i = 0; i < iArg; i++)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp int rc = RTProcCreate(apszArgs[0], apszArgs, RTENV_DEFAULT, RTPROC_FLAGS_SEARCH_PATH, &hProc);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to start '%s' (assembler): %Rrc", apszArgs[0], rc);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp rc = RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &Status);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTProcWait failed: %Rrc", rc);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp return RTMsgErrorExit(RTEXITCODE_FAILURE, "The assembler failed: signal %d", Status.iStatus);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp return RTMsgErrorExit(RTEXITCODE_FAILURE, "The assembler failed: abend");
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp return RTMsgErrorExit((RTEXITCODE)Status.iStatus, "The assembler failed: exit code %d", Status.iStatus);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Worker that does the boring bits when generating a file.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @returns Exit code.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @param pszOutput The name of the output file.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @param pszWhat What kind of file it is.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @param pfnGenerator The callback function that provides the contents
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * of the file.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic RTEXITCODE generateFile(const char *pszOutput, const char *pszWhat,
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp return RTMsgErrorExit(RTEXITCODE_FAILURE, "ScmStreamInitForWriting returned %Rrc when generating the %s file",
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Stream error %Rrc generating the %s file",
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "ScmStreamWriteToFile returned %Rrc when writing '%s' (%s)",
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp RTMsgInfo("================ %s - start ================", pszWhat);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp const char *pszLine;
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp while ((pszLine = ScmStreamGetLine(&Strm, &cchLine, &enmEol)) != NULL)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp RTMsgInfo("================ %s - end ================", pszWhat);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Formats a string and writes it to the SCM stream.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @returns The number of bytes written (>= 0). Negative value are IPRT error
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * status codes.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @param pStream The stream to write to.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @param pszFormat The format string.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @param va The arguments to format.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic ssize_t ScmStreamPrintfV(PSCMSTREAM pStream, const char *pszFormat, va_list va)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Formats a string and writes it to the SCM stream.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @returns The number of bytes written (>= 0). Negative value are IPRT error
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * status codes.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @param pStream The stream to write to.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @param pszFormat The format string.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @param ... The arguments to format.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic ssize_t ScmStreamPrintf(PSCMSTREAM pStream, const char *pszFormat, ...)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp ssize_t cch = ScmStreamPrintfV(pStream, pszFormat, va);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @callback_method_impl{FNRTSTRSPACECALLBACK, Writes the string table strings.}
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTrippstatic DECLCALLBACK(int) generateAssemblyStrTabCallback(PRTSTRSPACECORE pStr, void *pvUser)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " db '%s', 0 ; off=%u len=%zu\n",
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp pVtgStr->szString, pVtgStr->offStrTab, pVtgStr->Core.cchString);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Generate assembly source that can be turned into an object file.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * (This is a generateFile callback.)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @returns Exit code.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * @param pStrm The output stream.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Write the file header.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "; $Id$ \n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp ";; @file\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "; Automatically generated from %s. Do NOT edit!\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "%%include \"iprt/asmdefs.mac\"\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "; We put all the data in a dedicated section / segment.\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "; In order to find the probe location specifiers, we do the necessary\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "; trickery here, ASSUMING that this object comes in first in the link\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "; editing process.\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "%%ifdef ASM_FORMAT_OMF\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " %%macro VTG_GLOBAL 2\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " global NAME(%%1)\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " NAME(%%1):\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " %%endmacro\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " segment VTG.Obj public CLASS=DATA align=4096 use32\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "%%elifdef ASM_FORMAT_MACHO\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " %%macro VTG_GLOBAL 2\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " global NAME(%%1)\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " NAME(%%1):\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " %%endmacro\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " [section __VTG __VTGObj align=64]\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "%%elifdef ASM_FORMAT_PE\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " %%macro VTG_GLOBAL 2\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " global NAME(%%1)\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " NAME(%%1):\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " %%endmacro\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " [section VTGPrLc.Begin data align=64]\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp /*" times 16 db 0xcc\n"*/
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "VTG_GLOBAL g_aVTGPrLc, data\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " [section VTGPrLc.Data data align=4]\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " [section VTGPrLc.End data align=4]\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "VTG_GLOBAL g_aVTGPrLc_End, data\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp /*" times 16 db 0xcc\n"*/
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " [section VTGObj data align=32]\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "%%elifdef ASM_FORMAT_ELF\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " %%macro VTG_GLOBAL 2\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " global NAME(%%1):%%2 hidden\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " NAME(%%1):\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " %%endmacro\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " [section .VTGPrLc.Begin progbits alloc noexec write align=4096]\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "VTG_GLOBAL g_aVTGPrLc, data\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " [section .VTGPrLc progbits alloc noexec write align=1]\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " [section .VTGPrLc.End progbits alloc noexec write align=1]\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "VTG_GLOBAL g_aVTGPrLc_End, data\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " [section .VTGData progbits alloc noexec write align=4096]\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " %%error \"ASM_FORMAT_XXX is not defined\"\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "%%endif\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "VTG_GLOBAL g_VTGObjHeader, data\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " ;0 1 2 3\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " ;012345678901234567890123456789012\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " db 'VTG Object Header v1.4', 0, 0\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF NAME(g_aVTGProviders)\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF NAME(g_aVTGProviders_End) - NAME(g_aVTGProviders)\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF NAME(g_aVTGProbes)\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF NAME(g_aVTGProbes_End) - NAME(g_aVTGProbes)\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF NAME(g_afVTGProbeEnabled)\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF NAME(g_afVTGProbeEnabled_End) - NAME(g_afVTGProbeEnabled)\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF NAME(g_achVTGStringTable)\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF NAME(g_achVTGStringTable_End) - NAME(g_achVTGStringTable)\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF NAME(g_aVTGArgLists)\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF NAME(g_aVTGArgLists_End) - NAME(g_aVTGArgLists)\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "%%ifdef ASM_FORMAT_MACHO ; Apple has a real decent linker!\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "extern section$start$__VTG$__VTGPrLc\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF section$start$__VTG$__VTGPrLc\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "extern section$end$__VTG$__VTGPrLc\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF section$end$__VTG$__VTGPrLc\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF NAME(g_aVTGPrLc)\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF NAME(g_aVTGPrLc_End) ; cross section/segment size not possible\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "%%endif\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF 0\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF 0\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF 0\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " RTCCPTR_DEF 0\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Declare the probe enable flags.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "; Probe enabled flags. Since these will be accessed all the time\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "; they are placed together and early in the section to get some more\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "; cache and TLB hits when the probes are disabled.\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "VTG_GLOBAL g_afVTGProbeEnabled, data\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp RTListForEach(&pProvider->ProbeHead, pProbe, VTGPROBE, ListEntry)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "VTG_GLOBAL g_fVTGProbeEnabled_%s_%s, data\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp ScmStreamPrintf(pStrm, "VTG_GLOBAL g_afVTGProbeEnabled_End, data\n");
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp return RTMsgErrorExit(RTEXITCODE_FAILURE, "Too many probes: %u (max %u)", cProbes, _32K - 1);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Dump the string table before we start using the strings.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "; The string table.\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "VTG_GLOBAL g_achVTGStringTable, data\n");
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp RTStrSpaceEnumerate(&g_StrSpace, generateAssemblyStrTabCallback, pStrm);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "VTG_GLOBAL g_achVTGStringTable_End, data\n");
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Write out the argument lists before we use them.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "; The argument lists.\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "VTG_GLOBAL g_aVTGArgLists, data\n");
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp RTListForEach(&pProvider->ProbeHead, pProbe, VTGPROBE, ListEntry)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp /* Write it. */
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " ; off=%u\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " db %2u ; Argument count\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " db %u ; fHaveLargeArgs\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " db 0, 0 ; Reserved\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " dd %8u ; type '%s' (name '%s')\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " dd 0%08xh ; type flags\n",
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp strtabGetOff(pArg->pszType), pArg->pszType, pArg->pszName,
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp /* Look for matching argument lists (lazy bird walks the whole list). */
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp RTListForEach(&g_ProviderHead, pProv2, VTGPROVIDER, ListEntry)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp RTListForEach(&pProvider->ProbeHead, pProbe2, VTGPROBE, ListEntry)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp pArg = RTListNodeGetNext(&pProbe->ArgHead, VTGARG, ListEntry);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp pArg2 = RTListNodeGetNext(&pProbe2->ArgHead, VTGARG, ListEntry);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp while ( cArgs-- > 0
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp pArg = RTListNodeGetNext(&pArg->ListEntry, VTGARG, ListEntry);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp pArg2 = RTListNodeGetNext(&pArg2->ListEntry, VTGARG, ListEntry);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "VTG_GLOBAL g_aVTGArgLists_End, data\n");
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Probe definitions.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "; Prob definitions.\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "VTG_GLOBAL g_aVTGProbes, data\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp RTListForEach(&pProvider->ProbeHead, pProbe, VTGPROBE, ListEntry)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "VTG_GLOBAL g_VTGProbeData_%s_%s, data ; idx=#%4u\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " dd %6u ; name\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " dd %6u ; Argument list offset\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " dw NAME(g_fVTGProbeEnabled_%s_%s) - NAME(g_afVTGProbeEnabled)\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " dw %6u ; provider index\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " dd NAME(g_VTGObjHeader) - NAME(g_VTGProbeData_%s_%s) ; offset to the object header\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " dd 0 ; for the application\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " dd 0 ; for the application\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp ScmStreamPrintf(pStrm, "VTG_GLOBAL g_aVTGProbes_End, data\n");
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * The providers data.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "; Provider data.\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "VTG_GLOBAL g_aVTGProviders, data\n");
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " ; idx=#%4u - %s\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " dd %6u ; name\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " dw %6u ; index of first probe\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " dw %6u ; count of probes\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " db %d, %d, %d ; AttrSelf\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " db %d, %d, %d ; AttrModules\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " db %d, %d, %d ; AttrFunctions\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " db %d, %d, %d ; AttrName\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " db %d, %d, %d ; AttrArguments\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " db 0 ; reserved\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp pProvider->AttrSelf.enmCode, pProvider->AttrSelf.enmData, pProvider->AttrSelf.enmDataDep,
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp pProvider->AttrModules.enmCode, pProvider->AttrModules.enmData, pProvider->AttrModules.enmDataDep,
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp pProvider->AttrFunctions.enmCode, pProvider->AttrFunctions.enmData, pProvider->AttrFunctions.enmDataDep,
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp pProvider->AttrName.enmCode, pProvider->AttrName.enmData, pProvider->AttrName.enmDataDep,
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp pProvider->AttrArguments.enmCode, pProvider->AttrArguments.enmData, pProvider->AttrArguments.enmDataDep);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp ScmStreamPrintf(pStrm, "VTG_GLOBAL g_aVTGProviders_End, data\n");
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Emit code for the stub functions.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp bool const fWin64 = g_cBits == 64 && (!strcmp(g_pszAssemblerFmtVal, "win64") || !strcmp(g_pszAssemblerFmtVal, "pe64"));
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp bool const fMachO64 = g_cBits == 64 && !strcmp(g_pszAssemblerFmtVal, "macho64");
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp bool const fMachO32 = g_cBits == 32 && !strcmp(g_pszAssemblerFmtVal, "macho32");
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "; Prob stubs.\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "BEGINCODE\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "extern %sNAME(%s)\n",
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "g_pfnVtgProbeFn:\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " dq NAME(%s)\n",
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp RTListForEach(&pProvider->ProbeHead, pProbe, VTGPROBE, ListEntry)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp "VTG_GLOBAL VTGProbeStub_%s_%s, function; (VBOXTPGPROBELOC pVTGProbeLoc",
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp ScmStreamPrintf(pStrm, ", %s %s", pArg->pszType, pArg->pszName);
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Check if the probe in question is enabled.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " mov eax, [esp + 4]\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " test byte [eax+3], 0x80 ; fEnabled == true?\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " jz .return ; jump on false\n");
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " test byte [rcx+3], 0x80 ; fEnabled == true?\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " jz .return ; jump on false\n");
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " test byte [rdi+3], 0x80 ; fEnabled == true?\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " jz .return ; jump on false\n");
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp * Jump to the fire-probe function.
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " call .mov_ecx_eip_plus_5\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp ".got_eip:\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " add ecx, _GLOBAL_OFFSET_TABLE + ($$ - .got_eip) wrt ..gotpc\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " mov ecx, [%s@GOT + ecx]\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " jmp ecx\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp ".mov_ecx_eip_plus_5:\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " pop ecx\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " jmp ecx\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " mov ecx, IMP2(%s)\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " jmp ecx\n"
09688ec5ffb8b9cf9883a770e2f9ebd60b28888dTripp " jmp NAME(%s)\n"
else if (fWin64)
, g_pszProbeFnName);
, g_pszProbeFnName);
return RTEXITCODE_SUCCESS;
if (!pszTempAsm)
return rcExit;
static RTEXITCODE generateProbeDefineName(char *pszBuf, size_t cbBuf, const char *pszProvider, const char *pszProbe)
return RTMsgErrorExit(RTEXITCODE_FAILURE, "Probe '%s' in provider '%s' ends up with a too long defined\n", pszProbe, pszProvider);
while (*pszProvider)
while (*pszProbe)
pszProbe++;
return RTEXITCODE_SUCCESS;
while (*psz)
psz++;
szTmp);
, szTmp,
szTmp);
iArg++;
return RTEXITCODE_SUCCESS;
size_t const cchLeft = pStream->paLines[iLine].cch + pStream->paLines[iLine].off - (pStream->off - 1);
return NULL;
char ch;
off++;
return psz;
size_t const cchLeft = pStream->paLines[iLine].cch + pStream->paLines[iLine].off - (pStream->off - 1);
return NULL;
char ch;
off++;
return psz;
if (cb)
if (pszLine)
return RTEXITCODE_FAILURE;
return RTEXITCODE_SUCCESS;
unsigned ch;
return RTEXITCODE_SUCCESS;
return RTEXITCODE_FAILURE;
unsigned ch;
return RTEXITCODE_SUCCESS;
return rcExit;
unsigned ch;
return ch;
unsigned ch;
return ch;
return NULL;
switch (ch)
return kVTGStability_External;
return kVTGStability_Evolving;
return kVTGStability_Internal;
return kVTGStability_Obsolete;
return kVTGStability_Private;
return kVTGStability_Stable;
return kVTGStability_Standard;
return kVTGStability_Unstable;
return kVTGStability_Invalid;
switch (ch)
return kVTGClass_Common;
return kVTGClass_Cpu;
return kVTGClass_Group;
return kVTGClass_Isa;
return kVTGClass_Platform;
return kVTGClass_Unknown;
return kVTGClass_Invalid;
* "CodeStability/DataStability/DataDepClass" - no spaces allowed.
if (ch == ~(unsigned)0)
return RTEXITCODE_FAILURE;
return RTEXITCODE_FAILURE;
return RTEXITCODE_FAILURE;
return RTEXITCODE_FAILURE;
if (ch == ~(unsigned)0)
return RTEXITCODE_FAILURE;
if (!pszName)
if (!pszAspect)
return RTEXITCODE_SUCCESS;
if (ch == ~(unsigned)0)
if (ch == ~(unsigned)0)
return rcExit;
return VTG_TYPE_POINTER;
//if (MY_STRMATCH("uint128_t")) return VTG_TYPE_FIXED_SIZED | sizeof(uint128_t) | VTG_TYPE_UNSIGNED;
if (MY_STRMATCH("RTMSINTERVAL")) return VTG_TYPE_FIXED_SIZED | sizeof(RTMSINTERVAL) | VTG_TYPE_UNSIGNED;
if (MY_STRMATCH("RTHCPHYS")) return VTG_TYPE_FIXED_SIZED | sizeof(RTHCPHYS) | VTG_TYPE_UNSIGNED | VTG_TYPE_PHYS;
if (MY_STRMATCH("RTHCUINTPTR")) return VTG_TYPE_CTX_POINTER | VTG_TYPE_CTX_R3 | VTG_TYPE_CTX_R0 | VTG_TYPE_UNSIGNED;
if (MY_STRMATCH("RTHCINTPTR")) return VTG_TYPE_CTX_POINTER | VTG_TYPE_CTX_R3 | VTG_TYPE_CTX_R0 | VTG_TYPE_SIGNED;
if (MY_STRMATCH("RTUINTPTR")) return VTG_TYPE_CTX_POINTER | VTG_TYPE_CTX_R3 | VTG_TYPE_CTX_R0 | VTG_TYPE_CTX_RC | VTG_TYPE_UNSIGNED;
if (MY_STRMATCH("RTINTPTR")) return VTG_TYPE_CTX_POINTER | VTG_TYPE_CTX_R3 | VTG_TYPE_CTX_R0 | VTG_TYPE_CTX_RC | VTG_TYPE_SIGNED;
if (MY_STRMATCH("RTHCUINTREG")) return VTG_TYPE_HC_ARCH_SIZED | VTG_TYPE_CTX_R3 | VTG_TYPE_CTX_R0 | VTG_TYPE_UNSIGNED;
if (MY_STRMATCH("RTR3UINTREG")) return VTG_TYPE_HC_ARCH_SIZED | VTG_TYPE_CTX_R3 | VTG_TYPE_UNSIGNED;
if (MY_STRMATCH("RTR0UINTREG")) return VTG_TYPE_HC_ARCH_SIZED | VTG_TYPE_CTX_R3 | VTG_TYPE_UNSIGNED;
if (MY_STRMATCH("RTGCUINTREG")) return VTG_TYPE_FIXED_SIZED | sizeof(RTGCUINTREG) | VTG_TYPE_UNSIGNED | VTG_TYPE_CTX_GST;
if (MY_STRMATCH("RTGCPTR")) return VTG_TYPE_FIXED_SIZED | sizeof(RTGCPTR) | VTG_TYPE_UNSIGNED | VTG_TYPE_CTX_GST;
if (MY_STRMATCH("RTGCINTPTR")) return VTG_TYPE_FIXED_SIZED | sizeof(RTGCUINTPTR) | VTG_TYPE_SIGNED | VTG_TYPE_CTX_GST;
if (MY_STRMATCH("RTGCPTR32")) return VTG_TYPE_FIXED_SIZED | sizeof(RTGCPTR32) | VTG_TYPE_SIGNED | VTG_TYPE_CTX_GST;
if (MY_STRMATCH("RTGCPTR64")) return VTG_TYPE_FIXED_SIZED | sizeof(RTGCPTR64) | VTG_TYPE_SIGNED | VTG_TYPE_CTX_GST;
if (MY_STRMATCH("RTGCPHYS")) return VTG_TYPE_FIXED_SIZED | sizeof(RTGCPHYS) | VTG_TYPE_UNSIGNED | VTG_TYPE_PHYS | VTG_TYPE_CTX_GST;
if (MY_STRMATCH("RTGCPHYS32")) return VTG_TYPE_FIXED_SIZED | sizeof(RTGCPHYS32) | VTG_TYPE_UNSIGNED | VTG_TYPE_PHYS | VTG_TYPE_CTX_GST;
if (MY_STRMATCH("RTGCPHYS64")) return VTG_TYPE_FIXED_SIZED | sizeof(RTGCPHYS64) | VTG_TYPE_UNSIGNED | VTG_TYPE_PHYS | VTG_TYPE_CTX_GST;
pszType);
return VTG_TYPE_POINTER;
while (*pszSrc)
if (!pszProbe)
if (!pProbe)
switch (ch)
if (pArg)
if (!cchName)
return RTEXITCODE_SUCCESS;
if (!pszWord)
if (!pArg)
if (!pArg)
cchName = 0;
if (!pArg)
cchName = 0;
if (!pszName)
if (!pProv)
switch (ch)
return RTEXITCODE_SUCCESS;
return rcExit;
return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to open & read '%s' into memory: %Rrc", pszScript, rc);
if (g_cVerbosity > 0)
unsigned ch;
switch (ch)
if (ch == ~(unsigned)0)
return rcExit;
return rcExit;
rc = RTGetOptInit(&GetOptState, argc, argv, &s_aOpts[0], RT_ELEMENTS(s_aOpts), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
switch (rc)
case kVBoxTpGOpt_32Bit:
case kVBoxTpGOpt_64Bit:
g_fApplyCpp = true;
return RTEXITCODE_SUCCESS;
if (g_pszOutput)
if (g_pszScript)
g_cVerbosity++;
return RTEXITCODE_SUCCESS;
case VINF_GETOPT_NOT_OPTION:
case kVBoxTpGOpt_Assembler:
return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Too many assembly options (max %u)", RT_ELEMENTS(g_apszAssemblerOptions));
case kVBoxTpGOpt_Pic:
g_fPic = true;
case kVBoxTpGOpt_ProbeFnName:
g_fProbeFnImported = true;
g_fProbeFnImported = false;
if (!g_pszScript)
if (!g_pszOutput)
return RTEXITCODE_SUCCESS;
return rcExit;