VirtualBox

Changeset 100931 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Aug 21, 2023 11:11:01 PM (17 months ago)
Author:
vboxsync
Message:

IPRT/dbg: Early PDB support.

Location:
trunk/src/VBox/Runtime
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r100914 r100931  
    25012501        common/vfs/vfsbase.cpp \
    25022502        common/vfs/vfschain.cpp \
     2503        common/vfs/vfsiosmisc.cpp \
    25032504        common/vfs/vfsmemory.cpp \
    25042505        common/vfs/vfsmisc.cpp \
  • trunk/src/VBox/Runtime/common/dbg/dbgmod.cpp

    r99570 r100931  
    302302        if (RT_SUCCESS(rc))
    303303            rc = rtDbgModDebugInterpreterRegister(&g_rtDbgModVtDbgDbgHelp);
     304#else
     305        if (RT_SUCCESS(rc))
     306            rc = rtDbgModDebugInterpreterRegister(&g_rtDbgModVtDbgPdb);
    304307#endif
    305308        if (RT_SUCCESS(rc))
     
    433436                            pDbgMod->pDbgVt = pCur->pVt;
    434437                            pDbgMod->pvDbgPriv = NULL;
    435                             rc = pCur->pVt->pfnTryOpen(pDbgMod, RTLDRARCH_WHATEVER);
     438                            rc = pCur->pVt->pfnTryOpen(pDbgMod, RTLDRARCH_WHATEVER, NIL_RTDBGCFG);
    436439                            if (RT_SUCCESS(rc))
    437440                            {
     
    497500            pDbgMod->pDbgVt    = pDbg->pVt;
    498501            pDbgMod->pvDbgPriv = NULL;
    499             rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod));
     502            rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod), NIL_RTDBGCFG);
    500503            if (RT_SUCCESS(rc))
    501504            {
     
    543546            pDbgMod->pDbgVt    = pDbg->pVt;
    544547            pDbgMod->pvDbgPriv = NULL;
    545             rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod));
     548            rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod), NIL_RTDBGCFG);
    546549            if (RT_SUCCESS(rc))
    547550            {
     
    715718            pDbgMod->pDbgVt    = pDbg->pVt;
    716719            pDbgMod->pvDbgPriv = NULL;
    717             rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod));
     720            rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod), NIL_RTDBGCFG);
    718721            if (RT_SUCCESS(rc))
    719722            {
     
    907910                            pDbgMod->pDbgVt = pDbg->pVt;
    908911                            pDbgMod->pvDbgPriv = NULL;
    909                             rc = pDbg->pVt->pfnTryOpen(pDbgMod, enmArch);
     912                            rc = pDbg->pVt->pfnTryOpen(pDbgMod, enmArch, NIL_RTDBGCFG);
    910913                            if (RT_SUCCESS(rc))
    911914                            {
     
    13161319                        pDbgMod->pDbgVt    = pDbg->pVt;
    13171320                        pDbgMod->pvDbgPriv = NULL;
    1318                         rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod));
     1321                        rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod), NIL_RTDBGCFG);
    13191322                        if (RT_SUCCESS(rc))
    13201323                        {
  • trunk/src/VBox/Runtime/common/dbg/dbgmodcodeview.cpp

    r98103 r100931  
    6363#include <iprt/err.h>
    6464#include <iprt/file.h>
     65#include <iprt/fsvfs.h>
    6566#include <iprt/latin1.h>
    6667#include <iprt/log.h>
     
    7172#include <iprt/string.h>
    7273#include <iprt/strcache.h>
     74#include <iprt/vfs.h>
    7375#include "internal/dbgmod.h"
    7476#include "internal/magics.h"
     
    142144    uint32_t        cbImage;
    143145
    144     /** Indicates that we've loaded segments intot he container already. */
     146    /** Indicates that we've loaded segments into the container already. */
    145147    bool            fHaveLoadedSegments;
    146148    /** Alternative address translation method for DOS frames. */
     
    415417        CASE_RET_STR(V2_LThread);
    416418        CASE_RET_STR(V2_GThread);
    417         CASE_RET_STR(V2_Unknown_1010);
    418         CASE_RET_STR(V2_Unknown_1011);
     419        CASE_RET_STR(V2_LProcMips);
     420        CASE_RET_STR(V2_GProcMips);
    419421        CASE_RET_STR(V2_FrameInfo);
    420422        CASE_RET_STR(V2_Compliand);
     
    441443        CASE_RET_STR(V3_Unknown_1115);
    442444        CASE_RET_STR(V3_MSTool);
    443         CASE_RET_STR(V3_PubFunc1);
    444         CASE_RET_STR(V3_PubFunc2);
     445        CASE_RET_STR(V3_ProcRef);
     446        CASE_RET_STR(V3_LProcRef);
     447        CASE_RET_STR(V3_Unknown_1128);
    445448        CASE_RET_STR(V3_SectInfo);
    446449        CASE_RET_STR(V3_SubSectInfo);
     
    642645}
    643646
     647/**
     648 * Validates the a length prefixed string (aka pascal string).
     649 *
     650 * @returns String length if valid, UINT16_MAX if invalid.
     651 * @param   pchString   The string to validate.
     652 * @param   pvRec       The pointer to the record containing the string.
     653 * @param   cbRec       The record length.
     654 */
     655static uint16_t rtDbgModCvValidatePascalString(uint8_t cchString, const char *pchString, void const *pvRec, uint16_t cbRec)
     656{
     657    size_t  offStrMember = (uintptr_t)pchString - (uintptr_t)pvRec;
     658    AssertReturn(offStrMember <= cbRec, UINT16_MAX);
     659    cbRec -= (uint16_t)offStrMember;
     660    AssertReturn(cchString <= cbRec, UINT16_MAX);
     661
     662    int rc = RTStrValidateEncodingEx(pchString, cchString, RTSTR_VALIDATE_ENCODING_EXACT_LENGTH);
     663    AssertRCReturn(rc, UINT16_MAX);
     664
     665    return cchString;
     666}
     667
    644668
    645669/**
     
    775799                }
    776800
     801                case kCvSymType_V2_Pub:
     802                case kCvSymType_V2_LData:
     803                case kCvSymType_V2_GData:
     804                {
     805                    PCRTCVSYMV2TYPEDNAME pData = (PCRTCVSYMV2TYPEDNAME)uCursor.pv;
     806                    RTDBGMODCV_CHECK_NOMSG_RET_BF(cbRec >= 2 + RT_UOFFSETOF(RTCVSYMV2TYPEDNAME, achName));
     807                    uint16_t const cchName = rtDbgModCvValidatePascalString(pData->cchName, pData->achName, pData, cbRec);
     808                    if (cchName != UINT16_MAX && cchName > 0)
     809                        rc = rtDbgModCvAddSymbol(pThis, pData->iSection, pData->offSection, pData->achName, cchName, 0, 0);
     810                    else
     811                        Log3(("      cchName=%#x sec:off=%#x:%#x %.*Rhxs\n",
     812                              cchName, pData->iSection, pData->offSection, cbRec, pData));
     813                    break;
     814                }
     815
    777816                case kCvSymType_V3_Label:
    778817                {
    779818                    PCRTCVSYMV3LABEL pLabel = (PCRTCVSYMV3LABEL)uCursor.pv;
    780                     RTDBGMODCV_CHECK_NOMSG_RET_BF(cbRec >= sizeof(*pLabel));
     819                    RTDBGMODCV_CHECK_NOMSG_RET_BF(cbRec >= 2 + sizeof(*pLabel));
    781820                    uint16_t cchName = rtDbgModCvValidateZeroString(pLabel->szName, pLabel, cbRec);
    782821                    if (cchName != UINT16_MAX && cchName > 0)
     
    12981337
    12991338
    1300 static int rtDbgModCvLoadSegmentMap(PRTDBGMODCV pThis)
    1301 {
    1302     /*
    1303      * Search for the segment map and segment names. They will be at the end of the directory.
    1304      */
    1305     uint32_t iSegMap   = UINT32_MAX;
    1306     uint32_t iSegNames = UINT32_MAX;
    1307     uint32_t i = pThis->cDirEnts;
    1308     while (i-- > 0)
    1309     {
    1310         if (   pThis->paDirEnts[i].iMod != 0xffff
    1311             && pThis->paDirEnts[i].iMod != 0x0000)
    1312             break;
    1313         if (pThis->paDirEnts[i].uSubSectType == kCvSst_SegMap)
    1314             iSegMap = i;
    1315         else if (pThis->paDirEnts[i].uSubSectType == kCvSst_SegName)
    1316             iSegNames = i;
    1317     }
    1318     if (iSegMap == UINT32_MAX)
    1319     {
    1320         Log(("RTDbgModCv: No segment map present, using segment indexes as is then...\n"));
    1321         return VINF_SUCCESS;
    1322     }
    1323     RTDBGMODCV_CHECK_RET_BF(pThis->paDirEnts[iSegMap].cb >= sizeof(RTCVSEGMAPHDR),
    1324                             ("Bad sstSegMap entry: cb=%#x\n", pThis->paDirEnts[iSegMap].cb));
    1325     RTDBGMODCV_CHECK_NOMSG_RET_BF(iSegNames == UINT32_MAX || pThis->paDirEnts[iSegNames].cb > 0);
    1326 
    1327     /*
    1328      * Read them into memory.
    1329      */
    1330     int rc = rtDbgModCvReadAtAlloc(pThis, pThis->paDirEnts[iSegMap].off, (void **)&pThis->pSegMap,
    1331                                    pThis->paDirEnts[iSegMap].cb);
    1332     if (iSegNames != UINT32_MAX && RT_SUCCESS(rc))
    1333     {
    1334         pThis->cbSegNames = pThis->paDirEnts[iSegNames].cb;
    1335         rc = rtDbgModCvReadAtAlloc(pThis, pThis->paDirEnts[iSegNames].off, (void **)&pThis->pszzSegNames,
    1336                                    pThis->paDirEnts[iSegNames].cb);
    1337     }
    1338     if (RT_FAILURE(rc))
    1339         return rc;
    1340     RTDBGMODCV_CHECK_NOMSG_RET_BF(!pThis->pszzSegNames || !pThis->pszzSegNames[pThis->cbSegNames - 1]); /* must be terminated */
    1341 
     1339/**
     1340 * Processes a freshly loaded raw segment (section) map.
     1341 *
     1342 * This is used by both CV and PDB module types.
     1343 */
     1344static int rtDbgModCvProcessSegmentMap(PRTDBGMODCV pThis)
     1345{
    13421346    /* Use local pointers to avoid lots of indirection and typing. */
    13431347    PCRTCVSEGMAPHDR  pHdr    = &pThis->pSegMap->Hdr;
     
    13621366     */
    13631367    Log2(("RTDbgModCv: SegMap: cSegs=%#x cLogSegs=%#x (cbSegNames=%#x)\n", pHdr->cSegs, pHdr->cLogSegs, pThis->cbSegNames));
    1364     RTDBGMODCV_CHECK_RET_BF(pThis->paDirEnts[iSegMap].cb >= sizeof(*pHdr) + pHdr->cSegs * sizeof(paDescs[0]),
    1365                             ("SegMap is out of bounds: cbSubSect=%#x cSegs=%#x\n", pThis->paDirEnts[iSegMap].cb, pHdr->cSegs));
    13661368    RTDBGMODCV_CHECK_NOMSG_RET_BF(pHdr->cSegs >= pHdr->cLogSegs);
    13671369
     
    13691371
    13701372    bool fHaveDosFrames = false;
    1371     for (i = 0; i < pHdr->cSegs; i++)
     1373    for (uint32_t i = 0; i < pHdr->cSegs; i++)
    13721374    {
    13731375        if (i == pHdr->cLogSegs)
     
    14241426                && paDescs[i].iOverlay == 0
    14251427                && enmImgFmt != RTLDRFMT_PE
    1426                 && pThis->enmType != RTCVFILETYPE_DBG)
     1428                && pThis->enmType != RTCVFILETYPE_DBG
     1429                && pThis->enmType != RTCVFILETYPE_PDB)
    14271430                fHaveDosFrames = true; /* BIOS, only groups with frames. */
    14281431        }
     
    14351438    {
    14361439        if (fHaveDosFrames)
    1437             for (i = 0; i < pHdr->cSegs; i++)
     1440            for (uint32_t i = 0; i < pHdr->cSegs; i++)
    14381441            {
    14391442                RTDBGMODCV_CHECK_NOMSG_RET_BF(paDescs[i].iOverlay == 0);
     
    14451448            }
    14461449        else
    1447             for (i = 0; i < pHdr->cSegs; i++)
     1450            for (uint32_t i = 0; i < pHdr->cSegs; i++)
    14481451                RTDBGMODCV_CHECK_NOMSG_RET_BF(paDescs[i].off == 0);
    14491452    }
     
    14601463    if (!fNoGroups && !fHaveDosFrames)
    14611464    {
    1462         for (i = 0; i < pHdr->cSegs; i++)
     1465        for (uint32_t i = 0; i < pHdr->cSegs; i++)
    14631466            if (   !(paDescs[i].fFlags & (RTCVSEGMAPDESC_F_GROUP | RTCVSEGMAPDESC_F_ABS))
    14641467                && paDescs[i].iGroup == 0)
     
    14781481    if (!pThis->fHaveLoadedSegments)
    14791482    {
     1483        int      rc   = VINF_SUCCESS;
    14801484        uint16_t iSeg = 0;
    14811485        if (!fHaveDosFrames)
     
    14901494            }
    14911495
    1492             for (i = 0; RT_SUCCESS(rc) && i < pHdr->cSegs; i++)
     1496            for (uint32_t i = 0; RT_SUCCESS(rc) && i < pHdr->cSegs; i++)
    14931497                if ((paDescs[i].fFlags & RTCVSEGMAPDESC_F_GROUP) || fNoGroups)
    14941498                {
     
    15131517            /* Figure image base address. */
    15141518            uint64_t uImageBase = UINT64_MAX;
    1515             for (i = 0; RT_SUCCESS(rc) && i < pHdr->cSegs; i++)
     1519            for (uint32_t i = 0; RT_SUCCESS(rc) && i < pHdr->cSegs; i++)
    15161520            {
    15171521                uint64_t uAddr = (uint64_t)paDescs[i].off + ((uint32_t)paDescs[i].iFrame << 4);
     
    15221526            /* Add the segments. */
    15231527            uint64_t uMinAddr = uImageBase;
    1524             for (i = 0; RT_SUCCESS(rc) && i < pHdr->cSegs; i++)
     1528            for (uint32_t i = 0; RT_SUCCESS(rc) && i < pHdr->cSegs; i++)
    15251529            {
    15261530                /* Figure out the next one. */
     
    16481652
    16491653    /* Pass one: Fixate the group segment indexes. */
    1650     uint16_t iSeg0 = enmImgFmt == RTLDRFMT_PE || pThis->enmType == RTCVFILETYPE_DBG ? 1 : 0;
     1654    uint16_t iSeg0 = enmImgFmt == RTLDRFMT_PE || pThis->enmType == RTCVFILETYPE_DBG || pThis->enmType == RTCVFILETYPE_PDB ? 1 : 0;
    16511655    uint16_t iSeg = iSeg0 + (cbGroup0 > 0); /** @todo probably wrong... */
    1652     for (i = 0; i < pHdr->cSegs; i++)
     1656    for (uint32_t i = 0; i < pHdr->cSegs; i++)
    16531657        if (paDescs[i].fFlags & RTCVSEGMAPDESC_F_ABS)
    16541658            paDescs[i].iGroup = (uint16_t)(RTDBGSEGIDX_ABS & UINT16_MAX);
     
    16581662    /* Pass two: Resolve group references in to segment indexes. */
    16591663    Log2(("Mapped segments (both kinds):\n"));
    1660     for (i = 0; i < pHdr->cSegs; i++)
     1664    for (uint32_t i = 0; i < pHdr->cSegs; i++)
    16611665    {
    16621666        if (!fNoGroups && !(paDescs[i].fFlags & (RTCVSEGMAPDESC_F_GROUP | RTCVSEGMAPDESC_F_ABS)))
     
    16701674    return VINF_SUCCESS;
    16711675}
     1676
     1677
     1678/**
     1679 * Loads and processes the segment map.
     1680 */
     1681static int rtDbgModCvLoadSegmentMap(PRTDBGMODCV pThis)
     1682{
     1683    /*
     1684     * Search for the segment map and segment names. They will be at the end of the directory.
     1685     */
     1686    uint32_t iSegMap   = UINT32_MAX;
     1687    uint32_t iSegNames = UINT32_MAX;
     1688    uint32_t i = pThis->cDirEnts;
     1689    while (i-- > 0)
     1690    {
     1691        if (   pThis->paDirEnts[i].iMod != 0xffff
     1692            && pThis->paDirEnts[i].iMod != 0x0000)
     1693            break;
     1694        if (pThis->paDirEnts[i].uSubSectType == kCvSst_SegMap)
     1695            iSegMap = i;
     1696        else if (pThis->paDirEnts[i].uSubSectType == kCvSst_SegName)
     1697            iSegNames = i;
     1698    }
     1699    if (iSegMap == UINT32_MAX)
     1700    {
     1701        Log(("RTDbgModCv: No segment map present, using segment indexes as is then...\n"));
     1702        return VINF_SUCCESS;
     1703    }
     1704    RTDBGMODCV_CHECK_RET_BF(pThis->paDirEnts[iSegMap].cb >= sizeof(RTCVSEGMAPHDR),
     1705                            ("Bad sstSegMap entry: cb=%#x\n", pThis->paDirEnts[iSegMap].cb));
     1706    RTDBGMODCV_CHECK_NOMSG_RET_BF(iSegNames == UINT32_MAX || pThis->paDirEnts[iSegNames].cb > 0);
     1707
     1708    /*
     1709     * Read them into memory.
     1710     */
     1711    int rc = rtDbgModCvReadAtAlloc(pThis, pThis->paDirEnts[iSegMap].off, (void **)&pThis->pSegMap,
     1712                                   pThis->paDirEnts[iSegMap].cb);
     1713    if (iSegNames != UINT32_MAX && RT_SUCCESS(rc))
     1714    {
     1715        pThis->cbSegNames = pThis->paDirEnts[iSegNames].cb;
     1716        rc = rtDbgModCvReadAtAlloc(pThis, pThis->paDirEnts[iSegNames].off, (void **)&pThis->pszzSegNames,
     1717                                   pThis->paDirEnts[iSegNames].cb);
     1718    }
     1719    if (RT_FAILURE(rc))
     1720        return rc;
     1721    RTDBGMODCV_CHECK_NOMSG_RET_BF(!pThis->pszzSegNames || !pThis->pszzSegNames[pThis->cbSegNames - 1]); /* must be terminated */
     1722    RTDBGMODCV_CHECK_RET_BF(pThis->paDirEnts[iSegMap].cb >= RT_UOFFSETOF_DYN(RTCVSEGMAP, aDescs[pThis->pSegMap->Hdr.cSegs]),
     1723                            ("SegMap is out of bounds: cbSubSect=%#x cSegs=%#x\n",
     1724                             pThis->paDirEnts[iSegMap].cb, pThis->pSegMap->Hdr.cSegs));
     1725
     1726    /*
     1727     * Join paths with the PDB handling.
     1728     */
     1729    return rtDbgModCvProcessSegmentMap(pThis);
     1730}
     1731
     1732
    16721733
    16731734
     
    29162977        }
    29172978    }
    2918 
     2979    /*
     2980     * The NB10 is used to link to a PDB file.
     2981     * This is the case with the windows 2000 DBG files.
     2982     */
     2983    else if (pCvHdr->u32Magic == RTCVHDR_MAGIC_NB10)
     2984    {
     2985        if (pCvHdr->off == 0)
     2986        {
     2987            if (cb >= sizeof(CVPDB20INFO) && cb < _64K)
     2988            {
     2989                PCVPDB20INFO pInfo = (PCVPDB20INFO)RTMemTmpAlloc(cb);
     2990                if (pInfo)
     2991                {
     2992                    int rc2 = RTFileReadAt(hFile, off, pInfo, cb, NULL);
     2993                    if (RT_SUCCESS(rc2))
     2994                    {
     2995                        Log2(("RTDbgModCv: Found external PDB (v2.0): TS=%#010RX32 uAge=%x '%.*s'\n",  pInfo->uTimestamp,
     2996                              pInfo->uAge, cb - RT_UOFFSETOF(CVPDB20INFO, szPdbFilename), &pInfo->szPdbFilename[0]));
     2997                    }
     2998                }
     2999            }
     3000        }
     3001    }
    29193002    return rc;
    29203003}
     
    29763059}
    29773060
     3061#ifdef LOG_ENABLED
     3062/** Translate PE debug directory type value to string. */
     3063static const char *dbgPeDebugTypeName(uint32_t uType)
     3064{
     3065    switch (uType)
     3066    {
     3067        case IMAGE_DEBUG_TYPE_UNKNOWN:       return "UNKNOWN";
     3068        case IMAGE_DEBUG_TYPE_COFF:          return "COFF";
     3069        case IMAGE_DEBUG_TYPE_CODEVIEW:      return "CODEVIEW";
     3070        case IMAGE_DEBUG_TYPE_FPO:           return "FPO";
     3071        case IMAGE_DEBUG_TYPE_MISC:          return "MISC";
     3072        case IMAGE_DEBUG_TYPE_EXCEPTION:     return "EXCEPTION";
     3073        case IMAGE_DEBUG_TYPE_FIXUP:         return "FIXUP";
     3074        case IMAGE_DEBUG_TYPE_OMAP_TO_SRC:   return "OMAP_TO_SRC";
     3075        case IMAGE_DEBUG_TYPE_OMAP_FROM_SRC: return "OMAP_FROM_SRC";
     3076        case IMAGE_DEBUG_TYPE_BORLAND:       return "BORLAND";
     3077        case IMAGE_DEBUG_TYPE_RESERVED10:    return "RESERVED10";
     3078        case IMAGE_DEBUG_TYPE_CLSID:         return "CLSID";
     3079        case IMAGE_DEBUG_TYPE_VC_FEATURE:    return "VC_FEATURE";
     3080        case IMAGE_DEBUG_TYPE_POGO:          return "POGO";
     3081        case IMAGE_DEBUG_TYPE_ILTCG:         return "ILTCG";
     3082        case IMAGE_DEBUG_TYPE_MPX:           return "MPX";
     3083        case IMAGE_DEBUG_TYPE_REPRO:         return "REPRO";
     3084    }
     3085    return "??";
     3086}
     3087#endif
    29783088
    29793089/**
     
    30543164            if (RT_FAILURE(rc))
    30553165                break;
     3166            Log2(("DbgDir[%u]: Type=%#x Char=%#x TS=%#010x Ver=%#x.%#x Size=%#010x Addr=%#010x Ptr=%#010x %s\n",
     3167                  i, DbgDir.Type, DbgDir.Characteristics, DbgDir.TimeDateStamp, DbgDir.MajorVersion, DbgDir.MinorVersion,
     3168                  DbgDir.SizeOfData, DbgDir.AddressOfRawData, DbgDir.PointerToRawData, dbgPeDebugTypeName(DbgDir.Type)));
    30563169            if (DbgDir.Type == IMAGE_DEBUG_TYPE_CODEVIEW)
    30573170                rc = rtDbgModCvProbeFile2(pDbgMod, RTCVFILETYPE_DBG, hFile,
     
    30613174                rc = rtDbgModCvProbeCoff(pDbgMod, RTCVFILETYPE_DBG, hFile,
    30623175                                         DbgDir.PointerToRawData, DbgDir.SizeOfData, pszFilename);
    3063         }
     3176            else
     3177                continue;
     3178            Log2(("DbgDir[%u]: parsing -> %Rrc\n", i, rc));
     3179        }
     3180
     3181#ifdef LOG_ENABLED
     3182        /*
     3183         * Dump the section table.
     3184         */
     3185        for (uint32_t i = 0, offSecHdr = sizeof(DbgHdr);
     3186             i < DbgHdr.NumberOfSections;
     3187             i++, offSecHdr += sizeof(IMAGE_SECTION_HEADER))
     3188        {
     3189            IMAGE_SECTION_HEADER Sh;
     3190            rc = RTFileReadAt(hFile, offSecHdr, &Sh, sizeof(Sh), NULL);
     3191            if (RT_FAILURE(rc))
     3192                break;
     3193            Log2(("SHdr[%02u]: VA=%#08RX32 LB %#08RX32 Char=%#010RX32 Ptr=%#08RX32 LB %#08RX32 PtrLines=%#RX32 L %#RX32 PtrReloc=%#RX32 L %#RX32 '%.8s'\n",
     3194                  i, Sh.VirtualAddress, Sh.Misc.VirtualSize, Sh.Characteristics, Sh.PointerToRawData, Sh.SizeOfRawData,
     3195                  Sh.PointerToLinenumbers, Sh.NumberOfLinenumbers, Sh.PointerToRelocations, Sh.NumberOfRelocations, &Sh.Name[0]));
     3196        }
     3197#endif
    30643198
    30653199        /*
     
    31083242
    31093243/** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */
    3110 static DECLCALLBACK(int) rtDbgModCv_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
     3244static DECLCALLBACK(int) rtDbgModCv_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch, RTDBGCFG hDbgCfg)
    31113245{
    31123246    /*
     
    31573291    Log(("RTDbgCv: Debug info load error %Rrc\n", rc));
    31583292    rtDbgModCv_Close(pMod);
     3293    RT_NOREF(hDbgCfg);
    31593294    return rc;
    31603295}
     
    31963331};
    31973332
     3333
     3334/*
     3335 *
     3336 * PDB Debug module implementation.
     3337 * PDB Debug module implementation.
     3338 * PDB Debug module implementation.
     3339 *
     3340 */
     3341
     3342
     3343/** @interface_method_impl{RTDBGMODVTDBG,pfnUnwindFrame} */
     3344static DECLCALLBACK(int) rtDbgModPdb_UnwindFrame(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTDBGUNWINDSTATE pState)
     3345{
     3346    RT_NOREF(pMod, iSeg, off, pState);
     3347    return VERR_DBG_NO_UNWIND_INFO;
     3348}
     3349
     3350
     3351/** @interface_method_impl{RTDBGMODVTDBG,pfnLineByAddr} */
     3352static DECLCALLBACK(int) rtDbgModPdb_LineByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off,
     3353                                                PRTINTPTR poffDisp, PRTDBGLINE pLineInfo)
     3354{
     3355    PRTDBGMODCV pThis = (PRTDBGMODCV)pMod->pvDbgPriv;
     3356    return RTDbgModLineByAddr(pThis->hCnt, iSeg, off, poffDisp, pLineInfo);
     3357}
     3358
     3359
     3360/** @interface_method_impl{RTDBGMODVTDBG,pfnLineByOrdinal} */
     3361static DECLCALLBACK(int) rtDbgModPdb_LineByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo)
     3362{
     3363    PRTDBGMODCV pThis = (PRTDBGMODCV)pMod->pvDbgPriv;
     3364    return RTDbgModLineByOrdinal(pThis->hCnt, iOrdinal, pLineInfo);
     3365}
     3366
     3367
     3368/** @interface_method_impl{RTDBGMODVTDBG,pfnLineCount} */
     3369static DECLCALLBACK(uint32_t) rtDbgModPdb_LineCount(PRTDBGMODINT pMod)
     3370{
     3371    PRTDBGMODCV pThis = (PRTDBGMODCV)pMod->pvDbgPriv;
     3372    return RTDbgModLineCount(pThis->hCnt);
     3373}
     3374
     3375
     3376/** @interface_method_impl{RTDBGMODVTDBG,pfnLineAdd} */
     3377static DECLCALLBACK(int) rtDbgModPdb_LineAdd(PRTDBGMODINT pMod, const char *pszFile, size_t cchFile, uint32_t uLineNo,
     3378                                             uint32_t iSeg, RTUINTPTR off, uint32_t *piOrdinal)
     3379{
     3380    PRTDBGMODCV pThis = (PRTDBGMODCV)pMod->pvDbgPriv;
     3381    Assert(!pszFile[cchFile]); NOREF(cchFile);
     3382    return RTDbgModLineAdd(pThis->hCnt, pszFile, uLineNo, iSeg, off, piOrdinal);
     3383}
     3384
     3385
     3386/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByAddr} */
     3387static DECLCALLBACK(int) rtDbgModPdb_SymbolByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags,
     3388                                                  PRTINTPTR poffDisp, PRTDBGSYMBOL pSymInfo)
     3389{
     3390    PRTDBGMODCV pThis = (PRTDBGMODCV)pMod->pvDbgPriv;
     3391    return RTDbgModSymbolByAddr(pThis->hCnt, iSeg, off, fFlags, poffDisp, pSymInfo);
     3392}
     3393
     3394
     3395/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByName} */
     3396static DECLCALLBACK(int) rtDbgModPdb_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
     3397                                                  PRTDBGSYMBOL pSymInfo)
     3398{
     3399    PRTDBGMODCV pThis = (PRTDBGMODCV)pMod->pvDbgPriv;
     3400    Assert(!pszSymbol[cchSymbol]); RT_NOREF_PV(cchSymbol);
     3401    return RTDbgModSymbolByName(pThis->hCnt, pszSymbol/*, cchSymbol*/, pSymInfo);
     3402}
     3403
     3404
     3405/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByOrdinal} */
     3406static DECLCALLBACK(int) rtDbgModPdb_SymbolByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo)
     3407{
     3408    PRTDBGMODCV pThis = (PRTDBGMODCV)pMod->pvDbgPriv;
     3409    return RTDbgModSymbolByOrdinal(pThis->hCnt, iOrdinal, pSymInfo);
     3410}
     3411
     3412
     3413/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolCount} */
     3414static DECLCALLBACK(uint32_t) rtDbgModPdb_SymbolCount(PRTDBGMODINT pMod)
     3415{
     3416    PRTDBGMODCV pThis = (PRTDBGMODCV)pMod->pvDbgPriv;
     3417    return RTDbgModSymbolCount(pThis->hCnt);
     3418}
     3419
     3420
     3421/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolAdd} */
     3422static DECLCALLBACK(int) rtDbgModPdb_SymbolAdd(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
     3423                                               RTDBGSEGIDX iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags,
     3424                                               uint32_t *piOrdinal)
     3425{
     3426    PRTDBGMODCV pThis = (PRTDBGMODCV)pMod->pvDbgPriv;
     3427    Assert(!pszSymbol[cchSymbol]); NOREF(cchSymbol);
     3428    return RTDbgModSymbolAdd(pThis->hCnt, pszSymbol, iSeg, off, cb, fFlags, piOrdinal);
     3429}
     3430
     3431
     3432/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentByIndex} */
     3433static DECLCALLBACK(int) rtDbgModPdb_SegmentByIndex(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo)
     3434{
     3435    PRTDBGMODCV pThis = (PRTDBGMODCV)pMod->pvDbgPriv;
     3436    return RTDbgModSegmentByIndex(pThis->hCnt, iSeg, pSegInfo);
     3437}
     3438
     3439
     3440/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentCount} */
     3441static DECLCALLBACK(RTDBGSEGIDX) rtDbgModPdb_SegmentCount(PRTDBGMODINT pMod)
     3442{
     3443    PRTDBGMODCV pThis = (PRTDBGMODCV)pMod->pvDbgPriv;
     3444    return RTDbgModSegmentCount(pThis->hCnt);
     3445}
     3446
     3447
     3448/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentAdd} */
     3449static DECLCALLBACK(int) rtDbgModPdb_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName,
     3450                                                size_t cchName, uint32_t fFlags, PRTDBGSEGIDX piSeg)
     3451{
     3452    PRTDBGMODCV pThis = (PRTDBGMODCV)pMod->pvDbgPriv;
     3453    Assert(!pszName[cchName]); NOREF(cchName);
     3454    return RTDbgModSegmentAdd(pThis->hCnt, uRva, cb, pszName, fFlags, piSeg);
     3455}
     3456
     3457
     3458/** @interface_method_impl{RTDBGMODVTDBG,pfnImageSize} */
     3459static DECLCALLBACK(RTUINTPTR) rtDbgModPdb_ImageSize(PRTDBGMODINT pMod)
     3460{
     3461    PRTDBGMODCV pThis = (PRTDBGMODCV)pMod->pvDbgPriv;
     3462    if (pThis->cbImage)
     3463        return pThis->cbImage;
     3464    return RTDbgModImageSize(pThis->hCnt);
     3465}
     3466
     3467
     3468/** @interface_method_impl{RTDBGMODVTDBG,pfnRvaToSegOff} */
     3469static DECLCALLBACK(RTDBGSEGIDX) rtDbgModPdb_RvaToSegOff(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg)
     3470{
     3471    PRTDBGMODCV pThis = (PRTDBGMODCV)pMod->pvDbgPriv;
     3472    return RTDbgModRvaToSegOff(pThis->hCnt, uRva, poffSeg);
     3473}
     3474
     3475
     3476/** @interface_method_impl{RTDBGMODVTDBG,pfnClose} */
     3477static DECLCALLBACK(int) rtDbgModPdb_Close(PRTDBGMODINT pMod)
     3478{
     3479    PRTDBGMODCV pThis = (PRTDBGMODCV)pMod->pvDbgPriv;
     3480
     3481    RTDbgModRelease(pThis->hCnt);
     3482    if (pThis->hFile != NIL_RTFILE)
     3483        RTFileClose(pThis->hFile);
     3484    RTMemFree(pThis->paDirEnts);
     3485    RTMemFree(pThis);
     3486
     3487    pMod->pvDbgPriv = NULL; /* for internal use */
     3488    return VINF_SUCCESS;
     3489}
     3490
     3491
     3492/*
     3493 *
     3494 * Probing code used by rtDbgModPdb_TryOpen.
     3495 * Probing code used by rtDbgModPdb_TryOpen.
     3496 *
     3497 */
     3498
     3499static int rtDbgModPdb_ScanSymRecs(PRTDBGMODCV pThis, RTVFSFILE hVfsFileSymRecs)
     3500{
     3501    void    *pvSymRecs;
     3502    size_t   cbSymRecs;
     3503    int rc = RTVfsFileReadAll(hVfsFileSymRecs, &pvSymRecs, &cbSymRecs);
     3504    if (RT_SUCCESS(rc))
     3505    {
     3506        Log3(("rtDbgModPdb_ScanSymRecs: %p LB %#x\n", pvSymRecs, cbSymRecs));
     3507        rc = rtDbgModCvSsProcessV4PlusSymTab(pThis, pvSymRecs, cbSymRecs, 0 /*fFlags*/);
     3508
     3509        RTVfsFileReadAllFree(pvSymRecs, cbSymRecs);
     3510    }
     3511    else
     3512        Log(("rtDbgModPdb_ScanSymRecs: RTVfsFileReadAll failed - %Rrc\n", rc));
     3513    return rc;
     3514}
     3515
     3516
     3517static int rtDbgModPdb_LoadSegMap(PRTDBGMODCV pThis, RTVFS hVfsPdb)
     3518{
     3519    /*
     3520     * Open the DBI section map and read it into a regular heap block just like
     3521     * rtDbgModCvReadAtAlloc does for the other code path.
     3522     */
     3523    RTVFSFILE hVfsFile = NIL_RTVFSFILE;
     3524    int rc = RTVfsFileOpen(hVfsPdb, "dbi-section-map", RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, &hVfsFile);
     3525    if (RT_SUCCESS(rc))
     3526    {
     3527        uint64_t cbSegMap;
     3528        rc = RTVfsFileQuerySize(hVfsFile, &cbSegMap);
     3529        AssertRC(rc);
     3530        if (RT_SUCCESS(rc))
     3531        {
     3532            if (   cbSegMap >= RT_UOFFSETOF(RTCVSEGMAP, aDescs)
     3533                && cbSegMap <= RT_UOFFSETOF_DYN(RTCVSEGMAP, aDescs[4096]))  /* random upper limit */
     3534            {
     3535                pThis->pSegMap = (PRTCVSEGMAP)RTMemAlloc((size_t)cbSegMap);
     3536                if (pThis->pSegMap)
     3537                {
     3538                    rc = RTVfsFileReadAt(hVfsFile, 0, pThis->pSegMap, cbSegMap, NULL);
     3539                    if (RT_SUCCESS(rc))
     3540                    {
     3541                        /*
     3542                         * Join paths with the codeview module reader and process the map.
     3543                         */
     3544                        rc = rtDbgModCvProcessSegmentMap(pThis);
     3545
     3546                    }
     3547                    else
     3548                        Log(("rtDbgModPdb_LoadSegMap: Read error: %Rrc\n", rc));
     3549                }
     3550                else
     3551                    rc = VERR_NO_MEMORY;
     3552            }
     3553            else
     3554            {
     3555                Log(("rtDbgModPdb_LoadSegMap: Bogus section map size: %#RX64\n", cbSegMap));
     3556                rc = VERR_CV_BAD_FORMAT;
     3557            }
     3558        }
     3559        RTVfsFileRelease(hVfsFile);
     3560    }
     3561    else
     3562    {
     3563        Log(("rtDbgModPdb_LoadSegMap: Failed to open dbi-section-map: %Rrc\n", rc));
     3564        if (rc == VERR_PATH_NOT_FOUND || rc == VERR_FILE_NOT_FOUND)
     3565            rc = VINF_SUCCESS;
     3566    }
     3567    return rc;
     3568}
     3569
     3570
     3571
     3572DECLINLINE(uint32_t) rtDbgModPdb_AdjustSectionSizeByNextSection(PCIMAGE_SECTION_HEADER paSHdrs, size_t cSections,
     3573                                                                size_t iCur, uint32_t cbMapped)
     3574{
     3575    size_t iNext = iCur + 1;
     3576    while (iNext < cSections && (paSHdrs[iNext].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
     3577        iNext++;
     3578    if (iNext < cSections)
     3579    {
     3580        uint32_t cbAvailable = paSHdrs[iNext].VirtualAddress - (iCur != ~(size_t)0 ? paSHdrs[iCur].VirtualAddress : 0);
     3581        Assert(cbMapped <= cbAvailable);
     3582        return cbAvailable;
     3583    }
     3584    return cbMapped;
     3585}
     3586
     3587
     3588/**
     3589 * Helper for rtDbgModPdb_TryOpen that loads the section/segments into the
     3590 * container.
     3591 */
     3592static int rtDbgModPdb_LoadSections(PRTDBGMODINT pMod, PRTDBGMODCV pThis, RTVFSFILE hVfsFileSectionHeaders)
     3593{
     3594    /*
     3595     * Use the info from the image if present.
     3596     */
     3597    int rc;
     3598    if (pMod->pImgVt)
     3599        rc = pMod->pImgVt->pfnEnumSegments(pMod, rtDbgModCvAddSegmentsCallback, pThis);
     3600    /*
     3601     * Otherwise use the copy of the section table from the PDB.
     3602     */
     3603    else
     3604    {
     3605        PIMAGE_SECTION_HEADER paSHdrs;
     3606        size_t                cbSHdrs;
     3607        rc = RTVfsFileReadAll(hVfsFileSectionHeaders, (void **)&paSHdrs, &cbSHdrs);
     3608        if (RT_SUCCESS(rc))
     3609        {
     3610            size_t const cSections = cbSHdrs / sizeof(IMAGE_SECTION_HEADER);
     3611
     3612            /** @todo sanity check headers first? */
     3613
     3614            /* The first section is a fake one covering the headers. */
     3615            uint32_t cbMapped = 0x80 /*MZ Stub*/ + sizeof(IMAGE_NT_HEADERS32) + (uint32_t)cbSHdrs;
     3616            cbMapped = rtDbgModPdb_AdjustSectionSizeByNextSection(paSHdrs, cSections, ~(size_t)0, cbMapped);
     3617            rc = RTDbgModSegmentAdd(pThis->hCnt, 0, cbMapped, "NtHdrs", 0 /*fFlags*/, NULL);
     3618            if (RT_SUCCESS(rc))
     3619            {
     3620                /* Process the section headers.  This bears some resemblence of the code in rtldrPE_EnumSegments.  */
     3621                for (size_t i = 0; RT_SUCCESS(rc) && i < cSections; i++)
     3622                {
     3623                    Log(("Segment #%u: RVA=%#09RX32 cbVirt=%#09RX32 cbRaw=%#09RX32 Flags=%#010RX32 Name='%.8s'\n",
     3624                         i, paSHdrs[i].VirtualAddress, paSHdrs[i].Misc.VirtualSize, paSHdrs[i].SizeOfRawData,
     3625                         paSHdrs[i].Characteristics, paSHdrs[i].Name));
     3626                    char szName[9];
     3627                    memcpy(szName, paSHdrs[i].Name, sizeof(paSHdrs[i].Name));
     3628                    szName[sizeof(paSHdrs[i].Name)] = '\0';
     3629                    RTStrStripR(szName);
     3630
     3631                    /* If the segment doesn't have a mapping, just add a dummy so the indexing
     3632                       works out correctly (same as for the image). */
     3633                    uint32_t uRva = 0;
     3634                    cbMapped = 0;
     3635                    if (!(paSHdrs[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
     3636                    {
     3637                        uint32_t cbAlign  = (paSHdrs[i].Characteristics & IMAGE_SCN_ALIGN_MASK) >> IMAGE_SCN_ALIGN_SHIFT;
     3638                        if (cbAlign > 0)
     3639                            cbAlign = RT_BIT_32(cbAlign);
     3640                        else
     3641                            cbAlign = 1; /** @todo missing file header w/ default section alignment.  */
     3642                        cbMapped = RT_ALIGN(paSHdrs[i].Misc.VirtualSize, cbAlign);
     3643
     3644                        size_t iNext = i + 1;
     3645                        while (iNext < cSections && (paSHdrs[iNext].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
     3646                            iNext++;
     3647                        if (iNext < cSections)
     3648                            cbMapped = paSHdrs[iNext].VirtualAddress - paSHdrs[i].VirtualAddress;
     3649                        uRva = paSHdrs[i].VirtualAddress;
     3650                    }
     3651                    rc = RTDbgModSegmentAdd(pThis->hCnt, uRva, cbMapped, szName, 0 /*fFlags*/, NULL);
     3652                    if (RT_FAILURE(rc))
     3653                    {
     3654                        Log(("rtDbgModPdb_LoadSections: Failed on #%u: uRva=%#RX32 cbMapped=%#RX32 Flags=%#RX32 '%s' -> %Rrc\n",
     3655                             i + 1, uRva, cbMapped, szName, paSHdrs[i].Characteristics, rc));
     3656                        break;
     3657                    }
     3658                }
     3659            }
     3660            else
     3661                Log(("rtDbgModPdb_LoadSections: Failed on first: cbMapped=%#RX32 %Rrc\n", cbMapped, rc));
     3662            RTVfsFileReadAllFree(paSHdrs, cbSHdrs);
     3663        }
     3664        else
     3665            Log(("rtDbgModPdb_LoadSections: RTVfsFileReadAll failed - %Rrc\n", rc));
     3666    }
     3667    pThis->fHaveLoadedSegments = true;
     3668    return rc;
     3669}
     3670
     3671
     3672/** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */
     3673static DECLCALLBACK(int) rtDbgModPdb_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch, RTDBGCFG hDbgCfg)
     3674{
     3675    RT_NOREF(hDbgCfg); RT_NOREF(enmArch);
     3676
     3677    /*
     3678     * This only works for external files for now.
     3679     */
     3680    if (!pMod->pszDbgFile)
     3681        return VERR_DBG_NO_MATCHING_INTERPRETER;
     3682
     3683    /*
     3684     * Open the PDB as a VFS.
     3685     */
     3686    RTVFSFILE hVfsFilePdb = NIL_RTVFSFILE;
     3687    int rc = RTVfsFileOpenNormal(pMod->pszDbgFile, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, &hVfsFilePdb);
     3688    if (RT_SUCCESS(rc))
     3689    {
     3690        RTVFS           hVfsPdb = NIL_RTVFS;
     3691#ifdef LOG_ENABLED
     3692        RTERRINFOSTATIC ErrInfo;
     3693        rc = RTFsPdbVolOpen(hVfsFilePdb, 0, &hVfsPdb, RTErrInfoInitStatic(&ErrInfo));
     3694#else
     3695        rc = RTFsPdbVolOpen(hVfsFilePdb, 0, &hVfsPdb, NULL /*pErrInfo*/);
     3696#endif
     3697        RTVfsFileRelease(hVfsFilePdb);
     3698        if (RT_SUCCESS(rc))
     3699        {
     3700            /*
     3701             * Check if we've got the necessary bits present in the PDB.
     3702             */
     3703            /* We need section headers. We can get them from the image if we
     3704               have one, otherwise there is usally a copy of them in the PDB. */
     3705            RTVFSFILE hVfsFileSectionHeaders = NIL_RTVFSFILE;
     3706            /** @todo figure out how to deal with old PDBs w/o section headers...
     3707             *        (like w2ksp4 ones) */
     3708            if (!pMod->pImgVt)
     3709                rc = RTVfsFileOpen(hVfsPdb, "image-section-headers", RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE,
     3710                                   &hVfsFileSectionHeaders);
     3711            if (RT_SUCCESS(rc))
     3712            {
     3713                /* We also need the symbol records. */
     3714                RTVFSFILE hVfsFileSymRecs = NIL_RTVFSFILE;
     3715                rc = RTVfsFileOpen(hVfsPdb, "symbol-records", RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE,
     3716                                   &hVfsFileSymRecs);
     3717                if (RT_SUCCESS(rc))
     3718                {
     3719                    /*
     3720                     * Create an instance and process the available information.
     3721                     */
     3722                    PRTDBGMODCV pThis;
     3723                    rc = rtDbgModCvCreateInstance(pMod, RTCVFILETYPE_PDB, NIL_RTFILE, &pThis);
     3724                    if (RT_SUCCESS(rc))
     3725                    {
     3726                        rc = rtDbgModPdb_LoadSections(pMod, pThis, hVfsFileSectionHeaders);
     3727                        if (RT_SUCCESS(rc))
     3728                        {
     3729                            rc = rtDbgModPdb_LoadSegMap(pThis, hVfsPdb);
     3730                            if (RT_SUCCESS(rc))
     3731                            {
     3732                                rc = rtDbgModPdb_ScanSymRecs(pThis, hVfsFileSymRecs);
     3733                                if (RT_SUCCESS(rc))
     3734                                    Log(("rtDbgModPdb_TryOpen: Succeeded\n"));
     3735                                else
     3736                                    Log(("rtDbgModPdb_TryOpen: rtDbgModPdb_ScanSymRecs failed - %Rrc\n", rc));
     3737                            }
     3738                            else
     3739                                Log(("rtDbgModPdb_TryOpen: rtDbgModPdb_LoadSegMap failed - %Rrc\n", rc));
     3740                        }
     3741                        else
     3742                            Log(("rtDbgModPdb_TryOpen: rtDbgModPdb_LoadSections failed - %Rrc\n", rc));
     3743                    }
     3744                    RTVfsFileRelease(hVfsFileSymRecs);
     3745                }
     3746                else
     3747                    Log2(("rtDbgModPdb_TryOpen: Failed to open 'symbol-records' in '%s' -> %Rrc\n", pMod->pszDbgFile, rc));
     3748                RTVfsFileRelease(hVfsFileSectionHeaders);
     3749            }
     3750            else
     3751                Log2(("rtDbgModPdb_TryOpen: Failed to open 'image-section-headers' in '%s' -> %Rrc\n", pMod->pszDbgFile, rc));
     3752            RTVfsRelease(hVfsPdb);
     3753        }
     3754        else
     3755            Log2(("rtDbgModPdb_TryOpen: RTFsPdbVolOpen '%s' -> %Rrc%#RTeim\n", pMod->pszDbgFile, rc, &ErrInfo.Core));
     3756    }
     3757    else
     3758        Log2(("rtDbgModPdb_TryOpen: RTVfsFileOpenNormal '%s' -> %Rrc\n", pMod->pszDbgFile, rc));
     3759    return rc;
     3760}
     3761
     3762
     3763/** Virtual function table for the PDB debug info reader. */
     3764DECL_HIDDEN_CONST(RTDBGMODVTDBG) const g_rtDbgModVtDbgPdb =
     3765{
     3766    /*.u32Magic = */            RTDBGMODVTDBG_MAGIC,
     3767    /*.fSupports = */           RT_DBGTYPE_CODEVIEW,
     3768    /*.pszName = */             "pdb",
     3769    /*.pfnTryOpen = */          rtDbgModPdb_TryOpen,
     3770    /*.pfnClose = */            rtDbgModPdb_Close,
     3771
     3772    /*.pfnRvaToSegOff = */      rtDbgModPdb_RvaToSegOff,
     3773    /*.pfnImageSize = */        rtDbgModPdb_ImageSize,
     3774
     3775    /*.pfnSegmentAdd = */       rtDbgModPdb_SegmentAdd,
     3776    /*.pfnSegmentCount = */     rtDbgModPdb_SegmentCount,
     3777    /*.pfnSegmentByIndex = */   rtDbgModPdb_SegmentByIndex,
     3778
     3779    /*.pfnSymbolAdd = */        rtDbgModPdb_SymbolAdd,
     3780    /*.pfnSymbolCount = */      rtDbgModPdb_SymbolCount,
     3781    /*.pfnSymbolByOrdinal = */  rtDbgModPdb_SymbolByOrdinal,
     3782    /*.pfnSymbolByName = */     rtDbgModPdb_SymbolByName,
     3783    /*.pfnSymbolByAddr = */     rtDbgModPdb_SymbolByAddr,
     3784
     3785    /*.pfnLineAdd = */          rtDbgModPdb_LineAdd,
     3786    /*.pfnLineCount = */        rtDbgModPdb_LineCount,
     3787    /*.pfnLineByOrdinal = */    rtDbgModPdb_LineByOrdinal,
     3788    /*.pfnLineByAddr = */       rtDbgModPdb_LineByAddr,
     3789
     3790    /*.pfnUnwindFrame = */      rtDbgModPdb_UnwindFrame,
     3791
     3792    /*.u32EndMagic = */         RTDBGMODVTDBG_MAGIC
     3793};
     3794
     3795
  • trunk/src/VBox/Runtime/common/dbg/dbgmodcontainer.cpp

    r98103 r100931  
    879879
    880880/** @copydoc RTDBGMODVTDBG::pfnTryOpen */
    881 static DECLCALLBACK(int) rtDbgModContainer_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
    882 {
    883     NOREF(pMod); NOREF(enmArch);
     881static DECLCALLBACK(int) rtDbgModContainer_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch, RTDBGCFG hDbgCfg)
     882{
     883    NOREF(pMod); NOREF(enmArch); RT_NOREF_PV(hDbgCfg);
    884884    return VERR_INTERNAL_ERROR_5;
    885885}
  • trunk/src/VBox/Runtime/common/dbg/dbgmoddbghelp.cpp

    r98103 r100931  
    409409
    410410/** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */
    411 static DECLCALLBACK(int) rtDbgModDbgHelp_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
    412 {
    413     NOREF(enmArch);
     411static DECLCALLBACK(int) rtDbgModDbgHelp_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch, RTDBGCFG hDbgCfg)
     412{
     413    NOREF(enmArch); RT_NOREF_PV(hDbgCfg);
    414414
    415415    /*
  • trunk/src/VBox/Runtime/common/dbg/dbgmoddeferred.cpp

    r98103 r100931  
    432432
    433433/** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */
    434 static DECLCALLBACK(int) rtDbgModDeferredDbg_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
    435 {
    436     NOREF(enmArch);
     434static DECLCALLBACK(int) rtDbgModDeferredDbg_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch, RTDBGCFG hDbgCfg)
     435{
     436    NOREF(enmArch); RT_NOREF_PV(hDbgCfg);
    437437    return rtDbgModDeferredDoIt(pMod, true /*fForceRetry*/);
    438438}
  • trunk/src/VBox/Runtime/common/dbg/dbgmoddwarf.cpp

    r99775 r100931  
    61106110
    61116111/** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */
    6112 static DECLCALLBACK(int) rtDbgModDwarf_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
    6113 {
     6112static DECLCALLBACK(int) rtDbgModDwarf_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch, RTDBGCFG hDbgCfg)
     6113{
     6114    RT_NOREF_PV(hDbgCfg);
     6115
    61146116    /*
    61156117     * DWARF is only supported when part of an image.
  • trunk/src/VBox/Runtime/common/dbg/dbgmodghidra.cpp

    r98103 r100931  
    432432
    433433/** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */
    434 static DECLCALLBACK(int) rtDbgModGhidra_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
    435 {
    436     RT_NOREF(enmArch);
     434static DECLCALLBACK(int) rtDbgModGhidra_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch, RTDBGCFG hDbgCfg)
     435{
     436    RT_NOREF(enmArch); RT_NOREF_PV(hDbgCfg);
    437437
    438438    /*
  • trunk/src/VBox/Runtime/common/dbg/dbgmodmapsym.cpp

    r98103 r100931  
    518518
    519519/** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */
    520 static DECLCALLBACK(int) rtDbgModMapSym_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
    521 {
    522     NOREF(enmArch);
     520static DECLCALLBACK(int) rtDbgModMapSym_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch, RTDBGCFG hDbgCfg)
     521{
     522    NOREF(enmArch); RT_NOREF_PV(hDbgCfg);
    523523
    524524    /*
     
    581581            }
    582582        }
     583        else
     584            rc = VERR_DBG_NO_MATCHING_INTERPRETER;
    583585        RTFileClose(hFile);
    584586    }
  • trunk/src/VBox/Runtime/common/dbg/dbgmodnm.cpp

    r98103 r100931  
    496496
    497497/** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */
    498 static DECLCALLBACK(int) rtDbgModNm_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
    499 {
    500     NOREF(enmArch);
     498static DECLCALLBACK(int) rtDbgModNm_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch, RTDBGCFG hDbgCfg)
     499{
     500    NOREF(enmArch); RT_NOREF_PV(hDbgCfg);
    501501
    502502    /*
  • trunk/src/VBox/Runtime/include/internal/dbgmod.h

    r98103 r100931  
    316316     *                      initialize pDbgOps and pvDbgPriv.
    317317     * @param   enmArch     The desired architecture.
    318      */
    319     DECLCALLBACKMEMBER(int, pfnTryOpen,(PRTDBGMODINT pMod, RTLDRARCH enmArch));
     318     * @param   hDbgCfg     Optional DBG configuration handle, for loading
     319     *                      additional external files and later logging debug file
     320     *                      errors during load.  Specifically this is to try deal
     321     *                      with stuff like the Windows 2000 DBG files which
     322     *                      contains a link to the PDB file with the actual symbol
     323     *                      information.
     324     */
     325    DECLCALLBACKMEMBER(int, pfnTryOpen,(PRTDBGMODINT pMod, RTLDRARCH enmArch, RTDBGCFG hDbgCfg));
    320326
    321327    /**
     
    702708extern DECL_HIDDEN_DATA(RTSTRCACHE)             g_hDbgModStrCache;
    703709extern DECL_HIDDEN_DATA(RTDBGMODVTDBG const)    g_rtDbgModVtDbgCodeView;
     710extern DECL_HIDDEN_DATA(RTDBGMODVTDBG const)    g_rtDbgModVtDbgPdb;
    704711extern DECL_HIDDEN_DATA(RTDBGMODVTDBG const)    g_rtDbgModVtDbgDwarf;
    705712extern DECL_HIDDEN_DATA(RTDBGMODVTDBG const)    g_rtDbgModVtDbgNm;
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