VirtualBox

Ignore:
Timestamp:
Aug 22, 2023 10:56:32 PM (18 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
158886
Message:

IPRT/dbg: Rewroked the CV/DBG+PDB loading so that we support loading the PDB linked to by the windows 2000 area DBG files. Merged the PDB section loading code with the existing DBG one.

Location:
trunk/src/VBox/Runtime/common/dbg
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/dbg/dbgmod.cpp

    r100931 r100948  
    436436                            pDbgMod->pDbgVt = pCur->pVt;
    437437                            pDbgMod->pvDbgPriv = NULL;
    438                             rc = pCur->pVt->pfnTryOpen(pDbgMod, RTLDRARCH_WHATEVER, NIL_RTDBGCFG);
     438                            rc = pCur->pVt->pfnTryOpen(pDbgMod, RTLDRARCH_WHATEVER, hDbgCfg);
    439439                            if (RT_SUCCESS(rc))
    440440                            {
     
    527527    PCRTLDRDBGINFO      pDbgInfo  = (PCRTLDRDBGINFO)pvUser2;
    528528    RT_NOREF_PV(pDbgInfo); /** @todo consider a more direct search for a interpreter. */
    529     RT_NOREF_PV(hDbgCfg);
    530529
    531530    Assert(!pDbgMod->pDbgVt);
     
    546545            pDbgMod->pDbgVt    = pDbg->pVt;
    547546            pDbgMod->pvDbgPriv = NULL;
    548             rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod), NIL_RTDBGCFG);
     547            rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod), hDbgCfg);
    549548            if (RT_SUCCESS(rc))
    550549            {
     
    699698    PRTDBGMODINT        pDbgMod   = (PRTDBGMODINT)pvUser1;
    700699    RT_NOREF_PV(pvUser2); /** @todo image matching string or smth. */
    701     RT_NOREF_PV(hDbgCfg);
    702700
    703701    Assert(!pDbgMod->pDbgVt);
     
    718716            pDbgMod->pDbgVt    = pDbg->pVt;
    719717            pDbgMod->pvDbgPriv = NULL;
    720             rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod), NIL_RTDBGCFG);
     718            rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod), hDbgCfg);
    721719            if (RT_SUCCESS(rc))
    722720            {
     
    910908                            pDbgMod->pDbgVt = pDbg->pVt;
    911909                            pDbgMod->pvDbgPriv = NULL;
    912                             rc = pDbg->pVt->pfnTryOpen(pDbgMod, enmArch, NIL_RTDBGCFG);
     910                            rc = pDbg->pVt->pfnTryOpen(pDbgMod, enmArch, hDbgCfg);
    913911                            if (RT_SUCCESS(rc))
    914912                            {
     
    13191317                        pDbgMod->pDbgVt    = pDbg->pVt;
    13201318                        pDbgMod->pvDbgPriv = NULL;
    1321                         rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod), NIL_RTDBGCFG);
     1319                        rc = pDbg->pVt->pfnTryOpen(pDbgMod, pDbgMod->pImgVt->pfnGetArch(pDbgMod), hDbgCfg);
    13221320                        if (RT_SUCCESS(rc))
    13231321                        {
  • trunk/src/VBox/Runtime/common/dbg/dbgmodcodeview.cpp

    r100932 r100948  
    134134    /** @} */
    135135
     136    /** @name External PDB (v2) with a DBG file.
     137     * @{ */
     138    /** The resolved PDB path (RTStrFree). */
     139    char           *pszPdbFilename;
     140    /** The PDB VFS.  This is only valid between rtDbgModCvOpenPdb20Callback()
     141     *  and the end of rtDbgModCv_TryOpen(). */
     142    RTVFS           hVfsPdb;
     143    /** @} */
     144
    136145    /** The file type. */
    137146    RTCVFILETYPE    enmType;
     
    235244
    236245
     246
     247/*********************************************************************************************************************************
     248*   Internal Functions                                                                                                           *
     249*********************************************************************************************************************************/
     250static int rtDbgModPdb_CommonOpenWorker(PRTDBGMODCV pThis, const char *pszFilename, RTVFS hVfsPdb, RTDBGCFG hDbgCfg);
    237251
    238252
     
    26282642        RTFileClose(pThis->hFile);
    26292643    RTMemFree(pThis->paDirEnts);
     2644    RTStrFree(pThis->pszPdbFilename);
     2645    RTVfsRelease(pThis->hVfsPdb);
     2646    pThis->hVfsPdb = NIL_RTVFS;
    26302647    RTMemFree(pThis);
    26312648
     
    26652682
    26662683/**
     2684 * Helper for rounding the section size up to the start of the start of the
     2685 * next section (e.g. RTLDRSEG::cbMapped approximation).
     2686 */
     2687DECLINLINE(uint32_t) rtDbgModCvAdjustSectionSizeByNext(PCIMAGE_SECTION_HEADER paShs, uint32_t cShs,
     2688                                                       uint32_t iCur, uint32_t cbMapped)
     2689{
     2690    size_t iNext = iCur + 1;
     2691    while (iNext < cShs && (paShs[iNext].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
     2692        iNext++;
     2693    if (iNext < cShs)
     2694    {
     2695        uint32_t cbAvailable = paShs[iNext].VirtualAddress - (iCur != ~(size_t)0 ? paShs[iCur].VirtualAddress : 0);
     2696        Assert(cbMapped <= cbAvailable);
     2697        return cbAvailable;
     2698    }
     2699    return cbMapped;
     2700}
     2701
     2702
     2703/**
     2704 * Copies the sections over from the DBG file.
     2705 *
     2706 * Called if we don't have an associated executable image.
     2707 *
     2708 * @returns IPRT status code.
     2709 * @param   pThis               The CV module instance.
     2710 * @param   paShs               The section headers.
     2711 * @param   cShs                The number of section headers.
     2712 * @param   cbSectionAlign      The section alignment
     2713 *                              (IMAGE_SEPARATE_DEBUG_HEADER::SectionAlignment,
     2714 *                              IMAGE_OPTIONAL_HEADER32::SectionAlignment, ++).
     2715 * @param   cbImage             The image size (if not availble, UINT32_MAX).
     2716 * @param   pszFilename         The filename (for logging).
     2717 */
     2718static int rtDbgModCvAddSegmentsFromSectHdrs(PRTDBGMODCV pThis, PCIMAGE_SECTION_HEADER paShs, uint32_t cShs,
     2719                                             uint32_t cbSectionAlign, uint32_t cbImage, const char *pszFilename)
     2720{
     2721    RT_NOREF_PV(pszFilename);
     2722    Assert(RT_IS_POWER_OF_TWO(cbSectionAlign));
     2723
     2724    /*
     2725     * Do some basic validation of the section headers.
     2726     */
     2727    int      rc        = VINF_SUCCESS;
     2728    uint32_t cbHeaders = 0;
     2729    uint32_t uRvaPrev  = 0;
     2730    for (uint32_t i = 0; i < cShs; i++)
     2731    {
     2732        Log3(("RTDbgModCv: Section #%02u %#010x LB %#010x %.*s\n",
     2733              i, paShs[i].VirtualAddress, paShs[i].Misc.VirtualSize, sizeof(paShs[i].Name), paShs[i].Name));
     2734
     2735        if (paShs[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)
     2736            continue;
     2737
     2738        if (paShs[i].VirtualAddress < uRvaPrev)
     2739        {
     2740            Log(("RTDbgModCv: %s: Overlap or sorting error, VirtualAddress=%#x uRvaPrev=%#x - section #%d '%.*s'!!!\n",
     2741                 pszFilename, paShs[i].VirtualAddress, uRvaPrev, i, sizeof(paShs[i].Name), paShs[i].Name));
     2742            rc = VERR_CV_BAD_FORMAT;
     2743        }
     2744        else if (   paShs[i].VirtualAddress                             > cbImage
     2745                 || paShs[i].Misc.VirtualSize                           > cbImage
     2746                 || paShs[i].VirtualAddress + paShs[i].Misc.VirtualSize > cbImage)
     2747        {
     2748            Log(("RTDbgModCv: %s: VirtualAddress=%#x VirtualSize=%#x (total %x) - beyond image size (%#x) - section #%d '%.*s'!!!\n",
     2749                 pszFilename, paShs[i].VirtualAddress, paShs[i].Misc.VirtualSize,
     2750                 paShs[i].VirtualAddress + paShs[i].Misc.VirtualSize,
     2751                 pThis->cbImage, i, sizeof(paShs[i].Name), paShs[i].Name));
     2752            rc = VERR_CV_BAD_FORMAT;
     2753        }
     2754        else if (paShs[i].VirtualAddress & (cbSectionAlign - 1))
     2755        {
     2756            Log(("RTDbgModCv: %s: VirtualAddress=%#x misaligned (%#x) - section #%d '%.*s'!!!\n",
     2757                 pszFilename, paShs[i].VirtualAddress, cbSectionAlign, i, sizeof(paShs[i].Name), paShs[i].Name));
     2758            rc = VERR_CV_BAD_FORMAT;
     2759        }
     2760        else if (paShs[i].Characteristics & IMAGE_SCN_ALIGN_MASK)
     2761        {
     2762            uint32_t const cbAlign = RT_BIT_32((paShs[i].Characteristics & IMAGE_SCN_ALIGN_MASK) >> IMAGE_SCN_ALIGN_SHIFT);
     2763            if (RT_ALIGN_32(paShs[i].VirtualAddress, cbAlign) != paShs[i].VirtualAddress)
     2764            {
     2765                Log(("RTDbgModCv: %s: VirtualAddress=%#x misaligned by flags (%#x) - section #%d '%.*s'!!!\n",
     2766                     pszFilename, paShs[i].VirtualAddress, cbAlign, i, sizeof(paShs[i].Name), paShs[i].Name));
     2767                rc = VERR_CV_BAD_FORMAT;
     2768            }
     2769        }
     2770
     2771        if (uRvaPrev == 0)
     2772            cbHeaders = paShs[i].VirtualAddress;
     2773        uRvaPrev = paShs[i].VirtualAddress + paShs[i].Misc.VirtualSize;
     2774    }
     2775    if (uRvaPrev == 0)
     2776    {
     2777        Log(("RTDbgModCv: %s: No loadable sections.\n", pszFilename));
     2778        rc = VERR_CV_BAD_FORMAT;
     2779    }
     2780    if (cbHeaders == 0)
     2781    {
     2782        Log(("RTDbgModCv: %s: No space for PE headers.\n", pszFilename));
     2783        rc = VERR_CV_BAD_FORMAT;
     2784    }
     2785    if (RT_SUCCESS(rc))
     2786    {
     2787        /*
     2788         * Add sections.
     2789         */
     2790        rc = RTDbgModSegmentAdd(pThis->hCnt, 0, cbHeaders, "NtHdrs", 0 /*fFlags*/, NULL);
     2791        if (RT_SUCCESS(rc))
     2792        {
     2793            for (uint32_t i = 0; RT_SUCCESS(rc) && i < cShs; i++)
     2794            {
     2795                char szName[sizeof(paShs[i].Name) + 1];
     2796                memcpy(szName, paShs[i].Name, sizeof(paShs[i].Name));
     2797                szName[sizeof(szName) - 1] = '\0';
     2798                RTStrStripR(szName);
     2799
     2800                uint32_t uRva = paShs[i].VirtualAddress;
     2801                uint32_t cbMapped;
     2802                if (!(paShs[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
     2803                    cbMapped = rtDbgModCvAdjustSectionSizeByNext(paShs, cShs, i, paShs[i].Misc.VirtualSize);
     2804                else
     2805                    uRva = cbMapped = 0;
     2806                rc = RTDbgModSegmentAdd(pThis->hCnt, paShs[i].VirtualAddress, cbMapped, szName, 0 /*fFlags*/, NULL);
     2807                if (RT_FAILURE(rc))
     2808                {
     2809                    Log(("RTDbgModCv: RTDbgModSegmentAdd failed on #%u: uRva=%#RX32 cbMapped=%#RX32 Flags=%#RX32 '%s' -> %Rrc\n",
     2810                         i + 1, uRva, cbMapped, szName, paShs[i].Characteristics, rc));
     2811                    break;
     2812                }
     2813
     2814            }
     2815            if (RT_SUCCESS(rc))
     2816                pThis->fHaveLoadedSegments = true;
     2817        }
     2818        else
     2819            Log(("RTDbgModCv: RTDbgModSegmentAdd on 'NtHdrs': cbHeaders=%#RX32 - %Rrc\n", cbHeaders, rc));
     2820    }
     2821    return rc;
     2822}
     2823
     2824
     2825/**
    26672826 * Copies the sections over from the DBG file.
    26682827 *
     
    26872846        return VERR_CV_BAD_FORMAT;
    26882847    }
    2689     if (!RT_IS_POWER_OF_TWO(pDbgHdr->SectionAlignment))
    2690     {
    2691         Log(("RTDbgModCv: Bad SectionAlignment: %#x\n", pDbgHdr->SectionAlignment));
    2692         return VERR_CV_BAD_FORMAT;
    2693     }
    26942848
    26952849    /*
    26962850     * Read the section table.
    26972851     */
    2698     size_t cbShs = pDbgHdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
    2699     PIMAGE_SECTION_HEADER paShs = (PIMAGE_SECTION_HEADER)RTMemAlloc(cbShs);
    2700     if (!paShs)
    2701         return VERR_NO_MEMORY;
    2702     int rc = RTFileReadAt(pThis->hFile, sizeof(*pDbgHdr), paShs, cbShs, NULL);
    2703     if (RT_SUCCESS(rc))
    2704     {
    2705         /*
    2706          * Do some basic validation.
    2707          */
    2708         uint32_t cbHeaders = 0;
    2709         uint32_t uRvaPrev = 0;
    2710         for (uint32_t i = 0; i < pDbgHdr->NumberOfSections; i++)
    2711         {
    2712             Log3(("RTDbgModCv: Section #%02u %#010x LB %#010x %.*s\n",
    2713                   i, paShs[i].VirtualAddress, paShs[i].Misc.VirtualSize, sizeof(paShs[i].Name), paShs[i].Name));
    2714 
    2715             if (paShs[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)
    2716                 continue;
    2717 
    2718             if (paShs[i].VirtualAddress < uRvaPrev)
    2719             {
    2720                 Log(("RTDbgModCv: %s: Overlap or soring error, VirtualAddress=%#x uRvaPrev=%#x - section #%d '%.*s'!!!\n",
    2721                      pszFilename, paShs[i].VirtualAddress, uRvaPrev, i, sizeof(paShs[i].Name), paShs[i].Name));
    2722                 rc = VERR_CV_BAD_FORMAT;
    2723             }
    2724             else if (   paShs[i].VirtualAddress > pDbgHdr->SizeOfImage
    2725                      || paShs[i].Misc.VirtualSize > pDbgHdr->SizeOfImage
    2726                      || paShs[i].VirtualAddress + paShs[i].Misc.VirtualSize > pDbgHdr->SizeOfImage)
    2727             {
    2728                 Log(("RTDbgModCv: %s: VirtualAddress=%#x VirtualSize=%#x (total %x) - beyond image size (%#x) - section #%d '%.*s'!!!\n",
    2729                      pszFilename, paShs[i].VirtualAddress, paShs[i].Misc.VirtualSize,
    2730                      paShs[i].VirtualAddress + paShs[i].Misc.VirtualSize,
    2731                      pThis->cbImage, i, sizeof(paShs[i].Name), paShs[i].Name));
    2732                 rc = VERR_CV_BAD_FORMAT;
    2733             }
    2734             else if (paShs[i].VirtualAddress & (pDbgHdr->SectionAlignment - 1))
    2735             {
    2736                 Log(("RTDbgModCv: %s: VirtualAddress=%#x misaligned (%#x) - section #%d '%.*s'!!!\n",
    2737                      pszFilename, paShs[i].VirtualAddress, pDbgHdr->SectionAlignment, i, sizeof(paShs[i].Name), paShs[i].Name));
    2738                 rc = VERR_CV_BAD_FORMAT;
    2739             }
    2740             else
    2741             {
    2742                 if (uRvaPrev == 0)
    2743                     cbHeaders = paShs[i].VirtualAddress;
    2744                 uRvaPrev = paShs[i].VirtualAddress + paShs[i].Misc.VirtualSize;
    2745                 continue;
    2746             }
    2747         }
    2748         if (RT_SUCCESS(rc) && uRvaPrev == 0)
    2749         {
    2750             Log(("RTDbgModCv: %s: No loadable sections.\n", pszFilename));
    2751             rc = VERR_CV_BAD_FORMAT;
    2752         }
    2753         if (RT_SUCCESS(rc) && cbHeaders == 0)
    2754         {
    2755             Log(("RTDbgModCv: %s: No space for PE headers.\n", pszFilename));
    2756             rc = VERR_CV_BAD_FORMAT;
    2757         }
     2852    size_t const                cbShs = pDbgHdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
     2853    PIMAGE_SECTION_HEADER const paShs = (PIMAGE_SECTION_HEADER)RTMemTmpAlloc(cbShs);
     2854    if (paShs)
     2855    {
     2856        int rc = RTFileReadAt(pThis->hFile, sizeof(*pDbgHdr), paShs, cbShs, NULL);
    27582857        if (RT_SUCCESS(rc))
    27592858        {
    27602859            /*
    2761              * Add sections.
     2860             * Process them.
    27622861             */
    2763             rc = RTDbgModSegmentAdd(pThis->hCnt, 0, cbHeaders, "NtHdrs", 0 /*fFlags*/, NULL);
    2764             for (uint32_t i = 0; RT_SUCCESS(rc) && i < pDbgHdr->NumberOfSections; i++)
    2765             {
    2766                 char szName[sizeof(paShs[i].Name) + 1];
    2767                 memcpy(szName, paShs[i].Name, sizeof(paShs[i].Name));
    2768                 szName[sizeof(szName) - 1] = '\0';
    2769 
    2770                 if (paShs[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)
    2771                     rc = RTDbgModSegmentAdd(pThis->hCnt, 0, 0, szName, 0 /*fFlags*/, NULL);
    2772                 else
    2773                     rc = RTDbgModSegmentAdd(pThis->hCnt, paShs[i].VirtualAddress, paShs[i].Misc.VirtualSize, szName,
    2774                                             0 /*fFlags*/, NULL);
    2775             }
    2776             if (RT_SUCCESS(rc))
    2777                 pThis->fHaveLoadedSegments = true;
    2778         }
    2779     }
    2780 
    2781     RTMemFree(paShs);
    2782     return rc;
     2862            rc = rtDbgModCvAddSegmentsFromSectHdrs(pThis, paShs, pDbgHdr->NumberOfSections, pDbgHdr->SectionAlignment,
     2863                                                   pDbgHdr->SizeOfImage, pszFilename);
     2864        }
     2865        RTMemTmpFree(paShs);
     2866        return rc;
     2867    }
     2868    return VERR_NO_TMP_MEMORY;
    27832869}
    27842870
     
    28242910        pThis->offBase          = UINT32_MAX;
    28252911        pThis->offCoffDbgInfo   = UINT32_MAX;
     2912        pThis->hVfsPdb          = NIL_RTVFS;
    28262913        *ppThis = pThis;
    28272914        return VINF_SUCCESS;
     
    29233010}
    29243011
     3012/**
     3013 * Argument package for rtDbgModCvOpenPdb20Callback via pvUser2.
     3014 */
     3015typedef struct RTDBGMODCVOPENPDB20CALLBACK
     3016{
     3017    RTLDRARCH       enmArch;
     3018    RTFILE          hFile;
     3019    RTCVFILETYPE    enmFileType;
     3020    uint32_t        uTimestamp;
     3021    uint32_t        uAge;
     3022} RTDBGMODCVOPENPDB20CALLBACK;
     3023
     3024/** @callback_method_impl{FNRTDBGCFGOPEN,
     3025 *      For opening PDB linked in windows 2000 area DBG files.}
     3026 */
     3027static DECLCALLBACK(int) rtDbgModCvOpenPdb20Callback(RTDBGCFG hDbgCfg, const char *pszFilename, void *pvUser1, void *pvUser2)
     3028{
     3029    PRTDBGMODINT const                  pDbgMod = (PRTDBGMODINT)pvUser1;
     3030    RTDBGMODCVOPENPDB20CALLBACK * const pArgs   = (RTDBGMODCVOPENPDB20CALLBACK *)pvUser2;
     3031    RT_NOREF(hDbgCfg);
     3032
     3033    /*
     3034     * Open the file as a VFS and check that the timestamp and age matches
     3035     * what we're looking for.
     3036     */
     3037    Log2(("rtDbgModCvOpenPdb20Callback: Trying '%s'...\n", pszFilename));
     3038    RTVFSFILE hVfsFilePdb = NIL_RTVFSFILE;
     3039    int rc = RTVfsFileOpenNormal(pszFilename, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, &hVfsFilePdb);
     3040    if (RT_SUCCESS(rc))
     3041    {
     3042        RTVFS           hVfsPdb = NIL_RTVFS;
     3043#ifdef LOG_ENABLED
     3044        RTERRINFOSTATIC ErrInfo;
     3045        rc = RTFsPdbVolOpen(hVfsFilePdb, 0, &hVfsPdb, RTErrInfoInitStatic(&ErrInfo));
     3046#else
     3047        rc = RTFsPdbVolOpen(hVfsFilePdb, 0, &hVfsPdb, NULL /*pErrInfo*/);
     3048#endif
     3049        RTVfsFileRelease(hVfsFilePdb);
     3050        if (RT_SUCCESS(rc))
     3051        {
     3052            /*
     3053             * The timestamp + age is available as a string.
     3054             */
     3055            size_t cbRet;
     3056            char   szTimestampAndAge[64] = {0};
     3057            rc = RTVfsQueryLabel(hVfsPdb, false /*RTVFSQIEX_VOL_LABEL*/,
     3058                                 szTimestampAndAge, sizeof(szTimestampAndAge) - 1, &cbRet);
     3059            AssertRC(rc);
     3060            if (RT_SUCCESS(rc))
     3061            {
     3062                char szExpect[64];
     3063                RTStrPrintf(szExpect, sizeof(szExpect), "%08X%x", pArgs->uTimestamp, pArgs->uAge);
     3064                if (RTStrICmpAscii(szTimestampAndAge, szExpect) == 0)
     3065                {
     3066                    /** @todo check ARCH. It's usually in the DBI header.   */
     3067
     3068                    /*
     3069                     * Okay, we're good.
     3070                     */
     3071                    PRTDBGMODCV pThis;
     3072                    rc = rtDbgModCvCreateInstance(pDbgMod, pArgs->enmFileType, pArgs->hFile, &pThis);
     3073                    if (RT_SUCCESS(rc))
     3074                    {
     3075                        pThis->u32CvMagic     = RTCVHDR_MAGIC_NB10;
     3076                        pThis->offBase        = UINT32_MAX;
     3077                        pThis->cbDbgInfo      = 0;
     3078                        pThis->offDir         = 0;
     3079                        pThis->pszPdbFilename = RTStrDup(pszFilename);
     3080                        if (pThis->pszPdbFilename)
     3081                        {
     3082                            pThis->hVfsPdb = hVfsPdb;
     3083                            return VINF_CALLBACK_RETURN;
     3084                        }
     3085                    }
     3086                }
     3087                else
     3088                    Log2(("RTFsPdbVolOpen: timestamp+age mismatch: %s, expected %s (for '%s')\n",
     3089                          szTimestampAndAge, szExpect, pszFilename));
     3090            }
     3091        }
     3092        else
     3093            Log2(("RTFsPdbVolOpen: RTVfsFileOpenNormal '%s' failed: %Rrc%#RTeim\n", pszFilename, rc, &ErrInfo.Core));
     3094    }
     3095    else
     3096        Log2(("rtDbgModCvOpenPdb20Callback: RTVfsFileOpenNormal '%s' failed: %Rrc\n", pszFilename, rc));
     3097    return rc;
     3098}
     3099
    29253100
    29263101/**
     
    29363111 * @param   cb                  The number of bytes of debug info.
    29373112 * @param   enmArch             The desired image architecture.
     3113 * @param   cbImage             The image size, if available.
    29383114 * @param   pszFilename         The path to the file (for logging).
     3115 * @param   hDbgCfg             For dealing with external PDB found in windows
     3116 *                              2000 area DBG files.
    29393117 */
    29403118static int rtDbgModCvProbeCommon(PRTDBGMODINT pDbgMod, PRTCVHDR pCvHdr, RTCVFILETYPE enmFileType, RTFILE hFile,
    2941                                  uint32_t off, uint32_t cb, RTLDRARCH enmArch, const char *pszFilename)
     3119                                 uint32_t off, uint32_t cb, RTLDRARCH enmArch, size_t cbImage,
     3120                                 const char *pszFilename, RTDBGCFG hDbgCfg)
    29423121{
    29433122    int rc = VERR_DBG_NO_MATCHING_INTERPRETER;
     
    29853164        if (pCvHdr->off == 0)
    29863165        {
    2987             if (cb >= sizeof(CVPDB20INFO) && cb < _64K)
     3166            if (cb > RT_UOFFSETOF(CVPDB20INFO, szPdbFilename) && cb < _64K)
    29883167            {
     3168                /*
     3169                 * Read it into memory and validate it.
     3170                 */
    29893171                PCVPDB20INFO pInfo = (PCVPDB20INFO)RTMemTmpAlloc(cb);
    29903172                if (pInfo)
     
    29933175                    if (RT_SUCCESS(rc2))
    29943176                    {
    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]));
     3177                        uint32_t const cbPdbFilename = cb - RT_UOFFSETOF(CVPDB20INFO, szPdbFilename);
     3178                        rc2 = RTStrValidateEncodingEx((char const *)&pInfo->szPdbFilename[0], cbPdbFilename,
     3179                                                      RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED);
     3180                        if (RT_SUCCESS(rc2))
     3181                        {
     3182                            Log2(("RTDbgModCv: Found external PDB (v2.0): TS=%#010RX32 uAge=%x '%.*s'\n",  pInfo->uTimestamp,
     3183                                  pInfo->uAge, cb - RT_UOFFSETOF(CVPDB20INFO, szPdbFilename), &pInfo->szPdbFilename[0]));
     3184                            if (   hDbgCfg != NIL_RTDBGCFG
     3185                                && enmFileType == RTCVFILETYPE_DBG)
     3186                            {
     3187                                /*
     3188                                 * Try open it. Need to figure the image size first if
     3189                                 * we can, though not actually used by the function.
     3190                                 *
     3191                                 * The callback will create an instance if a PDB is found,
     3192                                 * but it won't actually read it. That's done later by the
     3193                                 * RTDbgModCv_TryOpen code.
     3194                                 */
     3195                                RTDBGMODCVOPENPDB20CALLBACK Args = { enmArch, hFile, enmFileType, pInfo->uTimestamp, pInfo->uAge };
     3196                                rc = RTDbgCfgOpenPdb20(hDbgCfg, (const char *)&pInfo->szPdbFilename[0],
     3197                                                       cbImage, pInfo->uTimestamp, pInfo->uAge,
     3198                                                       rtDbgModCvOpenPdb20Callback, pDbgMod, &Args);
     3199                                Log(("RTDbgModCv: RTDbgCfgOpenPdb20 returns %Rrc\n", rc));
     3200                            }
     3201                        }
     3202                        else
     3203                            Log(("RTDbgModCv: Found external PDB (v2.0) w/ invalid filename encoding: TS=%#010RX32 uAge=%x %.*Rhxs rc2=%Rrc\n",
     3204                                 pInfo->uTimestamp, pInfo->uAge, cbPdbFilename, &pInfo->szPdbFilename[0], rc2));
    29973205                    }
     3206                    else
     3207                        Log(("RTDbgModCv: NB10 read error - %Rrc\n", rc2));
     3208                    RTMemTmpFree(pInfo);
    29983209                }
     3210                else
     3211                    rc = VERR_NO_TMP_MEMORY;
    29993212            }
    3000         }
     3213            else
     3214                Log(("RTDbgModCv: NB10 with bogus size: %#x\n", cb));
     3215        }
     3216        else
     3217            Log(("RTDbgModCv: NB10 with non-zero offset!\n"));
    30013218    }
    30023219    return rc;
    30033220}
     3221
     3222
     3223/**
     3224 * Arguments passed to rtDbgModCvEnumCallback
     3225 */
     3226typedef struct RTDBGMODCVENUMCALLBACKARGS
     3227{
     3228    PRTDBGMODINT    pDbgMod;
     3229    RTDBGCFG        hDbgCfg;
     3230} RTDBGMODCVENUMCALLBACKARGS;
    30043231
    30053232
     
    30073234static DECLCALLBACK(int) rtDbgModCvEnumCallback(RTLDRMOD hLdrMod, PCRTLDRDBGINFO pDbgInfo, void *pvUser)
    30083235{
    3009     PRTDBGMODINT pDbgMod = (PRTDBGMODINT)pvUser;
     3236    RTDBGMODCVENUMCALLBACKARGS * const pArgs   = (RTDBGMODCVENUMCALLBACKARGS *)pvUser;
     3237    PRTDBGMODINT  const                pDbgMod = pArgs->pDbgMod;
    30103238    Assert(!pDbgMod->pvDbgPriv);
    30113239    RT_NOREF_PV(hLdrMod);
     
    30243252        if (RT_SUCCESS(rc))
    30253253            rc = rtDbgModCvProbeCommon(pDbgMod, &CvHdr, RTCVFILETYPE_IMAGE, NIL_RTFILE, pDbgInfo->offFile, pDbgInfo->cb,
    3026                                        pDbgMod->pImgVt->pfnGetArch(pDbgMod), pDbgMod->pszImgFile);
     3254                                       pDbgMod->pImgVt->pfnGetArch(pDbgMod), pDbgMod->pImgVt->pfnImageSize(pDbgMod),
     3255                                       pDbgMod->pszImgFile, pArgs->hDbgCfg);
    30273256    }
    30283257    else if (pDbgInfo->enmType == RTLDRDBGINFOTYPE_COFF)
     
    30473276 * @param   cb                  The number of bytes of debug info.
    30483277 * @param   enmArch             The desired image architecture.
     3278 * @param   cbImage             The image size (for PDB lookup, see hDbgCfg).
    30493279 * @param   pszFilename         The path to the file (for logging).
     3280 * @param   hDbgCfg             Optional debug config handle for locating PDB
     3281 *                              linked to by NB10 records (in DBG and
     3282 *                              elsewhere).
    30503283 */
    30513284static int rtDbgModCvProbeFile2(PRTDBGMODINT pThis, RTCVFILETYPE enmFileType, RTFILE hFile, uint32_t off, uint32_t cb,
    3052                                 RTLDRARCH enmArch, const char *pszFilename)
     3285                                RTLDRARCH enmArch, size_t cbImage, const char *pszFilename, RTDBGCFG hDbgCfg)
    30533286{
    30543287    RTCVHDR CvHdr;
    30553288    int rc = RTFileReadAt(hFile, off, &CvHdr, sizeof(CvHdr), NULL);
    30563289    if (RT_SUCCESS(rc))
    3057         rc = rtDbgModCvProbeCommon(pThis, &CvHdr, enmFileType, hFile, off, cb, enmArch, pszFilename);
     3290        rc = rtDbgModCvProbeCommon(pThis, &CvHdr, enmFileType, hFile, off, cb, enmArch, cbImage, pszFilename, hDbgCfg);
    30583291    return rc;
    30593292}
     
    30953328 * @param   pszFilename         The path to the file to probe.
    30963329 * @param   enmArch             The desired image architecture.
    3097  */
    3098 static int rtDbgModCvProbeFile(PRTDBGMODINT pDbgMod, const char *pszFilename, RTLDRARCH enmArch)
     3330 * @param   hDbgCfg             Optional debug config handle for locating PDB
     3331 *                              linked to by NB10 records (in DBG and
     3332 *                              elsewhere).
     3333 */
     3334static int rtDbgModCvProbeFile(PRTDBGMODINT pDbgMod, const char *pszFilename, RTLDRARCH enmArch, RTDBGCFG hDbgCfg)
    30993335{
    31003336    RTFILE hFile;
     
    31703406                rc = rtDbgModCvProbeFile2(pDbgMod, RTCVFILETYPE_DBG, hFile,
    31713407                                          DbgDir.PointerToRawData, DbgDir.SizeOfData,
    3172                                           enmArch, pszFilename);
     3408                                          enmArch, DbgHdr.SizeOfImage, pszFilename, hDbgCfg);
    31733409            else if (DbgDir.Type == IMAGE_DEBUG_TYPE_COFF)
    31743410                rc = rtDbgModCvProbeCoff(pDbgMod, RTCVFILETYPE_DBG, hFile,
     
    32313467        if (RT_SUCCESS(rc))
    32323468            rc = rtDbgModCvProbeFile2(pDbgMod, RTCVFILETYPE_OTHER_AT_END, hFile,
    3233                                       cbFile - CvHdr.off, CvHdr.off, enmArch, pszFilename);
     3469                                      cbFile - CvHdr.off, CvHdr.off, enmArch,
     3470                                      pDbgMod->pImgVt ? pDbgMod->pImgVt->pfnImageSize(pDbgMod) : 0 /*cbImage */,
     3471                                      pszFilename, hDbgCfg);
    32343472    }
    32353473
     
    32493487    int rc = VERR_DBG_NO_MATCHING_INTERPRETER;
    32503488    if (pMod->pszDbgFile)
    3251         rc = rtDbgModCvProbeFile(pMod, pMod->pszDbgFile, enmArch);
     3489        rc = rtDbgModCvProbeFile(pMod, pMod->pszDbgFile, enmArch, hDbgCfg);
    32523490
    32533491    if (!pMod->pvDbgPriv && pMod->pImgVt)
    32543492    {
    3255         int rc2 = pMod->pImgVt->pfnEnumDbgInfo(pMod, rtDbgModCvEnumCallback, pMod);
     3493        RTDBGMODCVENUMCALLBACKARGS Args = { pMod, hDbgCfg };
     3494        int rc2 = pMod->pImgVt->pfnEnumDbgInfo(pMod, rtDbgModCvEnumCallback, &Args);
    32563495        if (RT_FAILURE(rc2))
    32573496            rc = rc2;
     
    32603499        {
    32613500            /* Try the executable in case it has a NBxx tail header. */
    3262             rc2 = rtDbgModCvProbeFile(pMod, pMod->pszImgFile, enmArch);
     3501            rc2 = rtDbgModCvProbeFile(pMod, pMod->pszImgFile, enmArch, hDbgCfg);
    32633502            if (RT_FAILURE(rc2) && (RT_SUCCESS(rc) || rc == VERR_DBG_NO_MATCHING_INTERPRETER))
    32643503                rc = rc2;
     
    32693508    if (!pThis)
    32703509        return RT_SUCCESS_NP(rc) ? VERR_DBG_NO_MATCHING_INTERPRETER : rc;
    3271     Assert(pThis->offBase  != UINT32_MAX || pThis->offCoffDbgInfo != UINT32_MAX);
     3510    Assert(   pThis->offBase != UINT32_MAX
     3511           || pThis->offCoffDbgInfo != UINT32_MAX
     3512           || (pThis->pszPdbFilename != NULL && pThis->hVfsPdb != NIL_RTVFS && pThis->enmType == RTCVFILETYPE_DBG));
    32723513
    32733514    /*
     
    32833524    if (RT_SUCCESS(rc) && pThis->offCoffDbgInfo != UINT32_MAX)
    32843525        rc = rtDbgModCvLoadCoffInfo(pThis);
     3526    if (RT_SUCCESS(rc) && pThis->hVfsPdb != NIL_RTVFS)
     3527    {
     3528        rc = rtDbgModPdb_CommonOpenWorker(pThis, pThis->pszPdbFilename, pThis->hVfsPdb, hDbgCfg);
     3529        RTVfsRelease(pThis->hVfsPdb);
     3530        pThis->hVfsPdb = NIL_RTVFS;
     3531    }
    32853532    if (RT_SUCCESS(rc))
    32863533    {
     
    34773724static DECLCALLBACK(int) rtDbgModPdb_Close(PRTDBGMODINT pMod)
    34783725{
    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;
     3726    return rtDbgModCv_Close(pMod);
    34893727}
    34903728
     
    34973735 */
    34983736
    3499 static int rtDbgModPdb_ScanSymRecs(PRTDBGMODCV pThis, RTVFSFILE hVfsFileSymRecs)
    3500 {
    3501     void    *pvSymRecs;
    3502     size_t   cbSymRecs;
    3503     int rc = RTVfsFileReadAll(hVfsFileSymRecs, &pvSymRecs, &cbSymRecs);
     3737static int rtDbgModPdb_ScanSymRecs(PRTDBGMODCV pThis, RTVFS hVfsPdb)
     3738{
     3739    RTVFSFILE hVfsFileSymRecs = NIL_RTVFSFILE;
     3740    int rc = RTVfsFileOpen(hVfsPdb, "symbol-records", RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, &hVfsFileSymRecs);
    35043741    if (RT_SUCCESS(rc))
    35053742    {
    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));
     3743        void    *pvSymRecs;
     3744        size_t   cbSymRecs;
     3745        rc = RTVfsFileReadAll(hVfsFileSymRecs, &pvSymRecs, &cbSymRecs);
     3746        RTVfsFileRelease(hVfsFileSymRecs);
     3747        if (RT_SUCCESS(rc))
     3748        {
     3749            Log3(("rtDbgModPdb_ScanSymRecs: %p LB %#x\n", pvSymRecs, cbSymRecs));
     3750            rc = rtDbgModCvSsProcessV4PlusSymTab(pThis, pvSymRecs, cbSymRecs, 0 /*fFlags*/);
     3751
     3752            RTVfsFileReadAllFree(pvSymRecs, cbSymRecs);
     3753        }
     3754        else
     3755            Log(("rtDbgModPdb_ScanSymRecs: RTVfsFileReadAll failed - %Rrc\n", rc));
     3756    }
    35133757    return rc;
    35143758}
     
    35693813
    35703814
    3571 
    3572 DECLINLINE(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 
    35883815/**
    35893816 * Helper for rtDbgModPdb_TryOpen that loads the section/segments into the
    35903817 * container.
    35913818 */
    3592 static int rtDbgModPdb_LoadSections(PRTDBGMODINT pMod, PRTDBGMODCV pThis, RTVFSFILE hVfsFileSectionHeaders)
     3819static int rtDbgModPdb_LoadSections(PRTDBGMODCV pThis, PRTDBGMODINT pDbgMod, RTVFS hVfsPdb, const char *pszFilename)
    35933820{
    35943821    /*
     
    35963823     */
    35973824    int rc;
    3598     if (pMod->pImgVt)
    3599         rc = pMod->pImgVt->pfnEnumSegments(pMod, rtDbgModCvAddSegmentsCallback, pThis);
     3825    if (pDbgMod->pImgVt)
     3826        rc = pDbgMod->pImgVt->pfnEnumSegments(pDbgMod, rtDbgModCvAddSegmentsCallback, pThis);
    36003827    /*
    36013828     * Otherwise use the copy of the section table from the PDB.
     
    36033830    else
    36043831    {
    3605         PIMAGE_SECTION_HEADER paSHdrs;
    3606         size_t                cbSHdrs;
    3607         rc = RTVfsFileReadAll(hVfsFileSectionHeaders, (void **)&paSHdrs, &cbSHdrs);
     3832        RTVFSFILE hVfsFileSHdrs;
     3833        rc = RTVfsFileOpen(hVfsPdb, "image-section-headers", RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, &hVfsFileSHdrs);
    36083834        if (RT_SUCCESS(rc))
    36093835        {
    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);
     3836            PIMAGE_SECTION_HEADER paShs = NULL;
     3837            size_t                cbSHdrs = 0;
     3838            rc = RTVfsFileReadAll(hVfsFileSHdrs, (void **)&paShs, &cbSHdrs);
     3839            RTVfsFileRelease(hVfsFileSHdrs);
    36183840            if (RT_SUCCESS(rc))
    36193841            {
    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                 }
     3842                rc = rtDbgModCvAddSegmentsFromSectHdrs(pThis, paShs, cbSHdrs / sizeof(IMAGE_SECTION_HEADER),
     3843                                                       1 /* cbSectAlign - only for validation */,
     3844                                                       pThis->cbImage ? pThis->cbImage : UINT32_MAX /* only for validation */,
     3845                                                       pszFilename);
     3846                RTVfsFileReadAllFree(paShs, cbSHdrs);
    36593847            }
    36603848            else
    3661                 Log(("rtDbgModPdb_LoadSections: Failed on first: cbMapped=%#RX32 %Rrc\n", cbMapped, rc));
    3662             RTVfsFileReadAllFree(paSHdrs, cbSHdrs);
     3849                Log(("rtDbgModPdb_LoadSections: RTVfsFileReadAll failed - %Rrc\n", rc));
    36633850        }
    36643851        else
    3665             Log(("rtDbgModPdb_LoadSections: RTVfsFileReadAll failed - %Rrc\n", rc));
    3666     }
     3852            Log2(("rtDbgModPdb_TryOpen: Failed to open 'image-section-headers' in '%s' -> %Rrc\n", pszFilename, rc));
     3853    }
     3854    RT_NOREF(pszFilename);
    36673855    pThis->fHaveLoadedSegments = true;
    36683856    return rc;
     
    36703858
    36713859
     3860/**
     3861 * Common worker for rtDbgModPdb_TryOpen and rtDbgModCv_TryOpen (for DBG+PDB).
     3862 */
     3863static int rtDbgModPdb_CommonOpenWorker(PRTDBGMODCV pThis, const char *pszFilename, RTVFS hVfsPdb, RTDBGCFG hDbgCfg)
     3864{
     3865    RT_NOREF(hDbgCfg, pszFilename);
     3866
     3867    /*
     3868     * We need section headers to successfully deal with the section (segment)
     3869     * map and symbol records.  If there is an associated EXE or DBG file, they
     3870     * will have segment information we can enumerate or load.  In the DBG case,
     3871     * it's already done by the time we get here.   Otherwise, newer PDB files
     3872     * will include a copy of the section header and we can use that of we got
     3873     * no EXE or DBG files.
     3874     */
     3875    int rc = VINF_SUCCESS;
     3876    if (!pThis->fHaveLoadedSegments)
     3877        rc = rtDbgModPdb_LoadSections(pThis, pThis->pMod, hVfsPdb, pszFilename);
     3878    if (RT_SUCCESS(rc))
     3879    {
     3880        /*
     3881         * Load the section/segment map as we need to know how absolute segments
     3882         * and such.  This should definitely be done after loading sections.
     3883         * (Unfortuantely, the segement map doesn't not provide sufficient
     3884         * information to replace the section headers if we cannot find them.)
     3885         */
     3886        rc = rtDbgModPdb_LoadSegMap(pThis, hVfsPdb);
     3887        if (RT_SUCCESS(rc))
     3888        {
     3889            /*
     3890             * Scan symbol records for symbol addresses and anything else we find
     3891             * interesting.
     3892             */
     3893            rc = rtDbgModPdb_ScanSymRecs(pThis, hVfsPdb);
     3894            if (RT_SUCCESS(rc))
     3895            {
     3896                /*
     3897                 * We're good.
     3898                 */
     3899                /** @todo load source files and line numbers if present.   */
     3900                /** @todo load unwind information. */
     3901                Log(("rtDbgModPdb_TryOpen: Succeeded\n"));
     3902                return VINF_SUCCESS;
     3903            }
     3904            Log(("rtDbgModPdb_TryOpen: rtDbgModPdb_ScanSymRecs failed - %Rrc\n", rc));
     3905        }
     3906        else
     3907            Log(("rtDbgModPdb_TryOpen: rtDbgModPdb_LoadSegMap failed on '%s' -> %Rrc\n", pszFilename, rc));
     3908    }
     3909    else
     3910        Log(("rtDbgModPdb_TryOpen: rtDbgModPdb_LoadSections failed on '%s' -> %Rrc\n", pszFilename, rc));
     3911    return rc;
     3912}
     3913
     3914
    36723915/** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */
    36733916static DECLCALLBACK(int) rtDbgModPdb_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch, RTDBGCFG hDbgCfg)
    36743917{
    3675     RT_NOREF(hDbgCfg); RT_NOREF(enmArch);
    3676 
    36773918    /*
    36783919     * This only works for external files for now.
     
    36983939        if (RT_SUCCESS(rc))
    36993940        {
     3941            /** @todo check enmArch. It's part of the new DBI header. */
     3942            RT_NOREF(enmArch);
     3943
    37003944            /*
    3701              * Check if we've got the necessary bits present in the PDB.
     3945             * Create an instance so we can share the next bits with the DBG+PDB
     3946             * code path in rtDbgModCv_TryOpen.  We need to be able to check if
     3947             * section headers have been loaded among other things.
    37023948             */
    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);
     3949            PRTDBGMODCV pThis;
     3950            rc = rtDbgModCvCreateInstance(pMod, RTCVFILETYPE_PDB, NIL_RTFILE, &pThis);
    37113951            if (RT_SUCCESS(rc))
    37123952            {
    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);
     3953                rc = rtDbgModPdb_CommonOpenWorker(pThis, pMod->pszDbgFile, hVfsPdb, hDbgCfg);
     3954                if (RT_FAILURE(rc))
     3955                    rtDbgModCv_Close(pMod);
    37493956            }
    3750             else
    3751                 Log2(("rtDbgModPdb_TryOpen: Failed to open 'image-section-headers' in '%s' -> %Rrc\n", pMod->pszDbgFile, rc));
    37523957            RTVfsRelease(hVfsPdb);
    37533958        }
     
    37593964    return rc;
    37603965}
     3966
    37613967
    37623968
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