VirtualBox

Changeset 40572 in vbox for trunk


Ignore:
Timestamp:
Mar 22, 2012 2:17:39 AM (13 years ago)
Author:
vboxsync
Message:

Almost there... :-)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bldprogs/VBoxTpG.cpp

    r40570 r40572  
    104104    RTLISTNODE      ListEntry;
    105105    const char     *pszName;
     106
     107    uint16_t        iFirstProbe;
     108    uint16_t        cProbes;
    106109
    107110    VTGATTRS        AttrSelf;
     
    232235
    233236
     237/**
     238 * Invokes the assembler.
     239 *
     240 * @returns Exit code.
     241 * @param   pszOutput           The output file.
     242 * @param   pszTempAsm          The source file.
     243 */
    234244static RTEXITCODE generateInvokeAssembler(const char *pszOutput, const char *pszTempAsm)
    235245{
     
    297307    if (Status.enmReason == RTPROCEXITREASON_SIGNAL)
    298308        return RTMsgErrorExit(RTEXITCODE_FAILURE, "The assembler failed: signal %d", Status.iStatus);
    299     if (Status.enmReason == RTPROCEXITREASON_ABEND)
     309    if (Status.enmReason != RTPROCEXITREASON_NORMAL)
    300310        return RTMsgErrorExit(RTEXITCODE_FAILURE, "The assembler failed: abend");
    301     if (   Status.enmReason != RTPROCEXITREASON_NORMAL
    302         || Status.iStatus != 0)
    303         return RTMsgErrorExit(RTEXITCODE_FAILURE, "The assembler failed: exit code %d", Status.iStatus);
     311    if (Status.iStatus != 0)
     312        return RTMsgErrorExit((RTEXITCODE)Status.iStatus, "The assembler failed: exit code %d", Status.iStatus);
    304313
    305314    return RTEXITCODE_SUCCESS;
     
    307316
    308317
     318/**
     319 * Worker that does the boring bits when generating a file.
     320 *
     321 * @returns Exit code.
     322 * @param   pszOutput           The name of the output file.
     323 * @param   pszWhat             What kind of file it is.
     324 * @param   pfnGenerator        The callback function that provides the contents
     325 *                              of the file.
     326 */
    309327static RTEXITCODE generateFile(const char *pszOutput, const char *pszWhat,
    310328                               RTEXITCODE (*pfnGenerator)(PSCMSTREAM))
     
    347365}
    348366
     367
     368/**
     369 * Formats a string and writes it to the SCM stream.
     370 *
     371 * @returns The number of bytes written (>= 0). Negative value are IPRT error
     372 *          status codes.
     373 * @param   pStream             The stream to write to.
     374 * @param   pszFormat           The format string.
     375 * @param   va                  The arguments to format.
     376 */
    349377static ssize_t ScmStreamPrintfV(PSCMSTREAM pStream, const char *pszFormat, va_list va)
    350378{
     
    361389}
    362390
     391
     392/**
     393 * Formats a string and writes it to the SCM stream.
     394 *
     395 * @returns The number of bytes written (>= 0). Negative value are IPRT error
     396 *          status codes.
     397 * @param   pStream             The stream to write to.
     398 * @param   pszFormat           The format string.
     399 * @param   ...                 The arguments to format.
     400 */
    363401static ssize_t ScmStreamPrintf(PSCMSTREAM pStream, const char *pszFormat, ...)
    364402{
     
    389427
    390428
     429/**
     430 * Generate assembly source that can be turned into an object file.
     431 *
     432 * (This is a generateFile callback.)
     433 *
     434 * @returns Exit code.
     435 * @param   pStrm               The output stream.
     436 */
    391437static RTEXITCODE generateAssembly(PSCMSTREAM pStrm)
    392438{
     439    PVTGPROVIDER    pProvider;
     440    PVTGPROBE       pProbe;
     441    PVTGARG         pArg;
     442
     443
    393444    if (g_cVerbosity > 0)
    394445        RTMsgInfo("Generating assembly code...");
     
    452503                    "GLOBALNAME g_afVTGProbeEnabled\n"
    453504                    );
    454     PVTGPROVIDER pProv;
    455     RTListForEach(&g_ProviderHead, pProv, VTGPROVIDER, ListEntry)
    456     {
    457         PVTGPROBE pProbe;
    458         RTListForEach(&pProv->ProbeHead, pProbe, VTGPROBE, ListEntry)
     505    uint32_t        cProbes = 0;
     506    RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
     507    {
     508        RTListForEach(&pProvider->ProbeHead, pProbe, VTGPROBE, ListEntry)
    459509        {
    460510            ScmStreamPrintf(pStrm,
    461511                            "GLOBALNAME g_fVTGProbeEnabled_%s_%s\n"
    462512                            "    db 0\n",
    463                             pProv->pszName, pProbe->pszName);
     513                            pProvider->pszName, pProbe->pszName);
     514            cProbes++;
    464515        }
    465516    }
    466517    ScmStreamPrintf(pStrm, "GLOBALNAME g_afVTGProbeEnabled_End\n");
     518    if (cProbes >= _32K)
     519        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Too many probes: %u (max %u)", cProbes, _32K - 1);
    467520
    468521    /*
     
    470523     */
    471524    ScmStreamPrintf(pStrm,
     525                    "\n"
    472526                    ";\n"
    473527                    "; The string table.\n"
     
    483537     */
    484538    ScmStreamPrintf(pStrm,
     539                    "\n"
    485540                    ";\n"
    486541                    "; The argument lists.\n"
     
    488543                    "GLOBALNAME g_aVTGArgLists\n");
    489544    uint32_t off = 0;
    490     RTListForEach(&g_ProviderHead, pProv, VTGPROVIDER, ListEntry)
    491     {
    492         PVTGPROBE pProbe;
    493         RTListForEach(&pProv->ProbeHead, pProbe, VTGPROBE, ListEntry)
     545    RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
     546    {
     547        RTListForEach(&pProvider->ProbeHead, pProbe, VTGPROBE, ListEntry)
    494548        {
    495549            if (pProbe->offArgList != UINT32_MAX)
     
    504558                            , off, pProbe->cArgs);
    505559            off += 4;
    506             PVTGARG pArg;
    507560            RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
    508561            {
     
    520573            {
    521574                PVTGPROBE pProbe2;
    522                 RTListForEach(&pProv->ProbeHead, pProbe2, VTGPROBE, ListEntry)
     575                RTListForEach(&pProvider->ProbeHead, pProbe2, VTGPROBE, ListEntry)
    523576                {
    524577                    if (pProbe2->offArgList != UINT32_MAX)
     
    550603
    551604    /*
    552      * Probe definitions..
     605     * Probe definitions.
    553606     */
    554607    ScmStreamPrintf(pStrm,
     
    559612                    "GLOBALNAME g_aVTGProbes\n"
    560613                    "\n");
     614    uint32_t iProvider = 0;
    561615    uint32_t iProbe = 0;
    562     RTListForEach(&g_ProviderHead, pProv, VTGPROVIDER, ListEntry)
    563     {
    564         PVTGPROBE pProbe;
    565         RTListForEach(&pProv->ProbeHead, pProbe, VTGPROBE, ListEntry)
     616    RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
     617    {
     618        pProvider->iFirstProbe = iProbe;
     619        RTListForEach(&pProvider->ProbeHead, pProbe, VTGPROBE, ListEntry)
    566620        {
    567621            ScmStreamPrintf(pStrm,
    568                             "    ; idx=#%4u - %s::%s\n "
     622                            "GLOBALNAME g_VTGProbeData_%s_%s ; idx=#%4u\n"
    569623                            "    dd %6u  ; name\n"
    570                             "    dd %6u  ; provider index\n"
    571624                            "    dd %6u  ; Argument list offset\n"
    572                             "    dd g_fVTGProbeEnabled_%s_%s - g_afVTGProbeEnabled\n"
     625                            "    dw g_fVTGProbeEnabled_%s_%s - g_afVTGProbeEnabled\n"
     626                            "    dw %6u  ; provider index\n"
    573627                            ,
    574                             iProbe, pProv->pszName, pProbe->pszName,
     628                            pProvider->pszName, pProbe->pszName, iProbe,
    575629                            strtabGetOff(pProbe->pszName),
    576                             0 /** @todo provider index */,
    577630                            pProbe->offArgList,
    578                             pProv->pszName, pProbe->pszName);
     631                            pProvider->pszName, pProbe->pszName,
     632                            iProvider);
    579633            pProbe->iProbe = iProbe;
    580634            iProbe++;
    581635        }
     636        pProvider->cProbes = iProbe - pProvider->iFirstProbe;
     637        iProvider++;
    582638    }
    583639    ScmStreamPrintf(pStrm, "GLOBALNAME g_aVTGProbes_End\n");
     
    591647                    "; Provider data.\n"
    592648                    ";\n"
    593                     "GLOBALNAME g_aVTGProviders\n"
    594                     "\n");
    595     uint32_t iProvider = 0;
    596     RTListForEach(&g_ProviderHead, pProv, VTGPROVIDER, ListEntry)
     649                    "GLOBALNAME g_aVTGProviders\n");
     650    iProvider = 0;
     651    RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
    597652    {
    598653        ScmStreamPrintf(pStrm,
    599                         "    ; idx=#%4u - %s\n "
     654                        "    ; idx=#%4u - %s\n"
    600655                        "    dd %6u  ; name\n"
    601                         "    dd %6u  ; index of first probe\n"
    602                         "    dd %6u  ; index of last probe\n"
    603                         "    db 0, 0, 0  ; AttrSelf\n"
    604                         "    db 0, 0, 0  ; AttrModules\n"
    605                         "    db 0, 0, 0  ; AttrFunctions\n"
    606                         "    db 0, 0, 0  ; AttrName\n"
    607                         "    db 0, 0, 0  ; AttrArguments\n"
     656                        "    dw %6u  ; index of first probe\n"
     657                        "    dw %6u  ; count of probes\n"
     658                        "    db %d, %d, %d ; AttrSelf\n"
     659                        "    db %d, %d, %d ; AttrModules\n"
     660                        "    db %d, %d, %d ; AttrFunctions\n"
     661                        "    db %d, %d, %d ; AttrName\n"
     662                        "    db %d, %d, %d ; AttrArguments\n"
     663                        "    db 0       ; reserved\n"
    608664                        ,
    609                         iProvider, pProv->pszName,
    610                         strtabGetOff(pProv->pszName),
    611                         0 /** @todo probe index */,
    612                         0 /** @todo probe index */
    613                         /** @todo attributes */);
     665                        iProvider, pProvider->pszName,
     666                        strtabGetOff(pProvider->pszName),
     667                        pProvider->iFirstProbe,
     668                        pProvider->cProbes,
     669                        pProvider->AttrSelf.enmCode,        pProvider->AttrSelf.enmData,        pProvider->AttrSelf.enmDataDep,
     670                        pProvider->AttrModules.enmCode,     pProvider->AttrModules.enmData,     pProvider->AttrModules.enmDataDep,
     671                        pProvider->AttrFunctions.enmCode,   pProvider->AttrFunctions.enmData,   pProvider->AttrFunctions.enmDataDep,
     672                        pProvider->AttrName.enmCode,        pProvider->AttrName.enmData,        pProvider->AttrName.enmDataDep,
     673                        pProvider->AttrArguments.enmCode,   pProvider->AttrArguments.enmData,   pProvider->AttrArguments.enmDataDep);
    614674        iProvider++;
    615675    }
     
    619679     * Emit code for the stub functions.
    620680     */
     681    ScmStreamPrintf(pStrm,
     682                    "\n"
     683                    ";\n"
     684                    "; Prob stubs.\n"
     685                    ";\n"
     686                    "BEGINCODE\n"
     687                    "extern IMPNAME(SUPR0FireProbe)\n" /** @todo VBoxDrv may eventually need special handling wrt importing. */
     688                    );
     689    RTListForEach(&g_ProviderHead, pProvider, VTGPROVIDER, ListEntry)
     690    {
     691        RTListForEach(&pProvider->ProbeHead, pProbe, VTGPROBE, ListEntry)
     692        {
     693            ScmStreamPrintf(pStrm,
     694                            "\n"
     695                            "GLOBALNAME VTGProbeStub_%s_%s ; (VBOXTPGPROBELOC pVTGProbeLoc",
     696                            pProvider->pszName, pProbe->pszName);
     697            RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
     698            {
     699                ScmStreamPrintf(pStrm, ", %s %s", pArg->pszType, pArg->pszName);
     700            }
     701            ScmStreamPrintf(pStrm,
     702                            ");\n");
     703
     704            bool const fWin64   = g_cBits == 64 && (!strcmp(g_pszAssemblerFmtVal, "win64") || !strcmp(g_pszAssemblerFmtVal, "pe64"));
     705            bool const fMachO32 = g_cBits == 32 && !strcmp(g_pszAssemblerFmtVal, "macho32");
     706
     707            /*
     708             * Check if the probe in question is enabled.
     709             */
     710            if (g_cBits == 32)
     711                ScmStreamPrintf(pStrm,
     712                                "        mov     eax, [esp + 4]\n"
     713                                "        test    byte [eax+3], 0x80 ; fEnabled == true?\n"
     714                                "        jz      .return            ; jump on false\n");
     715            else if (fWin64)
     716                ScmStreamPrintf(pStrm,
     717                                "        test    byte [rcx+3], 0x80 ; fEnabled == true?\n"
     718                                "        jz      .return            ; jump on false\n");
     719            else
     720                ScmStreamPrintf(pStrm,
     721                                "        test    byte [rdi+3], 0x80 ; fEnabled == true?\n"
     722                                "        jz      .return            ; jump on false\n");
     723
     724            /*
     725             * Shuffle the arguments around, replacing the location pointer with the probe ID.
     726             */
     727            if (fMachO32)
     728            {
     729                /* Need to recreate the stack frame entirely here as the probe
     730                   function differs by taking all uint64_t arguments instead
     731                   of uintptr_t.  Understandable, but real PITA. */
     732                ScmStreamPrintf(pStrm, "int3\n");
     733            }
     734            else if (g_cBits == 32)
     735            {
     736                /** @todo Check that none of the first 5 arguments are larger than pointer or
     737                 *        32-bit!! */
     738                ScmStreamPrintf(pStrm,
     739                                "        mov     edx, [eax + 4]     ; idProbe\n"
     740                                "        mov     ecx, IMP(SUPR0FireProbe)\n"
     741                                "        mov     [esp + 4], edx     ; Replace pVTGProbeLoc with idProbe.\n"
     742                                "        jmp     ecx\n");
     743            }
     744            else if (fWin64)
     745                ScmStreamPrintf(pStrm,
     746                                "        mov     rax, IMP(SUPR0FireProbe) wrt RIP\n"
     747                                "        mov     ecx, [rcx + 4]     ; idProbe replaces pVTGProbeLoc.\n"
     748                                "        jmp     rax\n");
     749            else
     750                ScmStreamPrintf(pStrm,
     751                                "        lea     rax, [IMP(SUPR0FireProbe) wrt RIP]\n" //??? macho64?
     752                                "        mov     edi, [rdi + 4]     ; idProbe replaces pVTGProbeLoc.\n"
     753                                "        jmp     rax\n");
     754
     755            ScmStreamPrintf(pStrm,
     756                            ".return:\n"
     757                            "        ret                        ; The probe was disabled, return\n"
     758                            "\n");
     759        }
     760    }
    621761
    622762    return RTEXITCODE_SUCCESS;
     
    773913                            "        { \\\n"
    774914                            "            DECL_DATA_SECT(static, VBOXTPGPROBELOC, s_VTGProbeLoc, VTGPrLc) = \\\n"
    775                             "            { __LINE__, 0, UINT32_MAX, __PRETTY_FUNCTION__, __FILE__, /*&g_VTGProbeData_%s_%s*/ NULL }; \\\n"
    776                             "            /*VTGProbeStub_%s_%s(&s_VTGProbeLoc",
     915                            "            { __LINE__, 0, UINT32_MAX, __PRETTY_FUNCTION__, __FILE__, &g_VTGProbeData_%s_%s }; \\\n"
     916                            "            VTGProbeStub_%s_%s(&s_VTGProbeLoc",
    777917                            pProv->pszName, pProbe->pszName,
    778918                            pProv->pszName, pProbe->pszName,
     
    783923            }
    784924            ScmStreamPrintf(pStrm,
    785                             ");*/ RTAssertMsg2(\"%p\", &s_VTGProbeLoc); \\\n"
    786                             "        } \\\n"
     925                            "); \\\n"
     926                            "        } \\\n");
     927            RTListForEach(&pProbe->ArgHead, pArg, VTGARG, ListEntry)
     928            {
     929                ScmStreamPrintf(pStrm,
     930                                "        AssertCompile(sizeof(%s) <= sizeof(uintptr_t));\n"
     931                                "        AssertCompile(sizeof(%s) <= sizeof(uintptr_t));\n",
     932                                pArg->pszName,
     933                                pArg->pszType);
     934            }
     935            ScmStreamPrintf(pStrm,
    787936                            "    } while (0)\n"
    788937                            "\n");
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette