VirtualBox

Changeset 100911 in vbox for trunk


Ignore:
Timestamp:
Aug 19, 2023 2:59:14 AM (18 months ago)
Author:
vboxsync
Message:

IPRT/RTDbgSymCache: Added support for adding PDBs and DBGs to the symbol cache.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/tools/RTDbgSymCache.cpp

    r98103 r100911  
    4545#include <iprt/err.h>
    4646#include <iprt/file.h>
    47 #include <iprt/formats/mach-o.h>
     47#include <iprt/fsvfs.h>
    4848#include <iprt/getopt.h>
    4949#include <iprt/initterm.h>
     
    5757#include <iprt/vfs.h>
    5858#include <iprt/zip.h>
     59#include <iprt/formats/mach-o.h>
     60#include <iprt/formats/pecoff.h>
     61#include <iprt/formats/pdb.h>
    5962
    6063
     
    420423 * @param   pCfg            The configuration.
    421424 */
    422 static int rtDbgSymCacheAddOneFile(const char *pszSrcPath, const char *pszDstName, const char *pszExtraStuff,
     425static int rtDbgSymCacheAddOneFile(const char *pszSrcPath, const char *pszDstName, const char *pszExtraSuff,
    423426                                   const char *pszDstSubDir, PRTUUID pAddToUuidMap, const char *pszUuidMapDir,
    424427                                   PCRTDBGSYMCACHEADDCFG pCfg)
     
    453456    if (RT_FAILURE(rc))
    454457        return RTMsgErrorRc(rc, "Error constructing cache path for '%s': %Rrc", pszSrcPath, rc);
    455     if (pszExtraStuff)
    456     {
    457         rc = RTStrCat(szDstPath, sizeof(szDstPath), pszExtraStuff);
     458    if (pszExtraSuff)
     459    {
     460        rc = RTStrCat(szDstPath, sizeof(szDstPath), pszExtraSuff);
    458461        if (RT_FAILURE(rc))
    459462            return RTMsgErrorRc(rc, "Error constructing cache path for '%s': %Rrc", pszSrcPath, rc);
     
    512515 */
    513516static int rtDbgSymCacheAddImageFileWorker(const char *pszPath, const char *pszDstName, PCRTDBGSYMCACHEADDCFG pCfg,
    514                                            RTLDRMOD hLdrMod, const char *pszExtrSuff, const char *pszUuidMapDir)
     517                                           RTLDRMOD hLdrMod, const char *pszExtraSuff, const char *pszUuidMapDir)
    515518{
    516519    /*
     
    565568     * Now add it.
    566569     */
    567     return rtDbgSymCacheAddOneFile(pszPath, pszDstName, pszExtrSuff, szSubDir, pUuid, pszUuidMapDir, pCfg);
     570    return rtDbgSymCacheAddOneFile(pszPath, pszDstName, pszExtraSuff, szSubDir, pUuid, pszUuidMapDir, pCfg);
    568571}
    569572
     
    700703
    701704/**
    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 */
     714static 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.
    703733 *
    704734 * @returns IPRT status code
     
    711741static int rtDbgSymCacheAddDebugPdb(const char *pszPath, const char *pszDstName, PCRTDBGSYMCACHEADDCFG pCfg, RTFILE hFile)
    712742{
    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
    715830}
    716831
     
    740855        return RTMsgErrorRc(rc, "Error opening '%s': %Rrc", pszPath, rc);
    741856
    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);
    750859    if (RT_SUCCESS(rc))
    751860    {
    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        }
    764893        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);
    766895    }
    767896    else
    768         rc = RTMsgErrorRc(rc, "Error reading '%s': %Rrc", pszPath, rc);
     897        rc = RTMsgErrorRc(rc, "Error query size of '%s': %Rrc", pszPath, rc);
    769898
    770899    /* close the file. */
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