VBoxTpG.cpp revision 9b1d52365befbce1af8f32d53c2e563ee9169501
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync * VBox Build Tool - VBox Tracepoint Generator.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Copyright (C) 2012 Oracle Corporation
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * available from http://www.virtualbox.org. This file is free software;
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * you can redistribute it and/or modify it under the terms of the GNU
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * General Public License (GPL) as published by the Free Software
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync/*******************************************************************************
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync* Header Files *
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync*******************************************************************************/
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync/*******************************************************************************
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync* Structures and Typedefs *
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync*******************************************************************************/
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsynctypedef struct VTGATTRS
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsynctypedef struct VTGARG
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync const char *pszName;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync const char *pszType;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsynctypedef struct VTGPROBE
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsynctypedef struct VTGPROVIDER
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync const char *pszName;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * A string table string.
0c94a8282c9042b02f022302a3d987746140eab9vboxsynctypedef struct VTGSTRING
0c94a8282c9042b02f022302a3d987746140eab9vboxsync /** The string space core. */
0c94a8282c9042b02f022302a3d987746140eab9vboxsync /** The string table offset. */
0c94a8282c9042b02f022302a3d987746140eab9vboxsync /** The actual string. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync/*******************************************************************************
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync* Global Variables *
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync*******************************************************************************/
0c94a8282c9042b02f022302a3d987746140eab9vboxsync/** The string space organizing the string table strings. Each node is a VTGSTRING. */
0c94a8282c9042b02f022302a3d987746140eab9vboxsync/** Used by the string table enumerator to set VTGSTRING::offStrTab. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync/** List of providers created by the parser. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync/** @name Options
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic bool g_fApplyCpp = false;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char g_szAssemblerFmtVal32[] = "macho32";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char g_szAssemblerFmtVal64[] = "macho64";
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsyncstatic const char g_szAssemblerOsDef[] = "RT_OS_DARWIN";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char g_szAssemblerFmtVal64[] = "elf64";
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsyncstatic const char g_szAssemblerOsDef[] = "RT_OS_OS2";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char g_szAssemblerFmtVal32[] = "win32";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char g_szAssemblerFmtVal64[] = "win64";
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsyncstatic const char g_szAssemblerOsDef[] = "RT_OS_WINDOWS";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char g_szAssemblerFmtVal32[] = "elf32";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char g_szAssemblerFmtVal64[] = "elf64";
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsyncstatic const char g_szAssemblerOsDef[] = "RT_OS_FREEBSD";
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsyncstatic const char g_szAssemblerOsDef[] = "RT_OS_NETBSD";
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsyncstatic const char g_szAssemblerOsDef[] = "RT_OS_OPENBSD";
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsyncstatic const char g_szAssemblerOsDef[] = "RT_OS_LINUX";
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsyncstatic const char g_szAssemblerOsDef[] = "RT_OS_SOLARIS";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char *g_pszAssemblerFmtVal = RT_CONCAT(g_szAssemblerFmtVal, ARCH_BITS);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsyncstatic const char *g_pszAssemblerIncVal = __FILE__ "/../../../include/";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic unsigned g_cAssemblerOptions = 0;
1969e98a26e5b56b67fbe3b6bfa007f8f09e86ebvboxsyncstatic const char *g_pszProbeFnName = "SUPR0TracerFireProbe";
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsyncstatic bool g_fProbeFnImported = true;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * Inserts a string into the string table, reusing any matching existing string
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * if possible.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * @returns Read only string.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * @param pch The string to insert (need not be terminated).
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * @param cch The length of the string.
0c94a8282c9042b02f022302a3d987746140eab9vboxsyncstatic const char *strtabInsertN(const char *pch, size_t cch)
0c94a8282c9042b02f022302a3d987746140eab9vboxsync PVTGSTRING pStr = (PVTGSTRING)RTStrSpaceGetN(&g_StrSpace, pch, cch);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * Create a new entry.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync pStr = (PVTGSTRING)RTMemAlloc(RT_OFFSETOF(VTGSTRING, szString[cch + 1]));
0c94a8282c9042b02f022302a3d987746140eab9vboxsync bool fRc = RTStrSpaceInsert(&g_StrSpace, &pStr->Core);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Retrieves the string table offset of the given string table string.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @returns String table offset.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @param pszStrTabString The string table string.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsyncstatic uint32_t strtabGetOff(const char *pszStrTabString)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync PVTGSTRING pStr = RT_FROM_MEMBER(pszStrTabString, VTGSTRING, szString[0]);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Invokes the assembler.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @returns Exit code.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param pszOutput The output file.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param pszTempAsm The source file.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE generateInvokeAssembler(const char *pszOutput, const char *pszTempAsm)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync unsigned iArg = 0;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (!strcmp(g_pszAssemblerFmtVal, "macho32") || !strcmp(g_pszAssemblerFmtVal, "macho64"))
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync else if (!strcmp(g_pszAssemblerFmtVal, "obj") || !strcmp(g_pszAssemblerFmtVal, "omf"))
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Unknown assembler format '%s'", g_pszAssemblerFmtVal);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync for (unsigned i = 0; i < g_cAssemblerOptions; i++)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync RTMsgInfo("Starting assmbler '%s' with arguments:\n", g_pszAssembler);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync for (unsigned i = 0; i < iArg; i++)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync int rc = RTProcCreate(apszArgs[0], apszArgs, RTENV_DEFAULT, RTPROC_FLAGS_SEARCH_PATH, &hProc);
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to start '%s' (assembler): %Rrc", apszArgs[0], rc);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync rc = RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &Status);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTProcWait failed: %Rrc", rc);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "The assembler failed: signal %d", Status.iStatus);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "The assembler failed: abend");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync return RTMsgErrorExit((RTEXITCODE)Status.iStatus, "The assembler failed: exit code %d", Status.iStatus);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Worker that does the boring bits when generating a file.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @returns Exit code.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param pszOutput The name of the output file.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param pszWhat What kind of file it is.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param pfnGenerator The callback function that provides the contents
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * of the file.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE generateFile(const char *pszOutput, const char *pszWhat,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "ScmStreamInitForWriting returned %Rrc when generating the %s file",
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Stream error %Rrc generating the %s file",
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "ScmStreamWriteToFile returned %Rrc when writing '%s' (%s)",
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTMsgInfo("Successfully generated '%s'.", pszOutput);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTMsgInfo("================ %s - start ================", pszWhat);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync const char *pszLine;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync while ((pszLine = ScmStreamGetLine(&Strm, &cchLine, &enmEol)) != NULL)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTMsgInfo("================ %s - end ================", pszWhat);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Formats a string and writes it to the SCM stream.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @returns The number of bytes written (>= 0). Negative value are IPRT error
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * status codes.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param pStream The stream to write to.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param pszFormat The format string.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param va The arguments to format.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsyncstatic ssize_t ScmStreamPrintfV(PSCMSTREAM pStream, const char *pszFormat, va_list va)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Formats a string and writes it to the SCM stream.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @returns The number of bytes written (>= 0). Negative value are IPRT error
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * status codes.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param pStream The stream to write to.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param pszFormat The format string.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param ... The arguments to format.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsyncstatic ssize_t ScmStreamPrintf(PSCMSTREAM pStream, const char *pszFormat, ...)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ssize_t cch = ScmStreamPrintfV(pStream, pszFormat, va);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * @callback_method_impl{FNRTSTRSPACECALLBACK, Writes the string table strings.}
0c94a8282c9042b02f022302a3d987746140eab9vboxsyncstatic DECLCALLBACK(int) generateAssemblyStrTabCallback(PRTSTRSPACECORE pStr, void *pvUser)
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync g_offStrTab += (uint32_t)pVtgStr->Core.cchString + 1;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync " db '%s', 0 ; off=%u len=%zu\n",
0c94a8282c9042b02f022302a3d987746140eab9vboxsync pVtgStr->szString, pVtgStr->offStrTab, pVtgStr->Core.cchString);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Generate assembly source that can be turned into an object file.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * (This is a generateFile callback.)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @returns Exit code.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param pStrm The output stream.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE generateAssembly(PSCMSTREAM pStrm)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * Write the file header.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "; $Id$ \n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ";; @file\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "; Automatically generated from %s. Do NOT edit!\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "%%include \"iprt/asmdefs.mac\"\n"
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync "; We put all the data in a dedicated section / segment.\n"
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync "; In order to find the probe location specifiers, we do the necessary\n"
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync "; trickery here, ASSUMING that this object comes in first in the link\n"
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync "; editing process.\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "%%ifdef ASM_FORMAT_OMF\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " %%macro VTG_GLOBAL 2\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " global NAME(%%1)\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " NAME(%%1):\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " %%endmacro\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " segment VTG.Obj public CLASS=DATA align=4096 use32\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "%%elifdef ASM_FORMAT_MACHO\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " %%macro VTG_GLOBAL 2\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " global NAME(%%1)\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " NAME(%%1):\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " %%endmacro\n"
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync " [section __VTG __VTGObj align=64]\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "%%elifdef ASM_FORMAT_PE\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " %%macro VTG_GLOBAL 2\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " global NAME(%%1)\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " NAME(%%1):\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " %%endmacro\n"
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync " [section VTGPrLc.Begin data align=64]\n"
1379dfd407ada5fab15655776896f13b61a951fdvboxsync /*" times 16 db 0xcc\n"*/
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync "VTG_GLOBAL g_aVTGPrLc, data\n"
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync " [section VTGPrLc.Data data align=4]\n"
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync " [section VTGPrLc.End data align=4]\n"
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync "VTG_GLOBAL g_aVTGPrLc_End, data\n"
1379dfd407ada5fab15655776896f13b61a951fdvboxsync /*" times 16 db 0xcc\n"*/
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync " [section VTGObj data align=32]\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "%%elifdef ASM_FORMAT_ELF\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " %%macro VTG_GLOBAL 2\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " global NAME(%%1):%%2 hidden\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " NAME(%%1):\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " %%endmacro\n"
1379dfd407ada5fab15655776896f13b61a951fdvboxsync " [section .VTGPrLc.Begin progbits alloc noexec write align=4096]\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_aVTGPrLc, data\n"
1379dfd407ada5fab15655776896f13b61a951fdvboxsync " [section .VTGPrLc progbits alloc noexec write align=1]\n"
1379dfd407ada5fab15655776896f13b61a951fdvboxsync " [section .VTGPrLc.End progbits alloc noexec write align=1]\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_aVTGPrLc_End, data\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " [section .VTGData progbits alloc noexec write align=4096]\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " %%error \"ASM_FORMAT_XXX is not defined\"\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "%%endif\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_VTGObjHeader, data\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " ;0 1 2 3\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " ;012345678901234567890123456789012\n"
1379dfd407ada5fab15655776896f13b61a951fdvboxsync " db 'VTG Object Header v1.2', 0, 0\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " RTCCPTR_DEF NAME(g_aVTGProviders)\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " RTCCPTR_DEF NAME(g_aVTGProviders_End) - NAME(g_aVTGProviders)\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " RTCCPTR_DEF NAME(g_aVTGProbes)\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " RTCCPTR_DEF NAME(g_aVTGProbes_End) - NAME(g_aVTGProbes)\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " RTCCPTR_DEF NAME(g_afVTGProbeEnabled)\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " RTCCPTR_DEF NAME(g_afVTGProbeEnabled_End) - NAME(g_afVTGProbeEnabled)\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " RTCCPTR_DEF NAME(g_achVTGStringTable)\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " RTCCPTR_DEF NAME(g_achVTGStringTable_End) - NAME(g_achVTGStringTable)\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " RTCCPTR_DEF NAME(g_aVTGArgLists)\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " RTCCPTR_DEF NAME(g_aVTGArgLists_End) - NAME(g_aVTGArgLists)\n"
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync "%%ifdef ASM_FORMAT_MACHO ; Apple has a real decent linker!\n"
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync "extern section$start$__VTG$__VTGPrLc\n"
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync " RTCCPTR_DEF section$start$__VTG$__VTGPrLc\n"
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync "extern section$end$__VTG$__VTGPrLc\n"
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync " RTCCPTR_DEF section$end$__VTG$__VTGPrLc\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " RTCCPTR_DEF NAME(g_aVTGPrLc)\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " RTCCPTR_DEF NAME(g_aVTGPrLc_End) ; cross section/segment size not possible\n"
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync "%%endif\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " RTCCPTR_DEF 0\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " RTCCPTR_DEF 0\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " RTCCPTR_DEF 0\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " RTCCPTR_DEF 0\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Declare the probe enable flags.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "; Probe enabled flags. Since these will be accessed all the time\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "; they are placed together and early in the section to get some more\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "; cache and TLB hits when the probes are disabled.\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_afVTGProbeEnabled, data\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&pProvider->ProbeHead, pProbe, VTGPROBE, ListEntry)
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_fVTGProbeEnabled_%s_%s, data\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync ScmStreamPrintf(pStrm, "VTG_GLOBAL g_afVTGProbeEnabled_End, data\n");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Too many probes: %u (max %u)", cProbes, _32K - 1);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Dump the string table before we start using the strings.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync "; The string table.\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_achVTGStringTable, data\n");
0c94a8282c9042b02f022302a3d987746140eab9vboxsync RTStrSpaceEnumerate(&g_StrSpace, generateAssemblyStrTabCallback, pStrm);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_achVTGStringTable_End, data\n");
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Write out the argument lists before we use them.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "; The argument lists.\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_aVTGArgLists, data\n");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&pProvider->ProbeHead, pProbe, VTGPROBE, ListEntry)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /* Write it. */
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " ; off=%u\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " db %2u ; Argument count\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " db 0, 0, 0 ; Reserved\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " dd %6u ; type '%s'\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " dd %6u ; name '%s'\n",
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /* Look for matching argument lists (lazy bird walks the whole list). */
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync RTListForEach(&g_ProviderHead, pProv2, VTGPROVIDER, ListEntry)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&pProvider->ProbeHead, pProbe2, VTGPROBE, ListEntry)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync pArg = RTListNodeGetNext(&pProbe->ArgHead, VTGARG, ListEntry);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync pArg2 = RTListNodeGetNext(&pProbe2->ArgHead, VTGARG, ListEntry);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync while ( cArgs-- > 0
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync pArg = RTListNodeGetNext(&pArg->ListEntry, VTGARG, ListEntry);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync pArg2 = RTListNodeGetNext(&pArg2->ListEntry, VTGARG, ListEntry);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_aVTGArgLists_End, data\n");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Probe definitions.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "; Prob definitions.\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_aVTGProbes, data\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&pProvider->ProbeHead, pProbe, VTGPROBE, ListEntry)
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_VTGProbeData_%s_%s, data ; idx=#%4u\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " dd %6u ; name\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " dd %6u ; Argument list offset\n"
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync " dw NAME(g_fVTGProbeEnabled_%s_%s) - NAME(g_afVTGProbeEnabled)\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " dw %6u ; provider index\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " dd 0 ; for the application\n"
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync pProvider->pszName, pProbe->pszMangledName, iProbe,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pProvider->cProbes = iProbe - pProvider->iFirstProbe;
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync ScmStreamPrintf(pStrm, "VTG_GLOBAL g_aVTGProbes_End, data\n");
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * The providers data.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "; Provider data.\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_aVTGProviders, data\n");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " ; idx=#%4u - %s\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " dd %6u ; name\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " dw %6u ; index of first probe\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " dw %6u ; count of probes\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " db %d, %d, %d ; AttrSelf\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " db %d, %d, %d ; AttrModules\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " db %d, %d, %d ; AttrFunctions\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " db %d, %d, %d ; AttrName\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " db %d, %d, %d ; AttrArguments\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " db 0 ; reserved\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pProvider->AttrSelf.enmCode, pProvider->AttrSelf.enmData, pProvider->AttrSelf.enmDataDep,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pProvider->AttrModules.enmCode, pProvider->AttrModules.enmData, pProvider->AttrModules.enmDataDep,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pProvider->AttrFunctions.enmCode, pProvider->AttrFunctions.enmData, pProvider->AttrFunctions.enmDataDep,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pProvider->AttrName.enmCode, pProvider->AttrName.enmData, pProvider->AttrName.enmDataDep,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pProvider->AttrArguments.enmCode, pProvider->AttrArguments.enmData, pProvider->AttrArguments.enmDataDep);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync ScmStreamPrintf(pStrm, "VTG_GLOBAL g_aVTGProviders_End, data\n");
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Emit code for the stub functions.
9b1d52365befbce1af8f32d53c2e563ee9169501vboxsync bool const fWin64 = g_cBits == 64 && (!strcmp(g_pszAssemblerFmtVal, "win64") || !strcmp(g_pszAssemblerFmtVal, "pe64"));
9b1d52365befbce1af8f32d53c2e563ee9169501vboxsync bool const fMachO64 = g_cBits == 64 && !strcmp(g_pszAssemblerFmtVal, "macho64");
9b1d52365befbce1af8f32d53c2e563ee9169501vboxsync bool const fMachO32 = g_cBits == 32 && !strcmp(g_pszAssemblerFmtVal, "macho32");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync "; Prob stubs.\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync "BEGINCODE\n"
9c9db71d639cf066ed41d49629d46d48bff4be2fvboxsync "extern %sNAME(%s)\n",
9b1d52365befbce1af8f32d53c2e563ee9169501vboxsync "g_pfnVtgProbeFn:\n"
9b1d52365befbce1af8f32d53c2e563ee9169501vboxsync " dq NAME(%s)\n",
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&pProvider->ProbeHead, pProbe, VTGPROBE, ListEntry)
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL VTGProbeStub_%s_%s, function; (VBOXTPGPROBELOC pVTGProbeLoc",
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync ScmStreamPrintf(pStrm, ", %s %s", pArg->pszType, pArg->pszName);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Check if the probe in question is enabled.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " mov eax, [esp + 4]\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " test byte [eax+3], 0x80 ; fEnabled == true?\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " jz .return ; jump on false\n");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " test byte [rcx+3], 0x80 ; fEnabled == true?\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " jz .return ; jump on false\n");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " test byte [rdi+3], 0x80 ; fEnabled == true?\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " jz .return ; jump on false\n");
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync * Jump to the fire-probe function.
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " mov ecx, IMP2(%s)\n"
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " jmp ecx\n"
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " jmp NAME(%s)\n"
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " mov rax, IMP2(%s)\n"
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " jmp rax\n"
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " jmp NAME(%s)\n"
9b1d52365befbce1af8f32d53c2e563ee9169501vboxsync " jmp [g_pfnVtgProbeFn wrt rip]\n");
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " jmp rax\n"
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " jmp NAME(%s)\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync ".return:\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " ret ; The probe was disabled, return\n"
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE generateObject(const char *pszOutput, const char *pszTempAsm)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTEXITCODE rcExit = generateFile(pszTempAsm, "assembly", generateAssembly);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = generateInvokeAssembler(pszOutput, pszTempAsm);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsyncstatic RTEXITCODE generateProbeDefineName(char *pszBuf, size_t cbBuf, const char *pszProvider, const char *pszProbe)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync size_t cbMax = strlen(pszProvider) + 1 + strlen(pszProbe) + 1;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Probe '%s' in provider '%s' ends up with a too long defined\n", pszProbe, pszProvider);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE generateHeaderInner(PSCMSTREAM pStrm)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * Calc the double inclusion blocker define and then write the file header.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "File name is too long '%s'", pszName);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "/* $Id$ */\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "/** @file\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync " * Automatically generated from %s. Do NOT edit!\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "#ifndef %s\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "#define %s\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "#include <VBox/VBoxTpG.h>\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "RT_C_DECLS_BEGIN\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "#ifdef VBOX_WITH_DTRACE\n"
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync "# ifdef _MSC_VER\n"
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync "# pragma data_seg(VTG_LOC_SECT)\n"
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync "# pragma data_seg()\n"
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync "# endif\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * Declare data, code and macros for each probe.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync RTListForEach(&g_ProviderHead, pProv, VTGPROVIDER, ListEntry)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync RTListForEach(&pProv->ProbeHead, pProbe, VTGPROBE, ListEntry)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "extern bool g_fVTGProbeEnabled_%s_%s;\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "extern uint8_t g_VTGProbeData_%s_%s;\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "DECLASM(void) VTGProbeStub_%s_%s(PVTGPROBELOC",
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync generateProbeDefineName(szTmp, sizeof(szTmp), pProv->pszName, pProbe->pszMangledName);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "# define %s_ENABLED() \\\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync " (RT_UNLIKELY(g_fVTGProbeEnabled_%s_%s)) \n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "# define %s("
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (RTListNodeIsFirst(&pProbe->ArgHead, &pArg->ListEntry))
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync " do { \\\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " if (RT_UNLIKELY(g_fVTGProbeEnabled_%s_%s)) \\\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " VTG_DECL_VTGPROBELOC(s_VTGProbeLoc) = \\\n"
2cf9be9fb8dd19b4e5695e3f70c864390c500eb0vboxsync " { __LINE__, 0, UINT32_MAX, __FUNCTION__, &g_VTGProbeData_%s_%s }; \\\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " VTGProbeStub_%s_%s(&s_VTGProbeLoc",
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync " { \\\n" );
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync " AssertCompile(sizeof(%s) <= sizeof(uintptr_t)); \\\n"
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync " AssertCompile(sizeof(%s) <= sizeof(uintptr_t)); \\\n",
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync " } while (0)\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync RTListForEach(&g_ProviderHead, pProv, VTGPROVIDER, ListEntry)
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync RTListForEach(&pProv->ProbeHead, pProbe, VTGPROBE, ListEntry)
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync generateProbeDefineName(szTmp, sizeof(szTmp), pProv->pszName, pProbe->pszMangledName);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "# define %s_ENABLED() (false)\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "# define %s("
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync if (RTListNodeIsFirst(&pProbe->ArgHead, &pArg->ListEntry))
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync ") do { } while (0)\n");
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "RT_C_DECLS_END\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "#endif\n"));
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE generateHeader(const char *pszHeader)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return generateFile(pszHeader, "header", generateHeaderInner);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * If the given C word is at off - 1, return @c true and skip beyond it,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * otherwise return @c false.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @retval true if the given C-word is at the current position minus one char.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * The stream position changes.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @retval false if not. The stream position is unchanged.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param pStream The stream.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param cchWord The length of the word.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param pszWord The word.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsyncbool ScmStreamCMatchingWordM1(PSCMSTREAM pStream, const char *pszWord, size_t cchWord)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Check stream state. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Sufficient chars left on the line? */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync AssertReturn(pStream->off > pStream->paLines[iLine].off, false);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync size_t const cchLeft = pStream->paLines[iLine].cch + pStream->paLines[iLine].off - (pStream->off - 1);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return false;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Do they match? */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return false;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Is it the end of a C word? */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return false;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Skip ahead. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return true;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Get's the C word starting at the current position.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @returns Pointer to the word on success and the stream position advanced to
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * the end of it.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * NULL on failure, stream position normally unchanged.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param pStream The stream to get the C word from.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param pcchWord Where to return the word length.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncconst char *ScmStreamCGetWord(PSCMSTREAM pStream, size_t *pcchWord)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Check stream state. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Get the number of chars left on the line and locate the current char. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync size_t const cchLeft = pStream->paLines[iLine].cch + pStream->paLines[iLine].off - pStream->off;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Is it a leading C character. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Find the end of the word. */
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * Get's the C word starting at the current position minus one.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * @returns Pointer to the word on success and the stream position advanced to
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * the end of it.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * NULL on failure, stream position normally unchanged.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * @param pStream The stream to get the C word from.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * @param pcchWord Where to return the word length.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsyncconst char *ScmStreamCGetWordM1(PSCMSTREAM pStream, size_t *pcchWord)
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync /* Check stream state. */
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync /* Get the number of chars left on the line and locate the current char. */
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync size_t const cchLeft = pStream->paLines[iLine].cch + pStream->paLines[iLine].off - (pStream->off - 1);
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync /* Is it a leading C character. */
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync /* Find the end of the word. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Parser error with line and position.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @returns RTEXITCODE_FAILURE.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param pStrm The stream.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param cb The offset from the current position to the
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * point of failure.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param pszMsg The message to display.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE parseError(PSCMSTREAM pStrm, size_t cb, const char *pszMsg)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync RTPrintf("%s:%d:%zd: error: %s.\n", g_pszScript, iLine + 1, off - offLine + 1, pszMsg);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync const char *pszLine = ScmStreamGetLineByNo(pStrm, iLine, &cchLine, &enmEof);
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync * Parser error with line and position.
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync * @returns RTEXITCODE_FAILURE.
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync * @param pStrm The stream.
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync * @param cb The offset from the current position to the
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync * point of failure.
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync * @param pszMsg The message to display.
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsyncstatic RTEXITCODE parseErrorAbs(PSCMSTREAM pStrm, size_t off, const char *pszMsg)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Handles a C++ one line comment.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @returns Exit code.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param pStrm The stream.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE parseOneLineComment(PSCMSTREAM pStrm)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync ScmStreamSeekByLine(pStrm, ScmStreamTellLine(pStrm) + 1);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Handles a multi-line C/C++ comment.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @returns Exit code.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param pStrm The stream.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE parseMultiLineComment(PSCMSTREAM pStrm)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync while ((ch = ScmStreamGetCh(pStrm)) != ~(unsigned)0)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync parseError(pStrm, 1, "Expected end of comment, got end of file");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Skips spaces and comments.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param pStrm The stream..
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE parseSkipSpacesAndComments(PSCMSTREAM pStrm)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync while ((ch = ScmStreamPeekCh(pStrm)) != ~(unsigned)0)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync unsigned ch2 = ScmStreamGetCh(pStrm); AssertBreak(ch == ch2); NOREF(ch2);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = parseError(pStrm, 2, "Unexpected character");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return parseError(pStrm, 0, "Unexpected end of file");
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync * Skips spaces and comments, returning the next character.
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync * @returns Next non-space-non-comment character. ~(unsigned)0 on EOF or
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync * @param pStrm The stream.
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsyncstatic unsigned parseGetNextNonSpaceNonCommentCh(PSCMSTREAM pStrm)
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync while ((ch = ScmStreamGetCh(pStrm)) != ~(unsigned)0)
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync rcExit = parseError(pStrm, 2, "Unexpected character");
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync return ~(unsigned)0;
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync return ~(unsigned)0;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Get the next non-space-non-comment character on a preprocessor line.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @returns The next character. On error message and ~(unsigned)0.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @param pStrm The stream.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsyncstatic unsigned parseGetNextNonSpaceNonCommentChOnPpLine(PSCMSTREAM pStrm)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync while ((ch = ScmStreamGetCh(pStrm)) != ~(unsigned)0)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync parseErrorAbs(pStrm, off, "Invalid preprocessor statement");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return ~(unsigned)0;
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * Skips spaces and comments.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * @returns Same as ScmStreamCGetWord
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * @param pStrm The stream..
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * @param pcchWord Where to return the length.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsyncstatic const char *parseGetNextCWord(PSCMSTREAM pStrm, size_t *pcchWord)
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync if (parseSkipSpacesAndComments(pStrm) != RTEXITCODE_SUCCESS)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Parses interface stability.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @returns Interface stability if parsed correctly, otherwise error message and
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * kVTGStability_Invalid.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @param pStrm The stream.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @param ch The first character in the stability spec.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsyncstatic kVTGStability parseStability(PSCMSTREAM pStrm, unsigned ch)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("External")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Evolving")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Internal")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Obsolete")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Private")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Stable")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Standard")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Unstable")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync parseError(pStrm, 1, "Unknown stability specifier");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Parses data depndency class.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @returns Data dependency class if parsed correctly, otherwise error message
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * and kVTGClass_Invalid.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @param pStrm The stream.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @param ch The first character in the stability spec.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsyncstatic kVTGClass parseDataDepClass(PSCMSTREAM pStrm, unsigned ch)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Common")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Cpu")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Group")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Isa")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Platform")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Unknown")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync parseError(pStrm, 1, "Unknown data dependency class specifier");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Parses a pragma D attributes statement.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @returns Suitable exit code, errors message already written on failure.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @param pStrm The stream.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsyncstatic RTEXITCODE parsePragmaDAttributes(PSCMSTREAM pStrm)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * "CodeStability/DataStability/DataDepClass" - no spaces allowed.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync unsigned ch = parseGetNextNonSpaceNonCommentChOnPpLine(pStrm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch == ~(unsigned)0)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 1, "Expected '/' following the code stability specifier");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync kVTGStability enmData = parseStability(pStrm, ScmStreamGetCh(pStrm));
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 1, "Expected '/' following the data stability specifier");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync kVTGClass enmDataDep = parseDataDepClass(pStrm, ScmStreamGetCh(pStrm));
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Expecting 'provider' followed by the name of an provider defined earlier.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync ch = parseGetNextNonSpaceNonCommentChOnPpLine(pStrm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch == ~(unsigned)0)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch != 'p' || !ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("provider")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 1, "Expected 'provider'");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync const char *pszName = parseGetNextCWord(pStrm, &cchName);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 1, "Expected provider name");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync RTListForEach(&g_ProviderHead, pProv, VTGPROVIDER, ListEntry)
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync if (RTListNodeIsDummy(&g_ProviderHead, pProv, VTGPROVIDER, ListEntry))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, cchName, "Provider not found");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Which aspect of the provider?
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync const char *pszAspect = parseGetNextCWord(pStrm, &cchAspect);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 1, "Expected provider aspect");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (cchAspect == 8 && !memcmp(pszAspect, "provider", 8))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else if (cchAspect == 8 && !memcmp(pszAspect, "function", 8))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else if (cchAspect == 6 && !memcmp(pszAspect, "module", 6))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else if (cchAspect == 4 && !memcmp(pszAspect, "name", 4))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else if (cchAspect == 4 && !memcmp(pszAspect, "args", 4))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, cchAspect, "Unknown aspect");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, cchAspect, "You have already specified these attributes");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Parses a D pragma statement.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @returns Suitable exit code, errors message already written on failure.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @param pStrm The stream.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync unsigned ch = parseGetNextNonSpaceNonCommentChOnPpLine(pStrm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch == ~(unsigned)0)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else if (ch == 'D' && ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("D")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync ch = parseGetNextNonSpaceNonCommentChOnPpLine(pStrm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch == ~(unsigned)0)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else if (ch == 'a' && ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("attributes")))
8f7ee9e453c60b3b699799538a45950b35266665vboxsync * Unmangles the probe name.
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync * This involves translating double underscore to dash.
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync * @returns Pointer to the unmangled name in the string table.
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync * @param pszMangled The mangled name.
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsyncstatic const char *parseUnmangleProbeName(const char *pszMangled)
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync if (pszSrc[0] == '_' && pszSrc[1] == '_' && pszSrc[2] != '_')
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * Parses a D probe statement.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * @returns Suitable exit code, errors message already written on failure.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * @param pStrm The stream.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @param pProv The provider being parsed.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsyncstatic RTEXITCODE parseProbe(PSCMSTREAM pStrm, PVTGPROVIDER pProv)
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * Next up is a name followed by an opening parenthesis.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync const char *pszProbe = parseGetNextCWord(pStrm, &cchProbe);
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync return parseError(pStrm, 1, "Expected a probe name starting with an alphabetical character");
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync unsigned ch = parseGetNextNonSpaceNonCommentCh(pStrm);
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync return parseError(pStrm, 1, "Expected '(' after the probe name");
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * Create a probe instance.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync PVTGPROBE pProbe = (PVTGPROBE)RTMemAllocZ(sizeof(*pProbe));
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync RTListAppend(&pProv->ProbeHead, &pProbe->ListEntry);
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync pProbe->pszMangledName = RTStrDupN(pszProbe, cchProbe);
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync pProbe->pszUnmangledName = parseUnmangleProbeName(pProbe->pszMangledName);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Parse loop for the argument.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync /* commit the argument */
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 1, "Argument has no name");
9c9db71d639cf066ed41d49629d46d48bff4be2fvboxsync return parseError(pStrm, 1, "Argument type too long");
0c94a8282c9042b02f022302a3d987746140eab9vboxsync pArg->pszType = strtabInsertN(szArg, cchArg - cchName - 1);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync pArg->pszName = strtabInsertN(&szArg[cchArg - cchName], cchName);
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync const char *pszWord = ScmStreamCGetWordM1(pStrm, &cchWord);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync return parseError(pStrm, 1, "Too long parameter declaration");
0c94a8282c9042b02f022302a3d987746140eab9vboxsync return parseError(pStrm, 1, "Too long parameter declaration");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 1, "A parameter type does not start with an asterix");
0c94a8282c9042b02f022302a3d987746140eab9vboxsync return parseError(pStrm, 1, "Too long parameter declaration");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync case ~(unsigned)0:
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 0, "Missing closing ')' on probe");
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * Parses a D provider statement.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * @returns Suitable exit code, errors message already written on failure.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * @param pStrm The stream.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * Next up is a name followed by a curly bracket. Ignore comments.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTEXITCODE rcExit = parseSkipSpacesAndComments(pStrm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return parseError(pStrm, 1, "Expected a provider name starting with an alphabetical character");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync const char *pszName = ScmStreamCGetWord(pStrm, &cchName);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return parseError(pStrm, 1, "A provider name cannot end with digit");
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync unsigned ch = parseGetNextNonSpaceNonCommentCh(pStrm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return parseError(pStrm, 1, "Expected '{' after the provider name");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Create a provider instance.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync PVTGPROVIDER pProv = (PVTGPROVIDER)RTMemAllocZ(sizeof(*pProv));
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync * Parse loop.
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("probe")))
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync rcExit = parseError(pStrm, 1, "Unexpected character");
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync rcExit = parseErrorAbs(pStrm, off, "Expected ';'");
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync case ~(unsigned)0:
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync rcExit = parseError(pStrm, 0, "Missing closing '}' on provider");
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync rcExit = parseError(pStrm, 1, "Unexpected character");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE parseScript(const char *pszScript)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync int rc = ScmStreamInitForReading(&Strm, pszScript);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to open & read '%s' into memory: %Rrc", pszScript, rc);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync while ((ch = ScmStreamGetCh(&Strm)) != ~(unsigned)0)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = parseError(&Strm, 2, "Unexpected character");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (ScmStreamCMatchingWordM1(&Strm, RT_STR_TUPLE("provider")))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = parseError(&Strm, 1, "Unexpected character");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync ch = parseGetNextNonSpaceNonCommentChOnPpLine(&Strm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch == ~(unsigned)0)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else if (ch == 'p' && ScmStreamCMatchingWordM1(&Strm, RT_STR_TUPLE("pragma")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync rcExit = parseError(&Strm, 1, "Unsupported preprocessor directive");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = parseError(&Strm, 1, "Unexpected character");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (g_cVerbosity > 0 && rcExit == RTEXITCODE_SUCCESS)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Parses the arguments.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE parseArguments(int argc, char **argv)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Set / Adjust defaults.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync int rc = RTPathAbs(g_pszAssemblerIncVal, g_szAssemblerIncVal, sizeof(g_szAssemblerIncVal) - 1);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPathAbs failed: %Rrc", rc);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Option config.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* dtrace w/ long options */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync { "-32", kVBoxTpGOpt_32Bit, RTGETOPT_REQ_NOTHING },
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync { "-64", kVBoxTpGOpt_64Bit, RTGETOPT_REQ_NOTHING },
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync { "--generate-header", 'h', RTGETOPT_REQ_NOTHING },
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* out stuff */
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync { "--assembler", kVBoxTpGOpt_Assembler, RTGETOPT_REQ_STRING },
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync { "--assembler-fmt-opt", kVBoxTpGOpt_AssemblerFmtOpt, RTGETOPT_REQ_STRING },
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync { "--assembler-fmt-val", kVBoxTpGOpt_AssemblerFmtVal, RTGETOPT_REQ_STRING },
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync { "--assembler-output-opt", kVBoxTpGOpt_AssemblerOutputOpt, RTGETOPT_REQ_STRING },
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync { "--assembler-option", kVBoxTpGOpt_AssemblerOption, RTGETOPT_REQ_STRING },
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync { "--probe-fn-name", kVBoxTpGOpt_ProbeFnName, RTGETOPT_REQ_STRING },
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync { "--probe-fn-imported", kVBoxTpGOpt_ProbeFnImported, RTGETOPT_REQ_BOOL },
82e3a4017d20f44c30ff909e6b825ff78139cbbbvboxsync /** @todo We're missing a bunch of assembler options! */
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync rc = RTGetOptInit(&GetOptState, argc, argv, &s_aOpts[0], RT_ELEMENTS(s_aOpts), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Process \the options.
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync while ((rc = RTGetOpt(&GetOptState, &ValueUnion)) != 0)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * DTrace compatible options.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTMsgWarning("Ignoring the -C option - no preprocessing of the D script will be performed");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "-G and -h does not mix");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (!strcmp(GetOptState.pDef->pszLong, "--generate-header"))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "-h and -G does not mix");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* --help or similar */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync "Usage: %s [options]\n"
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTPrintf(" -%c,%s\n", s_aOpts[i].iShort, s_aOpts[i].pszLong);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Output file is already set to '%s'", g_pszOutput);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Script file is already set to '%s'", g_pszScript);
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync /* The following is assuming that svn does it's job here. */
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync const char *psz = RTStrStripL(strchr(s_szRev, ' '));
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync break; /* object files, ignore them. */
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync * Our options.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (g_cAssemblerOptions >= RT_ELEMENTS(g_apszAssemblerOptions))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Too many assembly options (max %u)", RT_ELEMENTS(g_apszAssemblerOptions));
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync g_apszAssemblerOptions[g_cAssemblerOptions] = ValueUnion.psz;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Errors and bugs.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Check that we've got all we need.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No action specified (-h or -G)");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No script file specified (-s)");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No output file specified (-o)");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Parse the script.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * Take action.