- Timestamp:
- Aug 19, 2023 2:59:14 AM (18 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/tools/RTDbgSymCache.cpp
r98103 r100911 45 45 #include <iprt/err.h> 46 46 #include <iprt/file.h> 47 #include <iprt/f ormats/mach-o.h>47 #include <iprt/fsvfs.h> 48 48 #include <iprt/getopt.h> 49 49 #include <iprt/initterm.h> … … 57 57 #include <iprt/vfs.h> 58 58 #include <iprt/zip.h> 59 #include <iprt/formats/mach-o.h> 60 #include <iprt/formats/pecoff.h> 61 #include <iprt/formats/pdb.h> 59 62 60 63 … … 420 423 * @param pCfg The configuration. 421 424 */ 422 static int rtDbgSymCacheAddOneFile(const char *pszSrcPath, const char *pszDstName, const char *pszExtraS tuff,425 static int rtDbgSymCacheAddOneFile(const char *pszSrcPath, const char *pszDstName, const char *pszExtraSuff, 423 426 const char *pszDstSubDir, PRTUUID pAddToUuidMap, const char *pszUuidMapDir, 424 427 PCRTDBGSYMCACHEADDCFG pCfg) … … 453 456 if (RT_FAILURE(rc)) 454 457 return RTMsgErrorRc(rc, "Error constructing cache path for '%s': %Rrc", pszSrcPath, rc); 455 if (pszExtraS tuff)456 { 457 rc = RTStrCat(szDstPath, sizeof(szDstPath), pszExtraS tuff);458 if (pszExtraSuff) 459 { 460 rc = RTStrCat(szDstPath, sizeof(szDstPath), pszExtraSuff); 458 461 if (RT_FAILURE(rc)) 459 462 return RTMsgErrorRc(rc, "Error constructing cache path for '%s': %Rrc", pszSrcPath, rc); … … 512 515 */ 513 516 static int rtDbgSymCacheAddImageFileWorker(const char *pszPath, const char *pszDstName, PCRTDBGSYMCACHEADDCFG pCfg, 514 RTLDRMOD hLdrMod, const char *pszExtr Suff, const char *pszUuidMapDir)517 RTLDRMOD hLdrMod, const char *pszExtraSuff, const char *pszUuidMapDir) 515 518 { 516 519 /* … … 565 568 * Now add it. 566 569 */ 567 return rtDbgSymCacheAddOneFile(pszPath, pszDstName, pszExtr Suff, szSubDir, pUuid, pszUuidMapDir, pCfg);570 return rtDbgSymCacheAddOneFile(pszPath, pszDstName, pszExtraSuff, szSubDir, pUuid, pszUuidMapDir, pCfg); 568 571 } 569 572 … … 700 703 701 704 /** 702 * Worker for rtDbgSymCacheAddDebugFile that adds PDBs to the cace. 705 * Worker for rtDbgSymCacheAddDebugFile that adds DBGs to the cache. 706 * 707 * @returns IPRT status code 708 * @param pszPath The path to the PDB file. 709 * @param pszDstName Add to the cache under this name. Typically the 710 * filename part of @a pszPath. 711 * @param pCfg The configuration. 712 * @param pHdr The DBG file header. 713 */ 714 static int rtDbgSymCacheAddDebugDbg(const char *pszPath, const char *pszDstName, PCRTDBGSYMCACHEADDCFG pCfg, 715 PCIMAGE_SEPARATE_DEBUG_HEADER pHdr) 716 { 717 if ( pHdr->SizeOfImage == 0 718 || pHdr->SizeOfImage >= UINT32_MAX / 2 719 || pHdr->TimeDateStamp < 16 720 || pHdr->TimeDateStamp >= UINT32_MAX - 16 721 || pHdr->NumberOfSections >= UINT16_MAX / 2) 722 return RTMsgErrorRc(VERR_OUT_OF_RANGE, 723 "Bogus separate debug header in '%s': SizeOfImage=%#RX32 TimeDateStamp=%#RX32 NumberOfSections=%#RX16", 724 pszPath, pHdr->SizeOfImage, pHdr->TimeDateStamp, pHdr->NumberOfSections); 725 char szSubDir[32]; 726 RTStrPrintf(szSubDir, sizeof(szSubDir), "%08X%x", pHdr->TimeDateStamp, pHdr->SizeOfImage); 727 return rtDbgSymCacheAddOneFile(pszPath, pszDstName, NULL, szSubDir, NULL, NULL, pCfg); 728 } 729 730 731 /** 732 * Worker for rtDbgSymCacheAddDebugFile that adds v7 PDBs to the cache. 703 733 * 704 734 * @returns IPRT status code … … 711 741 static int rtDbgSymCacheAddDebugPdb(const char *pszPath, const char *pszDstName, PCRTDBGSYMCACHEADDCFG pCfg, RTFILE hFile) 712 742 { 713 RT_NOREF(pCfg, hFile, pszDstName); 714 return RTMsgErrorRc(VERR_NOT_IMPLEMENTED, "PDB support not implemented: '%s'", pszPath); 743 /* 744 * Open the PDB as a VFS. 745 */ 746 RTVFSFILE hVfsFile = NIL_RTVFSFILE; 747 int rc = RTVfsFileFromRTFile(hFile, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, true /*fLeaveOpen*/, &hVfsFile); 748 if (RT_SUCCESS(rc)) 749 { 750 RTERRINFOSTATIC ErrInfo; 751 RTVFS hVfsPdb = NIL_RTVFS; 752 rc = RTFsPdbVolOpen(hVfsFile, 0, &hVfsPdb, RTErrInfoInitStatic(&ErrInfo)); 753 RTVfsFileRelease(hVfsFile); 754 if (RT_SUCCESS(rc)) 755 { 756 /* 757 * Get the version. 758 */ 759 char szPdbVer[16]; 760 rc = RTVfsQueryLabel(hVfsPdb, true /*fAlternative*/, szPdbVer, sizeof(szPdbVer), NULL); 761 if (RT_SUCCESS(rc)) 762 { 763 /* 764 * Read the PDB metadata header. 765 */ 766 RTVFSFILE hVfsFileHdr = NIL_RTVFSFILE; 767 rc = RTVfsFileOpen(hVfsPdb, "1", RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, &hVfsFileHdr); 768 if (RT_SUCCESS(rc)) 769 { 770 union 771 { 772 uint8_t abHdr[128]; 773 RTPDB70NAMES Hdr70; 774 RTPDB20NAMES Hdr20; 775 } uBuf = {{0}}; 776 size_t cbHdr = 0; 777 rc = RTVfsFileRead(hVfsFileHdr, &uBuf, sizeof(uBuf), &cbHdr); 778 RTVfsFileRelease(hVfsFileHdr); 779 if (RT_SUCCESS(rc)) 780 { 781 /* 782 * Use the header to determine the subdirectory name. 783 */ 784 char szSubDir[48]; 785 if (strcmp(szPdbVer, "pdb-v7") == 0) 786 RTStrPrintf(szSubDir, sizeof(szSubDir), "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%x", 787 uBuf.Hdr70.Uuid.Gen.u32TimeLow, 788 uBuf.Hdr70.Uuid.Gen.u16TimeMid, 789 uBuf.Hdr70.Uuid.Gen.u16TimeHiAndVersion, 790 uBuf.Hdr70.Uuid.Gen.u8ClockSeqHiAndReserved, 791 uBuf.Hdr70.Uuid.Gen.u8ClockSeqLow, 792 uBuf.Hdr70.Uuid.Gen.au8Node[0], 793 uBuf.Hdr70.Uuid.Gen.au8Node[1], 794 uBuf.Hdr70.Uuid.Gen.au8Node[2], 795 uBuf.Hdr70.Uuid.Gen.au8Node[3], 796 uBuf.Hdr70.Uuid.Gen.au8Node[4], 797 uBuf.Hdr70.Uuid.Gen.au8Node[5], 798 uBuf.Hdr70.uAge); 799 else if (strcmp(szPdbVer, "pdb-v2") == 0) 800 RTStrPrintf(szSubDir, sizeof(szSubDir), "%08X%x", uBuf.Hdr20.uTimestamp, uBuf.Hdr20.uAge); 801 else 802 { 803 szSubDir[0] = '\0'; 804 rc = RTMsgErrorRc(VERR_VERSION_MISMATCH, "Unsupported PDB version string: %s", szPdbVer); 805 } 806 807 /* 808 * Add it to the symbol cache if that went well. 809 */ 810 if (RT_SUCCESS(rc)) 811 rc = rtDbgSymCacheAddOneFile(pszPath, pszDstName, NULL, szSubDir, NULL, NULL, pCfg); 812 } 813 else 814 RTMsgErrorRc(rc, "RTVfsFileRead('1',) failed on '%s': %Rrc", pszPath, rc); 815 } 816 else 817 RTMsgErrorRc(rc, "RTVfsFileOpen('1',) failed on '%s': %Rrc", pszPath, rc); 818 } 819 else 820 RTMsgErrorRc(rc, "RTVfsQueryLabel failed on '%s': %Rrc", pszPath, rc); 821 RTVfsRelease(hVfsPdb); 822 } 823 else 824 RTMsgErrorRc(rc, "RTFsPdbVolOpen failed on '%s': %Rrc%#RTeim", pszPath, rc, &ErrInfo.Core); 825 } 826 else 827 RTMsgErrorRc(rc, "RTVfsFileFromRTFile failed on '%s': %Rrc", pszPath, rc); 828 return rc; 829 715 830 } 716 831 … … 740 855 return RTMsgErrorRc(rc, "Error opening '%s': %Rrc", pszPath, rc); 741 856 742 union 743 { 744 uint64_t au64[16]; 745 uint32_t au32[16]; 746 uint16_t au16[32]; 747 uint8_t ab[64]; 748 } uBuf; 749 rc = RTFileRead(hFile, &uBuf, sizeof(uBuf), NULL); 857 uint64_t cbFile = 0; 858 rc = RTFileQuerySize(hFile, &cbFile); 750 859 if (RT_SUCCESS(rc)) 751 860 { 752 /* 753 * Look for magics and call workers. 754 */ 755 if (!memcmp(uBuf.ab, RT_STR_TUPLE("Microsoft C/C++ MSF 7.00"))) 756 rc = rtDbgSymCacheAddDebugPdb(pszPath, pszDstName, pCfg, hFile); 757 else if ( uBuf.au32[0] == IMAGE_FAT_SIGNATURE 758 || uBuf.au32[0] == IMAGE_FAT_SIGNATURE_OE 759 || uBuf.au32[0] == IMAGE_MACHO32_SIGNATURE 760 || uBuf.au32[0] == IMAGE_MACHO64_SIGNATURE 761 || uBuf.au32[0] == IMAGE_MACHO32_SIGNATURE_OE 762 || uBuf.au32[0] == IMAGE_MACHO64_SIGNATURE_OE) 763 rc = rtDbgSymCacheAddDebugMachO(pszPath, pszDstName, pCfg); 861 862 union 863 { 864 uint64_t au64[16]; 865 uint32_t au32[16]; 866 uint16_t au16[32]; 867 uint8_t ab[64]; 868 RTPDB70HDR Pdb70Hdr; 869 RTPDB20HDR Pdb20Hdr; 870 IMAGE_SEPARATE_DEBUG_HEADER DbgHdr; 871 } uBuf; 872 rc = RTFileRead(hFile, &uBuf, sizeof(uBuf), NULL); 873 if (RT_SUCCESS(rc)) 874 { 875 /* 876 * Look for magics and call workers. 877 */ 878 if ( memcmp(uBuf.Pdb70Hdr.szSignature, RTPDB_SIGNATURE_700, sizeof(uBuf.Pdb70Hdr.szSignature)) == 0 879 || memcmp(uBuf.Pdb20Hdr.szSignature, RTPDB_SIGNATURE_200, sizeof(uBuf.Pdb20Hdr.szSignature)) == 0) 880 rc = rtDbgSymCacheAddDebugPdb(pszPath, pszDstName, pCfg, hFile); 881 else if (uBuf.au16[0] == IMAGE_SEPARATE_DEBUG_SIGNATURE) 882 rc = rtDbgSymCacheAddDebugDbg(pszPath, pszDstName, pCfg, &uBuf.DbgHdr); 883 else if ( uBuf.au32[0] == IMAGE_FAT_SIGNATURE 884 || uBuf.au32[0] == IMAGE_FAT_SIGNATURE_OE 885 || uBuf.au32[0] == IMAGE_MACHO32_SIGNATURE 886 || uBuf.au32[0] == IMAGE_MACHO64_SIGNATURE 887 || uBuf.au32[0] == IMAGE_MACHO32_SIGNATURE_OE 888 || uBuf.au32[0] == IMAGE_MACHO64_SIGNATURE_OE) 889 rc = rtDbgSymCacheAddDebugMachO(pszPath, pszDstName, pCfg); 890 else 891 rc = RTMsgErrorRc(VERR_INVALID_MAGIC, "Unsupported debug file '%s' magic: %#010x", pszPath, uBuf.au32[0]); 892 } 764 893 else 765 rc = RTMsgErrorRc( VERR_INVALID_MAGIC, "Unsupported debug file '%s' magic: %#010x", pszPath, uBuf.au32[0]);894 rc = RTMsgErrorRc(rc, "Error reading '%s': %Rrc", pszPath, rc); 766 895 } 767 896 else 768 rc = RTMsgErrorRc(rc, "Error reading'%s': %Rrc", pszPath, rc);897 rc = RTMsgErrorRc(rc, "Error query size of '%s': %Rrc", pszPath, rc); 769 898 770 899 /* close the file. */
Note:
See TracChangeset
for help on using the changeset viewer.