VirtualBox

Changeset 45994 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
May 12, 2013 7:16:16 PM (12 years ago)
Author:
vboxsync
Message:

RTDbgModCreateFromPeImage: Mostly implemented.

Location:
trunk/src/VBox/Runtime/common
Files:
2 added
6 edited

Legend:

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

    r45988 r45994  
    124124
    125125
     126
    126127/*******************************************************************************
    127128*   Defined Constants And Macros                                               *
     
    158159
    159160
     161RTDECL(int) RTDbgCfgOpenPeImage(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t cbImage, uint32_t uTimestamp,
     162                                PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
     163{
     164    int rc = pfnCallback(hDbgCfg, pszFilename, pvUser1, pvUser2);
     165    if (rc == VINF_CALLBACK_RETURN || rc == VERR_CALLBACK_RETURN)
     166        return rc;
     167
     168    return rc;
     169}
     170
     171RTDECL(int) RTDbgCfgOpenPdb70(RTDBGCFG hDbgCfg, const char *pszFilename, PCRTUUID pUuid, uint32_t uAge,
     172                              PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
     173{
     174    int rc = pfnCallback(hDbgCfg, pszFilename, pvUser1, pvUser2);
     175    if (rc == VINF_CALLBACK_RETURN || rc == VERR_CALLBACK_RETURN)
     176        return rc;
     177
     178    return rc;
     179}
     180
     181RTDECL(int) RTDbgCfgOpenPdb20(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t cbImage, uint32_t uTimestamp, uint32_t uAge,
     182                              PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
     183{
     184    return VERR_NOT_IMPLEMENTED;
     185}
     186
     187
     188RTDECL(int) RTDbgCfgOpenDbg(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t cbImage, uint32_t uTimestamp,
     189                            PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
     190{
     191    return VERR_NOT_IMPLEMENTED;
     192}
     193
     194
     195RTDECL(int) RTDbgCfgOpenDwo(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t uCrc32,
     196                            PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
     197{
     198    return VERR_NOT_IMPLEMENTED;
     199}
    160200
    161201
     
    695735                }
    696736                else if (rc != VERR_ENV_VAR_NOT_FOUND)
    697                         break;
     737                    break;
     738                else
     739                    rc = VINF_SUCCESS;
    698740            }
    699741            RTMemTmpFree(pszEnvVar);
  • trunk/src/VBox/Runtime/common/dbg/dbgmod.cpp

    r45984 r45994  
    2929*   Header Files                                                               *
    3030*******************************************************************************/
     31#define LOG_GROUP RTLOGGROUP_DBG
    3132#include <iprt/dbg.h>
    3233#include "internal/iprt.h"
     
    3738#include <iprt/err.h>
    3839#include <iprt/initterm.h>
     40#include <iprt/log.h>
    3941#include <iprt/mem.h>
    4042#include <iprt/once.h>
     
    484486                RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName);
    485487            }
     488            else
     489                rc = VERR_NO_STR_MEMORY;
    486490            RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile);
    487491        }
     492        else
     493            rc = VERR_NO_STR_MEMORY;
    488494        RTCritSectDelete(&pDbgMod->CritSect);
    489495    }
     
    563569                RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName);
    564570            }
     571            else
     572                rc = VERR_NO_STR_MEMORY;
    565573            RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszDbgFile);
    566574        }
     575        else
     576            rc = VERR_NO_STR_MEMORY;
    567577        RTCritSectDelete(&pDbgMod->CritSect);
    568578    }
     
    572582}
    573583RT_EXPORT_SYMBOL(RTDbgModCreateFromMap);
     584
     585
     586
     587
     588/*
     589 *
     590 *  P E   I M A G E
     591 *  P E   I M A G E
     592 *  P E   I M A G E
     593 *
     594 */
     595
     596
     597/**
     598 * Opens debug information for an image.
     599 *
     600 * @returns IPRT status code
     601 * @param   pDbgMod             The debug module structure.
     602 *
     603 * @note    This will generally not look for debug info stored in external
     604 *          files.  rtDbgModFromPeImageExtDbgInfoCallback can help with that.
     605 */
     606static int rtDbgModOpenDebugInfoInsideImage(PRTDBGMODINT pDbgMod)
     607{
     608    AssertReturn(!pDbgMod->pDbgVt, VERR_DBG_MOD_IPE);
     609    AssertReturn(pDbgMod->pImgVt, VERR_DBG_MOD_IPE);
     610
     611    int rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT);
     612    if (RT_SUCCESS(rc))
     613    {
     614        for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext)
     615        {
     616            pDbgMod->pDbgVt    = pDbg->pVt;
     617            pDbgMod->pvDbgPriv = NULL;
     618            rc = pDbg->pVt->pfnTryOpen(pDbgMod);
     619            if (RT_SUCCESS(rc))
     620            {
     621                /*
     622                 * That's it!
     623                 */
     624                ASMAtomicIncU32(&pDbg->cUsers);
     625                RTSemRWReleaseRead(g_hDbgModRWSem);
     626                return VINF_SUCCESS;
     627            }
     628            pDbgMod->pDbgVt    = NULL;
     629            Assert(pDbgMod->pvDbgPriv == NULL);
     630        }
     631        RTSemRWReleaseRead(g_hDbgModRWSem);
     632    }
     633
     634    return VERR_DBG_NO_MATCHING_INTERPRETER;
     635}
     636
     637
     638/** @callback_method_impl{FNRTDBGCFGOPEN} */
     639static DECLCALLBACK(int) rtDbgModExtDbgInfoOpenCallback(RTDBGCFG hDbgCfg, const char *pszFilename, void *pvUser1, void *pvUser2)
     640{
     641    PRTDBGMODINT        pDbgMod   = (PRTDBGMODINT)pvUser1;
     642    PCRTLDRDBGINFO      pDbgInfo  = (PCRTLDRDBGINFO)pvUser2;
     643    NOREF(pDbgInfo); /** @todo consider a more direct search for a interpreter. */
     644
     645    Assert(!pDbgMod->pDbgVt);
     646    Assert(!pDbgMod->pvDbgPriv);
     647    Assert(!pDbgMod->pszDbgFile);
     648
     649    /*
     650     * Set the debug file name and try possible interpreters.
     651     */
     652    pDbgMod->pszDbgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename);
     653
     654    int rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT);
     655    if (RT_SUCCESS(rc))
     656    {
     657        for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext)
     658        {
     659            pDbgMod->pDbgVt    = pDbg->pVt;
     660            pDbgMod->pvDbgPriv = NULL;
     661            rc = pDbg->pVt->pfnTryOpen(pDbgMod);
     662            if (RT_SUCCESS(rc))
     663            {
     664                /*
     665                 * Got it!
     666                 */
     667                ASMAtomicIncU32(&pDbg->cUsers);
     668                RTSemRWReleaseRead(g_hDbgModRWSem);
     669                return VINF_CALLBACK_RETURN;
     670            }
     671            pDbgMod->pDbgVt    = NULL;
     672            Assert(pDbgMod->pvDbgPriv == NULL);
     673        }
     674    }
     675
     676    /* No joy. */
     677    RTSemRWReleaseRead(g_hDbgModRWSem);
     678    RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszDbgFile);
     679    pDbgMod->pszDbgFile = NULL;
     680    return rc;
     681}
     682
     683
     684/**
     685 * Argument package used by rtDbgModOpenDebugInfoExternalToImage.
     686 */
     687typedef struct RTDBGMODOPENDIETI
     688{
     689    PRTDBGMODINT    pDbgMod;
     690    RTDBGCFG        hDbgCfg;
     691} RTDBGMODOPENDIETI;
     692
     693
     694/** @callback_method_impl{FNRTLDRENUMDBG} */
     695static DECLCALLBACK(int)
     696rtDbgModOpenDebugInfoExternalToImageCallback(RTLDRMOD hLdrMod, PCRTLDRDBGINFO pDbgInfo, void *pvUser)
     697{
     698    if (!pDbgInfo->pszExtFile)
     699        return VINF_SUCCESS;
     700
     701    int rc;
     702    RTDBGMODOPENDIETI *pArgs = (RTDBGMODOPENDIETI *)pvUser;
     703    switch (pDbgInfo->enmType)
     704    {
     705        case RTLDRDBGINFOTYPE_CODEVIEW_PDB70:
     706            rc = RTDbgCfgOpenPdb70(pArgs->hDbgCfg, pDbgInfo->pszExtFile,
     707                                   &pDbgInfo->u.Pdb70.Uuid,
     708                                   pDbgInfo->u.Pdb70.uAge,
     709                                   rtDbgModExtDbgInfoOpenCallback, pArgs->pDbgMod, (void *)pDbgInfo);
     710            break;
     711
     712        case RTLDRDBGINFOTYPE_CODEVIEW_PDB20:
     713            rc = RTDbgCfgOpenPdb20(pArgs->hDbgCfg, pDbgInfo->pszExtFile,
     714                                   pDbgInfo->u.Pdb20.cbImage,
     715                                   pDbgInfo->u.Pdb20.uTimestamp,
     716                                   pDbgInfo->u.Pdb20.uAge,
     717                                   rtDbgModExtDbgInfoOpenCallback, pArgs->pDbgMod, (void *)pDbgInfo);
     718            break;
     719
     720        case RTLDRDBGINFOTYPE_CODEVIEW_DBG:
     721            rc = RTDbgCfgOpenDbg(pArgs->hDbgCfg, pDbgInfo->pszExtFile,
     722                                 pDbgInfo->u.Dbg.cbImage,
     723                                 pDbgInfo->u.Dbg.uTimestamp,
     724                                 rtDbgModExtDbgInfoOpenCallback, pArgs->pDbgMod, (void *)pDbgInfo);
     725            break;
     726
     727        case RTLDRDBGINFOTYPE_DWARF_DWO:
     728            rc = RTDbgCfgOpenDwo(pArgs->hDbgCfg, pDbgInfo->pszExtFile,
     729                                 pDbgInfo->u.Dwo.uCrc32,
     730                                 rtDbgModExtDbgInfoOpenCallback, pArgs->pDbgMod, (void *)pDbgInfo);
     731            break;
     732
     733        default:
     734            Log(("rtDbgModOpenDebugInfoExternalToImageCallback: Don't know how to handle enmType=%d and pszFileExt=%s\n",
     735                 pDbgInfo->enmType, pDbgInfo->pszExtFile));
     736            return VERR_DBG_TODO;
     737    }
     738    if (RT_SUCCESS(rc))
     739    {
     740        LogFlow(("RTDbgMod: Successfully opened external debug info '%s' for '%s'\n",
     741                 pArgs->pDbgMod->pszDbgFile, pArgs->pDbgMod->pszImgFile));
     742        return VINF_CALLBACK_RETURN;
     743    }
     744    Log(("rtDbgModOpenDebugInfoExternalToImageCallback: '%s' (enmType=%d) for '%s'  -> %Rrc\n",
     745         pDbgInfo->pszExtFile, pDbgInfo->enmType, pArgs->pDbgMod->pszImgFile, rc));
     746    return rc;
     747}
     748
     749
     750/**
     751 * Opens debug info listed in the image that is stored in a separate file.
     752 *
     753 * @returns IPRT status code
     754 * @param   pDbgMod             The debug module.
     755 * @param   hDbgCfg             The debug config.  Can be NIL.
     756 */
     757static int rtDbgModOpenDebugInfoExternalToImage(PRTDBGMODINT pDbgMod, RTDBGCFG hDbgCfg)
     758{
     759    RTDBGMODOPENDIETI Args;
     760    Args.pDbgMod = pDbgMod;
     761    Args.hDbgCfg = hDbgCfg;
     762    int rc = pDbgMod->pImgVt->pfnEnumDbgInfo(pDbgMod, rtDbgModOpenDebugInfoExternalToImageCallback, &Args);
     763    if (RT_SUCCESS(rc) && pDbgMod->pDbgVt)
     764        return VINF_SUCCESS;
     765    return VERR_NOT_FOUND;
     766}
     767
     768
     769
     770/** @callback_method_impl{FNRTDBGCFGOPEN} */
     771static DECLCALLBACK(int) rtDbgModFromPeImageOpenCallback(RTDBGCFG hDbgCfg, const char *pszFilename, void *pvUser1, void *pvUser2)
     772{
     773    PRTDBGMODINT        pDbgMod   = (PRTDBGMODINT)pvUser1;
     774    PRTDBGMODDEFERRED   pDeferred = (PRTDBGMODDEFERRED)pvUser2;
     775    LogFlow(("rtDbgModFromPeImageOpenCallback: %s\n", pszFilename));
     776
     777    Assert(pDbgMod->pImgVt == NULL);
     778    Assert(pDbgMod->pvImgPriv == NULL);
     779    Assert(pDbgMod->pDbgVt == NULL);
     780    Assert(pDbgMod->pvDbgPriv == NULL);
     781
     782    /*
     783     * Find an image reader which groks the file.
     784     */
     785    int rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT);
     786    if (RT_SUCCESS(rc))
     787    {
     788        rc = VERR_DBG_NO_MATCHING_INTERPRETER;
     789        PRTDBGMODREGIMG pImg;
     790        for (pImg = g_pImgHead; pImg; pImg = pImg->pNext)
     791        {
     792            pDbgMod->pImgVt    = pImg->pVt;
     793            pDbgMod->pvImgPriv = NULL;
     794            rc = pImg->pVt->pfnTryOpen(pDbgMod);
     795            if (RT_SUCCESS(rc))
     796                break;
     797            pDbgMod->pImgVt    = NULL;
     798            Assert(pDbgMod->pvImgPriv == NULL);
     799        }
     800    }
     801    RTSemRWReleaseRead(g_hDbgModRWSem);
     802    if (RT_FAILURE(rc))
     803    {
     804        LogFlow(("rtDbgModFromPeImageOpenCallback: Failed %Rrc - %s\n", rc, pszFilename));
     805        return rc;
     806    }
     807
     808    /*
     809     * Check the deferred info.
     810     */
     811    RTUINTPTR cbImage = pDbgMod->pImgVt->pfnImageSize(pDbgMod);
     812    if (   pDeferred->cbImage == 0
     813        || pDeferred->cbImage == cbImage)
     814    {
     815        uint32_t uTimestamp = pDeferred->u.PeImage.uTimestamp; /** @todo add method for getting the timestamp. */
     816        if (   pDeferred->u.PeImage.uTimestamp == 0
     817            || pDeferred->u.PeImage.uTimestamp == uTimestamp)
     818        {
     819            Log(("RTDbgMod: Found matching PE image '%s'\n", pszFilename));
     820
     821            /*
     822             * We found the executable image we need, now go find any debug
     823             * info associated with it.  For PE images, this is generally
     824             * found in an external file, so we do a sweep for that first.
     825             */
     826            rc = rtDbgModOpenDebugInfoExternalToImage(pDbgMod, pDeferred->hDbgCfg);
     827            if (RT_SUCCESS(rc))
     828                return VINF_CALLBACK_RETURN;
     829
     830            /*
     831             * Try open debug info inside the module, falling back on exports.
     832             */
     833            rc = rtDbgModOpenDebugInfoInsideImage(pDbgMod);
     834            if (RT_SUCCESS(rc))
     835                return VINF_CALLBACK_RETURN;
     836            /** @todo search for external files that could contain more useful info, like
     837             *        .map files?? No? */
     838            rc = rtDbgModCreateForExports(pDbgMod);
     839            if (RT_SUCCESS(rc))
     840                return VINF_CALLBACK_RETURN;
     841
     842            /* Something bad happened, just give up. */
     843            Log(("rtDbgModFromPeImageOpenCallback: rtDbgModCreateForExports failed: %Rrc\n", rc));
     844        }
     845        else
     846        {
     847            LogFlow(("rtDbgModFromPeImageOpenCallback: uTimestamp mismatch (found %#x, expected %#x) - %s\n",
     848                     uTimestamp, pDeferred->u.PeImage.uTimestamp, pszFilename));
     849            rc = VERR_DBG_FILE_MISMATCH;
     850        }
     851    }
     852    else
     853    {
     854        LogFlow(("rtDbgModFromPeImageOpenCallback: cbImage mismatch (found %#x, expected %#x) - %s\n",
     855                 cbImage, pDeferred->cbImage, pszFilename));
     856        rc = VERR_DBG_FILE_MISMATCH;
     857    }
     858
     859    pDbgMod->pImgVt->pfnClose(pDbgMod);
     860    pDbgMod->pImgVt    = NULL;
     861    pDbgMod->pvImgPriv = NULL;
     862
     863    return rc;
     864}
     865
     866
     867/** @callback_method_impl{FNRTDBGMODDEFERRED}  */
     868static DECLCALLBACK(int) rtDbgModFromPeImageDeferredCallback(PRTDBGMODINT pDbgMod, PRTDBGMODDEFERRED pDeferred)
     869{
     870    int rc;
     871
     872    Assert(pDbgMod->pszImgFile);
     873    if (pDeferred->hDbgCfg != NIL_RTDBGCFG)
     874        rc = RTDbgCfgOpenPeImage(pDeferred->hDbgCfg, pDbgMod->pszImgFile,
     875                                 pDeferred->cbImage, pDeferred->u.PeImage.uTimestamp,
     876                                 rtDbgModFromPeImageOpenCallback, pDbgMod, pDeferred);
     877    else
     878        rc = rtDbgModFromPeImageOpenCallback(NIL_RTDBGCFG, pDbgMod->pszImgFile, pDbgMod, pDeferred);
     879
     880    return rc;
     881}
     882
     883
     884RTDECL(int) RTDbgModCreateFromPeImage(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, uint32_t cbImage,
     885                                      uint32_t uTimestamp, RTDBGCFG hDbgCfg)
     886{
     887    /*
     888     * Input validation and lazy initialization.
     889     */
     890    AssertPtrReturn(phDbgMod, VERR_INVALID_POINTER);
     891    *phDbgMod = NIL_RTDBGMOD;
     892    AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
     893    AssertReturn(*pszFilename, VERR_INVALID_PARAMETER);
     894    if (!pszName)
     895        pszName = RTPathFilename(pszFilename);
     896    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
     897
     898    int rc = rtDbgModLazyInit();
     899    if (RT_FAILURE(rc))
     900        return rc;
     901
     902    uint64_t fDbgCfg = 0;
     903    if (hDbgCfg)
     904    {
     905        rc = RTDbgCfgQueryUInt(hDbgCfg, RTDBGCFGPROP_FLAGS, &fDbgCfg);
     906        AssertRCReturn(rc, rc);
     907    }
     908
     909    /*
     910     * Allocate a new module instance.
     911     */
     912    PRTDBGMODINT pDbgMod = (PRTDBGMODINT)RTMemAllocZ(sizeof(*pDbgMod));
     913    if (!pDbgMod)
     914        return VERR_NO_MEMORY;
     915    pDbgMod->u32Magic = RTDBGMOD_MAGIC;
     916    pDbgMod->cRefs = 1;
     917    rc = RTCritSectInit(&pDbgMod->CritSect);
     918    if (RT_SUCCESS(rc))
     919    {
     920        pDbgMod->pszName = RTStrCacheEnter(g_hDbgModStrCache, pszName);
     921        if (pDbgMod->pszName)
     922        {
     923            pDbgMod->pszImgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename);
     924            if (pDbgMod->pszImgFile)
     925            {
     926                /*
     927                 * Do it now or procrastinate?
     928                 */
     929                if (!(fDbgCfg & RTDBGCFG_FLAGS_DEFERRED) || !cbImage)
     930                {
     931                    RTDBGMODDEFERRED Deferred;
     932                    Deferred.cbImage = cbImage;
     933                    Deferred.hDbgCfg = hDbgCfg;
     934                    Deferred.u.PeImage.uTimestamp = uTimestamp;
     935                    rc = rtDbgModFromPeImageDeferredCallback(pDbgMod, &Deferred);
     936                }
     937                else
     938                {
     939                    PRTDBGMODDEFERRED pDeferred;
     940                    rc = rtDbgModDeferredCreate(pDbgMod, rtDbgModFromPeImageDeferredCallback, cbImage, hDbgCfg, &pDeferred);
     941                    if (RT_SUCCESS(rc))
     942                        pDeferred->u.PeImage.uTimestamp = uTimestamp;
     943                }
     944                if (RT_SUCCESS(rc))
     945                {
     946                    *phDbgMod = pDbgMod;
     947                    return VINF_SUCCESS;
     948                }
     949
     950                /* bail out */
     951                RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName);
     952            }
     953            else
     954                rc = VERR_NO_STR_MEMORY;
     955            RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile);
     956        }
     957        else
     958            rc = VERR_NO_STR_MEMORY;
     959        RTCritSectDelete(&pDbgMod->CritSect);
     960    }
     961
     962    RTMemFree(pDbgMod);
     963    return rc;
     964}
     965RT_EXPORT_SYMBOL(RTDbgModCreateFromImage);
    574966
    575967
  • trunk/src/VBox/Runtime/common/dbg/dbgmoddwarf.cpp

    r45975 r45994  
    43084308
    43094309/** @callback_method_impl{FNRTLDRENUMDBG} */
    4310 static DECLCALLBACK(int) rtDbgModDwarfEnumCallback(RTLDRMOD hLdrMod, uint32_t iDbgInfo, RTLDRDBGINFOTYPE enmType,
    4311                                                    uint16_t iMajorVer, uint16_t iMinorVer, const char *pszPartNm,
    4312                                                    RTFOFF offFile, RTLDRADDR LinkAddress, RTLDRADDR cb,
    4313                                                    const char *pszExtFile, void *pvUser)
    4314 {
    4315     NOREF(hLdrMod); NOREF(iDbgInfo); NOREF(iMajorVer); NOREF(iMinorVer); NOREF(LinkAddress);
    4316 
     4310static DECLCALLBACK(int) rtDbgModDwarfEnumCallback(RTLDRMOD hLdrMod, PCRTLDRDBGINFO pDbgInfo, void *pvUser)
     4311{
    43174312    /*
    43184313     * Skip stuff we can't handle.
    43194314     */
    4320     if (   enmType != RTLDRDBGINFOTYPE_DWARF
    4321         || !pszPartNm
    4322         || pszExtFile)
     4315    if (pDbgInfo->enmType != RTLDRDBGINFOTYPE_DWARF)
    43234316        return VINF_SUCCESS;
     4317    const char *pszSection = pDbgInfo->u.Dwarf.pszSection;
     4318    if (!pszSection || !*pszSection)
     4319        return VINF_SUCCESS;
     4320    Assert(!pDbgInfo->pszExtFile);
    43244321
    43254322    /*
     
    43274324     * or underscores.
    43284325     */
    4329     if (!strncmp(pszPartNm, RT_STR_TUPLE(".debug_")))       /* ELF */
    4330         pszPartNm += sizeof(".debug_") - 1;
    4331     else if (!strncmp(pszPartNm, RT_STR_TUPLE("__debug_"))) /* Mach-O */
    4332         pszPartNm += sizeof("__debug_") - 1;
    4333     else if (!strcmp(pszPartNm, ".WATCOM_references"))
     4326    if (!strncmp(pszSection, RT_STR_TUPLE(".debug_")))       /* ELF */
     4327        pszSection += sizeof(".debug_") - 1;
     4328    else if (!strncmp(pszSection, RT_STR_TUPLE("__debug_"))) /* Mach-O */
     4329        pszSection += sizeof("__debug_") - 1;
     4330    else if (!strcmp(pszSection, ".WATCOM_references"))
    43344331        return VINF_SUCCESS; /* Ignore special watcom section for now.*/
    43354332    else
    4336         AssertMsgFailedReturn(("%s\n", pszPartNm), VINF_SUCCESS /*ignore*/);
     4333        AssertMsgFailedReturn(("%s\n", pszSection), VINF_SUCCESS /*ignore*/);
    43374334
    43384335    /*
     
    43414338    krtDbgModDwarfSect enmSect;
    43424339    if (0) { /* dummy */ }
    4343 #define ELSE_IF_STRCMP_SET(a_Name) else if (!strcmp(pszPartNm, #a_Name))  enmSect = krtDbgModDwarfSect_ ## a_Name
     4340#define ELSE_IF_STRCMP_SET(a_Name) else if (!strcmp(pszSection, #a_Name))  enmSect = krtDbgModDwarfSect_ ## a_Name
    43444341    ELSE_IF_STRCMP_SET(abbrev);
    43454342    ELSE_IF_STRCMP_SET(aranges);
     
    43584355    else
    43594356    {
    4360         AssertMsgFailed(("%s\n", pszPartNm));
     4357        AssertMsgFailed(("%s\n", pszSection));
    43614358        return VINF_SUCCESS;
    43624359    }
     
    43664363     */
    43674364    PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pvUser;
    4368     AssertMsgReturn(!pThis->aSections[enmSect].fPresent, ("duplicate %s\n", pszPartNm), VINF_SUCCESS /*ignore*/);
     4365    AssertMsgReturn(!pThis->aSections[enmSect].fPresent, ("duplicate %s\n", pszSection), VINF_SUCCESS /*ignore*/);
    43694366
    43704367    pThis->aSections[enmSect].fPresent  = true;
    4371     pThis->aSections[enmSect].offFile   = offFile;
     4368    pThis->aSections[enmSect].offFile   = pDbgInfo->offFile;
    43724369    pThis->aSections[enmSect].pv        = NULL;
    4373     pThis->aSections[enmSect].cb        = (size_t)cb;
    4374     if (pThis->aSections[enmSect].cb != cb)
     4370    pThis->aSections[enmSect].cb        = (size_t)pDbgInfo->cb;
     4371    if (pThis->aSections[enmSect].cb != pDbgInfo->cb)
    43754372        pThis->aSections[enmSect].cb    = ~(size_t)0;
    43764373
  • trunk/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h

    r45982 r45994  
    760760            continue;
    761761
     762        RTLDRDBGINFO DbgInfo;
    762763        const char *pszSectName = ELF_SH_STR(pModElf, paShdrs[iShdr].sh_name);
    763764        if (   !strncmp(pszSectName, RT_STR_TUPLE(".debug_"))
    764765            || !strcmp(pszSectName, ".WATCOM_references") )
    765766        {
    766             rc = pfnCallback(pMod, iShdr - 1, RTLDRDBGINFOTYPE_DWARF, 0, 0, pszSectName,
    767                              paShdrs[iShdr].sh_offset,
    768                              paShdrs[iShdr].sh_addr,
    769                              paShdrs[iShdr].sh_size,
    770                              NULL, pvUser);
    771             if (rc != VINF_SUCCESS)
    772                 return rc;
     767            RT_ZERO(DbgInfo.u);
     768            DbgInfo.enmType         = RTLDRDBGINFOTYPE_DWARF;
     769            DbgInfo.offFile         = paShdrs[iShdr].sh_offset;
     770            DbgInfo.cb              = paShdrs[iShdr].sh_size;
     771            DbgInfo.u.Dwarf.pszSection = pszSectName;
    773772        }
    774773        else if (!strcmp(pszSectName, ".gnu_debuglink"))
     
    776775            if ((paShdrs[iShdr].sh_size & 3) || paShdrs[iShdr].sh_size < 8)
    777776                return VERR_BAD_EXE_FORMAT;
    778             const char     *pszExtFile = (const char *)((uintptr_t)pModElf->pvBits + paShdrs[iShdr].sh_offset);
    779             if (!RTStrEnd(pszExtFile, paShdrs[iShdr].sh_size))
     777
     778            RT_ZERO(DbgInfo.u);
     779            DbgInfo.enmType         = RTLDRDBGINFOTYPE_DWARF_DWO;
     780            DbgInfo.pszExtFile      = (const char *)((uintptr_t)pModElf->pvBits + paShdrs[iShdr].sh_offset);
     781            if (!RTStrEnd(DbgInfo.pszExtFile, paShdrs[iShdr].sh_size))
    780782                return VERR_BAD_EXE_FORMAT;
    781 
    782             uint32_t uCrc32  = *(uint32_t *)((uintptr_t)pszExtFile + paShdrs[iShdr].sh_size - sizeof(uint32_t));
    783             char    szCrc32[16];
    784             RTStrPrintf(szCrc32, sizeof(szCrc32), "%#010x", uCrc32);
    785 
    786             rc = pfnCallback(pMod, iShdr - 1, RTLDRDBGINFOTYPE_DWARF, 0, 0, szCrc32,
    787                              paShdrs[iShdr].sh_offset,
    788                              paShdrs[iShdr].sh_addr,
    789                              paShdrs[iShdr].sh_size,
    790                              pszExtFile, pvUser);
    791             if (rc != VINF_SUCCESS)
    792                 return rc;
    793         }
     783            DbgInfo.u.Dwo.uCrc32    = *(uint32_t *)((uintptr_t)DbgInfo.pszExtFile + paShdrs[iShdr].sh_size - sizeof(uint32_t));
     784            DbgInfo.offFile         = -1;
     785            DbgInfo.cb              = 0;
     786        }
     787        else
     788            continue;
     789
     790        DbgInfo.LinkAddress         = NIL_RTLDRADDR;
     791        DbgInfo.iDbgInfo            = iShdr - 1;
     792
     793        rc = pfnCallback(pMod, &DbgInfo, pvUser);
     794        if (rc != VINF_SUCCESS)
     795            return rc;
     796
    794797    }
    795798
  • trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp

    r44528 r45994  
    3636#include <iprt/assert.h>
    3737#include <iprt/log.h>
     38#include <iprt/path.h>
    3839#include <iprt/string.h>
    3940#include <iprt/err.h>
     41#include <iprt/formats/codeview.h>
    4042#include "internal/ldrPE.h"
    4143#include "internal/ldr.h"
     
    7072    /** The offset of the NT headers. */
    7173    RTFOFF                  offNtHdrs;
     74    /** The offset of the first byte after the section table. */
     75    RTFOFF                  offEndOfHdrs;
    7276
    7377    /** The machine type (IMAGE_FILE_HEADER::Machine). */
     
    9498    /** The export data directory entry. */
    9599    IMAGE_DATA_DIRECTORY    ExportDir;
     100    /** The debug directory entry. */
     101    IMAGE_DATA_DIRECTORY    DebugDir;
    96102} RTLDRMODPE, *PRTLDRMODPE;
    97103
     
    752758                continue;
    753759            }
    754             else
    755                 /* Get plain export address */
    756                 Value = PE_RVA2TYPE(BaseAddress, uRVAExport, RTUINTPTR);
     760
     761            /* Get plain export address */
     762            Value = PE_RVA2TYPE(BaseAddress, uRVAExport, RTUINTPTR);
    757763
    758764            /*
     
    773779                                             PFNRTLDRENUMDBG pfnCallback, void *pvUser)
    774780{
    775     NOREF(pMod); NOREF(pvBits); NOREF(pfnCallback); NOREF(pvUser);
    776     return VINF_NOT_SUPPORTED;
     781    PRTLDRMODPE pModPe = (PRTLDRMODPE)pMod;
     782    int rc;
     783
     784    /*
     785     * Debug info directory empty?
     786     */
     787    if (   !pModPe->DebugDir.VirtualAddress
     788        || !pModPe->DebugDir.Size)
     789        return VINF_SUCCESS;
     790
     791    /*
     792     * No bits supplied? Do we need to read the bits?
     793     */
     794    if (!pvBits)
     795    {
     796        if (!pModPe->pvBits)
     797        {
     798            rc = rtldrPEReadBits(pModPe);
     799            if (RT_FAILURE(rc))
     800                return rc;
     801        }
     802        pvBits = pModPe->pvBits;
     803    }
     804
     805    /*
     806     * Enumerate the debug directory.
     807     */
     808    PCIMAGE_DEBUG_DIRECTORY paDbgDir = PE_RVA2TYPE(pvBits, pModPe->DebugDir.VirtualAddress, PCIMAGE_DEBUG_DIRECTORY);
     809    int                     rcRet    = VINF_SUCCESS;
     810    uint32_t const          cEntries = pModPe->DebugDir.Size / sizeof(paDbgDir[0]);
     811    for (uint32_t i = 0; i < cEntries; i++)
     812    {
     813        if (paDbgDir[i].PointerToRawData < pModPe->offEndOfHdrs)
     814            continue;
     815        if (paDbgDir[i].SizeOfData < 4)
     816            continue;
     817
     818        char         szPath[RTPATH_MAX];
     819        RTLDRDBGINFO DbgInfo;
     820        RT_ZERO(DbgInfo.u);
     821        DbgInfo.iDbgInfo    = i;
     822        DbgInfo.offFile     = paDbgDir[i].PointerToRawData;
     823        DbgInfo.LinkAddress =    paDbgDir[i].AddressOfRawData < pModPe->cbImage
     824                              && paDbgDir[i].AddressOfRawData >= pModPe->offEndOfHdrs
     825                            ? paDbgDir[i].AddressOfRawData : NIL_RTLDRADDR;
     826        DbgInfo.cb          = paDbgDir[i].SizeOfData;
     827        DbgInfo.pszExtFile  = NULL;
     828
     829        switch (paDbgDir[i].Type)
     830        {
     831            case IMAGE_DEBUG_TYPE_CODEVIEW:
     832                DbgInfo.enmType = RTLDRDBGINFOTYPE_CODEVIEW;
     833                DbgInfo.u.Cv.uMajorVer  = paDbgDir[i].MajorVersion;
     834                DbgInfo.u.Cv.uMinorVer  = paDbgDir[i].MinorVersion;
     835                DbgInfo.u.Cv.uTimestamp = paDbgDir[i].TimeDateStamp;
     836                if (   paDbgDir[i].SizeOfData < sizeof(szPath)
     837                    && paDbgDir[i].SizeOfData > 16
     838                    && DbgInfo.LinkAddress != NIL_RTLDRADDR)
     839                {
     840                    PCCVPDB20INFO pCv20 = PE_RVA2TYPE(pvBits, DbgInfo.LinkAddress, PCCVPDB20INFO);
     841                    if (   pCv20->u32Magic   == CVPDB20INFO_MAGIC
     842                        && pCv20->offDbgInfo == 0
     843                        && paDbgDir[i].SizeOfData > RT_OFFSETOF(CVPDB20INFO, szPdbFilename) )
     844                    {
     845                        DbgInfo.enmType             = RTLDRDBGINFOTYPE_CODEVIEW_PDB20;
     846                        DbgInfo.u.Pdb20.cbImage     = pModPe->cbImage;
     847                        DbgInfo.u.Pdb20.uTimestamp  = pCv20->uTimestamp;
     848                        DbgInfo.u.Pdb20.uAge        = pCv20->uAge;
     849                        DbgInfo.pszExtFile          = (const char *)&pCv20->szPdbFilename[0];
     850                    }
     851                    else if (   pCv20->u32Magic == CVPDB70INFO_MAGIC
     852                             && paDbgDir[i].SizeOfData > RT_OFFSETOF(CVPDB70INFO, szPdbFilename) )
     853                    {
     854                        PCCVPDB70INFO pCv70 = (PCCVPDB70INFO)pCv20;
     855                        DbgInfo.enmType             = RTLDRDBGINFOTYPE_CODEVIEW_PDB70;
     856                        DbgInfo.u.Pdb70.cbImage     = pModPe->cbImage;
     857                        DbgInfo.u.Pdb70.Uuid        = pCv70->PdbUuid;
     858                        DbgInfo.u.Pdb70.uAge        = pCv70->uAge;
     859                        DbgInfo.pszExtFile          = (const char *)&pCv70->szPdbFilename[0];
     860                    }
     861                }
     862                break;
     863
     864            case IMAGE_DEBUG_TYPE_MISC:
     865                if (   paDbgDir[i].SizeOfData < sizeof(szPath)
     866                    && paDbgDir[i].SizeOfData > RT_OFFSETOF(IMAGE_DEBUG_MISC, Data)
     867                    && DbgInfo.LinkAddress != NIL_RTLDRADDR)
     868                {
     869                    PCIMAGE_DEBUG_MISC pMisc = PE_RVA2TYPE(pvBits, DbgInfo.LinkAddress, PCIMAGE_DEBUG_MISC);
     870                    if (   pMisc->DataType == IMAGE_DEBUG_MISC_EXENAME
     871                        && pMisc->Length   == paDbgDir[i].SizeOfData)
     872                    {
     873                        if (!pMisc->Unicode)
     874                            DbgInfo.pszExtFile      = (const char *)&pMisc->Data[0];
     875                        else
     876                        {
     877                            char *pszPath = szPath;
     878                            rc = RTUtf16ToUtf8Ex((PCRTUTF16)&pMisc->Data[0],
     879                                                 (pMisc->Length - RT_OFFSETOF(IMAGE_DEBUG_MISC, Data)) / sizeof(RTUTF16),
     880                                                 &pszPath, sizeof(szPath), NULL);
     881                            if (RT_FAILURE(rc))
     882                            {
     883                                rcRet = rc;
     884                                continue;
     885                            }
     886                            DbgInfo.pszExtFile      = szPath;
     887                        }
     888                        DbgInfo.enmType             = RTLDRDBGINFOTYPE_CODEVIEW_DBG;
     889                        DbgInfo.u.Dbg.cbImage       = pModPe->cbImage;
     890                        DbgInfo.u.Dbg.uTimestamp    = paDbgDir[i].TimeDateStamp;
     891                    }
     892                }
     893                break;
     894
     895            default:
     896                DbgInfo.enmType = RTLDRDBGINFOTYPE_UNKNOWN;
     897                break;
     898        }
     899
     900        /* Fix (hack) the file name encoding.  We don't have Windows-1252 handy,
     901           so we'll be using Latin-1 as a reasonable approximation.
     902           (I don't think we know exactly which encoding this is anyway, as
     903           it's probably the current ANSI/Windows code page for the process
     904           generating the image anyways.) */
     905        if (DbgInfo.pszExtFile && DbgInfo.pszExtFile != szPath)
     906        {
     907            char *pszPath = szPath;
     908            rc = RTLatin1ToUtf8Ex(DbgInfo.pszExtFile,
     909                                  paDbgDir[i].SizeOfData - ((uintptr_t)DbgInfo.pszExtFile - (uintptr_t)pvBits),
     910                                  &pszPath, sizeof(szPath), NULL);
     911            if (RT_FAILURE(rc))
     912            {
     913                rcRet = rc;
     914                continue;
     915            }
     916        }
     917        if (DbgInfo.pszExtFile)
     918            RTPathChangeToUnixSlashes(szPath, true /*fForce*/);
     919
     920        rc = pfnCallback(pMod, &DbgInfo, pvUser);
     921        if (rc != VINF_SUCCESS)
     922            return rc;
     923    }
     924    return rcRet;
    777925}
    778926
     
    16061754    if (!paSections)
    16071755        return VERR_NO_MEMORY;
    1608     rc = pReader->pfnRead(pReader, paSections, cbSections, offNtHdrs + 4 + sizeof(IMAGE_FILE_HEADER) + FileHdr.SizeOfOptionalHeader);
     1756    rc = pReader->pfnRead(pReader, paSections, cbSections,
     1757                          offNtHdrs + 4 + sizeof(IMAGE_FILE_HEADER) + FileHdr.SizeOfOptionalHeader);
    16091758    if (RT_SUCCESS(rc))
    16101759    {
     
    16281777                pModPe->pvBits        = NULL;
    16291778                pModPe->offNtHdrs     = offNtHdrs;
     1779                pModPe->offEndOfHdrs  = offNtHdrs + 4 + sizeof(IMAGE_FILE_HEADER) + FileHdr.SizeOfOptionalHeader + cbSections;
    16301780                pModPe->u16Machine    = FileHdr.Machine;
    16311781                pModPe->fFile         = FileHdr.Characteristics;
     
    16391789                pModPe->RelocDir      = OptHdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
    16401790                pModPe->ExportDir     = OptHdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
     1791                pModPe->DebugDir      = OptHdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];
    16411792
    16421793                /*
  • trunk/src/VBox/Runtime/common/ldr/ldrkStuff.cpp

    r44528 r45994  
    599599    NOREF(pMod);
    600600
    601     RTLDRDBGINFOTYPE enmMyType;
     601    RTLDRDBGINFO DbgInfo;
     602    RT_ZERO(DbgInfo.u);
     603    DbgInfo.iDbgInfo        = iDbgInfo;
     604    DbgInfo.offFile         = offFile;
     605    DbgInfo.LinkAddress     = LinkAddress;
     606    DbgInfo.cb              = cb;
     607    DbgInfo.pszExtFile      = pszExtFile;
     608
    602609    switch (enmType)
    603610    {
    604         case KLDRDBGINFOTYPE_UNKNOWN:   enmMyType = RTLDRDBGINFOTYPE_UNKNOWN;  break;
    605         case KLDRDBGINFOTYPE_STABS:     enmMyType = RTLDRDBGINFOTYPE_STABS;    break;
    606         case KLDRDBGINFOTYPE_DWARF:     enmMyType = RTLDRDBGINFOTYPE_DWARF;    break;
    607         case KLDRDBGINFOTYPE_CODEVIEW:  enmMyType = RTLDRDBGINFOTYPE_CODEVIEW; break;
    608         case KLDRDBGINFOTYPE_WATCOM:    enmMyType = RTLDRDBGINFOTYPE_WATCOM;   break;
    609         case KLDRDBGINFOTYPE_HLL:       enmMyType = RTLDRDBGINFOTYPE_HLL;      break;
     611        case KLDRDBGINFOTYPE_UNKNOWN:
     612            DbgInfo.enmType = RTLDRDBGINFOTYPE_UNKNOWN;
     613            break;
     614        case KLDRDBGINFOTYPE_STABS:
     615            DbgInfo.enmType = RTLDRDBGINFOTYPE_STABS;
     616            break;
     617        case KLDRDBGINFOTYPE_DWARF:
     618            DbgInfo.enmType = RTLDRDBGINFOTYPE_DWARF;
     619            if (pszExtFile)
     620                DbgInfo.enmType = RTLDRDBGINFOTYPE_DWARF_DWO;
     621            break;
     622        case KLDRDBGINFOTYPE_CODEVIEW:
     623            DbgInfo.enmType = RTLDRDBGINFOTYPE_CODEVIEW;
     624            /* Should make some more effort here... Assume the IPRT loader will kick in before we get here! */
     625            break;
     626        case KLDRDBGINFOTYPE_WATCOM:
     627            DbgInfo.enmType = RTLDRDBGINFOTYPE_WATCOM;
     628            break;
     629        case KLDRDBGINFOTYPE_HLL:
     630            DbgInfo.enmType = RTLDRDBGINFOTYPE_HLL;
     631            break;
    610632        default:
    611633            AssertFailed();
    612             enmMyType = RTLDRDBGINFOTYPE_UNKNOWN;
     634            DbgInfo.enmType = RTLDRDBGINFOTYPE_UNKNOWN;
    613635            break;
    614636    }
    615637
    616     int rc = pArgs->u.pfnEnumDbgInfo(&pArgs->pMod->Core, iDbgInfo, enmMyType, iMajorVer, iMinorVer, pszPartNm,
    617                                      offFile, LinkAddress, cb, pszExtFile, pArgs->pvUser);
     638    int rc = pArgs->u.pfnEnumDbgInfo(&pArgs->pMod->Core, &DbgInfo, pArgs->pvUser);
    618639    if (RT_FAILURE(rc))
    619640        return rc; /* don't bother converting. */
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