Changeset 100948 in vbox for trunk/src/VBox/Runtime/common/dbg
- Timestamp:
- Aug 22, 2023 10:56:32 PM (18 months ago)
- svn:sync-xref-src-repo-rev:
- 158886
- Location:
- trunk/src/VBox/Runtime/common/dbg
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/dbg/dbgmod.cpp
r100931 r100948 436 436 pDbgMod->pDbgVt = pCur->pVt; 437 437 pDbgMod->pvDbgPriv = NULL; 438 rc = pCur->pVt->pfnTryOpen(pDbgMod, RTLDRARCH_WHATEVER, NIL_RTDBGCFG);438 rc = pCur->pVt->pfnTryOpen(pDbgMod, RTLDRARCH_WHATEVER, hDbgCfg); 439 439 if (RT_SUCCESS(rc)) 440 440 { … … 527 527 PCRTLDRDBGINFO pDbgInfo = (PCRTLDRDBGINFO)pvUser2; 528 528 RT_NOREF_PV(pDbgInfo); /** @todo consider a more direct search for a interpreter. */ 529 RT_NOREF_PV(hDbgCfg);530 529 531 530 Assert(!pDbgMod->pDbgVt); … … 546 545 pDbgMod->pDbgVt = pDbg->pVt; 547 546 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); 549 548 if (RT_SUCCESS(rc)) 550 549 { … … 699 698 PRTDBGMODINT pDbgMod = (PRTDBGMODINT)pvUser1; 700 699 RT_NOREF_PV(pvUser2); /** @todo image matching string or smth. */ 701 RT_NOREF_PV(hDbgCfg);702 700 703 701 Assert(!pDbgMod->pDbgVt); … … 718 716 pDbgMod->pDbgVt = pDbg->pVt; 719 717 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); 721 719 if (RT_SUCCESS(rc)) 722 720 { … … 910 908 pDbgMod->pDbgVt = pDbg->pVt; 911 909 pDbgMod->pvDbgPriv = NULL; 912 rc = pDbg->pVt->pfnTryOpen(pDbgMod, enmArch, NIL_RTDBGCFG);910 rc = pDbg->pVt->pfnTryOpen(pDbgMod, enmArch, hDbgCfg); 913 911 if (RT_SUCCESS(rc)) 914 912 { … … 1319 1317 pDbgMod->pDbgVt = pDbg->pVt; 1320 1318 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); 1322 1320 if (RT_SUCCESS(rc)) 1323 1321 { -
trunk/src/VBox/Runtime/common/dbg/dbgmodcodeview.cpp
r100932 r100948 134 134 /** @} */ 135 135 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 136 145 /** The file type. */ 137 146 RTCVFILETYPE enmType; … … 235 244 236 245 246 247 /********************************************************************************************************************************* 248 * Internal Functions * 249 *********************************************************************************************************************************/ 250 static int rtDbgModPdb_CommonOpenWorker(PRTDBGMODCV pThis, const char *pszFilename, RTVFS hVfsPdb, RTDBGCFG hDbgCfg); 237 251 238 252 … … 2628 2642 RTFileClose(pThis->hFile); 2629 2643 RTMemFree(pThis->paDirEnts); 2644 RTStrFree(pThis->pszPdbFilename); 2645 RTVfsRelease(pThis->hVfsPdb); 2646 pThis->hVfsPdb = NIL_RTVFS; 2630 2647 RTMemFree(pThis); 2631 2648 … … 2665 2682 2666 2683 /** 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 */ 2687 DECLINLINE(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 */ 2718 static 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 /** 2667 2826 * Copies the sections over from the DBG file. 2668 2827 * … … 2687 2846 return VERR_CV_BAD_FORMAT; 2688 2847 } 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 }2694 2848 2695 2849 /* 2696 2850 * Read the section table. 2697 2851 */ 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); 2758 2857 if (RT_SUCCESS(rc)) 2759 2858 { 2760 2859 /* 2761 * Add sections.2860 * Process them. 2762 2861 */ 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; 2783 2869 } 2784 2870 … … 2824 2910 pThis->offBase = UINT32_MAX; 2825 2911 pThis->offCoffDbgInfo = UINT32_MAX; 2912 pThis->hVfsPdb = NIL_RTVFS; 2826 2913 *ppThis = pThis; 2827 2914 return VINF_SUCCESS; … … 2923 3010 } 2924 3011 3012 /** 3013 * Argument package for rtDbgModCvOpenPdb20Callback via pvUser2. 3014 */ 3015 typedef 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 */ 3027 static 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 2925 3100 2926 3101 /** … … 2936 3111 * @param cb The number of bytes of debug info. 2937 3112 * @param enmArch The desired image architecture. 3113 * @param cbImage The image size, if available. 2938 3114 * @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. 2939 3117 */ 2940 3118 static 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) 2942 3121 { 2943 3122 int rc = VERR_DBG_NO_MATCHING_INTERPRETER; … … 2985 3164 if (pCvHdr->off == 0) 2986 3165 { 2987 if (cb > = sizeof(CVPDB20INFO) && cb < _64K)3166 if (cb > RT_UOFFSETOF(CVPDB20INFO, szPdbFilename) && cb < _64K) 2988 3167 { 3168 /* 3169 * Read it into memory and validate it. 3170 */ 2989 3171 PCVPDB20INFO pInfo = (PCVPDB20INFO)RTMemTmpAlloc(cb); 2990 3172 if (pInfo) … … 2993 3175 if (RT_SUCCESS(rc2)) 2994 3176 { 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)); 2997 3205 } 3206 else 3207 Log(("RTDbgModCv: NB10 read error - %Rrc\n", rc2)); 3208 RTMemTmpFree(pInfo); 2998 3209 } 3210 else 3211 rc = VERR_NO_TMP_MEMORY; 2999 3212 } 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")); 3001 3218 } 3002 3219 return rc; 3003 3220 } 3221 3222 3223 /** 3224 * Arguments passed to rtDbgModCvEnumCallback 3225 */ 3226 typedef struct RTDBGMODCVENUMCALLBACKARGS 3227 { 3228 PRTDBGMODINT pDbgMod; 3229 RTDBGCFG hDbgCfg; 3230 } RTDBGMODCVENUMCALLBACKARGS; 3004 3231 3005 3232 … … 3007 3234 static DECLCALLBACK(int) rtDbgModCvEnumCallback(RTLDRMOD hLdrMod, PCRTLDRDBGINFO pDbgInfo, void *pvUser) 3008 3235 { 3009 PRTDBGMODINT pDbgMod = (PRTDBGMODINT)pvUser; 3236 RTDBGMODCVENUMCALLBACKARGS * const pArgs = (RTDBGMODCVENUMCALLBACKARGS *)pvUser; 3237 PRTDBGMODINT const pDbgMod = pArgs->pDbgMod; 3010 3238 Assert(!pDbgMod->pvDbgPriv); 3011 3239 RT_NOREF_PV(hLdrMod); … … 3024 3252 if (RT_SUCCESS(rc)) 3025 3253 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); 3027 3256 } 3028 3257 else if (pDbgInfo->enmType == RTLDRDBGINFOTYPE_COFF) … … 3047 3276 * @param cb The number of bytes of debug info. 3048 3277 * @param enmArch The desired image architecture. 3278 * @param cbImage The image size (for PDB lookup, see hDbgCfg). 3049 3279 * @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). 3050 3283 */ 3051 3284 static 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) 3053 3286 { 3054 3287 RTCVHDR CvHdr; 3055 3288 int rc = RTFileReadAt(hFile, off, &CvHdr, sizeof(CvHdr), NULL); 3056 3289 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); 3058 3291 return rc; 3059 3292 } … … 3095 3328 * @param pszFilename The path to the file to probe. 3096 3329 * @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 */ 3334 static int rtDbgModCvProbeFile(PRTDBGMODINT pDbgMod, const char *pszFilename, RTLDRARCH enmArch, RTDBGCFG hDbgCfg) 3099 3335 { 3100 3336 RTFILE hFile; … … 3170 3406 rc = rtDbgModCvProbeFile2(pDbgMod, RTCVFILETYPE_DBG, hFile, 3171 3407 DbgDir.PointerToRawData, DbgDir.SizeOfData, 3172 enmArch, pszFilename);3408 enmArch, DbgHdr.SizeOfImage, pszFilename, hDbgCfg); 3173 3409 else if (DbgDir.Type == IMAGE_DEBUG_TYPE_COFF) 3174 3410 rc = rtDbgModCvProbeCoff(pDbgMod, RTCVFILETYPE_DBG, hFile, … … 3231 3467 if (RT_SUCCESS(rc)) 3232 3468 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); 3234 3472 } 3235 3473 … … 3249 3487 int rc = VERR_DBG_NO_MATCHING_INTERPRETER; 3250 3488 if (pMod->pszDbgFile) 3251 rc = rtDbgModCvProbeFile(pMod, pMod->pszDbgFile, enmArch );3489 rc = rtDbgModCvProbeFile(pMod, pMod->pszDbgFile, enmArch, hDbgCfg); 3252 3490 3253 3491 if (!pMod->pvDbgPriv && pMod->pImgVt) 3254 3492 { 3255 int rc2 = pMod->pImgVt->pfnEnumDbgInfo(pMod, rtDbgModCvEnumCallback, pMod); 3493 RTDBGMODCVENUMCALLBACKARGS Args = { pMod, hDbgCfg }; 3494 int rc2 = pMod->pImgVt->pfnEnumDbgInfo(pMod, rtDbgModCvEnumCallback, &Args); 3256 3495 if (RT_FAILURE(rc2)) 3257 3496 rc = rc2; … … 3260 3499 { 3261 3500 /* 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); 3263 3502 if (RT_FAILURE(rc2) && (RT_SUCCESS(rc) || rc == VERR_DBG_NO_MATCHING_INTERPRETER)) 3264 3503 rc = rc2; … … 3269 3508 if (!pThis) 3270 3509 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)); 3272 3513 3273 3514 /* … … 3283 3524 if (RT_SUCCESS(rc) && pThis->offCoffDbgInfo != UINT32_MAX) 3284 3525 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 } 3285 3532 if (RT_SUCCESS(rc)) 3286 3533 { … … 3477 3724 static DECLCALLBACK(int) rtDbgModPdb_Close(PRTDBGMODINT pMod) 3478 3725 { 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); 3489 3727 } 3490 3728 … … 3497 3735 */ 3498 3736 3499 static int rtDbgModPdb_ScanSymRecs(PRTDBGMODCV pThis, RTVFSFILE hVfsFileSymRecs) 3500 { 3501 void *pvSymRecs; 3502 size_t cbSymRecs; 3503 int rc = RTVfsFileReadAll(hVfsFileSymRecs, &pvSymRecs, &cbSymRecs); 3737 static 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); 3504 3741 if (RT_SUCCESS(rc)) 3505 3742 { 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 } 3513 3757 return rc; 3514 3758 } … … 3569 3813 3570 3814 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 3588 3815 /** 3589 3816 * Helper for rtDbgModPdb_TryOpen that loads the section/segments into the 3590 3817 * container. 3591 3818 */ 3592 static int rtDbgModPdb_LoadSections(PRTDBGMOD INT pMod, PRTDBGMODCV pThis, RTVFSFILE hVfsFileSectionHeaders)3819 static int rtDbgModPdb_LoadSections(PRTDBGMODCV pThis, PRTDBGMODINT pDbgMod, RTVFS hVfsPdb, const char *pszFilename) 3593 3820 { 3594 3821 /* … … 3596 3823 */ 3597 3824 int rc; 3598 if (p Mod->pImgVt)3599 rc = p Mod->pImgVt->pfnEnumSegments(pMod, rtDbgModCvAddSegmentsCallback, pThis);3825 if (pDbgMod->pImgVt) 3826 rc = pDbgMod->pImgVt->pfnEnumSegments(pDbgMod, rtDbgModCvAddSegmentsCallback, pThis); 3600 3827 /* 3601 3828 * Otherwise use the copy of the section table from the PDB. … … 3603 3830 else 3604 3831 { 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); 3608 3834 if (RT_SUCCESS(rc)) 3609 3835 { 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); 3618 3840 if (RT_SUCCESS(rc)) 3619 3841 { 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); 3659 3847 } 3660 3848 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)); 3663 3850 } 3664 3851 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); 3667 3855 pThis->fHaveLoadedSegments = true; 3668 3856 return rc; … … 3670 3858 3671 3859 3860 /** 3861 * Common worker for rtDbgModPdb_TryOpen and rtDbgModCv_TryOpen (for DBG+PDB). 3862 */ 3863 static 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 3672 3915 /** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */ 3673 3916 static DECLCALLBACK(int) rtDbgModPdb_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch, RTDBGCFG hDbgCfg) 3674 3917 { 3675 RT_NOREF(hDbgCfg); RT_NOREF(enmArch);3676 3677 3918 /* 3678 3919 * This only works for external files for now. … … 3698 3939 if (RT_SUCCESS(rc)) 3699 3940 { 3941 /** @todo check enmArch. It's part of the new DBI header. */ 3942 RT_NOREF(enmArch); 3943 3700 3944 /* 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. 3702 3948 */ 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); 3711 3951 if (RT_SUCCESS(rc)) 3712 3952 { 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); 3749 3956 } 3750 else3751 Log2(("rtDbgModPdb_TryOpen: Failed to open 'image-section-headers' in '%s' -> %Rrc\n", pMod->pszDbgFile, rc));3752 3957 RTVfsRelease(hVfsPdb); 3753 3958 } … … 3759 3964 return rc; 3760 3965 } 3966 3761 3967 3762 3968
Note:
See TracChangeset
for help on using the changeset viewer.