VirtualBox

Changeset 46101 in vbox


Ignore:
Timestamp:
May 15, 2013 3:36:43 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
85787
Message:

More NT4 debugging. Getting closer to working state...

Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/dbg.h

    r46083 r46101  
    972972
    973973/**
     974 * Gets the name of the debug info file we're using.
     975 *
     976 * @returns Pointer to a read only string containing the filename, NULL if we
     977 *          don't use one.
     978 *
     979 * @param   hDbgMod         The module handle.
     980 */
     981RTDECL(const char *) RTDbgModDebugFile(RTDBGMOD hDbgMod);
     982
     983/**
     984 * Gets the image filename (as specified by the user).
     985 *
     986 * @returns Pointer to a read only string containing the filename.
     987 *
     988 * @param   hDbgMod         The module handle.
     989 */
     990RTDECL(const char *) RTDbgModImageFile(RTDBGMOD hDbgMod);
     991
     992/**
     993 * Gets the image filename actually used if it differs from RTDbgModImageFile.
     994 *
     995 * @returns Pointer to a read only string containing the filename, NULL if same
     996 *          as RTDBgModImageFile.
     997 *
     998 * @param   hDbgMod         The module handle.
     999 */
     1000RTDECL(const char *) RTDbgModImageFileUsed(RTDBGMOD hDbgMod);
     1001
     1002/**
    9741003 * Converts an image relative address to a segment:offset address.
    9751004 *
  • trunk/include/iprt/mangling.h

    r46080 r46101  
    401401# define RTDbgModLineCount                              RT_MANGLER(RTDbgModLineCount)
    402402# define RTDbgModName                                   RT_MANGLER(RTDbgModName)
     403# define RTDbgModDebugFile                              RT_MANGLER(RTDbgModDebugFile)
     404# define RTDbgModImageFile                              RT_MANGLER(RTDbgModImageFile)
     405# define RTDbgModImageFileUsed                          RT_MANGLER(RTDbgModImageFileUsed)
    403406# define RTDbgModRelease                                RT_MANGLER(RTDbgModRelease)
    404407# define RTDbgModRetain                                 RT_MANGLER(RTDbgModRetain)
  • trunk/include/iprt/strcache.h

    r44529 r46101  
    8888
    8989/**
     90 * Enters a string into the cache in lower cased form.
     91 *
     92 * @returns Pointer to a read-only lower cased copy of the string.
     93 *
     94 * @param   hStrCache           Handle to the string cache.
     95 * @param   pchString           Pointer to a string. This does not need to be
     96 *                              zero terminated, but must not contain any zero
     97 *                              characters.
     98 * @param   cchString           The number of characters (bytes) to enter.
     99 *
     100 * @remarks It is implementation dependent whether the returned string pointer
     101 *          differs when entering the same string twice.
     102 */
     103RTDECL(const char *) RTStrCacheEnterLowerN(RTSTRCACHE hStrCache, const char *pchString, size_t cchString);
     104
     105/**
     106 * Enters a string into the cache in lower cased form.
     107 *
     108 * @returns Pointer to a read-only lower cased copy of the string.
     109 *
     110 * @param   hStrCache           Handle to the string cache.
     111 * @param   psz                 Pointer to a zero terminated string.
     112 *
     113 * @remarks See RTStrCacheEnterN.
     114 */
     115RTDECL(const char *) RTStrCacheEnterLower(RTSTRCACHE hStrCache, const char *psz);
     116
     117
     118/**
    90119 * Retains a reference to a string.
    91120 *
  • trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp

    r46078 r46101  
    342342    { "kh",         0,        0,        NULL,               0,                              0,       dbgcCmdStack,       "",                     "Callstack - hypervisor." },
    343343    { "lm",         0,        ~0U,      &g_aArgListMods[0], RT_ELEMENTS(g_aArgListMods),    0,       dbgcCmdListModules, "[module [..]]",        "List modules." },
     344    { "lmv",        0,        ~0U,      &g_aArgListMods[0], RT_ELEMENTS(g_aArgListMods),    0,       dbgcCmdListModules, "[module [..]]",        "List modules, verbose." },
    344345    { "lmo",        0,        ~0U,      &g_aArgListMods[0], RT_ELEMENTS(g_aArgListMods),    0,       dbgcCmdListModules, "[module [..]]",        "List modules and their segments." },
     346    { "lmov",       0,        ~0U,      &g_aArgListMods[0], RT_ELEMENTS(g_aArgListMods),    0,       dbgcCmdListModules, "[module [..]]",        "List modules and their segments, verbose." },
    345347    { "ln",         0,        ~0U,      &g_aArgListNear[0], RT_ELEMENTS(g_aArgListNear),    0,       dbgcCmdListNear,    "[addr/sym [..]]",      "List symbols near to the address. Default address is CS:EIP." },
    346348    { "ls",         0,        1,        &g_aArgListSource[0],RT_ELEMENTS(g_aArgListSource), 0,       dbgcCmdListSource,  "[addr]",               "Source." },
     
    38923894{
    38933895    bool const  fMappings   = pCmd->pszCmd[2] == 'o';
     3896    bool const  fVerbose    = pCmd->pszCmd[strlen(pCmd->pszCmd) - 1] == 'v';
    38943897    PDBGC       pDbgc       = DBGC_CMDHLP2DBGC(pCmdHlp);
    38953898
     
    39053908        if (hMod != NIL_RTDBGMOD)
    39063909        {
    3907             uint32_t const      cSegs   = RTDbgModSegmentCount(hMod);
    3908             const char * const  pszName = RTDbgModName(hMod);
     3910            uint32_t const      cSegs            = RTDbgModSegmentCount(hMod);
     3911            const char * const  pszName          = RTDbgModName(hMod);
     3912            const char * const  pszImgFile       = RTDbgModImageFile(hMod);
     3913            const char * const  pszImgFileUsed   = RTDbgModImageFileUsed(hMod);
     3914            const char * const  pszDbgFile       = RTDbgModDebugFile(hMod);
    39093915            if (    cArgs == 0
    39103916                ||  dbgcCmdListModuleMatch(pszName, paArgs, cArgs))
     
    39263932                                 ||  aMappings[iMap].iSeg == NIL_RTDBGSEGIDX))
    39273933                            uMin = aMappings[iMap].Address;
    3928                     DBGCCmdHlpPrintf(pCmdHlp, "%RGv %04x %s\n", (RTGCUINTPTR)uMin, cSegs, pszName);
     3934                    if (!fVerbose || !pszImgFile)
     3935                        DBGCCmdHlpPrintf(pCmdHlp, "%RGv %04x %s\n", (RTGCUINTPTR)uMin, cSegs, pszName);
     3936                    else
     3937                        DBGCCmdHlpPrintf(pCmdHlp, "%RGv %04x %-12s  %s\n", (RTGCUINTPTR)uMin, cSegs, pszName, pszImgFile);
     3938                    if (fVerbose && pszImgFileUsed)
     3939                        DBGCCmdHlpPrintf(pCmdHlp, "    Local image: %s\n", pszImgFileUsed);
     3940                    if (fVerbose && pszDbgFile)
     3941                        DBGCCmdHlpPrintf(pCmdHlp, "    Debug file:  %s\n", pszDbgFile);
    39293942
    39303943                    if (fMappings)
  • trunk/src/VBox/Debugger/DBGPlugInWinNt.cpp

    r46083 r46101  
    162162} NTPRODUCTTYPE;
    163163
    164 /**
    165  * PDB v2.0 in image debug info.
    166  * The URL is constructed from the timestamp and the %02x age?
    167  */
    168 typedef struct CV_INFO_PDB20
    169 {
    170     uint32_t    Signature;              /**< CV_SIGNATURE_PDB70. */
    171     int32_t     Offset;                 /**< Always 0. Used to be the offset to the real debug info. */
    172     uint32_t    TimeDateStamp;
    173     uint32_t    Age;
    174     uint8_t     PdbFilename[4];
    175 } CV_INFO_PDB20;
    176 /** The CV_INFO_PDB20 signature. */
    177 #define CV_SIGNATURE_PDB20  RT_MAKE_U32_FROM_U8('N','B','1','0')
    178 
    179 /**
    180  * PDB v7.0 in image debug info.
    181  * The URL is constructed from the signature and the %02x age.
    182  */
    183 #pragma pack(4)
    184 typedef struct CV_INFO_PDB70
    185 {
    186     uint32_t    CvSignature;            /**< CV_SIGNATURE_PDB70. */
    187     RTUUID      Signature;
    188     uint32_t    Age;
    189     uint8_t     PdbFilename[4];
    190 } CV_INFO_PDB70;
    191 #pragma pack()
    192 AssertCompileMemberOffset(CV_INFO_PDB70, Signature, 4);
    193 AssertCompileMemberOffset(CV_INFO_PDB70, Age, 4 + 16);
    194 /** The CV_INFO_PDB70 signature. */
    195 #define CV_SIGNATURE_PDB70  RT_MAKE_U32_FROM_U8('R','S','D','S')
     164
     165/** NT image header union. */
     166typedef union NTHDRSU
     167{
     168    IMAGE_NT_HEADERS32  vX_32;
     169    IMAGE_NT_HEADERS64  vX_64;
     170} NTHDRS;
     171/** Pointer to NT image header union. */
     172typedef NTHDRS *PNTHDRS;
     173/** Pointer to const NT image header union. */
     174typedef NTHDRS const *PCNTHDRS;
    196175
    197176/** @} */
     177
    198178
    199179
     
    251231    /** The image size. */
    252232    uint32_t            cbImage;
     233    /** The file offset of the SizeOfImage field in the optional header if it
     234     *  needs patching, otherwise set to UINT32_MAX. */
     235    uint32_t            offSizeOfImage;
     236    /** The correct image size. */
     237    uint32_t            cbCorrectImageSize;
    253238    /** Number of entries in the aMappings table. */
    254239    uint32_t            cMappings;
     
    310295{
    311296    PDBGDIGGERWINNTRDR pThis = (PDBGDIGGERWINNTRDR)pvUser;
     297    uint32_t           offFile = (uint32_t)off;
     298    AssertReturn(offFile == off, VERR_INVALID_PARAMETER);
    312299
    313300    uint32_t i = pThis->iHint;
    314     if (pThis->aMappings[i].offFile > off)
     301    if (pThis->aMappings[i].offFile > offFile)
    315302    {
    316303        i = pThis->cMappings;
    317304        while (i-- > 0)
    318             if (off >= pThis->aMappings[i].offFile)
     305            if (offFile >= pThis->aMappings[i].offFile)
    319306                break;
    320307        pThis->iHint = i;
     
    324311    {
    325312        uint32_t offNextMap =  i + 1 < pThis->cMappings ? pThis->aMappings[i + 1].offFile : pThis->cbImage;
    326         uint32_t offMap     = (uint32_t)off - pThis->aMappings[i].offFile;
     313        uint32_t offMap     = offFile - pThis->aMappings[i].offFile;
    327314
    328315        /* Read file bits backed by memory. */
    329         if (off < pThis->aMappings[i].cbMem)
     316        if (offMap < pThis->aMappings[i].cbMem)
    330317        {
    331318            uint32_t cbToRead = pThis->aMappings[i].cbMem - offMap;
     
    339326            if (RT_FAILURE(rc))
    340327                return rc;
     328
     329            /* Patch it? */
     330            if (   pThis->offSizeOfImage != UINT32_MAX
     331                && offFile            < pThis->offSizeOfImage + 4
     332                && offFile + cbToRead > pThis->offSizeOfImage)
     333            {
     334                uint32_t SizeOfImage = pThis->cbCorrectImageSize;
     335                int32_t  offPatch    = pThis->offSizeOfImage - offFile;
     336                uint8_t *pbPatch     = (uint8_t *)pvBuf + offPatch;
     337                uint32_t cbPatch     = sizeof(uint32_t);
     338                if (offFile + cbToRead < pThis->offSizeOfImage + cbPatch)
     339                    cbPatch = offFile + cbToRead - pThis->offSizeOfImage;
     340                while (cbPatch-- > 0)
     341                {
     342                    if (offPatch >= 0)
     343                        *pbPatch = (uint8_t)SizeOfImage;
     344                    offPatch++;
     345                    pbPatch++;
     346                    SizeOfImage >>= 8;
     347                }
     348            }
     349
     350            /* Done? */
    341351            if (cbToRead == cb)
    342352                break;
    343353
    344             off  += cbToRead;
    345             cb   -= cbToRead;
    346             pvBuf = (char *)pvBuf + cbToRead;
     354            offFile += cbToRead;
     355            cb      -= cbToRead;
     356            pvBuf    = (char *)pvBuf + cbToRead;
    347357        }
    348358
    349359        /* Mind the gap. */
    350         if (offNextMap > off)
    351         {
    352             uint32_t cbZero = offNextMap - (uint32_t)off;
     360        if (offNextMap > offFile)
     361        {
     362            uint32_t cbZero = offNextMap - offFile;
    353363            if (cbZero > cb)
    354364            {
     
    358368
    359369            RT_BZERO(pvBuf, cbZero);
    360             off  += cbZero;
    361             cb   -= cbZero;
    362             pvBuf = (char *)pvBuf + cbZero;
     370            offFile += cbZero;
     371            cb      -= cbZero;
     372            pvBuf   = (char *)pvBuf + cbZero;
    363373        }
    364374
     
    378388    pThis->pUVM = NULL;
    379389    RTMemFree(pvUser);
     390}
     391
     392
     393/**
     394 * Checks if the section headers look okay.
     395 *
     396 * @returns true / false.
     397 * @param   paShs               Pointer to the section headers.
     398 * @param   cShs                Number of headers.
     399 * @param   cbImage             The image size.
     400 */
     401static bool dbgDiggerWinNtIsSectionHeaderOk(PCIMAGE_SECTION_HEADER paShs, uint32_t cShs, uint32_t cbImage)
     402{
     403    for (uint32_t i = 0; i < cShs; i++)
     404    {
     405        if (!paShs[i].Name[0])
     406        {
     407            Log(("DigWinNt: Section header #%u has no name\n", i));
     408            return false;
     409        }
     410
     411        if (paShs[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)
     412            continue;
     413        if (paShs[i].VirtualAddress >= cbImage)
     414        {
     415            Log(("DigWinNt: Section header #%u has a virtual address beyond the image: %#x cbImage=%#x\n",
     416                 i, paShs[i].VirtualAddress, cbImage));
     417            return false;
     418        }
     419        if (paShs[i].Misc.VirtualSize >= cbImage) /* we don't check too strictly here becuase NT4 SP1 ntfs.sys. */
     420        {
     421            Log(("DigWinNt: Section header #%u has a end beyond the image: VirtualAddress=%#x VirtualSize=%#x cbImage=%#x\n",
     422                 i, paShs[i].VirtualAddress, paShs[i].Misc.VirtualSize, cbImage));
     423            return false;
     424        }
     425    }
     426    return true;
     427}
     428
     429
     430/**
     431 * Create a loader module for the in-guest-memory PE module.
     432 */
     433static int dbgDiggerWinNtCreateLdrMod(PDBGDIGGERWINNT pThis, PUVM pUVM, const char *pszName, PCDBGFADDRESS pImageAddr,
     434                                      uint32_t cbImage, uint8_t *pbBuf, size_t cbBuf,
     435                                      uint32_t offHdrs, PCNTHDRS pHdrs, PRTLDRMOD phLdrMod)
     436{
     437    /*
     438     * Allocate and create a reader instance.
     439     */
     440    uint32_t const      cShs = WINNT_UNION(pThis, pHdrs, FileHeader.NumberOfSections);
     441    PDBGDIGGERWINNTRDR  pRdr = (PDBGDIGGERWINNTRDR)RTMemAlloc(RT_OFFSETOF(DBGDIGGERWINNTRDR, aMappings[cShs + 2]));
     442    if (!pRdr)
     443        return VERR_NO_MEMORY;
     444
     445    VMR3RetainUVM(pUVM);
     446    pRdr->pUVM               = pUVM;
     447    pRdr->ImageAddr          = *pImageAddr;
     448    pRdr->cbImage            = cbImage;
     449    pRdr->cbCorrectImageSize = cbImage;
     450    pRdr->offSizeOfImage     = UINT32_MAX;
     451    pRdr->iHint              = 0;
     452
     453    /*
     454     * Use the section table to construct a more accurate view of the file/
     455     * image if it's in the buffer (it should be).
     456     */
     457    uint32_t offShs = offHdrs
     458                    + (  pThis->f32Bit
     459                       ? pHdrs->vX_32.FileHeader.SizeOfOptionalHeader + RT_OFFSETOF(IMAGE_NT_HEADERS32, OptionalHeader)
     460                       : pHdrs->vX_64.FileHeader.SizeOfOptionalHeader + RT_OFFSETOF(IMAGE_NT_HEADERS64, OptionalHeader));
     461    uint32_t cbShs  = cShs * sizeof(IMAGE_SECTION_HEADER);
     462    PCIMAGE_SECTION_HEADER paShs = (PCIMAGE_SECTION_HEADER)(pbBuf + offShs);
     463    if (   offShs + cbShs <= RT_MIN(cbImage, cbBuf)
     464        && dbgDiggerWinNtIsSectionHeaderOk(paShs, cShs, cbImage))
     465    {
     466        pRdr->cMappings = 0;
     467
     468        for (uint32_t i = 0; i < cShs; i++)
     469            if (   paShs[i].SizeOfRawData    > 0
     470                && paShs[i].PointerToRawData > 0)
     471            {
     472                uint32_t j = 1;
     473                if (!pRdr->cMappings)
     474                    pRdr->cMappings++;
     475                else
     476                {
     477                    while (j < pRdr->cMappings && pRdr->aMappings[j].offFile < paShs[i].PointerToRawData)
     478                        j++;
     479                    if (j < pRdr->cMappings)
     480                        memmove(&pRdr->aMappings[j + 1], &pRdr->aMappings[j], (pRdr->cMappings - j) * sizeof(pRdr->aMappings));
     481                }
     482                pRdr->aMappings[j].offFile = paShs[i].PointerToRawData;
     483                pRdr->aMappings[j].offMem  = paShs[i].VirtualAddress;
     484                pRdr->aMappings[j].cbMem   = i + 1 < cShs
     485                                           ? paShs[i + 1].VirtualAddress - paShs[i].VirtualAddress
     486                                           : paShs[i].Misc.VirtualSize;
     487                if (j == pRdr->cMappings)
     488                    pRdr->cbImage = paShs[i].PointerToRawData + paShs[i].SizeOfRawData;
     489                pRdr->cMappings++;
     490            }
     491
     492        /* Insert the mapping of the headers that isn't covered by the section table. */
     493        pRdr->aMappings[0].offFile = 0;
     494        pRdr->aMappings[0].offMem  = 0;
     495        pRdr->aMappings[0].cbMem   = pRdr->cMappings ? pRdr->aMappings[1].offFile : pRdr->cbImage;
     496
     497        int j = pRdr->cMappings - 1;
     498        while (j-- > 0)
     499        {
     500            uint32_t cbFile = pRdr->aMappings[j + 1].offFile - pRdr->aMappings[j].offFile;
     501            if (pRdr->aMappings[j].cbMem > cbFile)
     502                pRdr->aMappings[j].cbMem = cbFile;
     503        }
     504    }
     505    else
     506    {
     507        /*
     508         * Fallback, fake identity mapped file data.
     509         */
     510        pRdr->cMappings = 1;
     511        pRdr->aMappings[0].offFile = 0;
     512        pRdr->aMappings[0].offMem  = 0;
     513        pRdr->aMappings[0].cbMem   = pRdr->cbImage;
     514    }
     515
     516    /*
     517     * Call the loader to open the PE image for debugging.
     518     * Note! It always calls pfnDtor.
     519     */
     520    RTLDRMOD hLdrMod;
     521    int rc = RTLdrOpenInMemory(pszName, RTLDR_O_FOR_DEBUG, RTLDRARCH_WHATEVER, pRdr->cbImage,
     522                               dbgDiggerWinNtRdr_Read, dbgDiggerWinNtRdr_Dtor, pRdr,
     523                               &hLdrMod);
     524    if (RT_SUCCESS(rc))
     525        *phLdrMod = hLdrMod;
     526    else
     527        *phLdrMod = NIL_RTLDRMOD;
     528    return rc;
    380529}
    381530
     
    413562    /* Dig out the NT/PE headers. */
    414563    IMAGE_DOS_HEADER const *pMzHdr = (IMAGE_DOS_HEADER const *)pbBuf;
    415     typedef union NTHDRSU
    416     {
    417         IMAGE_NT_HEADERS32  vX_32;
    418         IMAGE_NT_HEADERS64  vX_64;
    419     } NTHDRS;
    420     NTHDRS const   *pHdrs;
     564    PCNTHDRS        pHdrs;
    421565    uint32_t        offHdrs;
    422566    if (pMzHdr->e_magic != IMAGE_DOS_SIGNATURE)
    423567    {
    424568        offHdrs = 0;
    425         pHdrs   = (NTHDRS const *)pbBuf;
     569        pHdrs   = (PCNTHDRS)pbBuf;
    426570    }
    427571    else if (   pMzHdr->e_lfanew >= cbImage
     
    460604        return;
    461605    }
     606    if (WINNT_UNION(pThis, pHdrs, FileHeader.NumberOfSections) > 64)
     607    {
     608        Log(("DigWinNt: %s: Too many sections: %#x\n", pszName, WINNT_UNION(pThis, pHdrs, FileHeader.NumberOfSections)));
     609        return;
     610    }
     611
    462612    const uint32_t TimeDateStamp = pHdrs->vX_32.FileHeader.TimeDateStamp;
    463613
     
    480630    }
    481631
    482     uint32_t uRvaDebugDir = 0;
    483     uint32_t cbDebugDir   = 0;
    484     IMAGE_DATA_DIRECTORY const *pDir = &WINNT_UNION(pThis, pHdrs, OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]);
    485     if (    pDir->VirtualAddress > offHdrs
    486         &&  pDir->VirtualAddress < cbImage
    487         &&  pDir->Size           >= sizeof(IMAGE_DEBUG_DIRECTORY)
    488         &&  pDir->Size           < cbImage
    489         &&  pDir->VirtualAddress + pDir->Size <= cbImage
    490        )
    491     {
    492         uRvaDebugDir = pDir->VirtualAddress;
    493         cbDebugDir   = pDir->Size;
    494     }
    495632
    496633    /*
    497      * Create the module.
     634     * Create the module using the in memory image first, falling back
     635     * on cached image.
    498636     */
     637    RTLDRMOD hLdrMod;
     638    int rc = dbgDiggerWinNtCreateLdrMod(pThis, pUVM, pszName, pImageAddr, cbImage, pbBuf, cbBuf, offHdrs, pHdrs,
     639                                        &hLdrMod);
     640    if (RT_FAILURE(rc))
     641        hLdrMod = NIL_RTLDRMOD;
     642
    499643    RTDBGMOD hMod;
    500     int rc = RTDbgModCreateFromPeImage(&hMod, pszName, NULL, NIL_RTLDRMOD,
    501                                        cbImageFromHdr, TimeDateStamp, DBGFR3AsGetConfig(pUVM));
     644    rc = RTDbgModCreateFromPeImage(&hMod, pszName, NULL, hLdrMod,
     645                                   cbImageFromHdr, TimeDateStamp, DBGFR3AsGetConfig(pUVM));
    502646    if (RT_FAILURE(rc))
    503647    {
    504648        /*
    505          * Probably didn't find the image any where, try fake an image
    506          * from guest memory.
     649         * Final fallback is a container module.
    507650         */
    508         uint32_t            cMappings = WINNT_UNION(pThis, pHdrs, FileHeader.NumberOfSections) + 3;
    509         PDBGDIGGERWINNTRDR  pRdr = (PDBGDIGGERWINNTRDR)RTMemAlloc(RT_OFFSETOF(DBGDIGGERWINNTRDR, aMappings[cMappings]));
    510         if (!pRdr)
     651        rc = RTDbgModCreate(&hMod, pszName, cbImage, 0);
     652        if (RT_FAILURE(rc))
    511653            return;
    512654
    513         VMR3RetainUVM(pUVM);
    514         pRdr->pUVM          = pUVM;
    515         pRdr->ImageAddr     = *pImageAddr;
    516         pRdr->cbImage       = cbImageFromHdr;
    517         pRdr->cMappings     = 1;
    518         pRdr->iHint         = 0;
    519         pRdr->aMappings[0].offFile = 0;
    520         pRdr->aMappings[0].offMem  =  0;
    521         pRdr->aMappings[0].cbMem   = cbImageFromHdr;
    522 
    523         RTLDRMOD hLdrMod;
    524         rc = RTLdrOpenInMemory(pszName, RTLDR_O_FOR_DEBUG, RTLDRARCH_WHATEVER, pRdr->cbImage,
    525                                dbgDiggerWinNtRdr_Read, dbgDiggerWinNtRdr_Dtor, pRdr,
    526                                &hLdrMod);
    527         if (RT_SUCCESS(rc))
    528         {
    529             rc = RTDbgModCreateFromPeImage(&hMod, pszName, NULL, hLdrMod,
    530                                            cbImageFromHdr, TimeDateStamp, DBGFR3AsGetConfig(pUVM));
    531             if (RT_FAILURE(rc))
    532                 RTLdrClose(hLdrMod);
    533         }
    534         if (RT_FAILURE(rc))
    535         {
    536             /*
    537              * Final fallback is a container module.
    538              */
    539             rc = RTDbgModCreate(&hMod, pszName, cbImage, 0);
    540             if (RT_FAILURE(rc))
    541                 return;
    542 
    543             rc = RTDbgModSymbolAdd(hMod, "Headers", 0 /*iSeg*/, 0, cbImage, 0 /*fFlags*/, NULL); AssertRC(rc);
    544         }
    545     }
    546     rc = RTDbgModSetTag(hMod, DIG_WINNT_MOD_TAG); AssertRC(rc);
    547 
    548 #if 0
    549     /*
    550      * Dig out debug info if possible.  What we're after is the CODEVIEW part.
    551      */
    552     /** @todo do we really need this? */
    553     if (uRvaDebugDir != 0)
    554     {
    555         DBGFADDRESS Addr = *pImageAddr;
    556         DBGFR3AddrAdd(&Addr, uRvaDebugDir);
    557         rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, &Addr, pbBuf, RT_MIN(cbDebugDir, cbBuf));
    558         if (RT_SUCCESS(rc))
    559         {
    560             IMAGE_DEBUG_DIRECTORY const    *pa = (IMAGE_DEBUG_DIRECTORY const *)pbBuf;
    561             size_t                          c  = RT_MIN(RT_MIN(cbDebugDir, cbBuf) / sizeof(*pa), 10);
    562             for (uint32_t i = 0; i < c; i++)
    563                 if (    pa[i].AddressOfRawData > offHdrs
    564                     &&  pa[i].AddressOfRawData < cbImage
    565                     &&  pa[i].SizeOfData       < cbImage
    566                     &&  pa[i].AddressOfRawData + pa[i].SizeOfData <= cbImage
    567                     &&  pa[i].TimeDateStamp   == TimeDateStamp /* too paranoid? */
    568                     &&  pa[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW
    569                     )
    570                 {
    571                 }
    572         }
    573     }
    574 #endif
     655        rc = RTDbgModSymbolAdd(hMod, "Headers", 0 /*iSeg*/, 0, cbImage, 0 /*fFlags*/, NULL);
     656        AssertRC(rc);
     657    }
     658
     659    /* Tag the module. */
     660    rc = RTDbgModSetTag(hMod, DIG_WINNT_MOD_TAG);
     661    AssertRC(rc);
    575662
    576663    /*
  • trunk/src/VBox/Runtime/common/dbg/dbgmod.cpp

    r46083 r46101  
    3333#include "internal/iprt.h"
    3434
     35#include <iprt/alloca.h>
    3536#include <iprt/asm.h>
    3637#include <iprt/assert.h>
     
    302303
    303304
     305/**
     306 * Performs lazy init of our global variables.
     307 * @returns IPRT status code.
     308 */
    304309DECLINLINE(int) rtDbgModLazyInit(void)
    305310{
     
    308313
    309314
    310 /**
    311  * Creates a module based on the default debug info container.
    312  *
    313  * This can be used to manually load a module and its symbol. The primary user
    314  * group is the debug info interpreters, which use this API to create an
    315  * efficient debug info container behind the scenes and forward all queries to
    316  * it once the info has been loaded.
    317  *
    318  * @returns IPRT status code.
    319  *
    320  * @param   phDbgMod        Where to return the module handle.
    321  * @param   pszName         The name of the module (mandatory).
    322  * @param   cbSeg           The size of initial segment. If zero, segments will
    323  *                          have to be added manually using RTDbgModSegmentAdd.
    324  * @param   fFlags          Flags reserved for future extensions, MBZ for now.
    325  */
    326315RTDECL(int) RTDbgModCreate(PRTDBGMOD phDbgMod, const char *pszName, RTUINTPTR cbSeg, uint32_t fFlags)
    327316{
     
    350339    if (RT_SUCCESS(rc))
    351340    {
    352         pDbgMod->pszName = RTStrCacheEnter(g_hDbgModStrCache, pszName);
     341        pDbgMod->pszImgFileSpecified = RTStrCacheEnter(g_hDbgModStrCache, pszName);
     342        pDbgMod->pszName             = RTStrCacheEnterLower(g_hDbgModStrCache, RTPathFilename(pszName));
    353343        if (pDbgMod->pszName)
    354344        {
     
    359349                return rc;
    360350            }
     351            RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile);
    361352            RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName);
    362353        }
     
    399390    if (RT_SUCCESS(rc))
    400391    {
    401         pDbgMod->pszName = RTStrCacheEnter(g_hDbgModStrCache, pszName);
     392        pDbgMod->pszName = RTStrCacheEnterLower(g_hDbgModStrCache, pszName);
    402393        if (pDbgMod->pszName)
    403394        {
     
    405396            if (pDbgMod->pszImgFile)
    406397            {
     398                RTStrCacheRetain(pDbgMod->pszImgFile);
     399                pDbgMod->pszImgFileSpecified = pDbgMod->pszImgFile;
     400
    407401                /*
    408402                 * Find an image reader which groks the file.
     
    488482                    RTSemRWReleaseRead(g_hDbgModRWSem);
    489483                }
    490                 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName);
     484                RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFileSpecified);
     485                RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile);
    491486            }
    492487            else
    493488                rc = VERR_NO_STR_MEMORY;
    494             RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile);
     489            RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName);
    495490        }
    496491        else
     
    537532    if (RT_SUCCESS(rc))
    538533    {
    539         pDbgMod->pszName = RTStrCacheEnter(g_hDbgModStrCache, pszName);
     534        pDbgMod->pszName = RTStrCacheEnterLower(g_hDbgModStrCache, pszName);
    540535        if (pDbgMod->pszName)
    541536        {
     
    700695rtDbgModOpenDebugInfoExternalToImageCallback(RTLDRMOD hLdrMod, PCRTLDRDBGINFO pDbgInfo, void *pvUser)
    701696{
    702     if (!pDbgInfo->pszExtFile)
    703         return VINF_SUCCESS;
    704 
     697    RTDBGMODOPENDIETI *pArgs = (RTDBGMODOPENDIETI *)pvUser;
     698
     699    Assert(pDbgInfo->enmType > RTLDRDBGINFOTYPE_INVALID && pDbgInfo->enmType < RTLDRDBGINFOTYPE_END);
     700    const char *pszExtFile = pDbgInfo->pszExtFile;
     701    if (!pszExtFile)
     702    {
     703        /*
     704         * If a external debug type comes without a file name, calculate a
     705         * likely debug filename for it. (Hack for NT4 drivers.)
     706         */
     707        const char *pszExt = NULL;
     708        if (pDbgInfo->enmType == RTLDRDBGINFOTYPE_CODEVIEW_DBG)
     709            pszExt = ".dbg";
     710        else if (   pDbgInfo->enmType == RTLDRDBGINFOTYPE_CODEVIEW_PDB20
     711                 || pDbgInfo->enmType == RTLDRDBGINFOTYPE_CODEVIEW_PDB70)
     712            pszExt = ".pdb";
     713        if (pszExt && pArgs->pDbgMod->pszName)
     714        {
     715            size_t cchName = strlen(pArgs->pDbgMod->pszName);
     716            char *psz = (char *)alloca(cchName + strlen(pszExt) + 1);
     717            if (psz)
     718            {
     719                memcpy(psz, pArgs->pDbgMod->pszName, cchName + 1);
     720                RTPathStripExt(psz);
     721                pszExtFile = strcat(psz, pszExt);
     722            }
     723        }
     724
     725        if (!pszExtFile)
     726        {
     727            Log2(("rtDbgModOpenDebugInfoExternalToImageCallback: enmType=%d\n", pDbgInfo->enmType));
     728            return VINF_SUCCESS;
     729        }
     730    }
     731
     732    /*
     733     * Switch on type and call the appropriate search function.
     734     */
    705735    int rc;
    706     RTDBGMODOPENDIETI *pArgs = (RTDBGMODOPENDIETI *)pvUser;
    707736    switch (pDbgInfo->enmType)
    708737    {
    709738        case RTLDRDBGINFOTYPE_CODEVIEW_PDB70:
    710             rc = RTDbgCfgOpenPdb70(pArgs->hDbgCfg, pDbgInfo->pszExtFile,
     739            rc = RTDbgCfgOpenPdb70(pArgs->hDbgCfg, pszExtFile,
    711740                                   &pDbgInfo->u.Pdb70.Uuid,
    712741                                   pDbgInfo->u.Pdb70.uAge,
     
    715744
    716745        case RTLDRDBGINFOTYPE_CODEVIEW_PDB20:
    717             rc = RTDbgCfgOpenPdb20(pArgs->hDbgCfg, pDbgInfo->pszExtFile,
     746            rc = RTDbgCfgOpenPdb20(pArgs->hDbgCfg, pszExtFile,
    718747                                   pDbgInfo->u.Pdb20.cbImage,
    719748                                   pDbgInfo->u.Pdb20.uTimestamp,
     
    723752
    724753        case RTLDRDBGINFOTYPE_CODEVIEW_DBG:
    725             rc = RTDbgCfgOpenDbg(pArgs->hDbgCfg, pDbgInfo->pszExtFile,
     754            rc = RTDbgCfgOpenDbg(pArgs->hDbgCfg, pszExtFile,
    726755                                 pDbgInfo->u.Dbg.cbImage,
    727756                                 pDbgInfo->u.Dbg.uTimestamp,
     
    730759
    731760        case RTLDRDBGINFOTYPE_DWARF_DWO:
    732             rc = RTDbgCfgOpenDwo(pArgs->hDbgCfg, pDbgInfo->pszExtFile,
     761            rc = RTDbgCfgOpenDwo(pArgs->hDbgCfg, pszExtFile,
    733762                                 pDbgInfo->u.Dwo.uCrc32,
    734763                                 rtDbgModExtDbgInfoOpenCallback, pArgs->pDbgMod, (void *)pDbgInfo);
     
    737766        default:
    738767            Log(("rtDbgModOpenDebugInfoExternalToImageCallback: Don't know how to handle enmType=%d and pszFileExt=%s\n",
    739                  pDbgInfo->enmType, pDbgInfo->pszExtFile));
     768                 pDbgInfo->enmType, pszExtFile));
    740769            return VERR_DBG_TODO;
    741770    }
     
    747776    }
    748777    Log(("rtDbgModOpenDebugInfoExternalToImageCallback: '%s' (enmType=%d) for '%s'  -> %Rrc\n",
    749          pDbgInfo->pszExtFile, pDbgInfo->enmType, pArgs->pDbgMod->pszImgFile, rc));
     778         pszExtFile, pDbgInfo->enmType, pArgs->pDbgMod->pszImgFile, rc));
    750779    return rc;
    751780}
     
    761790static int rtDbgModOpenDebugInfoExternalToImage(PRTDBGMODINT pDbgMod, RTDBGCFG hDbgCfg)
    762791{
     792    Assert(!pDbgMod->pDbgVt);
     793
    763794    RTDBGMODOPENDIETI Args;
    764795    Args.pDbgMod = pDbgMod;
     
    767798    if (RT_SUCCESS(rc) && pDbgMod->pDbgVt)
    768799        return VINF_SUCCESS;
     800
     801    LogFlow(("rtDbgModOpenDebugInfoExternalToImage: rc=%Rrc\n", rc));
    769802    return VERR_NOT_FOUND;
    770803}
     
    944977            if (pDbgMod->pszImgFile)
    945978            {
     979                RTStrCacheRetain(pDbgMod->pszImgFile);
     980                pDbgMod->pszImgFileSpecified = pDbgMod->pszImgFile;
     981
    946982                /*
    947983                 * If we have a loader module, we must instantiate the loader
     
    9931029            else
    9941030                rc = VERR_NO_STR_MEMORY;
     1031            RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFileSpecified);
    9951032            RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile);
    9961033        }
     
    10381075    RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName);
    10391076    RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile);
     1077    RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFileSpecified);
    10401078    RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszDbgFile);
    10411079    RTCritSectLeave(&pDbgMod->CritSect); /* paranoia  */
     
    10451083
    10461084
    1047 /**
    1048  * Retains another reference to the module.
    1049  *
    1050  * @returns New reference count, UINT32_MAX on invalid handle (asserted).
    1051  *
    1052  * @param   hDbgMod         The module handle.
    1053  *
    1054  * @remarks Will not take any locks.
    1055  */
    10561085RTDECL(uint32_t) RTDbgModRetain(RTDBGMOD hDbgMod)
    10571086{
     
    10631092
    10641093
    1065 /**
    1066  * Release a reference to the module.
    1067  *
    1068  * When the reference count reaches zero, the module is destroyed.
    1069  *
    1070  * @returns New reference count, UINT32_MAX on invalid handle (asserted).
    1071  *
    1072  * @param   hDbgMod         The module handle. The NIL handle is quietly ignored
    1073  *                          and 0 is returned.
    1074  *
    1075  * @remarks Will not take any locks.
    1076  */
    10771094RTDECL(uint32_t) RTDbgModRelease(RTDBGMOD hDbgMod)
    10781095{
     
    10901107
    10911108
    1092 /**
    1093  * Gets the module name.
    1094  *
    1095  * @returns Pointer to a read only string containing the name.
    1096  *
    1097  * @param   hDbgMod         The module handle.
    1098  */
    10991109RTDECL(const char *) RTDbgModName(RTDBGMOD hDbgMod)
    11001110{
     
    11061116
    11071117
    1108 /**
    1109  * Converts an image relative address to a segment:offset address.
    1110  *
    1111  * @returns Segment index on success.
    1112  *          NIL_RTDBGSEGIDX is returned if the module handle or the RVA are
    1113  *          invalid.
    1114  *
    1115  * @param   hDbgMod         The module handle.
    1116  * @param   uRva            The image relative address to convert.
    1117  * @param   poffSeg         Where to return the segment offset. Optional.
    1118  */
     1118RTDECL(const char *) RTDbgModDebugFile(RTDBGMOD hDbgMod)
     1119{
     1120    PRTDBGMODINT pDbgMod = hDbgMod;
     1121    RTDBGMOD_VALID_RETURN_RC(pDbgMod, NULL);
     1122    if (pDbgMod->fDeferred || pDbgMod->fExports)
     1123        return NULL;
     1124    return pDbgMod->pszDbgFile;
     1125}
     1126RT_EXPORT_SYMBOL(RTDbgModDebugFile);
     1127
     1128
     1129RTDECL(const char *) RTDbgModImageFile(RTDBGMOD hDbgMod)
     1130{
     1131    PRTDBGMODINT pDbgMod = hDbgMod;
     1132    RTDBGMOD_VALID_RETURN_RC(pDbgMod, NULL);
     1133    return pDbgMod->pszImgFileSpecified;
     1134}
     1135RT_EXPORT_SYMBOL(RTDbgModImageFile);
     1136
     1137
     1138RTDECL(const char *) RTDbgModImageFileUsed(RTDBGMOD hDbgMod)
     1139{
     1140    PRTDBGMODINT pDbgMod = hDbgMod;
     1141    RTDBGMOD_VALID_RETURN_RC(pDbgMod, NULL);
     1142    return pDbgMod->pszImgFile == pDbgMod->pszImgFileSpecified ? NULL : pDbgMod->pszImgFile;
     1143}
     1144RT_EXPORT_SYMBOL(RTDbgModImageFileUsed);
     1145
     1146
    11191147RTDECL(RTDBGSEGIDX) RTDbgModRvaToSegOff(RTDBGMOD hDbgMod, RTUINTPTR uRva, PRTUINTPTR poffSeg)
    11201148{
     
    11311159
    11321160
    1133 /**
    1134  * Image size when mapped if segments are mapped adjacently.
    1135  *
    1136  * For ELF, PE, and Mach-O images this is (usually) a natural query, for LX and
    1137  * NE and such it's a bit odder and the answer may not make much sense for them.
    1138  *
    1139  * @returns Image mapped size.
    1140  *          RTUINTPTR_MAX is returned if the handle is invalid.
    1141  *
    1142  * @param   hDbgMod         The module handle.
    1143  */
    11441161RTDECL(RTUINTPTR) RTDbgModImageSize(RTDBGMOD hDbgMod)
    11451162{
     
    11561173
    11571174
    1158 /**
    1159  * Gets the module tag value if any.
    1160  *
    1161  * @returns The tag. 0 if hDbgMod is invalid.
    1162  *
    1163  * @param   hDbgMod         The module handle.
    1164  */
    11651175RTDECL(uint64_t) RTDbgModGetTag(RTDBGMOD hDbgMod)
    11661176{
     
    11721182
    11731183
    1174 /**
    1175  * Tags or untags the module.
    1176  *
    1177  * @returns IPRT status code.
    1178  * @retval  VERR_INVALID_HANDLE if hDbgMod is invalid.
    1179  *
    1180  * @param   hDbgMod         The module handle.
    1181  * @param   uTag            The tag value.  The convention is that 0 is no tag
    1182  *                          and any other value means it's tagged.  It's adviced
    1183  *                          to use some kind of unique number like an address
    1184  *                          (global or string cache for instance) to avoid
    1185  *                          collisions with other users
    1186  */
    11871184RTDECL(int) RTDbgModSetTag(RTDBGMOD hDbgMod, uint64_t uTag)
    11881185{
     
    11991196
    12001197
    1201 /**
    1202  * Adds a segment to the module. Optional feature.
    1203  *
    1204  * This method is intended used for manually constructing debug info for a
    1205  * module. The main usage is from other debug info interpreters that want to
    1206  * avoid writing a debug info database and instead uses the standard container
    1207  * behind the scenes.
    1208  *
    1209  * @returns IPRT status code.
    1210  * @retval  VERR_NOT_SUPPORTED if this feature isn't support by the debug info
    1211  *          interpreter. This is a common return code.
    1212  * @retval  VERR_INVALID_HANDLE if hDbgMod is invalid.
    1213  * @retval  VERR_DBG_ADDRESS_WRAP if uRva+cb wraps around.
    1214  * @retval  VERR_DBG_SEGMENT_NAME_OUT_OF_RANGE if pszName is too short or long.
    1215  * @retval  VERR_INVALID_PARAMETER if fFlags contains undefined flags.
    1216  * @retval  VERR_DBG_SPECIAL_SEGMENT if *piSeg is a special segment.
    1217  * @retval  VERR_DBG_INVALID_SEGMENT_INDEX if *piSeg doesn't meet expectations.
    1218  *
    1219  * @param   hDbgMod             The module handle.
    1220  * @param   uRva                The image relative address of the segment.
    1221  * @param   cb                  The size of the segment.
    1222  * @param   pszName             The segment name. Does not normally need to be
    1223  *                              unique, although this is somewhat up to the
    1224  *                              debug interpreter to decide.
    1225  * @param   fFlags              Segment flags. Reserved for future used, MBZ.
    1226  * @param   piSeg               The segment index or NIL_RTDBGSEGIDX on input.
    1227  *                              The assigned segment index on successful return.
    1228  *                              Optional.
    1229  */
    12301198RTDECL(int) RTDbgModSegmentAdd(RTDBGMOD hDbgMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName,
    12311199                               uint32_t fFlags, PRTDBGSEGIDX piSeg)
     
    12581226
    12591227
    1260 /**
    1261  * Gets the number of segments in the module.
    1262  *
    1263  * This is can be used to determine the range which can be passed to
    1264  * RTDbgModSegmentByIndex and derivatives.
    1265  *
    1266  * @returns The segment relative address.
    1267  *          NIL_RTDBGSEGIDX if the handle is invalid.
    1268  *
    1269  * @param   hDbgMod         The module handle.
    1270  */
    12711228RTDECL(RTDBGSEGIDX) RTDbgModSegmentCount(RTDBGMOD hDbgMod)
    12721229{
     
    12831240
    12841241
    1285 /**
    1286  * Query information about a segment.
    1287  *
    1288  * This can be used together with RTDbgModSegmentCount to enumerate segments.
    1289  * The index starts a 0 and stops one below RTDbgModSegmentCount.
    1290  *
    1291  * @returns IPRT status code.
    1292  * @retval  VERR_DBG_INVALID_SEGMENT_INDEX if iSeg is too high.
    1293  * @retval  VERR_DBG_SPECIAL_SEGMENT if iSeg indicates a special segment.
    1294  * @retval  VERR_INVALID_HANDLE if hDbgMod is invalid.
    1295  *
    1296  * @param   hDbgMod         The module handle.
    1297  * @param   iSeg            The segment index. No special segments.
    1298  * @param   pSegInfo        Where to return the segment info. The
    1299  *                          RTDBGSEGMENT::Address member will be set to
    1300  *                          RTUINTPTR_MAX or the load address used at link time.
    1301  */
    13021242RTDECL(int) RTDbgModSegmentByIndex(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo)
    13031243{
     
    13151255
    13161256
    1317 /**
    1318  * Gets the size of a segment.
    1319  *
    1320  * This is a just a wrapper around RTDbgModSegmentByIndex.
    1321  *
    1322  * @returns The segment size.
    1323  *          RTUINTPTR_MAX is returned if either the handle and segment index are
    1324  *          invalid.
    1325  *
    1326  * @param   hDbgMod         The module handle.
    1327  * @param   iSeg            The segment index. RTDBGSEGIDX_ABS is not allowed.
    1328  *                          If RTDBGSEGIDX_RVA is used, the functions returns
    1329  *                          the same value as RTDbgModImageSize.
    1330  */
    13311257RTDECL(RTUINTPTR) RTDbgModSegmentSize(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg)
    13321258{
     
    13401266
    13411267
    1342 /**
    1343  * Gets the image relative address of a segment.
    1344  *
    1345  * This is a just a wrapper around RTDbgModSegmentByIndex.
    1346  *
    1347  * @returns The segment relative address.
    1348  *          RTUINTPTR_MAX is returned if either the handle and segment index are
    1349  *          invalid.
    1350  *
    1351  * @param   hDbgMod         The module handle.
    1352  * @param   iSeg            The segment index. No special segment indexes
    1353  *                          allowed (asserted).
    1354  */
    13551268RTDECL(RTUINTPTR) RTDbgModSegmentRva(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg)
    13561269{
     
    13621275
    13631276
    1364 /**
    1365  * Adds a line number to the module.
    1366  *
    1367  * @returns IPRT status code.
    1368  * @retval  VERR_NOT_SUPPORTED if the module interpret doesn't support adding
    1369  *          custom symbols. This is a common place occurrence.
    1370  * @retval  VERR_INVALID_HANDLE if hDbgMod is invalid.
    1371  * @retval  VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE if the symbol name is too long or
    1372  *          short.
    1373  * @retval  VERR_DBG_INVALID_RVA if an image relative address is specified and
    1374  *          it's not inside any of the segments defined by the module.
    1375  * @retval  VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.
    1376  * @retval  VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the
    1377  *          end of the segment.
    1378  * @retval  VERR_DBG_ADDRESS_WRAP if off+cb wraps around.
    1379  * @retval  VERR_INVALID_PARAMETER if the symbol flags sets undefined bits.
    1380  *
    1381  * @param   hDbgMod         The module handle.
    1382  * @param   pszSymbol       The symbol name.
    1383  * @param   iSeg            The segment index.
    1384  * @param   off             The segment offset.
    1385  * @param   cb              The size of the symbol. Can be zero, although this
    1386  *                          may depend somewhat on the debug interpreter.
    1387  * @param   fFlags          Symbol flags. Reserved for the future, MBZ.
    1388  * @param   piOrdinal       Where to return the symbol ordinal on success. If
    1389  *                          the interpreter doesn't do ordinals, this will be set to
    1390  *                          UINT32_MAX. Optional.
    1391  */
    13921277RTDECL(int) RTDbgModSymbolAdd(RTDBGMOD hDbgMod, const char *pszSymbol, RTDBGSEGIDX iSeg, RTUINTPTR off,
    13931278                              RTUINTPTR cb, uint32_t fFlags, uint32_t *piOrdinal)
     
    14361321
    14371322
    1438 /**
    1439  * Gets the symbol count.
    1440  *
    1441  * This can be used together wtih RTDbgModSymbolByOrdinal or
    1442  * RTDbgModSymbolByOrdinalA to enumerate all the symbols.
    1443  *
    1444  * @returns The number of symbols in the module.
    1445  *          UINT32_MAX is returned if the module handle is invalid or some other
    1446  *          error occurs.
    1447  *
    1448  * @param   hDbgMod             The module handle.
    1449  */
    14501323RTDECL(uint32_t) RTDbgModSymbolCount(RTDBGMOD hDbgMod)
    14511324{
     
    14621335
    14631336
    1464 /**
    1465  * Queries symbol information by ordinal number.
    1466  *
    1467  * @returns IPRT status code.
    1468  * @retval  VERR_SYMBOL_NOT_FOUND if there is no symbol at the given number.
    1469  * @retval  VERR_DBG_NO_SYMBOLS if there aren't any symbols.
    1470  * @retval  VERR_INVALID_HANDLE if hDbgMod is invalid.
    1471  * @retval  VERR_NOT_SUPPORTED if lookup by ordinal is not supported.
    1472  *
    1473  * @param   hDbgMod             The module handle.
    1474  * @param   iOrdinal            The symbol ordinal number. 0-based. The highest
    1475  *                              number is RTDbgModSymbolCount() - 1.
    1476  * @param   pSymInfo            Where to store the symbol information.
    1477  */
    14781337RTDECL(int) RTDbgModSymbolByOrdinal(RTDBGMOD hDbgMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo)
    14791338{
     
    14901349
    14911350
    1492 /**
    1493  * Queries symbol information by ordinal number.
    1494  *
    1495  * @returns IPRT status code.
    1496  * @retval  VERR_DBG_NO_SYMBOLS if there aren't any symbols.
    1497  * @retval  VERR_NOT_SUPPORTED if lookup by ordinal is not supported.
    1498  * @retval  VERR_SYMBOL_NOT_FOUND if there is no symbol at the given number.
    1499  * @retval  VERR_NO_MEMORY if RTDbgSymbolAlloc fails.
    1500  *
    1501  * @param   hDbgMod             The module handle.
    1502  * @param   iOrdinal            The symbol ordinal number. 0-based. The highest
    1503  *                              number is RTDbgModSymbolCount() - 1.
    1504  * @param   ppSymInfo           Where to store the pointer to the returned
    1505  *                              symbol information. Always set. Free with
    1506  *                              RTDbgSymbolFree.
    1507  */
    15081351RTDECL(int) RTDbgModSymbolByOrdinalA(RTDBGMOD hDbgMod, uint32_t iOrdinal, PRTDBGSYMBOL *ppSymInfo)
    15091352{
     
    15261369
    15271370
    1528 /**
    1529  * Queries symbol information by address.
    1530  *
    1531  * The returned symbol is what the debug info interpreter considers the symbol
    1532  * most applicable to the specified address. This usually means a symbol with an
    1533  * address equal or lower than the requested.
    1534  *
    1535  * @returns IPRT status code.
    1536  * @retval  VERR_SYMBOL_NOT_FOUND if no suitable symbol was found.
    1537  * @retval  VERR_DBG_NO_SYMBOLS if there aren't any symbols.
    1538  * @retval  VERR_INVALID_HANDLE if hDbgMod is invalid.
    1539  * @retval  VERR_DBG_INVALID_RVA if an image relative address is specified and
    1540  *          it's not inside any of the segments defined by the module.
    1541  * @retval  VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.
    1542  * @retval  VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the
    1543  *          end of the segment.
    1544  * @retval  VERR_INVALID_PARAMETER if incorrect flags.
    1545  *
    1546  * @param   hDbgMod             The module handle.
    1547  * @param   iSeg                The segment number.
    1548  * @param   off                 The offset into the segment.
    1549  * @param   fFlags              Symbol search flags, see RTDBGSYMADDR_FLAGS_XXX.
    1550  * @param   poffDisp            Where to store the distance between the
    1551  *                              specified address and the returned symbol.
    1552  *                              Optional.
    1553  * @param   pSymInfo            Where to store the symbol information.
    1554  */
    15551371RTDECL(int) RTDbgModSymbolByAddr(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags,
    15561372                                 PRTINTPTR poffDisp, PRTDBGSYMBOL pSymInfo)
     
    15911407
    15921408
    1593 /**
    1594  * Queries symbol information by address.
    1595  *
    1596  * The returned symbol is what the debug info interpreter considers the symbol
    1597  * most applicable to the specified address. This usually means a symbol with an
    1598  * address equal or lower than the requested.
    1599  *
    1600  * @returns IPRT status code.
    1601  * @retval  VERR_SYMBOL_NOT_FOUND if no suitable symbol was found.
    1602  * @retval  VERR_DBG_NO_SYMBOLS if there aren't any symbols.
    1603  * @retval  VERR_INVALID_HANDLE if hDbgMod is invalid.
    1604  * @retval  VERR_DBG_INVALID_RVA if an image relative address is specified and
    1605  *          it's not inside any of the segments defined by the module.
    1606  * @retval  VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.
    1607  * @retval  VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the
    1608  *          end of the segment.
    1609  * @retval  VERR_NO_MEMORY if RTDbgSymbolAlloc fails.
    1610  * @retval  VERR_INVALID_PARAMETER if incorrect flags.
    1611  *
    1612  * @param   hDbgMod             The module handle.
    1613  * @param   iSeg                The segment index.
    1614  * @param   off                 The offset into the segment.
    1615  * @param   fFlags              Symbol search flags, see RTDBGSYMADDR_FLAGS_XXX.
    1616  * @param   poffDisp            Where to store the distance between the
    1617  *                              specified address and the returned symbol. Optional.
    1618  * @param   ppSymInfo           Where to store the pointer to the returned
    1619  *                              symbol information. Always set. Free with
    1620  *                              RTDbgSymbolFree.
    1621  */
    16221409RTDECL(int) RTDbgModSymbolByAddrA(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags,
    16231410                                  PRTINTPTR poffDisp, PRTDBGSYMBOL *ppSymInfo)
     
    16411428
    16421429
    1643 /**
    1644  * Queries symbol information by symbol name.
    1645  *
    1646  * @returns IPRT status code.
    1647  * @retval  VERR_DBG_NO_SYMBOLS if there aren't any symbols.
    1648  * @retval  VERR_SYMBOL_NOT_FOUND if no suitable symbol was found.
    1649  * @retval  VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE if the symbol name is too long or
    1650  *          short.
    1651  *
    1652  * @param   hDbgMod             The module handle.
    1653  * @param   pszSymbol           The symbol name.
    1654  * @param   pSymInfo            Where to store the symbol information.
    1655  */
    16561430RTDECL(int) RTDbgModSymbolByName(RTDBGMOD hDbgMod, const char *pszSymbol, PRTDBGSYMBOL pSymInfo)
    16571431{
     
    16791453
    16801454
    1681 /**
    1682  * Queries symbol information by symbol name.
    1683  *
    1684  * @returns IPRT status code.
    1685  * @retval  VERR_DBG_NO_SYMBOLS if there aren't any symbols.
    1686  * @retval  VERR_SYMBOL_NOT_FOUND if no suitable symbol was found.
    1687  * @retval  VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE if the symbol name is too long or
    1688  *          short.
    1689  * @retval  VERR_NO_MEMORY if RTDbgSymbolAlloc fails.
    1690  *
    1691  * @param   hDbgMod             The module handle.
    1692  * @param   pszSymbol           The symbol name.
    1693  * @param   ppSymInfo           Where to store the pointer to the returned
    1694  *                              symbol information. Always set. Free with
    1695  *                              RTDbgSymbolFree.
    1696  */
    16971455RTDECL(int) RTDbgModSymbolByNameA(RTDBGMOD hDbgMod, const char *pszSymbol, PRTDBGSYMBOL *ppSymInfo)
    16981456{
     
    17151473
    17161474
    1717 /**
    1718  * Adds a line number to the module.
    1719  *
    1720  * @returns IPRT status code.
    1721  * @retval  VERR_NOT_SUPPORTED if the module interpret doesn't support adding
    1722  *          custom symbols. This should be consider a normal response.
    1723  * @retval  VERR_INVALID_HANDLE if hDbgMod is invalid.
    1724  * @retval  VERR_DBG_FILE_NAME_OUT_OF_RANGE if the file name is too longer or
    1725  *          empty.
    1726  * @retval  VERR_DBG_INVALID_RVA if an image relative address is specified and
    1727  *          it's not inside any of the segments defined by the module.
    1728  * @retval  VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.
    1729  * @retval  VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the
    1730  *          end of the segment.
    1731  * @retval  VERR_INVALID_PARAMETER if the line number flags sets undefined bits.
    1732  *
    1733  * @param   hDbgMod             The module handle.
    1734  * @param   pszFile             The file name.
    1735  * @param   uLineNo             The line number.
    1736  * @param   iSeg                The segment index.
    1737  * @param   off                 The segment offset.
    1738  * @param   piOrdinal           Where to return the line number ordinal on
    1739  *                              success. If  the interpreter doesn't do ordinals,
    1740  *                              this will be set to UINT32_MAX. Optional.
    1741  */
    17421475RTDECL(int) RTDbgModLineAdd(RTDBGMOD hDbgMod, const char *pszFile, uint32_t uLineNo,
    17431476                            RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t *piOrdinal)
     
    17841517
    17851518
    1786 /**
    1787  * Gets the line number count.
    1788  *
    1789  * This can be used together wtih RTDbgModLineByOrdinal or RTDbgModSymbolByLineA
    1790  * to enumerate all the line number information.
    1791  *
    1792  * @returns The number of line numbers in the module.
    1793  *          UINT32_MAX is returned if the module handle is invalid or some other
    1794  *          error occurs.
    1795  *
    1796  * @param   hDbgMod             The module handle.
    1797  */
    17981519RTDECL(uint32_t) RTDbgModLineCount(RTDBGMOD hDbgMod)
    17991520{
     
    18101531
    18111532
    1812 /**
    1813  * Queries line number information by ordinal number.
    1814  *
    1815  * This can be used to enumerate the line numbers for the module. Use
    1816  * RTDbgModLineCount() to figure the end of the ordinals.
    1817  *
    1818  * @returns IPRT status code.
    1819  * @retval  VERR_DBG_NO_LINE_NUMBERS if there aren't any line numbers.
    1820  * @retval  VERR_DBG_LINE_NOT_FOUND if there is no line number with that
    1821  *          ordinal.
    1822  * @retval  VERR_INVALID_HANDLE if hDbgMod is invalid.
    1823 
    1824  * @param   hDbgMod             The module handle.
    1825  * @param   iOrdinal            The line number ordinal number.
    1826  * @param   pLineInfo           Where to store the information about the line
    1827  *                              number.
    1828  */
    18291533RTDECL(int) RTDbgModLineByOrdinal(RTDBGMOD hDbgMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo)
    18301534{
     
    18411545
    18421546
    1843 /**
    1844  * Queries line number information by ordinal number.
    1845  *
    1846  * This can be used to enumerate the line numbers for the module. Use
    1847  * RTDbgModLineCount() to figure the end of the ordinals.
    1848  *
    1849  * @returns IPRT status code.
    1850  * @retval  VERR_DBG_NO_LINE_NUMBERS if there aren't any line numbers.
    1851  * @retval  VERR_DBG_LINE_NOT_FOUND if there is no line number with that
    1852  *          ordinal.
    1853  * @retval  VERR_INVALID_HANDLE if hDbgMod is invalid.
    1854  * @retval  VERR_NO_MEMORY if RTDbgLineAlloc fails.
    1855  *
    1856  * @param   hDbgMod             The module handle.
    1857  * @param   iOrdinal            The line number ordinal number.
    1858  * @param   ppLineInfo          Where to store the pointer to the returned line
    1859  *                              number information. Always set. Free with
    1860  *                              RTDbgLineFree.
    1861  */
    18621547RTDECL(int) RTDbgModLineByOrdinalA(RTDBGMOD hDbgMod, uint32_t iOrdinal, PRTDBGLINE *ppLineInfo)
    18631548{
     
    18801565
    18811566
    1882 /**
    1883  * Queries line number information by address.
    1884  *
    1885  * The returned line number is what the debug info interpreter considers the
    1886  * one most applicable to the specified address. This usually means a line
    1887  * number with an address equal or lower than the requested.
    1888  *
    1889  * @returns IPRT status code.
    1890  * @retval  VERR_DBG_NO_LINE_NUMBERS if there aren't any line numbers.
    1891  * @retval  VERR_DBG_LINE_NOT_FOUND if no suitable line number was found.
    1892  * @retval  VERR_INVALID_HANDLE if hDbgMod is invalid.
    1893  * @retval  VERR_DBG_INVALID_RVA if an image relative address is specified and
    1894  *          it's not inside any of the segments defined by the module.
    1895  * @retval  VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.
    1896  * @retval  VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the
    1897  *          end of the segment.
    1898  *
    1899  * @param   hDbgMod             The module handle.
    1900  * @param   iSeg                The segment number.
    1901  * @param   off                 The offset into the segment.
    1902  * @param   poffDisp            Where to store the distance between the
    1903  *                              specified address and the returned symbol.
    1904  *                              Optional.
    1905  * @param   pLineInfo           Where to store the line number information.
    1906  */
    19071567RTDECL(int) RTDbgModLineByAddr(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTINTPTR poffDisp, PRTDBGLINE pLineInfo)
    19081568{
     
    19381598
    19391599
    1940 /**
    1941  * Queries line number information by address.
    1942  *
    1943  * The returned line number is what the debug info interpreter considers the
    1944  * one most applicable to the specified address. This usually means a line
    1945  * number with an address equal or lower than the requested.
    1946  *
    1947  * @returns IPRT status code.
    1948  * @retval  VERR_DBG_NO_LINE_NUMBERS if there aren't any line numbers.
    1949  * @retval  VERR_DBG_LINE_NOT_FOUND if no suitable line number was found.
    1950  * @retval  VERR_INVALID_HANDLE if hDbgMod is invalid.
    1951  * @retval  VERR_DBG_INVALID_RVA if an image relative address is specified and
    1952  *          it's not inside any of the segments defined by the module.
    1953  * @retval  VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.
    1954  * @retval  VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the
    1955  *          end of the segment.
    1956  * @retval  VERR_NO_MEMORY if RTDbgLineAlloc fails.
    1957  *
    1958  * @param   hDbgMod             The module handle.
    1959  * @param   iSeg                The segment number.
    1960  * @param   off                 The offset into the segment.
    1961  * @param   poffDisp            Where to store the distance between the
    1962  *                              specified address and the returned symbol.
    1963  *                              Optional.
    1964  * @param   ppLineInfo          Where to store the pointer to the returned line
    1965  *                              number information. Always set. Free with
    1966  *                              RTDbgLineFree.
    1967  */
    19681600RTDECL(int) RTDbgModLineByAddrA(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTINTPTR poffDisp, PRTDBGLINE *ppLineInfo)
    19691601{
  • trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp

    r46083 r46101  
    9090    /** Size of the header (IMAGE_OPTIONAL_HEADER32::SizeOfHeaders). */
    9191    uint32_t                cbHeaders;
     92    /** The image timestamp. */
     93    uint32_t                uTimestamp;
    9294    /** The import data directory entry. */
    9395    IMAGE_DATA_DIRECTORY    ImportDir;
     
    135137static void rtldrPEConvert32BitOptionalHeaderTo64Bit(PIMAGE_OPTIONAL_HEADER64 pOptHdr);
    136138static void rtldrPEConvert32BitLoadConfigTo64Bit(PIMAGE_LOAD_CONFIG_DIRECTORY64 pLoadCfg);
    137 static int rtldrPEApplyFixups(PRTLDRMODPE pModPe, const void *pvBitsR, void *pvBitsW, RTUINTPTR BaseAddress, RTUINTPTR OldBaseAddress);
     139static int  rtldrPEApplyFixups(PRTLDRMODPE pModPe, const void *pvBitsR, void *pvBitsW, RTUINTPTR BaseAddress, RTUINTPTR OldBaseAddress);
     140
     141
     142
     143/**
     144 * Reads a section of a PE image given by RVA + size, using mapped bits if
     145 * available or allocating heap memory and reading from the file.
     146 *
     147 * @returns IPRT status code.
     148 * @param   pThis               Pointer to the PE loader module structure.
     149 * @param   pvBits              Read only bits if available. NULL if not.
     150 * @param   uRva                The RVA to read at.
     151 * @param   cbMem               The number of bytes to read.
     152 * @param   ppvMem              Where to return the memory on success (heap or
     153 *                              inside pvBits).
     154 */
     155static int rtldrPEReadPartByRva(PRTLDRMODPE pThis, const void *pvBits, uint32_t uRva, uint32_t cbMem, void const **ppvMem)
     156{
     157    *ppvMem = NULL;
     158    if (!cbMem)
     159        return VINF_SUCCESS;
     160
     161    /*
     162     * Use bits if we've got some.
     163     */
     164    if (pvBits)
     165    {
     166        *ppvMem = (uint8_t const *)pvBits + uRva;
     167        return VINF_SUCCESS;
     168    }
     169    if (pThis->pvBits)
     170    {
     171        *ppvMem = (uint8_t const *)pThis->pvBits + uRva;
     172        return VINF_SUCCESS;
     173    }
     174
     175    /*
     176     * Allocate a buffer and read the bits from the file (or whatever).
     177     */
     178    if (!pThis->Core.pReader)
     179        return VERR_ACCESS_DENIED;
     180
     181    uint8_t *pbMem = (uint8_t *)RTMemAllocZ(cbMem);
     182    if (!pbMem)
     183        return VERR_NO_MEMORY;
     184    *ppvMem = pbMem;
     185
     186    /* Do the reading on a per section base. */
     187    RTFOFF const cbFile = pThis->Core.pReader->pfnSize(pThis->Core.pReader);
     188    for (;;)
     189    {
     190        /* Translate the RVA into a file offset. */
     191        uint32_t offFile  = uRva;
     192        uint32_t cbToRead = cbMem;
     193        uint32_t cbToAdv  = cbMem;
     194
     195        if (uRva < pThis->paSections[0].VirtualAddress)
     196        {
     197            /* Special header section. */
     198            cbToRead = pThis->paSections[0].VirtualAddress - uRva;
     199            if (cbToRead > cbMem)
     200                cbToRead = cbMem;
     201            cbToAdv = cbToRead;
     202
     203            /* The following capping is an approximation. */
     204            uint32_t offFirstRawData = RT_ALIGN(pThis->cbHeaders, _4K);
     205            if (   pThis->paSections[0].PointerToRawData > 0
     206                && pThis->paSections[0].SizeOfRawData > 0)
     207                offFirstRawData = pThis->paSections[0].PointerToRawData;
     208            if (offFile > offFirstRawData)
     209                cbToRead = 0;
     210            else if (offFile + cbToRead > offFirstRawData)
     211                cbToRead = offFile + cbToRead - offFirstRawData;
     212        }
     213        else
     214        {
     215            /* Find the matching section and its mapping size. */
     216            uint32_t j         = 0;
     217            uint32_t cbMapping = 0;
     218            while (j < pThis->cSections)
     219            {
     220                cbMapping = (j + 1 < pThis->cSections ? pThis->paSections[j + 1].VirtualAddress : pThis->cbImage)
     221                          - pThis->paSections[j].VirtualAddress;
     222                if (uRva - pThis->paSections[j].VirtualAddress < cbMapping)
     223                    break;
     224                j++;
     225            }
     226            if (j >= cbMapping)
     227                break; /* This shouldn't happen, just return zeros if it does. */
     228
     229            /* Adjust the sizes and calc the file offset. */
     230            if (cbToAdv > cbMapping)
     231                cbToAdv = cbToRead = cbMapping;
     232            if (   pThis->paSections[j].PointerToRawData > 0
     233                && pThis->paSections[j].SizeOfRawData > 0)
     234            {
     235                offFile = uRva - pThis->paSections[j].VirtualAddress;
     236                if (offFile + cbToRead > pThis->paSections[j].SizeOfRawData)
     237                    cbToRead = pThis->paSections[j].SizeOfRawData - offFile;
     238                offFile += pThis->paSections[j].PointerToRawData;
     239            }
     240            else
     241            {
     242                offFile  = -1;
     243                cbToRead = 0;
     244            }
     245        }
     246
     247        /* Perform the read after adjusting a little (paranoia). */
     248        if (offFile > cbFile)
     249            cbToRead = 0;
     250        if (cbToRead)
     251        {
     252            if ((RTFOFF)offFile + cbToRead > cbFile)
     253                cbToRead = cbFile - (RTFOFF)offFile;
     254            int rc = pThis->Core.pReader->pfnRead(pThis->Core.pReader, pbMem, cbToRead, offFile);
     255            if (RT_FAILURE(rc))
     256            {
     257                RTMemFree((void *)*ppvMem);
     258                *ppvMem = NULL;
     259                return rc;
     260            }
     261        }
     262
     263        /* Advance */
     264        if (cbMem == cbToRead)
     265            break;
     266        cbMem -= cbToRead;
     267        pbMem += cbToRead;
     268        uRva  += cbToRead;
     269    }
     270
     271    return VINF_SUCCESS;
     272}
     273
     274
     275/**
     276 * Reads a part of a PE file from the file and into a heap block.
     277 *
     278 * @returns IRPT status code.
     279 * @param   pThis               Pointer to the PE loader module structure..
     280 * @param   offFile             The file offset.
     281 * @param   cbMem               The number of bytes to read.
     282 * @param   ppvMem              Where to return the heap block with the bytes on
     283 *                              success.
     284 */
     285static int rtldrPEReadPartFromFile(PRTLDRMODPE pThis, uint32_t offFile, uint32_t cbMem, void const **ppvMem)
     286{
     287    *ppvMem = NULL;
     288    if (!cbMem)
     289        return VINF_SUCCESS;
     290
     291    /*
     292     * Allocate a buffer and read the bits from the file (or whatever).
     293     */
     294    if (!pThis->Core.pReader)
     295        return VERR_ACCESS_DENIED;
     296
     297    uint8_t *pbMem = (uint8_t *)RTMemAlloc(cbMem);
     298    if (!pbMem)
     299        return VERR_NO_MEMORY;
     300
     301    int rc = pThis->Core.pReader->pfnRead(pThis->Core.pReader, pbMem, cbMem, offFile);
     302    if (RT_FAILURE(rc))
     303    {
     304        RTMemFree((void *)*ppvMem);
     305        return rc;
     306    }
     307
     308    *ppvMem = pbMem;
     309    return VINF_SUCCESS;
     310}
     311
     312
     313/**
     314 * Reads a part of a PE image into memory one way or another.
     315 *
     316 * Either the RVA or the offFile must be valid.  We'll prefer the RVA if
     317 * possible.
     318 *
     319 * @returns IPRT status code.
     320 * @param   pThis               Pointer to the PE loader module structure.
     321 * @param   pvBits              Read only bits if available. NULL if not.
     322 * @param   uRva                The RVA to read at.
     323 * @param   offFile             The file offset.
     324 * @param   cbMem               The number of bytes to read.
     325 * @param   ppvMem              Where to return the memory on success (heap or
     326 *                              inside pvBits).
     327 */
     328static int rtldrPEReadPart(PRTLDRMODPE pThis, const void *pvBits, RTFOFF offFile, RTLDRADDR uRva,
     329                           uint32_t cbMem, void const **ppvMem)
     330{
     331    if (uRva == NIL_RTLDRADDR || uRva > pThis->cbImage)
     332    {
     333        if (offFile < 0)
     334            return VERR_INVALID_PARAMETER;
     335        return rtldrPEReadPartFromFile(pThis, offFile, cbMem, ppvMem);
     336    }
     337    return rtldrPEReadPartByRva(pThis, pvBits, uRva, cbMem, ppvMem);
     338}
     339
     340
     341/**
     342 * Frees up memory returned by rtldrPEReadPart*.
     343 *
     344 * @param   pThis               Pointer to the PE loader module structure..
     345 * @param   pvBits              Read only bits if available. NULL if not..
     346 * @param   pvMem               The memory we were given by the reader method.
     347 */
     348static void rtldrPEFreePart(PRTLDRMODPE pThis, const void *pvBits, void const *pvMem)
     349{
     350    if (!pvMem)
     351        return;
     352
     353    if (pvBits        && (uintptr_t)pvBits        - (uintptr_t)pvMem < pThis->cbImage)
     354        return;
     355    if (pThis->pvBits && (uintptr_t)pThis->pvBits - (uintptr_t)pvMem < pThis->cbImage)
     356        return;
     357
     358    RTMemFree((void *)pvMem);
     359}
    138360
    139361
     
    7881010
    7891011    /*
    790      * No bits supplied? Do we need to read the bits?
     1012     * Get the debug directory.
    7911013     */
    7921014    if (!pvBits)
    793     {
    794         if (!pModPe->pvBits)
    795         {
    796             rc = rtldrPEReadBits(pModPe);
    797             if (RT_FAILURE(rc))
    798                 return rc;
    799         }
    8001015        pvBits = pModPe->pvBits;
    801     }
     1016
     1017    PCIMAGE_DEBUG_DIRECTORY paDbgDir;
     1018    int rcRet = rtldrPEReadPartByRva(pModPe, pvBits, pModPe->DebugDir.VirtualAddress, pModPe->DebugDir.Size,
     1019                                     (void const **)&paDbgDir);
     1020    if (RT_FAILURE(rcRet))
     1021        return rcRet;
    8021022
    8031023    /*
    8041024     * Enumerate the debug directory.
    8051025     */
    806     PCIMAGE_DEBUG_DIRECTORY paDbgDir = PE_RVA2TYPE(pvBits, pModPe->DebugDir.VirtualAddress, PCIMAGE_DEBUG_DIRECTORY);
    807     int                     rcRet    = VINF_SUCCESS;
    808     uint32_t const          cEntries = pModPe->DebugDir.Size / sizeof(paDbgDir[0]);
     1026    uint32_t const cEntries = pModPe->DebugDir.Size / sizeof(paDbgDir[0]);
    8091027    for (uint32_t i = 0; i < cEntries; i++)
    8101028    {
     
    8141032            continue;
    8151033
    816         char         szPath[RTPATH_MAX];
    817         RTLDRDBGINFO DbgInfo;
     1034        void const     *pvPart = NULL;
     1035        char            szPath[RTPATH_MAX];
     1036        RTLDRDBGINFO    DbgInfo;
    8181037        RT_ZERO(DbgInfo.u);
    8191038        DbgInfo.iDbgInfo    = i;
     
    8251044        DbgInfo.pszExtFile  = NULL;
    8261045
     1046        rc = VINF_SUCCESS;
    8271047        switch (paDbgDir[i].Type)
    8281048        {
     
    8341054                if (   paDbgDir[i].SizeOfData < sizeof(szPath)
    8351055                    && paDbgDir[i].SizeOfData > 16
    836                     && DbgInfo.LinkAddress != NIL_RTLDRADDR)
     1056                    && (   DbgInfo.LinkAddress != NIL_RTLDRADDR
     1057                        || DbgInfo.offFile > 0)
     1058                    )
    8371059                {
    838                     PCCVPDB20INFO pCv20 = PE_RVA2TYPE(pvBits, DbgInfo.LinkAddress, PCCVPDB20INFO);
    839                     if (   pCv20->u32Magic   == CVPDB20INFO_MAGIC
    840                         && pCv20->offDbgInfo == 0
    841                         && paDbgDir[i].SizeOfData > RT_UOFFSETOF(CVPDB20INFO, szPdbFilename) )
     1060                    rc = rtldrPEReadPart(pModPe, pvBits, DbgInfo.offFile, DbgInfo.LinkAddress, paDbgDir[i].SizeOfData, &pvPart);
     1061                    if (RT_SUCCESS(rc))
    8421062                    {
    843                         DbgInfo.enmType             = RTLDRDBGINFOTYPE_CODEVIEW_PDB20;
    844                         DbgInfo.u.Pdb20.cbImage     = pModPe->cbImage;
    845                         DbgInfo.u.Pdb20.uTimestamp  = pCv20->uTimestamp;
    846                         DbgInfo.u.Pdb20.uAge        = pCv20->uAge;
    847                         DbgInfo.pszExtFile          = (const char *)&pCv20->szPdbFilename[0];
     1063                        PCCVPDB20INFO pCv20 = (PCCVPDB20INFO)pvPart;
     1064                        if (   pCv20->u32Magic   == CVPDB20INFO_MAGIC
     1065                            && pCv20->offDbgInfo == 0
     1066                            && paDbgDir[i].SizeOfData > RT_UOFFSETOF(CVPDB20INFO, szPdbFilename) )
     1067                        {
     1068                            DbgInfo.enmType             = RTLDRDBGINFOTYPE_CODEVIEW_PDB20;
     1069                            DbgInfo.u.Pdb20.cbImage     = pModPe->cbImage;
     1070                            DbgInfo.u.Pdb20.uTimestamp  = pCv20->uTimestamp;
     1071                            DbgInfo.u.Pdb20.uAge        = pCv20->uAge;
     1072                            DbgInfo.pszExtFile          = (const char *)&pCv20->szPdbFilename[0];
     1073                        }
     1074                        else if (   pCv20->u32Magic == CVPDB70INFO_MAGIC
     1075                                 && paDbgDir[i].SizeOfData > RT_UOFFSETOF(CVPDB70INFO, szPdbFilename) )
     1076                        {
     1077                            PCCVPDB70INFO pCv70 = (PCCVPDB70INFO)pCv20;
     1078                            DbgInfo.enmType             = RTLDRDBGINFOTYPE_CODEVIEW_PDB70;
     1079                            DbgInfo.u.Pdb70.cbImage     = pModPe->cbImage;
     1080                            DbgInfo.u.Pdb70.Uuid        = pCv70->PdbUuid;
     1081                            DbgInfo.u.Pdb70.uAge        = pCv70->uAge;
     1082                            DbgInfo.pszExtFile          = (const char *)&pCv70->szPdbFilename[0];
     1083                        }
    8481084                    }
    849                     else if (   pCv20->u32Magic == CVPDB70INFO_MAGIC
    850                              && paDbgDir[i].SizeOfData > RT_UOFFSETOF(CVPDB70INFO, szPdbFilename) )
    851                     {
    852                         PCCVPDB70INFO pCv70 = (PCCVPDB70INFO)pCv20;
    853                         DbgInfo.enmType             = RTLDRDBGINFOTYPE_CODEVIEW_PDB70;
    854                         DbgInfo.u.Pdb70.cbImage     = pModPe->cbImage;
    855                         DbgInfo.u.Pdb70.Uuid        = pCv70->PdbUuid;
    856                         DbgInfo.u.Pdb70.uAge        = pCv70->uAge;
    857                         DbgInfo.pszExtFile          = (const char *)&pCv70->szPdbFilename[0];
    858                     }
     1085                    else
     1086                        rcRet = rc;
    8591087                }
    8601088                break;
    8611089
    8621090            case IMAGE_DEBUG_TYPE_MISC:
     1091                DbgInfo.enmType = RTLDRDBGINFOTYPE_UNKNOWN;
    8631092                if (   paDbgDir[i].SizeOfData < sizeof(szPath)
    864                     && paDbgDir[i].SizeOfData > RT_UOFFSETOF(IMAGE_DEBUG_MISC, Data)
    865                     && DbgInfo.LinkAddress != NIL_RTLDRADDR)
     1093                    && paDbgDir[i].SizeOfData > RT_UOFFSETOF(IMAGE_DEBUG_MISC, Data))
    8661094                {
    867                     PCIMAGE_DEBUG_MISC pMisc = PE_RVA2TYPE(pvBits, DbgInfo.LinkAddress, PCIMAGE_DEBUG_MISC);
    868                     if (   pMisc->DataType == IMAGE_DEBUG_MISC_EXENAME
    869                         && pMisc->Length   == paDbgDir[i].SizeOfData)
     1095                    DbgInfo.enmType             = RTLDRDBGINFOTYPE_CODEVIEW_DBG;
     1096                    DbgInfo.u.Dbg.cbImage       = pModPe->cbImage;
     1097                    if (DbgInfo.LinkAddress != NIL_RTLDRADDR)
     1098                        DbgInfo.u.Dbg.uTimestamp = paDbgDir[i].TimeDateStamp;
     1099                    else
     1100                        DbgInfo.u.Dbg.uTimestamp = pModPe->uTimestamp; /* NT4 SP1 ntfs.sys hack. Generic? */
     1101
     1102                    rc = rtldrPEReadPart(pModPe, pvBits, DbgInfo.offFile, DbgInfo.LinkAddress, paDbgDir[i].SizeOfData, &pvPart);
     1103                    if (RT_SUCCESS(rc))
    8701104                    {
    871                         if (!pMisc->Unicode)
    872                             DbgInfo.pszExtFile      = (const char *)&pMisc->Data[0];
    873                         else
     1105                        PCIMAGE_DEBUG_MISC pMisc = (PCIMAGE_DEBUG_MISC)pvPart;
     1106                        if (   pMisc->DataType == IMAGE_DEBUG_MISC_EXENAME
     1107                            && pMisc->Length   == paDbgDir[i].SizeOfData)
    8741108                        {
    875                             char *pszPath = szPath;
    876                             rc = RTUtf16ToUtf8Ex((PCRTUTF16)&pMisc->Data[0],
    877                                                  (pMisc->Length - RT_OFFSETOF(IMAGE_DEBUG_MISC, Data)) / sizeof(RTUTF16),
    878                                                  &pszPath, sizeof(szPath), NULL);
    879                             if (RT_FAILURE(rc))
     1109                            if (!pMisc->Unicode)
     1110                                DbgInfo.pszExtFile      = (const char *)&pMisc->Data[0];
     1111                            else
    8801112                            {
    881                                 rcRet = rc;
    882                                 continue;
     1113                                char *pszPath = szPath;
     1114                                rc = RTUtf16ToUtf8Ex((PCRTUTF16)&pMisc->Data[0],
     1115                                                     (pMisc->Length - RT_OFFSETOF(IMAGE_DEBUG_MISC, Data)) / sizeof(RTUTF16),
     1116                                                     &pszPath, sizeof(szPath), NULL);
     1117                                if (RT_SUCCESS(rc))
     1118                                    DbgInfo.pszExtFile = szPath;
     1119                                else
     1120                                    rcRet = rc; /* continue without a filename. */
    8831121                            }
    884                             DbgInfo.pszExtFile      = szPath;
    8851122                        }
    886                         DbgInfo.enmType             = RTLDRDBGINFOTYPE_CODEVIEW_DBG;
    887                         DbgInfo.u.Dbg.cbImage       = pModPe->cbImage;
    888                         DbgInfo.u.Dbg.uTimestamp    = paDbgDir[i].TimeDateStamp;
    8891123                    }
     1124                    else
     1125                        rcRet = rc; /* continue without a filename. */
    8901126                }
    8911127                break;
     
    9101146            {
    9111147                rcRet = rc;
    912                 continue;
     1148                DbgInfo.pszExtFile = NULL;
    9131149            }
    9141150        }
     
    9171153
    9181154        rc = pfnCallback(pMod, &DbgInfo, pvUser);
     1155        rtldrPEFreePart(pModPe, pvBits, pvPart);
    9191156        if (rc != VINF_SUCCESS)
    920             return rc;
    921     }
     1157        {
     1158            rcRet = rc;
     1159            break;
     1160        }
     1161    }
     1162
     1163    rtldrPEFreePart(pModPe, pvBits, paDbgDir);
    9221164    return rcRet;
    9231165}
     
    13301572 * @param   pFileHdr    Pointer to the file header (valid).
    13311573 * @param   cbRawImage  The raw image size.
     1574 * @param   fFlags      Loader flags.
    13321575 */
    13331576static int rtldrPEValidateOptionalHeader(const IMAGE_OPTIONAL_HEADER64 *pOptHdr, const char *pszLogName, RTFOFF offNtHdrs,
    1334                                          const IMAGE_FILE_HEADER *pFileHdr, RTFOFF cbRawImage)
     1577                                         const IMAGE_FILE_HEADER *pFileHdr, RTFOFF cbRawImage, uint32_t fFlags)
    13351578{
    13361579    const uint16_t CorrectMagic = pFileHdr->SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32)
     
    14871730            return VERR_BAD_EXE_FORMAT;
    14881731        }
    1489         if (pDir->Size > cb - pDir->VirtualAddress)
     1732        if (    pDir->Size > cb - pDir->VirtualAddress
     1733            && !(fFlags & RTLDR_O_FOR_DEBUG) /* NT4 SP1 ntfs.sys base relocs. */ )
    14901734        {
    14911735            Log(("rtldrPEOpen: %s: dir no. %d Size=%#x is invalid (rva=%#x, limit=%#x)!!!\n",
     
    18582102    if (FileHdr.SizeOfOptionalHeader != sizeof(OptHdr))
    18592103        rtldrPEConvert32BitOptionalHeaderTo64Bit(&OptHdr);
    1860     rc = rtldrPEValidateOptionalHeader(&OptHdr, pszLogName, offNtHdrs, &FileHdr, pReader->pfnSize(pReader));
     2104    rc = rtldrPEValidateOptionalHeader(&OptHdr, pszLogName, offNtHdrs, &FileHdr, pReader->pfnSize(pReader), fFlags);
    18612105    if (RT_FAILURE(rc))
    18622106        return rc;
     
    19012145                pModPe->cbImage       = OptHdr.SizeOfImage;
    19022146                pModPe->cbHeaders     = OptHdr.SizeOfHeaders;
     2147                pModPe->uTimestamp    = FileHdr.TimeDateStamp;
    19032148                pModPe->ImportDir     = OptHdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
    19042149                pModPe->RelocDir      = OptHdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
  • trunk/src/VBox/Runtime/common/string/strcache.cpp

    r44529 r46101  
    167167
    168168
     169RTDECL(const char *) RTStrCacheEnterLowerN(RTSTRCACHE hStrCache, const char *pchString, size_t cchString)
     170{
     171    AssertPtr(pchString);
     172    AssertReturn(cchString < _1G, NULL);
     173    Assert(!RTStrEnd(pchString, cchString));
     174
     175    char *pszRet = (char *)RTMemPoolDupEx((RTMEMPOOL)hStrCache, pchString, cchString, 1);
     176    if (!pszRet)
     177        RTStrToLower(pszRet);
     178    return pszRet;
     179}
     180RT_EXPORT_SYMBOL(RTStrCacheEnterLowerN);
     181
     182
     183RTDECL(const char *) RTStrCacheEnterLower(RTSTRCACHE hStrCache, const char *psz)
     184{
     185    return RTStrCacheEnterLowerN(hStrCache, psz, strlen(psz));
     186}
     187RT_EXPORT_SYMBOL(RTStrCacheEnterLower);
     188
     189
    169190RTDECL(uint32_t) RTStrCacheRetain(const char *psz)
    170191{
  • trunk/src/VBox/Runtime/generic/strcache-stubs-generic.cpp

    r44529 r46101  
    7878
    7979
     80RTDECL(const char *) RTStrCacheEnterLowerN(RTSTRCACHE hStrCache, const char *pchString, size_t cchString)
     81{
     82    AssertPtr(pchString);
     83    AssertReturn(cchString < _1G, NULL);
     84    Assert(!RTStrEnd(pchString, cchString));
     85
     86    char *pszRet = (char *)RTMemPoolDupEx((RTMEMPOOL)hStrCache, pchString, cchString, 1);
     87    if (!pszRet)
     88        RTStrToLower(pszRet);
     89    return pszRet;
     90}
     91RT_EXPORT_SYMBOL(RTStrCacheEnterLowerN);
     92
     93
     94RTDECL(const char *) RTStrCacheEnterLower(RTSTRCACHE hStrCache, const char *psz)
     95{
     96    return RTStrCacheEnterLowerN(hStrCache, psz, strlen(psz));
     97}
     98RT_EXPORT_SYMBOL(RTStrCacheEnterLower);
     99
     100
    80101RTDECL(uint32_t) RTStrCacheRetain(const char *psz)
    81102{
  • trunk/src/VBox/Runtime/include/internal/dbgmod.h

    r46083 r46101  
    529529    /** The module name (short). */
    530530    char const         *pszName;
     531    /** The image file specified by the user.  Can be NULL. */
     532    char const         *pszImgFileSpecified;
    531533    /** The module filename. Can be NULL. */
    532534    char const         *pszImgFile;
  • trunk/src/VBox/Runtime/include/internal/ldrPE.h

    r46048 r46101  
    55
    66/*
    7  * Copyright (C) 2006-2010 Oracle Corporation
     7 * Copyright (C) 2006-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2929
    3030#include <iprt/types.h>
    31 
    32 #pragma pack(4)
     31#include <iprt/assert.h>
     32
     33#pragma pack(4) /** @todo Necessary? */
    3334
    3435
     
    222223    uint16_t  Characteristics;
    223224} IMAGE_FILE_HEADER;
     225AssertCompileSize(IMAGE_FILE_HEADER, 2+2+4+4+4+2+2);
    224226typedef IMAGE_FILE_HEADER *PIMAGE_FILE_HEADER;
    225227typedef IMAGE_FILE_HEADER const *PCIMAGE_FILE_HEADER;
     
    315317    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
    316318} IMAGE_NT_HEADERS32;
     319AssertCompileMemberOffset(IMAGE_NT_HEADERS32, FileHeader, 4);
     320AssertCompileMemberOffset(IMAGE_NT_HEADERS32, OptionalHeader, 24);
    317321typedef IMAGE_NT_HEADERS32 *PIMAGE_NT_HEADERS32;
    318322typedef IMAGE_NT_HEADERS32 const *PCIMAGE_NT_HEADERS32;
     
    324328    IMAGE_OPTIONAL_HEADER64 OptionalHeader;
    325329} IMAGE_NT_HEADERS64;
     330AssertCompileMemberOffset(IMAGE_NT_HEADERS64, FileHeader, 4);
     331AssertCompileMemberOffset(IMAGE_NT_HEADERS64, OptionalHeader, 24);
    326332typedef IMAGE_NT_HEADERS64 *PIMAGE_NT_HEADERS64;
    327333typedef IMAGE_NT_HEADERS64 const *PCIMAGE_NT_HEADERS64;
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