VirtualBox

Changeset 21046 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jun 30, 2009 1:11:28 AM (16 years ago)
Author:
vboxsync
Message:

IPRT: Added a reader of NM-style map files. (Mainly for linux /proc/kallsyms and System.map.)

Location:
trunk/src/VBox/Runtime
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r20933 r21046  
    204204        common/dbg/dbgmod.cpp \
    205205        common/dbg/dbgmodcontainer.cpp \
     206        common/dbg/dbgmodnm.cpp \
    206207        common/err/errmsg.cpp \
    207208        common/err/RTErrConvertFromErrno.cpp \
  • trunk/src/VBox/Runtime/common/dbg/dbgmod.cpp

    r20801 r21046  
    4242#include <iprt/once.h>
    4343#include <iprt/param.h>
     44#include <iprt/path.h>
    4445#include <iprt/semaphore.h>
    4546#include <iprt/strcache.h>
     
    112113static RTSEMRW          g_hDbgModRWSem = NIL_RTSEMRW;
    113114/** List of registered image interpreters.  */
    114 static RTDBGMODREGIMG   g_pImgHead;
     115static PRTDBGMODREGIMG  g_pImgHead;
    115116/** List of registered debug infor interpreters.  */
    116 static RTDBGMODREGDBG   g_pDbgHead;
     117static PRTDBGMODREGDBG  g_pDbgHead;
    117118/** String cache for the debug info interpreters.
    118119 * RTSTRCACHE is thread safe. */
    119120DECLHIDDEN(RTSTRCACHE)  g_hDbgModStrCache = NIL_RTSTRCACHE;
     121
    120122
    121123
     
    137139        g_hDbgModStrCache = NIL_RTSTRCACHE;
    138140
    139         /** @todo deregister interpreters. */
     141        PRTDBGMODREGDBG pCur = g_pDbgHead;
     142        g_pDbgHead = NULL;
     143        while (pCur)
     144        {
     145            PRTDBGMODREGDBG pNext = pCur->pNext;
     146            AssertMsg(pCur->cUsers == 0, ("%#x %s\n", pCur->cUsers, pCur->pVt->pszName));
     147            RTMemFree(pCur);
     148            pCur = pNext;
     149        }
     150
     151        Assert(!g_pImgHead);
    140152    }
     153}
     154
     155
     156/**
     157 * Internal worker for register a debug interpreter.
     158 *
     159 * Called while owning the write lock or when locking isn't required.
     160 *
     161 * @returns IPRT status code.
     162 * @retval  VERR_NO_MEMORY
     163 * @retval  VERR_ALREADY_EXISTS
     164 *
     165 * @param   pVt                 The virtual function table of the debug
     166 *                              module interpreter.
     167 */
     168static int rtDbgModDebugInterpreterRegister(PCRTDBGMODVTDBG pVt)
     169{
     170    /*
     171     * Search or duplicate registration.
     172     */
     173    PRTDBGMODREGDBG pPrev = NULL;
     174    for (PRTDBGMODREGDBG pCur = g_pDbgHead; pCur; pCur = pCur->pNext)
     175    {
     176        if (pCur->pVt == pVt)
     177            return VERR_ALREADY_EXISTS;
     178        if (!strcmp(pCur->pVt->pszName, pVt->pszName))
     179            return VERR_ALREADY_EXISTS;
     180        pPrev = pCur;
     181    }
     182
     183    /*
     184     * Create a new record and add it to the end of the list.
     185     */
     186    PRTDBGMODREGDBG pReg = (PRTDBGMODREGDBG)RTMemAlloc(sizeof(*pReg));
     187    if (!pReg)
     188        return VERR_NO_MEMORY;
     189    pReg->pVt    = pVt;
     190    pReg->cUsers = 0;
     191    pReg->pNext  = NULL;
     192    if (pPrev)
     193        pPrev->pNext = pReg;
     194    else
     195        g_pDbgHead   = pReg;
     196    return VINF_SUCCESS;
    141197}
    142198
     
    164220         * Register the interpreters.
    165221         */
    166         /** @todo */
    167 
     222        rc = rtDbgModDebugInterpreterRegister(&g_rtDbgModVtDbgNm);
    168223        if (RT_SUCCESS(rc))
    169224        {
     
    174229            if (RT_SUCCESS(rc))
    175230                return VINF_SUCCESS;
     231
     232            /* bail out: use the termination callback. */
    176233        }
    177 
    178         RTStrCacheDestroy(g_hDbgModStrCache);
     234    }
     235    else
    179236        g_hDbgModStrCache = NIL_RTSTRCACHE;
    180     }
    181 
    182     RTSemRWDestroy(g_hDbgModRWSem);
    183     g_hDbgModRWSem = NIL_RTSEMRW;
    184 
     237    rtDbgModTermCallback(RTTERMREASON_UNLOAD, 0, NULL);
    185238    return rc;
    186239}
     
    265318}
    266319
    267 RTDECL(int)         RTDbgModCreateFromMap(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, RTUINTPTR uSubtrahend, uint32_t fFlags)
    268 {
    269     return VERR_NOT_IMPLEMENTED;
     320
     321RTDECL(int) RTDbgModCreateFromMap(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, RTUINTPTR uSubtrahend, uint32_t fFlags)
     322{
     323    /*
     324     * Input validation and lazy initialization.
     325     */
     326    AssertPtrReturn(phDbgMod, VERR_INVALID_POINTER);
     327    *phDbgMod = NIL_RTDBGMOD;
     328    AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
     329    AssertReturn(*pszFilename, VERR_INVALID_PARAMETER);
     330    AssertPtrNullReturn(pszName, VERR_INVALID_POINTER);
     331    AssertReturn(fFlags == 0, VERR_INVALID_PARAMETER);
     332
     333    int rc = rtDbgModLazyInit();
     334    if (RT_FAILURE(rc))
     335        return rc;
     336
     337    if (!pszName)
     338        pszName = RTPathFilename(pszFilename);
     339
     340    /*
     341     * Allocate a new module instance.
     342     */
     343    PRTDBGMODINT pDbgMod = (PRTDBGMODINT)RTMemAllocZ(sizeof(*pDbgMod));
     344    if (!pDbgMod)
     345        return VERR_NO_MEMORY;
     346    pDbgMod->u32Magic = RTDBGMOD_MAGIC;
     347    pDbgMod->cRefs = 1;
     348    rc = RTCritSectInit(&pDbgMod->CritSect);
     349    if (RT_SUCCESS(rc))
     350    {
     351        pDbgMod->pszName = RTStrCacheEnter(g_hDbgModStrCache, pszName);
     352        if (pDbgMod->pszName)
     353        {
     354            pDbgMod->pszDbgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename);
     355            if (pDbgMod->pszDbgFile)
     356            {
     357                /*
     358                 * Try the map file readers.
     359                 */
     360                rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT);
     361                if (RT_SUCCESS(rc))
     362                {
     363                    rc = VERR_DBG_NO_MATCHING_INTERPRETER;
     364                    for (PRTDBGMODREGDBG pCur = g_pDbgHead; pCur; pCur = pCur->pNext)
     365                    {
     366                        if (pCur->pVt->fSupports & RT_DBGTYPE_MAP)
     367                        {
     368                            pDbgMod->pDbgVt = pCur->pVt;
     369                            pDbgMod->pvDbgPriv = NULL;
     370                            rc = pCur->pVt->pfnTryOpen(pDbgMod);
     371                            if (RT_SUCCESS(rc))
     372                            {
     373                                ASMAtomicIncU32(&pCur->cUsers);
     374                                RTSemRWReleaseRead(g_hDbgModRWSem);
     375
     376                                *phDbgMod = pDbgMod;
     377                                return rc;
     378                            }
     379                        }
     380                    }
     381
     382                    /* bail out */
     383                    RTSemRWReleaseRead(g_hDbgModRWSem);
     384                }
     385                RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName);
     386            }
     387            RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszDbgFile);
     388        }
     389        RTCritSectDelete(&pDbgMod->CritSect);
     390    }
     391
     392    RTMemFree(pDbgMod);
     393    return rc;
    270394}
    271395
     
    454578    RTDBGMOD_VALID_RETURN_RC(pDbgMod, VERR_INVALID_HANDLE);
    455579    AssertMsgReturn(uRva + cb >= uRva, ("uRva=%RTptr cb=%RTptr\n", uRva, cb), VERR_DBG_ADDRESS_WRAP);
    456     AssertPtr(*pszName);
     580    Assert(*pszName);
    457581    size_t cchName = strlen(pszName);
    458582    AssertReturn(cchName > 0, VERR_DBG_SEGMENT_NAME_OUT_OF_RANGE);
     
    525649
    526650    RTDBGMOD_UNLOCK(pDbgMod);
    527     return RT_SUCCESS(rc);
     651    return rc;
    528652}
    529653
  • trunk/src/VBox/Runtime/common/dbg/dbgmodcontainer.cpp

    r21005 r21046  
    247247    AssertMsgReturn(iSeg < pThis->cSegs,          ("iSeg=%#x cSegs=%#x\n", pThis->cSegs),
    248248                    VERR_DBG_INVALID_SEGMENT_INDEX);
    249     AssertMsgReturn(pThis->paSegs[iSeg].cb < off, ("off=%RTptr cbSeg=%RTptr\n", off, pThis->paSegs[iSeg].cb),
     249    AssertMsgReturn(off < pThis->paSegs[iSeg].cb, ("off=%RTptr cbSeg=%RTptr\n", off, pThis->paSegs[iSeg].cb),
    250250                    VERR_DBG_INVALID_SEGMENT_OFFSET);
    251251
     
    385385                    VERR_DBG_INVALID_SEGMENT_INDEX);
    386386    AssertMsgReturn(    iSeg >= RTDBGSEGIDX_SPECIAL_FIRST
    387                     ||  pThis->paSegs[iSeg].cb <= off + cb,
     387                    ||  off + cb <= pThis->paSegs[iSeg].cb,
    388388                    ("off=%RTptr cb=%RTptr cbSeg=%RTptr\n", off, cb, pThis->paSegs[iSeg].cb),
    389389                    VERR_DBG_INVALID_SEGMENT_OFFSET);
     
    397397
    398398    pSymbol->AddrCore.Key       = off;
    399     pSymbol->AddrCore.KeyLast   = off + RT_MAX(cb, 1);
     399    pSymbol->AddrCore.KeyLast   = off + (cb ? cb - 1 : 0);
    400400    pSymbol->OrdinalCore.Key    = pThis->iNextSymbolOrdinal;
    401401    pSymbol->iSeg               = iSeg;
  • trunk/src/VBox/Runtime/include/internal/dbgmod.h

    r20801 r21046  
    400400
    401401
    402 extern DECLHIDDEN(RTSTRCACHE) g_hDbgModStrCache;
    403 
     402extern DECLHIDDEN(RTSTRCACHE)           g_hDbgModStrCache;
     403extern DECLHIDDEN(RTDBGMODVTDBG const)  g_rtDbgModVtDbgNm;
    404404
    405405int rtDbgModContainerCreate(PRTDBGMODINT pMod, RTUINTPTR cbSeg);
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