VBoxTpG.cpp revision 8865793e4f3435f5e2c728d9e6739cd24d08c0de
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync/* $Id$ */
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync/** @file
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync * VBox Build Tool - VBox Tracepoint Generator.
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync */
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync/*
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Copyright (C) 2012 Oracle Corporation
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync *
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
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync/*******************************************************************************
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync* Header Files *
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync*******************************************************************************/
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync#include <VBox/VBoxTpG.h>
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync#include <iprt/alloca.h>
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include <iprt/assert.h>
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include <iprt/ctype.h>
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include <iprt/env.h>
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include <iprt/err.h>
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync#include <iprt/file.h>
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include <iprt/getopt.h>
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include <iprt/initterm.h>
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync#include <iprt/list.h>
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include <iprt/mem.h>
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include <iprt/message.h>
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync#include <iprt/path.h>
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync#include <iprt/process.h>
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include <iprt/stream.h>
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include <iprt/string.h>
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync#include "scmstream.h"
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync/*******************************************************************************
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync* Structures and Typedefs *
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync*******************************************************************************/
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsynctypedef struct VTGATTRS
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync{
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync kVTGStability enmCode;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync kVTGStability enmData;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync kVTGClass enmDataDep;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync} VTGATTRS;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsynctypedef VTGATTRS *PVTGATTRS;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsynctypedef struct VTGARG
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync{
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync RTLISTNODE ListEntry;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync const char *pszName;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync const char *pszType;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync} VTGARG;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsynctypedef VTGARG *PVTGARG;
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsynctypedef struct VTGPROBE
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTLISTNODE ListEntry;
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync char *pszMangledName;
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync const char *pszUnmangledName;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync RTLISTANCHOR ArgHead;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync uint32_t cArgs;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t offArgList;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t iProbe;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync} VTGPROBE;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsynctypedef VTGPROBE *PVTGPROBE;
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsynctypedef struct VTGPROVIDER
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync{
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTLISTNODE ListEntry;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync const char *pszName;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync uint16_t iFirstProbe;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync uint16_t cProbes;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync VTGATTRS AttrSelf;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync VTGATTRS AttrModules;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync VTGATTRS AttrFunctions;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync VTGATTRS AttrName;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync VTGATTRS AttrArguments;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTLISTANCHOR ProbeHead;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync} VTGPROVIDER;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsynctypedef VTGPROVIDER *PVTGPROVIDER;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync/**
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * A string table string.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync */
0c94a8282c9042b02f022302a3d987746140eab9vboxsynctypedef struct VTGSTRING
0c94a8282c9042b02f022302a3d987746140eab9vboxsync{
0c94a8282c9042b02f022302a3d987746140eab9vboxsync /** The string space core. */
0c94a8282c9042b02f022302a3d987746140eab9vboxsync RTSTRSPACECORE Core;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync /** The string table offset. */
0c94a8282c9042b02f022302a3d987746140eab9vboxsync uint32_t offStrTab;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync /** The actual string. */
0c94a8282c9042b02f022302a3d987746140eab9vboxsync char szString[1];
0c94a8282c9042b02f022302a3d987746140eab9vboxsync} VTGSTRING;
0c94a8282c9042b02f022302a3d987746140eab9vboxsynctypedef VTGSTRING *PVTGSTRING;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync/*******************************************************************************
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync* Global Variables *
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync*******************************************************************************/
0c94a8282c9042b02f022302a3d987746140eab9vboxsync/** The string space organizing the string table strings. Each node is a VTGSTRING. */
0c94a8282c9042b02f022302a3d987746140eab9vboxsyncstatic RTSTRSPACE g_StrSpace = NULL;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync/** Used by the string table enumerator to set VTGSTRING::offStrTab. */
0c94a8282c9042b02f022302a3d987746140eab9vboxsyncstatic uint32_t g_offStrTab;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync/** List of providers created by the parser. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTLISTANCHOR g_ProviderHead;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync/** @name Options
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @{ */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic enum
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync kVBoxTpGAction_Nothing,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync kVBoxTpGAction_GenerateHeader,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync kVBoxTpGAction_GenerateObject
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync} g_enmAction = kVBoxTpGAction_Nothing;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic uint32_t g_cBits = ARCH_BITS;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic bool g_fApplyCpp = false;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic uint32_t g_cVerbosity = 0;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char *g_pszOutput = NULL;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char *g_pszScript = NULL;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char *g_pszTempAsm = NULL;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync#ifdef RT_OS_DARWIN
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char *g_pszAssembler = "yasm";
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsyncstatic const char *g_pszAssemblerFmtOpt = "-f";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char g_szAssemblerFmtVal32[] = "macho32";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char g_szAssemblerFmtVal64[] = "macho64";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync#elif defined(RT_OS_OS2)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char *pszAssembler = "nasm.exe";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char *pszAssemblerFmtOpt = "-f";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char g_szAssemblerFmtVal32[] = "obj";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char g_szAssemblerFmtVal64[] = "elf64";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync#elif defined(RT_OS_WINDOWS)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char *g_pszAssembler = "yasm.exe";
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsyncstatic const char *g_pszAssemblerFmtOpt = "-f";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char g_szAssemblerFmtVal32[] = "win32";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char g_szAssemblerFmtVal64[] = "win64";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync#else
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char *g_pszAssembler = "yasm";
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsyncstatic const char *g_pszAssemblerFmtOpt = "-f";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char g_szAssemblerFmtVal32[] = "elf32";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char g_szAssemblerFmtVal64[] = "elf64";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync#endif
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char *g_pszAssemblerFmtVal = RT_CONCAT(g_szAssemblerFmtVal, ARCH_BITS);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsyncstatic const char *g_pszAssemblerDefOpt = "-D";
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsyncstatic const char *g_pszAssemblerIncOpt = "-I";
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsyncstatic char g_szAssemblerIncVal[RTPATH_MAX];
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsyncstatic const char *g_pszAssemblerIncVal = __FILE__ "/../../../include/";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char *g_pszAssemblerOutputOpt = "-o";
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic unsigned g_cAssemblerOptions = 0;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic const char *g_apszAssemblerOptions[32];
1969e98a26e5b56b67fbe3b6bfa007f8f09e86ebvboxsyncstatic const char *g_pszProbeFnName = "SUPR0TracerFireProbe";
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsyncstatic bool g_fProbeFnImported = true;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync/** @} */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync/**
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * Inserts a string into the string table, reusing any matching existing string
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * if possible.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync *
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * @returns Read only string.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * @param pch The string to insert (need not be terminated).
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * @param cch The length of the string.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync */
0c94a8282c9042b02f022302a3d987746140eab9vboxsyncstatic const char *strtabInsertN(const char *pch, size_t cch)
0c94a8282c9042b02f022302a3d987746140eab9vboxsync{
0c94a8282c9042b02f022302a3d987746140eab9vboxsync PVTGSTRING pStr = (PVTGSTRING)RTStrSpaceGetN(&g_StrSpace, pch, cch);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync if (pStr)
0c94a8282c9042b02f022302a3d987746140eab9vboxsync return pStr->szString;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync /*
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * Create a new entry.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync */
0c94a8282c9042b02f022302a3d987746140eab9vboxsync pStr = (PVTGSTRING)RTMemAlloc(RT_OFFSETOF(VTGSTRING, szString[cch + 1]));
0c94a8282c9042b02f022302a3d987746140eab9vboxsync if (!pStr)
0c94a8282c9042b02f022302a3d987746140eab9vboxsync return NULL;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync pStr->Core.pszString = pStr->szString;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync memcpy(pStr->szString, pch, cch);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync pStr->szString[cch] = '\0';
0c94a8282c9042b02f022302a3d987746140eab9vboxsync pStr->offStrTab = UINT32_MAX;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync bool fRc = RTStrSpaceInsert(&g_StrSpace, &pStr->Core);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync Assert(fRc); NOREF(fRc);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync return pStr->szString;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync}
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync/**
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Retrieves the string table offset of the given string table string.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync *
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @returns String table offset.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @param pszStrTabString The string table string.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync */
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsyncstatic uint32_t strtabGetOff(const char *pszStrTabString)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync{
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync PVTGSTRING pStr = RT_FROM_MEMBER(pszStrTabString, VTGSTRING, szString[0]);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync Assert(pStr->Core.pszString == pszStrTabString);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return pStr->offStrTab;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync}
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync/**
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Invokes the assembler.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync *
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @returns Exit code.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param pszOutput The output file.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param pszTempAsm The source file.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE generateInvokeAssembler(const char *pszOutput, const char *pszTempAsm)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync const char *apszArgs[64];
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync unsigned iArg = 0;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = g_pszAssembler;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = g_pszAssemblerFmtOpt;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = g_pszAssemblerFmtVal;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = g_pszAssemblerDefOpt;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (!strcmp(g_pszAssemblerFmtVal, "macho32") || !strcmp(g_pszAssemblerFmtVal, "macho64"))
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = "ASM_FORMAT_MACHO";
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync else if (!strcmp(g_pszAssemblerFmtVal, "obj") || !strcmp(g_pszAssemblerFmtVal, "omf"))
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = "ASM_FORMAT_OMF";
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync else if ( !strcmp(g_pszAssemblerFmtVal, "win32")
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync || !strcmp(g_pszAssemblerFmtVal, "win64")
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync || !strcmp(g_pszAssemblerFmtVal, "pe32")
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync || !strcmp(g_pszAssemblerFmtVal, "pe64")
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync || !strcmp(g_pszAssemblerFmtVal, "pe") )
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = "ASM_FORMAT_PE";
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync else if ( !strcmp(g_pszAssemblerFmtVal, "elf32")
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync || !strcmp(g_pszAssemblerFmtVal, "elf64")
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync || !strcmp(g_pszAssemblerFmtVal, "elf"))
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = "ASM_FORMAT_ELF";
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync else
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Unknown assembler format '%s'", g_pszAssemblerFmtVal);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = g_pszAssemblerDefOpt;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (g_cBits == 32)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = "ARCH_BITS=32";
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync else
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = "ARCH_BITS=64";
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = g_pszAssemblerDefOpt;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (g_cBits == 32)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = "RT_ARCH_X86";
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync else
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = "RT_ARCH_AMD64";
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = g_pszAssemblerIncOpt;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = g_pszAssemblerIncVal;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = g_pszAssemblerOutputOpt;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = pszOutput;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync for (unsigned i = 0; i < g_cAssemblerOptions; i++)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = g_apszAssemblerOptions[i];
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg++] = pszTempAsm;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync apszArgs[iArg] = NULL;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (g_cVerbosity > 1)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync RTMsgInfo("Starting assmbler '%s' with arguments:\n", g_pszAssembler);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync for (unsigned i = 0; i < iArg; i++)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync RTMsgInfo(" #%02u: '%s'\n", i, apszArgs[i]);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync RTPROCESS hProc;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync int rc = RTProcCreate(apszArgs[0], apszArgs, RTENV_DEFAULT, RTPROC_FLAGS_SEARCH_PATH, &hProc);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (RT_FAILURE(rc))
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to start '%s' (assembler): %Rrc", apszArgs[0], rc);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync RTPROCSTATUS Status;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync rc = RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &Status);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (RT_FAILURE(rc))
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync RTProcTerminate(hProc);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTProcWait failed: %Rrc", rc);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (Status.enmReason == RTPROCEXITREASON_SIGNAL)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "The assembler failed: signal %d", Status.iStatus);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (Status.enmReason != RTPROCEXITREASON_NORMAL)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "The assembler failed: abend");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (Status.iStatus != 0)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync return RTMsgErrorExit((RTEXITCODE)Status.iStatus, "The assembler failed: exit code %d", Status.iStatus);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return RTEXITCODE_SUCCESS;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync/**
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Worker that does the boring bits when generating a file.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync *
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.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE generateFile(const char *pszOutput, const char *pszWhat,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTEXITCODE (*pfnGenerator)(PSCMSTREAM))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync SCMSTREAM Strm;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync int rc = ScmStreamInitForWriting(&Strm, NULL);
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync if (RT_FAILURE(rc))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "ScmStreamInitForWriting returned %Rrc when generating the %s file",
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rc, pszWhat);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTEXITCODE rcExit = pfnGenerator(&Strm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (RT_FAILURE(ScmStreamGetStatus(&Strm)))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Stream error %Rrc generating the %s file",
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync ScmStreamGetStatus(&Strm), pszWhat);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (rcExit == RTEXITCODE_SUCCESS)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rc = ScmStreamWriteToFile(&Strm, "%s", pszOutput);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (RT_FAILURE(rc))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "ScmStreamWriteToFile returned %Rrc when writing '%s' (%s)",
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rc, pszOutput, pszWhat);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (rcExit == RTEXITCODE_SUCCESS)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (g_cVerbosity > 0)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTMsgInfo("Successfully generated '%s'.", pszOutput);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (g_cVerbosity > 1)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTMsgInfo("================ %s - start ================", pszWhat);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync ScmStreamRewindForReading(&Strm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync const char *pszLine;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync size_t cchLine;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync SCMEOL enmEol;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync while ((pszLine = ScmStreamGetLine(&Strm, &cchLine, &enmEol)) != NULL)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTPrintf("%.*s\n", cchLine, pszLine);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTMsgInfo("================ %s - end ================", pszWhat);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync ScmStreamDelete(&Strm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return rcExit;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync/**
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Formats a string and writes it to the SCM stream.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync *
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.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync */
66b58af085e22ee26be57f98127fb49ee2e91790vboxsyncstatic ssize_t ScmStreamPrintfV(PSCMSTREAM pStream, const char *pszFormat, va_list va)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync{
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync char *psz;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ssize_t cch = RTStrAPrintfV(&psz, pszFormat, va);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (cch)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync int rc = ScmStreamWrite(pStream, psz, cch);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync RTStrFree(psz);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (RT_FAILURE(rc))
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync cch = rc;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync }
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync return cch;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync}
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync/**
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Formats a string and writes it to the SCM stream.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync *
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.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync */
66b58af085e22ee26be57f98127fb49ee2e91790vboxsyncstatic ssize_t ScmStreamPrintf(PSCMSTREAM pStream, const char *pszFormat, ...)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync{
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync va_list va;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync va_start(va, pszFormat);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ssize_t cch = ScmStreamPrintfV(pStream, pszFormat, va);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync va_end(va);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync return cch;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync}
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync/**
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * @callback_method_impl{FNRTSTRSPACECALLBACK, Writes the string table strings.}
0c94a8282c9042b02f022302a3d987746140eab9vboxsync */
0c94a8282c9042b02f022302a3d987746140eab9vboxsyncstatic DECLCALLBACK(int) generateAssemblyStrTabCallback(PRTSTRSPACECORE pStr, void *pvUser)
0c94a8282c9042b02f022302a3d987746140eab9vboxsync{
0c94a8282c9042b02f022302a3d987746140eab9vboxsync PVTGSTRING pVtgStr = (PVTGSTRING)pStr;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync PSCMSTREAM pStrm = (PSCMSTREAM)pvUser;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync pVtgStr->offStrTab = g_offStrTab;
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync g_offStrTab += (uint32_t)pVtgStr->Core.cchString + 1;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync ScmStreamPrintf(pStrm,
0c94a8282c9042b02f022302a3d987746140eab9vboxsync " db '%s', 0 ; off=%u len=%zu\n",
0c94a8282c9042b02f022302a3d987746140eab9vboxsync pVtgStr->szString, pVtgStr->offStrTab, pVtgStr->Core.cchString);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync return VINF_SUCCESS;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync}
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync/**
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Generate assembly source that can be turned into an object file.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync *
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * (This is a generateFile callback.)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync *
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @returns Exit code.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param pStrm The output stream.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE generateAssembly(PSCMSTREAM pStrm)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync PVTGPROVIDER pProvider;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync PVTGPROBE pProbe;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync PVTGARG pArg;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (g_cVerbosity > 0)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTMsgInfo("Generating assembly code...");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync /*
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * Write the file header.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync */
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ScmStreamPrintf(pStrm,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "; $Id$ \n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ";; @file\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "; Automatically generated from %s. Do NOT edit!\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ";\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "%%include \"iprt/asmdefs.mac\"\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync ";"
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync "; We put all the data in a dedicated section / segment.\n"
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync ";\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 ";\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"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "\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"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " ;[section VTG Obj align=4096]\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " [section .data]\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "\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"
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync /*" times 24 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"
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync /*" times 24 db 0xcc\n"*/
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync " [section VTGObj data align=32]\n"
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync "\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"
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync " [section .VTGPrLc.Start progbits alloc noexec write align=1]\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_aVTGPrLc, data\n"
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync " [section .VTGPrLc progbits alloc noexec write align=1]\n"
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync " [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"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "%%else\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " %%error \"ASM_FORMAT_XXX is not defined\"\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "%%endif\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_VTGObjHeader, data\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " ;0 1 2 3\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " ;012345678901234567890123456789012\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " db 'VTG Object Header v1.0', 0, 0\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " dd %u\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " dd 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"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " RTCCPTR_DEF NAME(g_aVTGPrLc)\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " RTCCPTR_DEF NAME(g_aVTGPrLc_End) ; cross section/segment size not possible\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " RTCCPTR_DEF 0\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " RTCCPTR_DEF 0\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " RTCCPTR_DEF 0\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " RTCCPTR_DEF 0\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ,
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync g_pszScript, g_cBits);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync /*
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Declare the probe enable flags.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync */
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync ScmStreamPrintf(pStrm,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync ";\n"
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"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync ";\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_afVTGProbeEnabled, data\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync );
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync uint32_t cProbes = 0;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&pProvider->ProbeHead, pProbe, VTGPROBE, ListEntry)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync ScmStreamPrintf(pStrm,
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_fVTGProbeEnabled_%s_%s, data\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " db 0\n",
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync pProvider->pszName, pProbe->pszMangledName);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync cProbes++;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync ScmStreamPrintf(pStrm, "VTG_GLOBAL g_afVTGProbeEnabled_End, data\n");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (cProbes >= _32K)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Too many probes: %u (max %u)", cProbes, _32K - 1);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /*
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Dump the string table before we start using the strings.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync */
0c94a8282c9042b02f022302a3d987746140eab9vboxsync ScmStreamPrintf(pStrm,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync "\n"
0c94a8282c9042b02f022302a3d987746140eab9vboxsync ";\n"
0c94a8282c9042b02f022302a3d987746140eab9vboxsync "; The string table.\n"
0c94a8282c9042b02f022302a3d987746140eab9vboxsync ";\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_achVTGStringTable, data\n");
0c94a8282c9042b02f022302a3d987746140eab9vboxsync g_offStrTab = 0;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync RTStrSpaceEnumerate(&g_StrSpace, generateAssemblyStrTabCallback, pStrm);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync ScmStreamPrintf(pStrm,
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_achVTGStringTable_End, data\n");
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync /*
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Write out the argument lists before we use them.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync */
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ScmStreamPrintf(pStrm,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync "\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ";\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "; The argument lists.\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ";\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_aVTGArgLists, data\n");
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t off = 0;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&pProvider->ProbeHead, pProbe, VTGPROBE, ListEntry)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (pProbe->offArgList != UINT32_MAX)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync continue;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /* Write it. */
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync pProbe->offArgList = off;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ScmStreamPrintf(pStrm,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " ; off=%u\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " db %2u ; Argument count\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " db 0, 0, 0 ; Reserved\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync , off, pProbe->cArgs);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync off += 4;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync ScmStreamPrintf(pStrm,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " dd %6u ; type '%s'\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " dd %6u ; name '%s'\n",
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync strtabGetOff(pArg->pszType), pArg->pszType,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync strtabGetOff(pArg->pszName), pArg->pszName);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync off += 8;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /* Look for matching argument lists (lazy bird walks the whole list). */
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync PVTGPROVIDER pProv2;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync RTListForEach(&g_ProviderHead, pProv2, VTGPROVIDER, ListEntry)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync PVTGPROBE pProbe2;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&pProvider->ProbeHead, pProbe2, VTGPROBE, ListEntry)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (pProbe2->offArgList != UINT32_MAX)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync continue;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (pProbe2->cArgs != pProbe->cArgs)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync continue;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync PVTGARG pArg2;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync pArg = RTListNodeGetNext(&pProbe->ArgHead, VTGARG, ListEntry);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync pArg2 = RTListNodeGetNext(&pProbe2->ArgHead, VTGARG, ListEntry);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync int32_t cArgs = pProbe->cArgs;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync while ( cArgs-- > 0
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync && pArg2->pszName == pArg2->pszName
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync && pArg2->pszType == pArg2->pszType)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync pArg = RTListNodeGetNext(&pArg->ListEntry, VTGARG, ListEntry);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync pArg2 = RTListNodeGetNext(&pArg2->ListEntry, VTGARG, ListEntry);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (cArgs >= 0)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync continue;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync pProbe2->offArgList = pProbe->offArgList;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync }
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync }
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync ScmStreamPrintf(pStrm,
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_aVTGArgLists_End, data\n");
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync /*
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Probe definitions.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync */
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ScmStreamPrintf(pStrm,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ";\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "; Prob definitions.\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ";\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_aVTGProbes, data\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "\n");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync uint32_t iProvider = 0;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync uint32_t iProbe = 0;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pProvider->iFirstProbe = iProbe;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&pProvider->ProbeHead, pProbe, VTGPROBE, ListEntry)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync ScmStreamPrintf(pStrm,
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_VTGProbeData_%s_%s, data ; idx=#%4u\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " dd %6u ; name\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync " dd %6u ; Argument list offset\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " dw g_fVTGProbeEnabled_%s_%s - g_afVTGProbeEnabled\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " dw %6u ; provider index\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " dd 0 ; for the application\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync ,
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync pProvider->pszName, pProbe->pszMangledName, iProbe,
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync strtabGetOff(pProbe->pszUnmangledName),
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync pProbe->offArgList,
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync pProvider->pszName, pProbe->pszMangledName,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync iProvider);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync pProbe->iProbe = iProbe;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync iProbe++;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync }
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pProvider->cProbes = iProbe - pProvider->iFirstProbe;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync iProvider++;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync }
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync ScmStreamPrintf(pStrm, "VTG_GLOBAL g_aVTGProbes_End, data\n");
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /*
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * The providers data.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync */
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync ScmStreamPrintf(pStrm,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync ";\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync "; Provider data.\n"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync ";\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL g_aVTGProviders, data\n");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync iProvider = 0;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync ScmStreamPrintf(pStrm,
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"
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync ,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync iProvider, pProvider->pszName,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync strtabGetOff(pProvider->pszName),
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pProvider->iFirstProbe,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pProvider->cProbes,
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);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync iProvider++;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync }
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync ScmStreamPrintf(pStrm, "VTG_GLOBAL g_aVTGProviders_End, data\n");
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /*
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Emit code for the stub functions.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync */
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync ScmStreamPrintf(pStrm,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync "\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync ";\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync "; Prob stubs.\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync ";\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync "BEGINCODE\n"
9c9db71d639cf066ed41d49629d46d48bff4be2fvboxsync "extern %sNAME(%s)\n",
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync g_fProbeFnImported ? "IMP" : "",
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync g_pszProbeFnName);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&pProvider->ProbeHead, pProbe, VTGPROBE, ListEntry)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync ScmStreamPrintf(pStrm,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync "\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "VTG_GLOBAL VTGProbeStub_%s_%s, function; (VBOXTPGPROBELOC pVTGProbeLoc",
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync pProvider->pszName, pProbe->pszMangledName);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync ScmStreamPrintf(pStrm, ", %s %s", pArg->pszType, pArg->pszName);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync }
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync ScmStreamPrintf(pStrm,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync ");\n");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync bool const fWin64 = g_cBits == 64 && (!strcmp(g_pszAssemblerFmtVal, "win64") || !strcmp(g_pszAssemblerFmtVal, "pe64"));
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync bool const fMachO32 = g_cBits == 32 && !strcmp(g_pszAssemblerFmtVal, "macho32");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync /*
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Check if the probe in question is enabled.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync */
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (g_cBits == 32)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync ScmStreamPrintf(pStrm,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " mov eax, [esp + 4]\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " test byte [eax+3], 0x80 ; fEnabled == true?\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " jz .return ; jump on false\n");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync else if (fWin64)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync ScmStreamPrintf(pStrm,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " test byte [rcx+3], 0x80 ; fEnabled == true?\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " jz .return ; jump on false\n");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync else
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync ScmStreamPrintf(pStrm,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " test byte [rdi+3], 0x80 ; fEnabled == true?\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " jz .return ; jump on false\n");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync#if 0
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync /*
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Shuffle the arguments around, replacing the location pointer with the probe ID.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync */
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (fMachO32)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync /* Need to recreate the stack frame entirely here as the probe
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync function differs by taking all uint64_t arguments instead
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync of uintptr_t. Understandable, but real PITA. */
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync ScmStreamPrintf(pStrm, "int3\n");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync }
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync else if (g_cBits == 32)
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync /* Assumes the size of the arguments are no larger than a
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync pointer. This is asserted in the header. */
9c9db71d639cf066ed41d49629d46d48bff4be2fvboxsync ScmStreamPrintf(pStrm, g_fProbeFnImported ?
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " mov edx, [eax + 4] ; idProbe\n"
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync " mov ecx, IMP2(%s)\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " mov [esp + 4], edx ; Replace pVTGProbeLoc with idProbe.\n"
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync " jmp ecx\n"
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync :
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync " mov edx, [eax + 4] ; idProbe\n"
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync " mov [esp + 4], edx ; Replace pVTGProbeLoc with idProbe.\n"
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync " jmp NAME(%s)\n"
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync , g_pszProbeFnName);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync else if (fWin64)
9c9db71d639cf066ed41d49629d46d48bff4be2fvboxsync ScmStreamPrintf(pStrm, g_fProbeFnImported ?
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync " mov rax, IMP2(%s)\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " mov ecx, [rcx + 4] ; idProbe replaces pVTGProbeLoc.\n"
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync " jmp rax\n"
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync :
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync " mov ecx, [rcx + 4] ; idProbe replaces pVTGProbeLoc.\n"
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " jmp NAME(%s)\n"
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync , g_pszProbeFnName);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync else
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync ScmStreamPrintf(pStrm, g_fProbeFnImported ?
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync " lea rax, [IMP2(%s)]\n" //??? macho64?
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync " mov edi, [rdi + 4] ; idProbe replaces pVTGProbeLoc.\n"
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync " jmp rax\n"
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync :
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " mov edi, [rdi + 4] ; idProbe replaces pVTGProbeLoc.\n"
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " jmp NAME(%s)\n"
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync , g_pszProbeFnName);
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync#else
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync /*
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync * Jump to the fire-probe function.
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync */
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync if (g_cBits == 32)
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync ScmStreamPrintf(pStrm, g_fProbeFnImported ?
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " mov ecx, IMP2(%s)\n"
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " jmp ecx\n"
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync :
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " jmp NAME(%s)\n"
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync , g_pszProbeFnName);
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync else if (fWin64)
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync ScmStreamPrintf(pStrm, g_fProbeFnImported ?
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " mov rax, IMP2(%s)\n"
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " jmp rax\n"
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync :
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " jmp NAME(%s)\n"
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync , g_pszProbeFnName);
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync else
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync ScmStreamPrintf(pStrm, g_fProbeFnImported ?
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " lea rax, [IMP2(%s)]\n" //??? macho64?
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " jmp rax\n"
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync :
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync " jmp NAME(%s)\n"
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync , g_pszProbeFnName);
8865793e4f3435f5e2c728d9e6739cd24d08c0devboxsync#endif
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync ScmStreamPrintf(pStrm,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync ".return:\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " ret ; The probe was disabled, return\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync "\n");
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync }
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync }
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTEXITCODE_SUCCESS;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE generateObject(const char *pszOutput, const char *pszTempAsm)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (!pszTempAsm)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync size_t cch = strlen(pszOutput);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync char *psz = (char *)alloca(cch + sizeof(".asm"));
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync memcpy(psz, pszOutput, cch);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync memcpy(psz + cch, ".asm", sizeof(".asm"));
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync pszTempAsm = psz;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTEXITCODE rcExit = generateFile(pszTempAsm, "assembly", generateAssembly);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (rcExit == RTEXITCODE_SUCCESS)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = generateInvokeAssembler(pszOutput, pszTempAsm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTFileDelete(pszTempAsm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return rcExit;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsyncstatic RTEXITCODE generateProbeDefineName(char *pszBuf, size_t cbBuf, const char *pszProvider, const char *pszProbe)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync{
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync size_t cbMax = strlen(pszProvider) + 1 + strlen(pszProbe) + 1;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (cbMax > cbBuf || cbMax > 80)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Probe '%s' in provider '%s' ends up with a too long defined\n", pszProbe, pszProvider);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync while (*pszProvider)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync *pszBuf++ = RT_C_TO_UPPER(*pszProvider++);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync *pszBuf++ = '_';
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync while (*pszProbe)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (pszProbe[0] == '_' && pszProbe[1] == '_')
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync pszProbe++;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync *pszBuf++ = RT_C_TO_UPPER(*pszProbe++);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync }
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync *pszBuf = '\0';
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync return RTEXITCODE_SUCCESS;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync}
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE generateHeaderInner(PSCMSTREAM pStrm)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync /*
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * Calc the double inclusion blocker define and then write the file header.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync */
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync char szTmp[4096];
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync const char *pszName = RTPathFilename(g_pszScript);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync size_t cchName = strlen(pszName);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (cchName >= sizeof(szTmp) - 64)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "File name is too long '%s'", pszName);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync szTmp[0] = '_';
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync szTmp[1] = '_';
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync szTmp[2] = '_';
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync memcpy(&szTmp[3], pszName, cchName);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync szTmp[3 + cchName + 0] = '_';
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync szTmp[3 + cchName + 1] = '_';
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync szTmp[3 + cchName + 2] = '_';
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync szTmp[3 + cchName + 3] = '\0';
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync char *psz = &szTmp[3];
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync while (*psz)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (!RT_C_IS_ALNUM(*psz) && *psz != '_')
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync *psz = '_';
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync psz++;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync }
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ScmStreamPrintf(pStrm,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "/* $Id$ */\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "/** @file\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync " * Automatically generated from %s. Do NOT edit!\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync " */\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "#ifndef %s\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "#define %s\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "#include <VBox/VBoxTpG.h>\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "RT_C_DECLS_BEGIN\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "#ifdef VBOX_WITH_DTRACE\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "\n"
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync "# ifdef _MSC_VER\n"
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync "# pragma data_seg(VTG_LOC_SECT)\n"
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync "# pragma data_seg()\n"
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync "# endif\n"
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync "\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync g_pszScript,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync szTmp,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync szTmp);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync /*
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * Declare data, code and macros for each probe.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync */
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync PVTGPROVIDER pProv;
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync PVTGPROBE pProbe;
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync PVTGARG pArg;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync RTListForEach(&g_ProviderHead, pProv, VTGPROVIDER, ListEntry)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync RTListForEach(&pProv->ProbeHead, pProbe, VTGPROBE, ListEntry)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ScmStreamPrintf(pStrm,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "extern bool g_fVTGProbeEnabled_%s_%s;\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "extern uint8_t g_VTGProbeData_%s_%s;\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "DECLASM(void) VTGProbeStub_%s_%s(PVTGPROBELOC",
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync pProv->pszName, pProbe->pszMangledName,
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync pProv->pszName, pProbe->pszMangledName,
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync pProv->pszName, pProbe->pszMangledName);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ScmStreamPrintf(pStrm, ", %s", pArg->pszType);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync }
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync generateProbeDefineName(szTmp, sizeof(szTmp), pProv->pszName, pProbe->pszMangledName);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ScmStreamPrintf(pStrm,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ");\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "# define %s_ENABLED() \\\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync " (RT_UNLIKELY(g_fVTGProbeEnabled_%s_%s)) \n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "# define %s("
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync , szTmp,
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync pProv->pszName, pProbe->pszMangledName,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync szTmp);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if (RTListNodeIsFirst(&pProbe->ArgHead, &pArg->ListEntry))
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ScmStreamPrintf(pStrm, "%s", pArg->pszName);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync else
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ScmStreamPrintf(pStrm, ", %s", pArg->pszName);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync }
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ScmStreamPrintf(pStrm,
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ") \\\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync " do { \\\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " if (RT_UNLIKELY(g_fVTGProbeEnabled_%s_%s)) \\\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync " { \\\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync " VTG_DECL_VTGPROBELOC(s_VTGProbeLoc) = \\\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " { __LINE__, 0, UINT32_MAX, __PRETTY_FUNCTION__, __FILE__, &g_VTGProbeData_%s_%s }; \\\n"
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync " VTGProbeStub_%s_%s(&s_VTGProbeLoc",
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync pProv->pszName, pProbe->pszMangledName,
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync pProv->pszName, pProbe->pszMangledName,
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync pProv->pszName, pProbe->pszMangledName);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync {
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ScmStreamPrintf(pStrm, ", %s", pArg->pszName);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync }
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ScmStreamPrintf(pStrm,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync "); \\\n"
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync " } \\\n"
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync " { \\\n" );
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync ScmStreamPrintf(pStrm,
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync " AssertCompile(sizeof(%s) <= sizeof(uintptr_t)); \\\n"
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync " AssertCompile(sizeof(%s) <= sizeof(uintptr_t)); \\\n",
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pArg->pszName,
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync pArg->pszType);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync }
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync ScmStreamPrintf(pStrm,
e70bda5438c3582164d26f171a8bc8d3d7da1e12vboxsync " } \\\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync " } while (0)\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "\n");
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync }
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync }
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync ScmStreamPrintf(pStrm,
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "#else\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "\n");
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync RTListForEach(&g_ProviderHead, pProv, VTGPROVIDER, ListEntry)
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync {
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync RTListForEach(&pProv->ProbeHead, pProbe, VTGPROBE, ListEntry)
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync {
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync generateProbeDefineName(szTmp, sizeof(szTmp), pProv->pszName, pProbe->pszMangledName);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync ScmStreamPrintf(pStrm,
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "# define %s_ENABLED() (false)\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "# define %s("
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync , szTmp, szTmp);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync {
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync if (RTListNodeIsFirst(&pProbe->ArgHead, &pArg->ListEntry))
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync ScmStreamPrintf(pStrm, "%s", pArg->pszName);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync else
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync ScmStreamPrintf(pStrm, ", %s", pArg->pszName);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync }
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync ScmStreamPrintf(pStrm,
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync ") do { } while (0)\n");
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync }
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync }
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync ScmStreamWrite(pStrm, RT_STR_TUPLE("\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "#endif\n"
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync "\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "RT_C_DECLS_END\n"
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync "#endif\n"));
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTEXITCODE_SUCCESS;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE generateHeader(const char *pszHeader)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return generateFile(pszHeader, "header", generateHeaderInner);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync/**
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * If the given C word is at off - 1, return @c true and skip beyond it,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * otherwise return @c false.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync *
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 *
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param pStream The stream.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param cchWord The length of the word.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param pszWord The word.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync */
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsyncbool ScmStreamCMatchingWordM1(PSCMSTREAM pStream, const char *pszWord, size_t cchWord)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Check stream state. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync AssertReturn(!pStream->fWriteOrRead, false);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync AssertReturn(RT_SUCCESS(pStream->rc), false);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync AssertReturn(pStream->fFullyLineated, false);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Sufficient chars left on the line? */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync size_t const iLine = pStream->iLine;
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 if (cchWord > cchLeft)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return false;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Do they match? */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync const char *psz = &pStream->pch[pStream->off - 1];
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (memcmp(psz, pszWord, cchWord))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return false;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Is it the end of a C word? */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (cchWord < cchLeft)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync psz += cchWord;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (RT_C_IS_ALNUM(*psz) || *psz == '_')
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return false;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Skip ahead. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync pStream->off += cchWord - 1;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return true;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync/**
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Get's the C word starting at the current position.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync *
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.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncconst char *ScmStreamCGetWord(PSCMSTREAM pStream, size_t *pcchWord)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Check stream state. */
8f7ee9e453c60b3b699799538a45950b35266665vboxsync AssertReturn(!pStream->fWriteOrRead, NULL);
8f7ee9e453c60b3b699799538a45950b35266665vboxsync AssertReturn(RT_SUCCESS(pStream->rc), NULL);
8f7ee9e453c60b3b699799538a45950b35266665vboxsync AssertReturn(pStream->fFullyLineated, NULL);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Get the number of chars left on the line and locate the current char. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync size_t const iLine = pStream->iLine;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync size_t const cchLeft = pStream->paLines[iLine].cch + pStream->paLines[iLine].off - pStream->off;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync const char *psz = &pStream->pch[pStream->off];
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Is it a leading C character. */
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync if (!RT_C_IS_ALPHA(*psz) && *psz == '_')
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return NULL;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* Find the end of the word. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync char ch;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync size_t off = 1;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync while ( off < cchLeft
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync && ( (ch = psz[off]) == '_'
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync || RT_C_IS_ALNUM(ch)))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync off++;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync pStream->off += off;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync *pcchWord = off;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return psz;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync/**
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * Get's the C word starting at the current position minus one.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync *
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.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync */
88e56f700a3b8dfdf1646f96320f335e22339caavboxsyncconst char *ScmStreamCGetWordM1(PSCMSTREAM pStream, size_t *pcchWord)
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync{
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync /* Check stream state. */
8f7ee9e453c60b3b699799538a45950b35266665vboxsync AssertReturn(!pStream->fWriteOrRead, NULL);
8f7ee9e453c60b3b699799538a45950b35266665vboxsync AssertReturn(RT_SUCCESS(pStream->rc), NULL);
8f7ee9e453c60b3b699799538a45950b35266665vboxsync AssertReturn(pStream->fFullyLineated, NULL);
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync /* Get the number of chars left on the line and locate the current char. */
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync size_t const iLine = pStream->iLine;
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync size_t const cchLeft = pStream->paLines[iLine].cch + pStream->paLines[iLine].off - (pStream->off - 1);
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync const char *psz = &pStream->pch[pStream->off - 1];
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync /* Is it a leading C character. */
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync if (!RT_C_IS_ALPHA(*psz) && *psz == '_')
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync return NULL;
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync /* Find the end of the word. */
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync char ch;
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync size_t off = 1;
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync while ( off < cchLeft
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync && ( (ch = psz[off]) == '_'
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync || RT_C_IS_ALNUM(ch)))
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync off++;
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync pStream->off += off - 1;
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync *pcchWord = off;
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync return psz;
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync}
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync/**
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Parser error with line and position.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync *
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.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE parseError(PSCMSTREAM pStrm, size_t cb, const char *pszMsg)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (cb)
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync ScmStreamSeekRelative(pStrm, -(ssize_t)cb);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync size_t const off = ScmStreamTell(pStrm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync size_t const iLine = ScmStreamTellLine(pStrm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync ScmStreamSeekByLine(pStrm, iLine);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync size_t const offLine = ScmStreamTell(pStrm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync RTPrintf("%s:%d:%zd: error: %s.\n", g_pszScript, iLine + 1, off - offLine + 1, pszMsg);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync size_t cchLine;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync SCMEOL enmEof;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync const char *pszLine = ScmStreamGetLineByNo(pStrm, iLine, &cchLine, &enmEof);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (pszLine)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTPrintf(" %.*s\n"
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync " %*s^\n",
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync cchLine, pszLine, off - offLine, "");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTEXITCODE_FAILURE;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync/**
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync * Parser error with line and position.
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync *
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.
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync */
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsyncstatic RTEXITCODE parseErrorAbs(PSCMSTREAM pStrm, size_t off, const char *pszMsg)
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync{
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync ScmStreamSeekAbsolute(pStrm, off);
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync return parseError(pStrm, 0, pszMsg);
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync}
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync/**
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Handles a C++ one line comment.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync *
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @returns Exit code.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param pStrm The stream.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE parseOneLineComment(PSCMSTREAM pStrm)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync ScmStreamSeekByLine(pStrm, ScmStreamTellLine(pStrm) + 1);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTEXITCODE_SUCCESS;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync/**
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Handles a multi-line C/C++ comment.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync *
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @returns Exit code.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param pStrm The stream.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE parseMultiLineComment(PSCMSTREAM pStrm)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync unsigned ch;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync while ((ch = ScmStreamGetCh(pStrm)) != ~(unsigned)0)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (ch == '*')
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync do
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync ch = ScmStreamGetCh(pStrm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync while (ch == '*');
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (ch == '/')
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTEXITCODE_SUCCESS;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync parseError(pStrm, 1, "Expected end of comment, got end of file");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTEXITCODE_FAILURE;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync/**
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Skips spaces and comments.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync *
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param pStrm The stream..
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE parseSkipSpacesAndComments(PSCMSTREAM pStrm)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync unsigned ch;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync while ((ch = ScmStreamPeekCh(pStrm)) != ~(unsigned)0)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (!RT_C_IS_SPACE(ch) && ch != '/')
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTEXITCODE_SUCCESS;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync unsigned ch2 = ScmStreamGetCh(pStrm); AssertBreak(ch == ch2); NOREF(ch2);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (ch == '/')
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync ch = ScmStreamGetCh(pStrm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTEXITCODE rcExit;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (ch == '*')
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = parseMultiLineComment(pStrm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync else if (ch == '/')
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = parseOneLineComment(pStrm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync else
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = parseError(pStrm, 2, "Unexpected character");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (rcExit != RTEXITCODE_SUCCESS)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return rcExit;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return parseError(pStrm, 0, "Unexpected end of file");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync/**
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync * Skips spaces and comments, returning the next character.
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync *
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync * @returns Next non-space-non-comment character. ~(unsigned)0 on EOF or
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync * failure.
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync * @param pStrm The stream.
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync */
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsyncstatic unsigned parseGetNextNonSpaceNonCommentCh(PSCMSTREAM pStrm)
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync{
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync unsigned ch;
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync while ((ch = ScmStreamGetCh(pStrm)) != ~(unsigned)0)
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync {
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync if (!RT_C_IS_SPACE(ch) && ch != '/')
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync return ch;
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync if (ch == '/')
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync {
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync ch = ScmStreamGetCh(pStrm);
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync RTEXITCODE rcExit;
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync if (ch == '*')
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync rcExit = parseMultiLineComment(pStrm);
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync else if (ch == '/')
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync rcExit = parseOneLineComment(pStrm);
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync else
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync rcExit = parseError(pStrm, 2, "Unexpected character");
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync if (rcExit != RTEXITCODE_SUCCESS)
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync return ~(unsigned)0;
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync }
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync }
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync parseError(pStrm, 0, "Unexpected end of file");
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync return ~(unsigned)0;
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync}
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync/**
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Get the next non-space-non-comment character on a preprocessor line.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync *
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @returns The next character. On error message and ~(unsigned)0.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @param pStrm The stream.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync */
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsyncstatic unsigned parseGetNextNonSpaceNonCommentChOnPpLine(PSCMSTREAM pStrm)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync{
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync size_t off = ScmStreamTell(pStrm) - 1;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync unsigned ch;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync while ((ch = ScmStreamGetCh(pStrm)) != ~(unsigned)0)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync {
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (RT_C_IS_SPACE(ch))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync {
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch == '\n' || ch == '\r')
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync {
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync parseErrorAbs(pStrm, off, "Invalid preprocessor statement");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync break;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync }
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync }
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else if (ch == '\\')
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync {
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync size_t off2 = ScmStreamTell(pStrm) - 1;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync ch = ScmStreamGetCh(pStrm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch == '\r')
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync ch = ScmStreamGetCh(pStrm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch != '\n')
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync {
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync parseErrorAbs(pStrm, off2, "Expected new line");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync break;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync }
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync }
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return ch;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync }
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return ~(unsigned)0;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync}
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync/**
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * Skips spaces and comments.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync *
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * @returns Same as ScmStreamCGetWord
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * @param pStrm The stream..
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * @param pcchWord Where to return the length.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync */
88e56f700a3b8dfdf1646f96320f335e22339caavboxsyncstatic const char *parseGetNextCWord(PSCMSTREAM pStrm, size_t *pcchWord)
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync{
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync if (parseSkipSpacesAndComments(pStrm) != RTEXITCODE_SUCCESS)
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync return NULL;
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync return ScmStreamCGetWord(pStrm, pcchWord);
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync/**
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Parses interface stability.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync *
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.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync */
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsyncstatic kVTGStability parseStability(PSCMSTREAM pStrm, unsigned ch)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync{
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync switch (ch)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync {
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync case 'E':
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("External")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return kVTGStability_External;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Evolving")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return kVTGStability_Evolving;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync break;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync case 'I':
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Internal")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return kVTGStability_Internal;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync break;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync case 'O':
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Obsolete")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return kVTGStability_Obsolete;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync break;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync case 'P':
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Private")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return kVTGStability_Private;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync break;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync case 'S':
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Stable")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return kVTGStability_Stable;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Standard")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return kVTGStability_Standard;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync break;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync case 'U':
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Unstable")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return kVTGStability_Unstable;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync break;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync }
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync parseError(pStrm, 1, "Unknown stability specifier");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return kVTGStability_Invalid;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync}
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync/**
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Parses data depndency class.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync *
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.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync */
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsyncstatic kVTGClass parseDataDepClass(PSCMSTREAM pStrm, unsigned ch)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync{
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync switch (ch)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync {
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync case 'C':
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Common")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return kVTGClass_Common;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Cpu")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return kVTGClass_Cpu;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync break;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync case 'G':
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Group")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return kVTGClass_Group;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync break;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync case 'I':
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Isa")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return kVTGClass_Isa;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync break;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync case 'P':
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Platform")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return kVTGClass_Platform;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync break;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync case 'U':
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("Unknown")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return kVTGClass_Unknown;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync break;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync }
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync parseError(pStrm, 1, "Unknown data dependency class specifier");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return kVTGClass_Invalid;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync}
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync/**
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Parses a pragma D attributes statement.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync *
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @returns Suitable exit code, errors message already written on failure.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @param pStrm The stream.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync */
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsyncstatic RTEXITCODE parsePragmaDAttributes(PSCMSTREAM pStrm)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync{
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync /*
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * "CodeStability/DataStability/DataDepClass" - no spaces allowed.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync */
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync unsigned ch = parseGetNextNonSpaceNonCommentChOnPpLine(pStrm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch == ~(unsigned)0)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return RTEXITCODE_FAILURE;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync kVTGStability enmCode = parseStability(pStrm, ch);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (enmCode == kVTGStability_Invalid)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return RTEXITCODE_FAILURE;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync ch = ScmStreamGetCh(pStrm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch != '/')
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 1, "Expected '/' following the code stability specifier");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync kVTGStability enmData = parseStability(pStrm, ScmStreamGetCh(pStrm));
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (enmData == kVTGStability_Invalid)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return RTEXITCODE_FAILURE;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync ch = ScmStreamGetCh(pStrm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch != '/')
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 1, "Expected '/' following the data stability specifier");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync kVTGClass enmDataDep = parseDataDepClass(pStrm, ScmStreamGetCh(pStrm));
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (enmDataDep == kVTGClass_Invalid)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return RTEXITCODE_FAILURE;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync /*
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Expecting 'provider' followed by the name of an provider defined earlier.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync */
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync ch = parseGetNextNonSpaceNonCommentChOnPpLine(pStrm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch == ~(unsigned)0)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return RTEXITCODE_FAILURE;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch != 'p' || !ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("provider")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 1, "Expected 'provider'");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync size_t cchName;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync const char *pszName = parseGetNextCWord(pStrm, &cchName);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (!pszName)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 1, "Expected provider name");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync PVTGPROVIDER pProv;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync RTListForEach(&g_ProviderHead, pProv, VTGPROVIDER, ListEntry)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync {
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if ( !strncmp(pProv->pszName, pszName, cchName)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync && pProv->pszName[cchName] == '\0')
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync break;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync }
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync if (RTListNodeIsDummy(&g_ProviderHead, pProv, VTGPROVIDER, ListEntry))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, cchName, "Provider not found");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync /*
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Which aspect of the provider?
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync */
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync size_t cchAspect;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync const char *pszAspect = parseGetNextCWord(pStrm, &cchAspect);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (!pszAspect)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 1, "Expected provider aspect");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync PVTGATTRS pAttrs;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (cchAspect == 8 && !memcmp(pszAspect, "provider", 8))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync pAttrs = &pProv->AttrSelf;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else if (cchAspect == 8 && !memcmp(pszAspect, "function", 8))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync pAttrs = &pProv->AttrFunctions;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else if (cchAspect == 6 && !memcmp(pszAspect, "module", 6))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync pAttrs = &pProv->AttrModules;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else if (cchAspect == 4 && !memcmp(pszAspect, "name", 4))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync pAttrs = &pProv->AttrName;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else if (cchAspect == 4 && !memcmp(pszAspect, "args", 4))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync pAttrs = &pProv->AttrArguments;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, cchAspect, "Unknown aspect");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (pAttrs->enmCode != kVTGStability_Invalid)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, cchAspect, "You have already specified these attributes");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync pAttrs->enmCode = enmCode;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync pAttrs->enmData = enmData;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync pAttrs->enmDataDep = enmDataDep;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return RTEXITCODE_SUCCESS;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync}
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync/**
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Parses a D pragma statement.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync *
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @returns Suitable exit code, errors message already written on failure.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @param pStrm The stream.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync */
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsyncstatic RTEXITCODE parsePragma(PSCMSTREAM pStrm)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync{
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync RTEXITCODE rcExit;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync unsigned ch = parseGetNextNonSpaceNonCommentChOnPpLine(pStrm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch == ~(unsigned)0)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync rcExit = RTEXITCODE_FAILURE;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else if (ch == 'D' && ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("D")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync {
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync ch = parseGetNextNonSpaceNonCommentChOnPpLine(pStrm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch == ~(unsigned)0)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync rcExit = RTEXITCODE_FAILURE;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else if (ch == 'a' && ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("attributes")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync rcExit = parsePragmaDAttributes(pStrm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync rcExit = parseError(pStrm, 1, "Unknown pragma D");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync }
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync rcExit = parseError(pStrm, 1, "Unknown pragma");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return rcExit;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync}
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync/**
8f7ee9e453c60b3b699799538a45950b35266665vboxsync * Unmangles the probe name.
8f7ee9e453c60b3b699799538a45950b35266665vboxsync *
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync * This involves translating double underscore to dash.
8f7ee9e453c60b3b699799538a45950b35266665vboxsync *
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync * @returns Pointer to the unmangled name in the string table.
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync * @param pszMangled The mangled name.
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync */
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsyncstatic const char *parseUnmangleProbeName(const char *pszMangled)
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync{
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync size_t cchMangled = strlen(pszMangled);
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync char *pszTmp = (char *)alloca(cchMangled + 2);
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync const char *pszSrc = pszMangled;
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync char *pszDst = pszTmp;
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync while (*pszSrc)
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync {
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync if (pszSrc[0] == '_' && pszSrc[1] == '_' && pszSrc[2] != '_')
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync {
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync *pszDst++ = '-';
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync pszSrc += 2;
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync }
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync else
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync *pszDst++ = *pszSrc++;
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync }
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync *pszDst = '\0';
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync return strtabInsertN(pszTmp, pszDst - pszTmp);
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync}
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync/**
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * Parses a D probe statement.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync *
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * @returns Suitable exit code, errors message already written on failure.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * @param pStrm The stream.
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * @param pProv The provider being parsed.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync */
88e56f700a3b8dfdf1646f96320f335e22339caavboxsyncstatic RTEXITCODE parseProbe(PSCMSTREAM pStrm, PVTGPROVIDER pProv)
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync{
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync /*
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * Next up is a name followed by an opening parenthesis.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync */
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync size_t cchProbe;
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync const char *pszProbe = parseGetNextCWord(pStrm, &cchProbe);
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync if (!pszProbe)
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync return parseError(pStrm, 1, "Expected a probe name starting with an alphabetical character");
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync unsigned ch = parseGetNextNonSpaceNonCommentCh(pStrm);
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync if (ch != '(')
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync return parseError(pStrm, 1, "Expected '(' after the probe name");
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync /*
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * Create a probe instance.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync */
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync PVTGPROBE pProbe = (PVTGPROBE)RTMemAllocZ(sizeof(*pProbe));
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync if (!pProbe)
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync return parseError(pStrm, 0, "Out of memory");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync RTListInit(&pProbe->ArgHead);
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync RTListAppend(&pProv->ProbeHead, &pProbe->ListEntry);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync pProbe->offArgList = UINT32_MAX;
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync pProbe->pszMangledName = RTStrDupN(pszProbe, cchProbe);
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync if (!pProbe->pszMangledName)
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync return parseError(pStrm, 0, "Out of memory");
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync pProbe->pszUnmangledName = parseUnmangleProbeName(pProbe->pszMangledName);
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync if (!pProbe->pszUnmangledName)
fdb40b7d2efa84fc6f03b7a695cb4b2e035c30c7vboxsync return parseError(pStrm, 0, "Out of memory");
8f7ee9e453c60b3b699799538a45950b35266665vboxsync
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync /*
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync * Parse loop for the argument.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync */
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync PVTGARG pArg = NULL;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync size_t cchName = 0;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync size_t cchArg = 0;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync char szArg[4096];
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync for (;;)
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync {
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync ch = parseGetNextNonSpaceNonCommentCh(pStrm);
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync switch (ch)
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync {
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync case ')':
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync case ',':
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync {
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync /* commit the argument */
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (pArg)
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync {
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (!cchName)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 1, "Argument has no name");
9c9db71d639cf066ed41d49629d46d48bff4be2fvboxsync if (cchArg - cchName - 1 >= 128)
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);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync if (!pArg->pszType || !pArg->pszName)
0c94a8282c9042b02f022302a3d987746140eab9vboxsync return parseError(pStrm, 1, "Out of memory");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync pArg = NULL;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync cchName = cchArg = 0;
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync }
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch == ')')
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync {
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync size_t off = ScmStreamTell(pStrm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync ch = parseGetNextNonSpaceNonCommentCh(pStrm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch != ';')
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseErrorAbs(pStrm, off, "Expected ';'");
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync return RTEXITCODE_SUCCESS;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync }
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync break;
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync }
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync default:
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync {
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync size_t cchWord;
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync const char *pszWord = ScmStreamCGetWordM1(pStrm, &cchWord);
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync if (!pszWord)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 0, "Expected argument");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (!pArg)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync {
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync pArg = (PVTGARG)RTMemAllocZ(sizeof(*pArg));
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (!pArg)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 1, "Out of memory");
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync RTListAppend(&pProbe->ArgHead, &pArg->ListEntry);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync pProbe->cArgs++;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync if (cchWord + 1 > sizeof(szArg))
0c94a8282c9042b02f022302a3d987746140eab9vboxsync return parseError(pStrm, 1, "Too long parameter declaration");
0c94a8282c9042b02f022302a3d987746140eab9vboxsync memcpy(szArg, pszWord, cchWord);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync szArg[cchWord] = '\0';
0c94a8282c9042b02f022302a3d987746140eab9vboxsync cchArg = cchWord;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync cchName = 0;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync }
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync else
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync {
0c94a8282c9042b02f022302a3d987746140eab9vboxsync if (cchArg + 1 + cchWord + 1 > sizeof(szArg))
0c94a8282c9042b02f022302a3d987746140eab9vboxsync return parseError(pStrm, 1, "Too long parameter declaration");
0c94a8282c9042b02f022302a3d987746140eab9vboxsync
0c94a8282c9042b02f022302a3d987746140eab9vboxsync szArg[cchArg++] = ' ';
0c94a8282c9042b02f022302a3d987746140eab9vboxsync memcpy(&szArg[cchArg], pszWord, cchWord);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync cchArg += cchWord;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync szArg[cchArg] = '\0';
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync cchName = cchWord;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync }
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync break;
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync }
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync case '*':
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync {
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (!pArg)
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 1, "A parameter type does not start with an asterix");
0c94a8282c9042b02f022302a3d987746140eab9vboxsync if (cchArg + sizeof(" *") >= sizeof(szArg))
0c94a8282c9042b02f022302a3d987746140eab9vboxsync return parseError(pStrm, 1, "Too long parameter declaration");
0c94a8282c9042b02f022302a3d987746140eab9vboxsync szArg[cchArg++] = ' ';
0c94a8282c9042b02f022302a3d987746140eab9vboxsync szArg[cchArg++] = '*';
0c94a8282c9042b02f022302a3d987746140eab9vboxsync szArg[cchArg ] = '\0';
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync cchName = 0;
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync break;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync }
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync case ~(unsigned)0:
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync return parseError(pStrm, 0, "Missing closing ')' on probe");
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync }
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync }
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync}
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync/**
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * Parses a D provider statement.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync *
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * @returns Suitable exit code, errors message already written on failure.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * @param pStrm The stream.
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE parseProvider(PSCMSTREAM pStrm)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /*
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync * Next up is a name followed by a curly bracket. Ignore comments.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTEXITCODE rcExit = parseSkipSpacesAndComments(pStrm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (rcExit != RTEXITCODE_SUCCESS)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return parseError(pStrm, 1, "Expected a provider name starting with an alphabetical character");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync size_t cchName;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync const char *pszName = ScmStreamCGetWord(pStrm, &cchName);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (!pszName)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return parseError(pStrm, 0, "Bad provider name");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (RT_C_IS_DIGIT(pszName[cchName - 1]))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return parseError(pStrm, 1, "A provider name cannot end with digit");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync unsigned ch = parseGetNextNonSpaceNonCommentCh(pStrm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (ch != '{')
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return parseError(pStrm, 1, "Expected '{' after the provider name");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /*
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Create a provider instance.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync PVTGPROVIDER pProv = (PVTGPROVIDER)RTMemAllocZ(sizeof(*pProv));
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (!pProv)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return parseError(pStrm, 0, "Out of memory");
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync RTListInit(&pProv->ProbeHead);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTListAppend(&g_ProviderHead, &pProv->ListEntry);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync pProv->pszName = strtabInsertN(pszName, cchName);
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync if (!pProv->pszName)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return parseError(pStrm, 0, "Out of memory");
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync /*
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync * Parse loop.
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync */
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync for (;;)
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync {
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync ch = parseGetNextNonSpaceNonCommentCh(pStrm);
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync switch (ch)
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync {
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync case 'p':
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync if (ScmStreamCMatchingWordM1(pStrm, RT_STR_TUPLE("probe")))
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync rcExit = parseProbe(pStrm, pProv);
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync else
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync rcExit = parseError(pStrm, 1, "Unexpected character");
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync break;
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync case '}':
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync {
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync size_t off = ScmStreamTell(pStrm);
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync ch = parseGetNextNonSpaceNonCommentCh(pStrm);
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync if (ch == ';')
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync return RTEXITCODE_SUCCESS;
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync rcExit = parseErrorAbs(pStrm, off, "Expected ';'");
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync break;
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync case ~(unsigned)0:
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync rcExit = parseError(pStrm, 0, "Missing closing '}' on provider");
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync break;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync default:
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync rcExit = parseError(pStrm, 1, "Unexpected character");
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync break;
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync }
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync if (rcExit != RTEXITCODE_SUCCESS)
88e56f700a3b8dfdf1646f96320f335e22339caavboxsync return rcExit;
49a6b09abb20015b0af3e618a1f92b7e26785e90vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE parseScript(const char *pszScript)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync SCMSTREAM Strm;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync int rc = ScmStreamInitForReading(&Strm, pszScript);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (RT_FAILURE(rc))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to open & read '%s' into memory: %Rrc", pszScript, rc);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (g_cVerbosity > 0)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTMsgInfo("Parsing '%s'...", pszScript);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync unsigned ch;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync while ((ch = ScmStreamGetCh(&Strm)) != ~(unsigned)0)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (RT_C_IS_SPACE(ch))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync continue;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync switch (ch)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync case '/':
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync ch = ScmStreamGetCh(&Strm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (ch == '*')
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = parseMultiLineComment(&Strm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync else if (ch == '/')
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = parseOneLineComment(&Strm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync else
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = parseError(&Strm, 2, "Unexpected character");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync case 'p':
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (ScmStreamCMatchingWordM1(&Strm, RT_STR_TUPLE("provider")))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = parseProvider(&Strm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync else
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = parseError(&Strm, 1, "Unexpected character");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync case '#':
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync {
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync ch = parseGetNextNonSpaceNonCommentChOnPpLine(&Strm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync if (ch == ~(unsigned)0)
38745c55f37c31ba8b78cc728d2f08ea6eec38d6vboxsync rcExit = RTEXITCODE_FAILURE;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else if (ch == 'p' && ScmStreamCMatchingWordM1(&Strm, RT_STR_TUPLE("pragma")))
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync rcExit = parsePragma(&Strm);
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync else
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync rcExit = parseError(&Strm, 1, "Unsupported preprocessor directive");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
5c4d7e2aae42bbf39793dfa686925f076a56b4d5vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync default:
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync rcExit = parseError(&Strm, 1, "Unexpected character");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (rcExit != RTEXITCODE_SUCCESS)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return rcExit;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync ScmStreamDelete(&Strm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (g_cVerbosity > 0 && rcExit == RTEXITCODE_SUCCESS)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTMsgInfo("Successfully parsed '%s'.", pszScript);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return rcExit;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync/**
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Parses the arguments.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncstatic RTEXITCODE parseArguments(int argc, char **argv)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /*
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Set / Adjust defaults.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync */
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync int rc = RTPathAbs(g_pszAssemblerIncVal, g_szAssemblerIncVal, sizeof(g_szAssemblerIncVal) - 1);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync if (RT_FAILURE(rc))
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPathAbs failed: %Rrc", rc);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync strcat(g_szAssemblerIncVal, "/");
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync g_pszAssemblerIncVal = g_szAssemblerIncVal;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /*
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Option config.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync enum
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync kVBoxTpGOpt_32Bit = 1000,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync kVBoxTpGOpt_64Bit,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync kVBoxTpGOpt_Assembler,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync kVBoxTpGOpt_AssemblerFmtOpt,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync kVBoxTpGOpt_AssemblerFmtVal,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync kVBoxTpGOpt_AssemblerOutputOpt,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync kVBoxTpGOpt_AssemblerOption,
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync kVBoxTpGOpt_ProbeFnName,
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync kVBoxTpGOpt_ProbeFnImported,
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync kVBoxTpGOpt_End
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync };
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync static RTGETOPTDEF const s_aOpts[] =
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* dtrace w/ long options */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync { "-32", kVBoxTpGOpt_32Bit, RTGETOPT_REQ_NOTHING },
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync { "-64", kVBoxTpGOpt_64Bit, RTGETOPT_REQ_NOTHING },
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync { "--apply-cpp", 'C', RTGETOPT_REQ_NOTHING },
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync { "--generate-obj", 'G', RTGETOPT_REQ_NOTHING },
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync { "--generate-header", 'h', RTGETOPT_REQ_NOTHING },
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync { "--output", 'o', RTGETOPT_REQ_STRING },
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync { "--script", 's', RTGETOPT_REQ_STRING },
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync { "--verbose", 'v', 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 },
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync };
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync RTGETOPTUNION ValueUnion;
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync RTGETOPTSTATE GetOptState;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync rc = RTGetOptInit(&GetOptState, argc, argv, &s_aOpts[0], RT_ELEMENTS(s_aOpts), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync AssertReleaseRCReturn(rc, RTEXITCODE_FAILURE);
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync /*
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Process \the options.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync */
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync while ((rc = RTGetOpt(&GetOptState, &ValueUnion)) != 0)
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync {
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync switch (rc)
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /*
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * DTrace compatible options.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync case kVBoxTpGOpt_32Bit:
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync g_cBits = 32;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync g_pszAssemblerFmtVal = g_szAssemblerFmtVal32;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync case kVBoxTpGOpt_64Bit:
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync g_cBits = 64;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync g_pszAssemblerFmtVal = g_szAssemblerFmtVal64;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync case 'C':
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync g_fApplyCpp = true;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTMsgWarning("Ignoring the -C option - no preprocessing of the D script will be performed");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync case 'G':
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if ( g_enmAction != kVBoxTpGAction_Nothing
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync && g_enmAction != kVBoxTpGAction_GenerateObject)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "-G and -h does not mix");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync g_enmAction = kVBoxTpGAction_GenerateObject;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync case 'h':
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (!strcmp(GetOptState.pDef->pszLong, "--generate-header"))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if ( g_enmAction != kVBoxTpGAction_Nothing
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync && g_enmAction != kVBoxTpGAction_GenerateHeader)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "-h and -G does not mix");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync g_enmAction = kVBoxTpGAction_GenerateHeader;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync else
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /* --help or similar */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTPrintf("VirtualBox Tracepoint Generator\n"
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync "\n"
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync "Usage: %s [options]\n"
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync "\n"
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync "Options:\n", RTProcShortName());
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync for (size_t i = 0; i < RT_ELEMENTS(s_aOpts); i++)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if ((unsigned)s_aOpts[i].iShort < 128)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTPrintf(" -%c,%s\n", s_aOpts[i].iShort, s_aOpts[i].pszLong);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync else
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTPrintf(" %s\n", s_aOpts[i].pszLong);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTEXITCODE_SUCCESS;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync case 'o':
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (g_pszOutput)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Output file is already set to '%s'", g_pszOutput);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync g_pszOutput = ValueUnion.psz;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync case 's':
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (g_pszScript)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Script file is already set to '%s'", g_pszScript);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync g_pszScript = ValueUnion.psz;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync case 'v':
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync g_cVerbosity++;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync case 'V':
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync {
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync /* The following is assuming that svn does it's job here. */
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync static const char s_szRev[] = "$Revision$";
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync const char *psz = RTStrStripL(strchr(s_szRev, ' '));
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync RTPrintf("r%.*s\n", strchr(psz, ' ') - psz, psz);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTEXITCODE_SUCCESS;
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync }
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync case VINF_GETOPT_NOT_OPTION:
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (g_enmAction == kVBoxTpGAction_GenerateObject)
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync break; /* object files, ignore them. */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTGetOptPrintError(rc, &ValueUnion);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /*
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync * Our options.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync case kVBoxTpGOpt_Assembler:
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync g_pszAssembler = ValueUnion.psz;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync case kVBoxTpGOpt_AssemblerFmtOpt:
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync g_pszAssemblerFmtOpt = ValueUnion.psz;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync case kVBoxTpGOpt_AssemblerFmtVal:
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync g_pszAssemblerFmtVal = ValueUnion.psz;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync case kVBoxTpGOpt_AssemblerOutputOpt:
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync g_pszAssemblerOutputOpt = ValueUnion.psz;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync case kVBoxTpGOpt_AssemblerOption:
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 g_cAssemblerOptions++;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync break;
9c9db71d639cf066ed41d49629d46d48bff4be2fvboxsync
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync case kVBoxTpGOpt_ProbeFnName:
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync g_pszProbeFnName = ValueUnion.psz;
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync break;
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync case kVBoxTpGOpt_ProbeFnImported:
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync g_pszProbeFnName = ValueUnion.psz;
44372afb953dc9f1f1ec71943f5f561a607c0307vboxsync break;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /*
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Errors and bugs.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync */
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync default:
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync return RTGetOptPrintError(rc, &ValueUnion);
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync }
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync }
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /*
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Check that we've got all we need.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync */
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (g_enmAction == kVBoxTpGAction_Nothing)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No action specified (-h or -G)");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (!g_pszScript)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No script file specified (-s)");
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (!g_pszOutput)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No output file specified (-o)");
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return RTEXITCODE_SUCCESS;
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsyncint main(int argc, char **argv)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync{
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync int rc = RTR3InitExe(argc, &argv, 0);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (RT_FAILURE(rc))
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return 1;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync RTEXITCODE rcExit = parseArguments(argc, argv);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync if (rcExit == RTEXITCODE_SUCCESS)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync /*
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Parse the script.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync */
0c94a8282c9042b02f022302a3d987746140eab9vboxsync RTListInit(&g_ProviderHead);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync rcExit = parseScript(g_pszScript);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync if (rcExit == RTEXITCODE_SUCCESS)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync {
0c94a8282c9042b02f022302a3d987746140eab9vboxsync /*
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * Take action.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync */
0c94a8282c9042b02f022302a3d987746140eab9vboxsync if (g_enmAction == kVBoxTpGAction_GenerateHeader)
0c94a8282c9042b02f022302a3d987746140eab9vboxsync rcExit = generateHeader(g_pszOutput);
0c94a8282c9042b02f022302a3d987746140eab9vboxsync else
0c94a8282c9042b02f022302a3d987746140eab9vboxsync rcExit = generateObject(g_pszOutput, g_pszTempAsm);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync }
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return rcExit;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync}
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync