VirtualBox

Changeset 20740 in vbox


Ignore:
Timestamp:
Jun 21, 2009 2:09:28 AM (15 years ago)
Author:
vboxsync
Message:

iprt: More RTDbg coding; added a new AVL tree for RTUINPTR.

Location:
trunk
Files:
1 added
9 edited
1 copied

Legend:

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

    r20374 r20740  
    615615
    616616
     617/** AVL tree of RTUINTPTR.
     618 * @{
     619 */
     620
     621/**
     622 * AVL RTUINTPTR node core.
     623 */
     624typedef struct _AVLUIntPtrNodeCore
     625{
     626    /** Key value. */
     627    RTUINTPTR                   Key;
     628    /** Offset to the left leaf node, relative to this field. */
     629    struct _AVLUIntPtrNodeCore *pLeft;
     630    /** Offset to the right leaf node, relative to this field. */
     631    struct _AVLUIntPtrNodeCore *pRight;
     632    /** Height of this tree: max(height(left), height(right)) + 1 */
     633    unsigned char               uchHeight;
     634} AVLUINTPTRNODECORE;
     635/** Pointer to a RTUINTPTR AVL node core.*/
     636typedef AVLUINTPTRNODECORE *PAVLUINTPTRNODECORE;
     637
     638/** A pointer based tree with RTUINTPTR keys. */
     639typedef PAVLUINTPTRNODECORE AVLUINTPTRTREE;
     640/** Pointer to a offset base tree with RTUINTPTR keys. */
     641typedef AVLUINTPTRTREE     *PAVLUINTPTRTREE;
     642
     643/** Pointer to an internal tree pointer.
     644 * In this case it's a pointer to a pointer. */
     645typedef AVLUINTPTRTREE     *PPAVLUINTPTRNODECORE;
     646
     647/** Callback function for RTAvlUIntPtrDoWithAll() and RTAvlUIntPtrDestroy(). */
     648typedef DECLCALLBACK(int)    AVLUINTPTRCALLBACK(PAVLUINTPTRNODECORE pNode, void *pvUser);
     649/** Pointer to callback function for RTAvlUIntPtrDoWithAll() and RTAvlUIntPtrDestroy(). */
     650typedef AVLUINTPTRCALLBACK *PAVLUINTPTRCALLBACK;
     651
     652RTDECL(bool)                    RTAvlUIntPtrInsert(    PAVLUINTPTRTREE pTree, PAVLUINTPTRNODECORE pNode);
     653RTDECL(PAVLUINTPTRNODECORE)     RTAvlUIntPtrRemove(    PAVLUINTPTRTREE pTree, RTUINTPTR Key);
     654RTDECL(PAVLUINTPTRNODECORE)     RTAvlUIntPtrGet(       PAVLUINTPTRTREE pTree, RTUINTPTR Key);
     655RTDECL(PAVLUINTPTRNODECORE)     RTAvlUIntPtrGetBestFit(PAVLUINTPTRTREE pTree, RTUINTPTR Key, bool fAbove);
     656RTDECL(int)                     RTAvlUIntPtrDoWithAll( PAVLUINTPTRTREE pTree, int fFromLeft, PAVLUINTPTRCALLBACK pfnCallBack, void *pvParam);
     657RTDECL(int)                     RTAvlUIntPtrDestroy(   PAVLUINTPTRTREE pTree, PAVLUINTPTRCALLBACK pfnCallBack, void *pvParam);
     658RTDECL(PAVLUINTPTRNODECORE)     RTAvlUIntPtrGetRoot(   PAVLUINTPTRTREE pTree);
     659RTDECL(PAVLUINTPTRNODECORE)     RTAvlUIntPtrGetLeft(   PAVLUINTPTRNODECORE pNode);
     660RTDECL(PAVLUINTPTRNODECORE)     RTAvlUIntPtrGetRight(  PAVLUINTPTRNODECORE pNode);
     661
     662/** @} */
     663
     664
    617665/** AVL tree of RTUINTPTR ranges.
    618666 * @{
     
    620668
    621669/**
    622  * AVL Core node.
     670 * AVL RTUINTPTR range node core.
    623671 */
    624672typedef struct _AVLRUIntPtrNodeCore
    625673{
    626674    /** First key value in the range (inclusive). */
    627     RTUINTPTR           Key;
     675    RTUINTPTR                       Key;
    628676    /** Last key value in the range (inclusive). */
    629     RTUINTPTR           KeyLast;
    630     /** Offset to the left leaf node, relative to this field. */
    631     struct _AVLRUIntPtrNodeCore *pLeft;
    632     /** Offset to the right leaf node, relative to this field. */
    633     struct _AVLRUIntPtrNodeCore *pRight;
    634     /** Height of this tree: max(height(left), height(right)) + 1 */
    635     unsigned char       uchHeight;
    636 } AVLRUINTPTRNODECORE, *PAVLRUINTPTRNODECORE;
    637 
    638 /** A offset base tree with RTUINTPTR keys. */
     677    RTUINTPTR                       KeyLast;
     678    /** Offset to the left leaf node, relative to this field. */
     679    struct _AVLRUIntPtrNodeCore    *pLeft;
     680    /** Offset to the right leaf node, relative to this field. */
     681    struct _AVLRUIntPtrNodeCore    *pRight;
     682    /** Height of this tree: max(height(left), height(right)) + 1 */
     683    unsigned char                   uchHeight;
     684} AVLRUINTPTRNODECORE;
     685/** Pointer to an AVL RTUINTPTR range node code. */
     686typedef AVLRUINTPTRNODECORE *PAVLRUINTPTRNODECORE;
     687
     688/** A pointer based tree with RTUINTPTR ranges. */
    639689typedef PAVLRUINTPTRNODECORE AVLRUINTPTRTREE;
    640 /** Pointer to a offset base tree with RTUINTPTR keys. */
     690/** Pointer to a pointer based tree with RTUINTPTR ranges. */
    641691typedef AVLRUINTPTRTREE     *PAVLRUINTPTRTREE;
    642692
    643693/** Pointer to an internal tree pointer.
    644  * In this case it's a pointer to a relative offset. */
     694 * In this case it's a pointer to a pointer. */
    645695typedef AVLRUINTPTRTREE     *PPAVLRUINTPTRNODECORE;
    646696
  • trunk/include/iprt/dbg.h

    r20738 r20740  
    7171typedef struct RTDBGSYMBOL
    7272{
    73     /** Symbol value (address). */
     73    /** Symbol value (address).
     74     * This depends a bit who you ask. It will be the same as offSeg when you
     75     * as RTDbgMod, but the mapping address if you ask RTDbgAs. */
    7476    RTUINTPTR           Value;
    75     /** Segment number when applicable or NIL_RTDBGSEGIDX. */
     77    /** Offset into the segment specified by iSeg. */
     78    RTUINTPTR           offSeg;
     79    /** Segment number. */
    7680    RTDBGSEGIDX         iSeg;
    7781    /** Symbol size. */
     
    8791typedef const RTDBGSYMBOL *PCRTDBGSYMBOL;
    8892
     93/**
     94 * Allocate a new symbol structure.
     95 *
     96 * @returns Pointer to a new structure on success, NULL on failure.
     97 */
    8998RTDECL(PRTDBGSYMBOL) RTDbgSymbolAlloc(void);
     99
     100/**
     101 * Duplicates a symbol structure.
     102 *
     103 * @returns Pointer to duplicate on success, NULL on failure.
     104 *
     105 * @param   pSymbol         The symbol to duplicate.
     106 */
    90107RTDECL(PRTDBGSYMBOL) RTDbgSymbolDup(PCRTDBGSYMBOL pSymbol);
    91 RTDECL(void)         RTDbgSymbolFree(PRTDBGSYMBOL pSymbol);
     108
     109/**
     110 * Free a symbol structure previously allocated by a RTDbg method.
     111 *
     112 * @param   pSymbol         The symbol to free. NULL is ignored.
     113 */
     114RTDECL(void) RTDbgSymbolFree(PRTDBGSYMBOL pSymbol);
     115
     116
     117/** Max length (including '\\0') of a debug info file name. */
     118#define RTDBG_FILE_NAME_LENGTH   (260)
    92119
    93120
     
    97124typedef struct RTDBGLINE
    98125{
    99     /** Address. */
     126    /** Address.
     127     * This depends a bit who you ask. It will be the same as offSeg when you
     128     * as RTDbgMod, but the mapping address if you ask RTDbgAs. */
    100129    RTUINTPTR           Address;
    101     /** Segment number when applicable or NIL_RTDBGSEGIDX. */
     130    /** Offset into the segment specified by iSeg. */
     131    RTUINTPTR           offSeg;
     132    /** Segment number. */
    102133    RTDBGSEGIDX         iSeg;
    103134    /** Line number. */
    104135    uint32_t            uLineNo;
    105136    /** Filename. */
    106     char                szFilename[260];
     137    char                szFilename[RTDBG_FILE_NAME_LENGTH];
    107138} RTDBGLINE;
    108139/** Pointer to debug line number. */
     
    360391 * @retval  VERR_INVALID_HANDLE if hDbgAs is invalid.
    361392 * @retval  VERR_NOT_FOUND if no module was found at the specified address.
     393 * @retval  VERR_NOT_SUPPORTED if the module interpret doesn't support adding
     394 *          custom symbols.
    362395 *
    363396 * @param   hDbgAs          The address space handle.
     
    365398 * @param   Addr            The address of the symbol.
    366399 * @param   cb              The size of the symbol.
    367  */
    368 RTDECL(int) RTDbgAsSymbolAdd(RTDBGAS hDbgAs, const char *pszSymbol, RTUINTPTR Addr, uint32_t cb);
     400 * @param   fFlags          Symbol flags.
     401 */
     402RTDECL(int) RTDbgAsSymbolAdd(RTDBGAS hDbgAs, const char *pszSymbol, RTUINTPTR Addr, RTUINTPTR cb, uint32_t fFlags);
    369403
    370404/**
     
    472506RTDECL(RTUINTPTR)   RTDbgModImageSize(RTDBGMOD hDbgMod);
    473507RTDECL(RTUINTPTR)   RTDbgModSegmentSize(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg);
     508RTDECL(RTUINTPTR)   RTDbgModSegmentRva(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg);
    474509RTDECL(RTDBGSEGIDX) RTDbgModSegmentCount(RTDBGMOD hDbgMod);
    475510
    476 RTDECL(int)         RTDbgModSymbolAdd(RTDBGMOD hDbgMod, const char *pszSymbol, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t cb);
     511RTDECL(int)         RTDbgModSymbolAdd(RTDBGMOD hDbgMod, const char *pszSymbol, RTDBGSEGIDX iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags);
    477512RTDECL(uint32_t)    RTDbgModSymbolCount(RTDBGMOD hDbgMod);
    478513RTDECL(int)         RTDbgModSymbolByIndex(RTDBGMOD hDbgMod, uint32_t iSymbol, PRTDBGSYMBOL pSymbol);
     
    482517RTDECL(int)         RTDbgModSymbolByNameA(RTDBGMOD hDbgMod, const char *pszSymbol, PRTDBGSYMBOL *ppSymbol);
    483518
     519RTDECL(int)         RTDbgModLineAdd(RTDBGMOD hDbgMod, const char *pszFile, uint32_t uLineNo, RTDBGSEGIDX iSeg, RTUINTPTR off);
    484520RTDECL(int)         RTDbgModLineByAddr(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTINTPTR poffDisp, PRTDBGLINE pLine);
    485521RTDECL(int)         RTDbgModLineByAddrA(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTINTPTR poffDisp, PRTDBGLINE *ppLine);
  • trunk/include/iprt/err.h

    r20739 r20740  
    946946/** Invalid segment offset. */
    947947#define VERR_DBG_INVALID_SEGMENT_OFFSET         (-652)
     948/** Invalid image relative virtual address. */
     949#define VERR_DBG_INVALID_RVA                    (-653)
    948950/** The module contains no line number information. */
    949 #define VERR_DBG_NO_LINE_NUMBERS                (-653)
     951#define VERR_DBG_NO_LINE_NUMBERS                (-654)
     952/** Address conflict within a module/segment.
     953 * Attempted to add a symbol or line number that fully or partially overlaps with an existing one.  */
     954#define VERR_DBG_ADDRESS_CONFLICT               (-655)
     955/** Duplicate symbol within the module.
     956 * Attempted to add a symbol which name already exists within the module.  */
     957#define VERR_DBG_DUPLICATE_SYMBOL               (-656)
     958/** The length of the symbol name is out of range.
     959 * This means it is an empty string or that it's greater or equal to
     960 * RTDBG_SYMBOL_NAME_LENGTH. */
     961#define VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE       (-657)
     962/** The length of the file name is out of range.
     963 * This means it is an empty string or that it's greater or equal to
     964 * RTDBG_FILE_NAME_LENGTH. */
     965#define VERR_DBG_FILE_NAME_OUT_OF_RANGE         (-658)
    950966/** @} */
    951967
  • trunk/include/iprt/types.h

    r20360 r20740  
    388388/** Pointer const to unsigned integer which can contain both GC and HC pointers. */
    389389typedef const RTUINTPTR *PCRTUINTPTR;
     390/** The maximum value the RTUINTPTR type can hold. */
     391#if (HC_ARCH_BITS == 32 && GC_ARCH_BITS == 32)
     392# define RTUINTPTR_MAX  UINT32_MAX
     393#elif (HC_ARCH_BITS == 64 || GC_ARCH_BITS == 64)
     394# define RTUINTPTR_MAX  UINT64_MAX
     395#else
     396#  error Unsupported HC_ARCH_BITS and/or GC_ARCH_BITS values.
     397#endif
    390398
    391399/** Signed integer. */
  • trunk/src/VBox/Runtime/Makefile.kmk

    r20449 r20740  
    200200        common/checksum/md5.cpp \
    201201        common/checksum/ipv4.cpp \
     202        common/dbg/dbg.cpp \
    202203        common/dbg/dbgas.cpp \
    203204        common/dbg/dbgmod.cpp \
     
    269270        common/table/avlruintptr.cpp \
    270271        common/table/avlu32.cpp \
     272        common/table/avluintptr.cpp \
    271273        common/table/avlul.cpp \
    272274        common/table/table.cpp \
  • trunk/src/VBox/Runtime/common/dbg/dbgas.cpp

    r20355 r20740  
    6262    AVLPVNODECORE       Core;
    6363    /** Pointer to the first mapping of the module or a segment within it. */
    64     RTDBGASMAP         *pMapHead;
     64    PRTDBGASMAP         pMapHead;
    6565    /** Pointer to the next module with an identical name. */
    6666    PRTDBGASMOD         pNextName;
     
    10291029 * @param   piSeg           where to return the segment index.
    10301030 * @param   poffSeg         Where to return the segment offset.
    1031  */
    1032 DECLINLINE(RTDBGMOD) rtDbgAsModuleByAddr(PRTDBGASINT pDbgAs, RTUINTPTR Addr, PRTDBGSEGIDX piSeg, PRTUINTPTR poffSeg)
     1031 * @param   pMapAddr        The mapping address (RTDBGASMAP::Core.Key).
     1032 */
     1033DECLINLINE(RTDBGMOD) rtDbgAsModuleByAddr(PRTDBGASINT pDbgAs, RTUINTPTR Addr, PRTDBGSEGIDX piSeg, PRTUINTPTR poffSeg, PRTUINTPTR pMapAddr)
    10331034{
    10341035    RTDBGMOD hMod = NIL_RTDBGMOD;
     
    10401041        hMod = (RTDBGMOD)pMap->pMod->Core.Key;
    10411042        RTDbgModRetain(hMod);
    1042         *piSeg = pMap->iSeg;
     1043        *piSeg = pMap->iSeg != NIL_RTDBGSEGIDX ? pMap->iSeg : RTDBGSEGIDX_RVA;
    10431044        *poffSeg = Addr - pMap->Core.Key;
     1045        if (pMapAddr)
     1046            *pMapAddr = pMap->Core.Key;
    10441047    }
    10451048    RTDBGAS_UNLOCK_READ(pDbgAs);
    10461049
    10471050    return hMod;
     1051}
     1052
     1053
     1054/**
     1055 * Adjusts the address to correspond to the mapping of the module/segment.
     1056 *
     1057 * @param   pSymbol         The returned symbol info.
     1058 * @param   pMap            The mapping record.
     1059 * @param   hDbgMod         The module handle.
     1060 * @param   MapAddr         The mapping address.
     1061 * @param   iMapSeg         The segment that's mapped, NIL_RTDBGSEGIDX or
     1062 *                          RTDBGSEGIDX_RVA if the whole module is mapped here.
     1063 */
     1064DECLINLINE(void) rtDbgAsAdjustAddressByMapping(PRTUINTPTR pAddr, RTDBGSEGIDX iSeg,
     1065                                               RTDBGMOD hDbgMod, RTUINTPTR MapAddr, RTDBGSEGIDX iMapSeg)
     1066{
     1067    if (iSeg == RTDBGSEGIDX_ABS)
     1068        return;
     1069
     1070    if (iSeg == RTDBGSEGIDX_RVA)
     1071    {
     1072        if (    iMapSeg == RTDBGSEGIDX_RVA
     1073            ||  iMapSeg == NIL_RTDBGSEGIDX)
     1074            *pAddr += MapAddr;
     1075        else
     1076        {
     1077            RTUINTPTR SegRva = RTDbgModSegmentRva(hDbgMod, iMapSeg);
     1078            AssertReturnVoid(SegRva != RTUINTPTR_MAX);
     1079            AssertMsg(SegRva <= *pAddr, ("SegRva=%RTptr *pAddr=%RTptr\n", SegRva, *pAddr));
     1080            *pAddr += MapAddr - SegRva;
     1081        }
     1082    }
     1083    else
     1084    {
     1085        if (    iMapSeg != RTDBGSEGIDX_RVA
     1086            &&  iMapSeg != NIL_RTDBGSEGIDX)
     1087        {
     1088            Assert(iMapSeg == iSeg);
     1089            *pAddr += MapAddr;
     1090        }
     1091        else
     1092        {
     1093            RTUINTPTR SegRva = RTDbgModSegmentRva(hDbgMod, iSeg);
     1094            AssertReturnVoid(SegRva != RTUINTPTR_MAX);
     1095            *pAddr += MapAddr + SegRva;
     1096        }
     1097    }
     1098}
     1099
     1100
     1101/**
     1102 * Adjusts the symbol value to correspond to the mapping of the module/segment.
     1103 *
     1104 * @param   pSymbol         The returned symbol info.
     1105 * @param   hDbgMod         The module handle.
     1106 * @param   MapAddr         The mapping address.
     1107 * @param   iMapSeg         The segment that's mapped, NIL_RTDBGSEGIDX if the
     1108 *                          whole module is mapped here.
     1109 */
     1110DECLINLINE(void) rtDbgAsAdjustSymbolValue(PRTDBGSYMBOL pSymbol, RTDBGMOD hDbgMod, RTUINTPTR MapAddr, RTDBGSEGIDX iMapSeg)
     1111{
     1112    Assert(pSymbol->iSeg   != NIL_RTDBGSEGIDX);
     1113    Assert(pSymbol->offSeg == pSymbol->Value);
     1114    rtDbgAsAdjustAddressByMapping(&pSymbol->Value, pSymbol->iSeg, hDbgMod, MapAddr, iMapSeg);
     1115}
     1116
     1117
     1118/**
     1119 * Adjusts the line number address to correspond to the mapping of the module/segment.
     1120 *
     1121 * @param   pLine           The returned line number info.
     1122 * @param   hDbgMod         The module handle.
     1123 * @param   MapAddr         The mapping address.
     1124 * @param   iMapSeg         The segment that's mapped, NIL_RTDBGSEGIDX if the
     1125 *                          whole module is mapped here.
     1126 */
     1127DECLINLINE(void) rtDbgAsAdjustLineAddress(PRTDBGLINE pLine, RTDBGMOD hDbgMod, RTUINTPTR MapAddr, RTDBGSEGIDX iMapSeg)
     1128{
     1129    Assert(pLine->iSeg   != NIL_RTDBGSEGIDX);
     1130    Assert(pLine->offSeg == pLine->Address);
     1131    rtDbgAsAdjustAddressByMapping(&pLine->Address, pLine->iSeg, hDbgMod, MapAddr, iMapSeg);
    10481132}
    10491133
     
    10551139 * @retval  VERR_INVALID_HANDLE if hDbgAs is invalid.
    10561140 * @retval  VERR_NOT_FOUND if no module was found at the specified address.
     1141 * @retval  VERR_NOT_SUPPORTED if the module interpret doesn't support adding
     1142 *          custom symbols.
    10571143 *
    10581144 * @param   hDbgAs          The address space handle.
     
    10601146 * @param   Addr            The address of the symbol.
    10611147 * @param   cb              The size of the symbol.
    1062  */
    1063 RTDECL(int) RTDbgAsSymbolAdd(RTDBGAS hDbgAs, const char *pszSymbol, RTUINTPTR Addr, uint32_t cb)
     1148 * @param   fFlags          Symbol flags.
     1149 */
     1150RTDECL(int) RTDbgAsSymbolAdd(RTDBGAS hDbgAs, const char *pszSymbol, RTUINTPTR Addr, RTUINTPTR cb, uint32_t fFlags)
    10641151{
    10651152    /*
     
    10711158    RTDBGSEGIDX iSeg;
    10721159    RTUINTPTR offSeg;
    1073     RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg);
     1160    RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, NULL);
    10741161    if (hMod == NIL_RTDBGMOD)
    10751162        return VERR_NOT_FOUND;
     
    10781165     * Forward the call.
    10791166     */
    1080     int rc = RTDbgModSymbolAdd(hMod, pszSymbol, iSeg, offSeg, cb);
     1167    int rc = RTDbgModSymbolAdd(hMod, pszSymbol, iSeg, offSeg, cb, fFlags);
    10811168    RTDbgModRelease(hMod);
    10821169    return rc;
     
    11061193
    11071194    RTDBGSEGIDX iSeg;
    1108     RTUINTPTR offSeg;
    1109     RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg);
     1195    RTUINTPTR   offSeg;
     1196    RTUINTPTR   MapAddr;
     1197    RTDBGMOD    hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, &MapAddr);
    11101198    if (hMod == NIL_RTDBGMOD)
    11111199        return VERR_NOT_FOUND;
     
    11151203     */
    11161204    int rc = RTDbgModSymbolByAddr(hMod, iSeg, offSeg, poffDisp, pSymbol);
     1205    if (RT_SUCCESS(rc))
     1206        rtDbgAsAdjustSymbolValue(pSymbol, hMod, MapAddr, iSeg);
    11171207    RTDbgModRelease(hMod);
    11181208    return rc;
     
    11431233
    11441234    RTDBGSEGIDX iSeg;
    1145     RTUINTPTR offSeg;
    1146     RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg);
     1235    RTUINTPTR   offSeg;
     1236    RTUINTPTR   MapAddr;
     1237    RTDBGMOD    hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, &MapAddr);
    11471238    if (hMod == NIL_RTDBGMOD)
    11481239        return VERR_NOT_FOUND;
     
    11521243     */
    11531244    int rc = RTDbgModSymbolByAddrA(hMod, iSeg, offSeg, poffDisp, ppSymbol);
     1245    if (RT_SUCCESS(rc))
     1246        rtDbgAsAdjustSymbolValue(*ppSymbol, hMod, MapAddr, iSeg);
    11541247    RTDbgModRelease(hMod);
    11551248    return rc;
     
    11891282
    11901283/**
     1284 * Attempts to find a mapping of the specified symbol/module and
     1285 * adjust it's Value field accordingly.
     1286 *
     1287 * @returns true / false success indicator.
     1288 * @param   pDbgAs          The address space.
     1289 * @param   hDbgMod         The module handle.
     1290 * @param   pSymbol         The symbol info.
     1291 */
     1292static bool rtDbgAsFindMappingAndAdjustSymbolValue(PRTDBGASINT pDbgAs, RTDBGMOD hDbgMod, PRTDBGSYMBOL pSymbol)
     1293{
     1294    /*
     1295     * Absolute segments needs no fixing.
     1296     */
     1297    RTDBGSEGIDX const iSeg = pSymbol->iSeg;
     1298    if (iSeg)
     1299        return true;
     1300
     1301    RTDBGAS_LOCK_READ(pDbgAs);
     1302
     1303    /*
     1304     * Lookup up the module by it's handle and iterate the mappings looking for one
     1305     * that either encompasses the entire module or the segment in question.
     1306     */
     1307    PRTDBGASMOD pMod = (PRTDBGASMOD)RTAvlPVGet(&pDbgAs->ModTree, hDbgMod);
     1308    if (pMod)
     1309    {
     1310        for (PRTDBGASMAP pMap = pMod->pMapHead; pMap; pMap = pMap->pNext)
     1311        {
     1312            /* Exact segment match or full-mapping. */
     1313            if (    iSeg == pMap->iSeg
     1314                ||  pMap->iSeg == NIL_RTDBGSEGIDX)
     1315            {
     1316                RTUINTPTR   MapAddr = pMap->Core.Key;
     1317                RTDBGSEGIDX iMapSeg = pMap->iSeg;
     1318
     1319                RTDBGAS_UNLOCK_READ(pDbgAs);
     1320                rtDbgAsAdjustSymbolValue(pSymbol, hDbgMod, MapAddr, iMapSeg);
     1321                return true;
     1322            }
     1323
     1324            /* Symbol uses RVA and the mapping doesn't, see if it's in the mapped segment. */
     1325            if (iSeg == RTDBGSEGIDX_RVA)
     1326            {
     1327                Assert(pMap->iSeg != NIL_RTDBGSEGIDX);
     1328                RTUINTPTR SegRva = RTDbgModSegmentRva(hDbgMod, pMap->iSeg);
     1329                Assert(SegRva != RTUINTPTR_MAX);
     1330                RTUINTPTR cbSeg = RTDbgModSegmentSize(hDbgMod, pMap->iSeg);
     1331                if (SegRva - pSymbol->Value < cbSeg)
     1332                {
     1333                    RTUINTPTR   MapAddr = pMap->Core.Key;
     1334                    RTDBGSEGIDX iMapSeg = pMap->iSeg;
     1335
     1336                    RTDBGAS_UNLOCK_READ(pDbgAs);
     1337                    rtDbgAsAdjustSymbolValue(pSymbol, hDbgMod, MapAddr, iMapSeg);
     1338                    return true;
     1339                }
     1340            }
     1341        }
     1342    }
     1343    /* else: Unmapped while we were searching. */
     1344
     1345    RTDBGAS_UNLOCK_READ(pDbgAs);
     1346    return false;
     1347}
     1348
     1349
     1350/**
    11911351 * Query a symbol by name.
    11921352 *
     
    12191379    {
    12201380        int rc = RTDbgModSymbolByName(paModules[i], pszSymbol, pSymbol);
    1221         RTDbgModRelease(paModules[i]);
    12221381        if (RT_SUCCESS(rc))
    12231382        {
    1224             for (i = i + 1; i < cModules; i++)
    1225                 RTDbgModRelease(paModules[i]);
    1226             RTMemTmpFree(paModules);
    1227             return rc;
     1383            if (rtDbgAsFindMappingAndAdjustSymbolValue(pDbgAs, paModules[i], pSymbol))
     1384            {
     1385                for (; i < cModules; i++)
     1386                    RTDbgModRelease(paModules[i]);
     1387                RTMemTmpFree(paModules);
     1388                return rc;
     1389            }
    12281390        }
     1391        RTDbgModRelease(paModules[i]);
    12291392    }
    12301393
     
    12671430    {
    12681431        int rc = RTDbgModSymbolByNameA(paModules[i], pszSymbol, ppSymbol);
    1269         RTDbgModRelease(paModules[i]);
    12701432        if (RT_SUCCESS(rc))
    12711433        {
    1272             for (i = i + 1; i < cModules; i++)
    1273                 RTDbgModRelease(paModules[i]);
    1274             RTMemTmpFree(paModules);
    1275             return rc;
     1434            if (rtDbgAsFindMappingAndAdjustSymbolValue(pDbgAs, paModules[i], *ppSymbol))
     1435            {
     1436                for (; i < cModules; i++)
     1437                    RTDbgModRelease(paModules[i]);
     1438                RTMemTmpFree(paModules);
     1439                return rc;
     1440            }
     1441
     1442            RTDbgSymbolFree(*ppSymbol);
     1443            *ppSymbol = NULL;
    12761444        }
     1445        RTDbgModRelease(paModules[i]);
    12771446    }
    12781447
    12791448    RTMemTmpFree(paModules);
    12801449    return VERR_SYMBOL_NOT_FOUND;
     1450}
     1451
     1452
     1453/**
     1454 * Adds a line number to a module in the address space.
     1455 *
     1456 * @returns IPRT status code. See RTDbgModSymbolAdd for more specific ones.
     1457 * @retval  VERR_INVALID_HANDLE if hDbgAs is invalid.
     1458 * @retval  VERR_NOT_FOUND if no module was found at the specified address.
     1459 * @retval  VERR_NOT_SUPPORTED if the module interpret doesn't support adding
     1460 *          custom symbols.
     1461 *
     1462 * @param   hDbgAs          The address space handle.
     1463 * @param   pszFile         The file name.
     1464 * @param   uLineNo         The line number.
     1465 * @param   Addr            The address of the symbol.
     1466 */
     1467RTDECL(int) RTDbgAsLineAdd(RTDBGAS hDbgAs, const char *pszFile, uint32_t uLineNo, RTUINTPTR Addr)
     1468{
     1469    /*
     1470    * Validate input and resolve the address.
     1471     */
     1472    PRTDBGASINT pDbgAs = hDbgAs;
     1473    RTDBGAS_VALID_RETURN_RC(pDbgAs, VERR_INVALID_HANDLE);
     1474
     1475    RTDBGSEGIDX iSeg;
     1476    RTUINTPTR offSeg;
     1477    RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, NULL);
     1478    if (hMod == NIL_RTDBGMOD)
     1479        return VERR_NOT_FOUND;
     1480
     1481    /*
     1482     * Forward the call.
     1483     */
     1484    int rc = RTDbgModLineAdd(hMod, pszFile, uLineNo, iSeg, offSeg);
     1485    RTDbgModRelease(hMod);
     1486    return rc;
    12811487}
    12821488
     
    13041510
    13051511    RTDBGSEGIDX iSeg;
    1306     RTUINTPTR offSeg;
    1307     RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg);
     1512    RTUINTPTR   offSeg;
     1513    RTUINTPTR   MapAddr;
     1514    RTDBGMOD    hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, &MapAddr);
    13081515    if (hMod == NIL_RTDBGMOD)
    13091516        return VERR_NOT_FOUND;
     
    13131520     */
    13141521    int rc = RTDbgModLineByAddr(hMod, iSeg, offSeg, poffDisp, pLine);
     1522    if (RT_SUCCESS(rc))
     1523        rtDbgAsAdjustLineAddress(pLine, hMod, MapAddr, iSeg);
    13151524    RTDbgModRelease(hMod);
    13161525    return rc;
     
    13411550
    13421551    RTDBGSEGIDX iSeg;
    1343     RTUINTPTR offSeg;
    1344     RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg);
     1552    RTUINTPTR   offSeg;
     1553    RTUINTPTR   MapAddr;
     1554    RTDBGMOD    hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, &MapAddr);
    13451555    if (hMod == NIL_RTDBGMOD)
    13461556        return VERR_NOT_FOUND;
     
    13501560     */
    13511561    int rc = RTDbgModLineByAddrA(hMod, iSeg, offSeg, poffDisp, ppLine);
     1562    if (RT_SUCCESS(rc))
     1563        rtDbgAsAdjustLineAddress(*ppLine, hMod, MapAddr, iSeg);
    13521564    RTDbgModRelease(hMod);
    13531565    return rc;
  • trunk/src/VBox/Runtime/common/dbg/dbgmod.cpp

    r20739 r20740  
    375375}
    376376
     377RTDECL(RTUINTPTR)   RTDbgModSegmentRva(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg)
     378{
     379    return 0;
     380}
     381
    377382RTDECL(RTDBGSEGIDX) RTDbgModSegmentCount(RTDBGMOD hDbgMod)
    378383{
     
    380385}
    381386
    382 RTDECL(int)         RTDbgModSymbolAdd(RTDBGMOD hDbgMod, const char *pszSymbol, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t cb)
    383 {
    384     return VERR_NOT_IMPLEMENTED;
    385 }
     387
     388/**
     389 * Adds a line number to the module.
     390 *
     391 * @returns IPRT status code.
     392 * @retval  VERR_INVALID_HANDLE if hDbgMod is invalid.
     393 * @retval  VERR_NOT_SUPPORTED if the module interpret doesn't support adding
     394 *          custom symbols.
     395 * @retval  VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE
     396 * @retval  VERR_DBG_INVALID_RVA
     397 * @retval  VERR_DBG_INVALID_SEGMENT_INDEX
     398 * @retval  VERR_DBG_INVALID_SEGMENT_OFFSET
     399 * @retval  VERR_INVALID_PARAMETER
     400 *
     401 * @param   hDbgMod         The module handle.
     402 * @param   pszSymbol       The symbol name.
     403 * @param   iSeg            The segment index.
     404 * @param   off             The segment offset.
     405 * @param   cb              The size of the symbol.
     406 * @param   fFlags          Symbol flags.
     407 */
     408RTDECL(int) RTDbgModSymbolAdd(RTDBGMOD hDbgMod, const char *pszSymbol, RTDBGSEGIDX iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags)
     409{
     410    /*
     411     * Validate input.
     412     */
     413    PRTDBGMODINT pDbgMod = hDbgMod;
     414    RTDBGMOD_VALID_RETURN_RC(pDbgMod, VERR_INVALID_HANDLE);
     415    AssertPtr(pszSymbol);
     416    size_t cchSymbol = strlen(pszSymbol);
     417    AssertReturn(cchSymbol, VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE);
     418    AssertReturn(cchSymbol < RTDBG_SYMBOL_NAME_LENGTH, VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE);
     419    AssertMsgReturn(   iSeg <= RTDBGSEGIDX_LAST
     420                    || (    iSeg >= RTDBGSEGIDX_SPECIAL_FIRST
     421                        &&  iSeg <= RTDBGSEGIDX_SPECIAL_LAST),
     422                    ("%#x\n", iSeg),
     423                    VERR_DBG_INVALID_SEGMENT_INDEX);
     424    AssertReturn(!fFlags, VERR_INVALID_PARAMETER); /* currently reserved. */
     425
     426    RTDBGMOD_LOCK(pDbgMod);
     427
     428    /*
     429     * Convert RVAs.
     430     */
     431    if (iSeg == RTDBGSEGIDX_RVA)
     432    {
     433        iSeg = pDbgMod->pDbgVt->pfnRvaToSegOff(pDbgMod, off, &off);
     434        if (iSeg == NIL_RTDBGSEGIDX)
     435        {
     436            RTDBGMOD_UNLOCK(pDbgMod);
     437            return VERR_DBG_INVALID_RVA;
     438        }
     439    }
     440
     441    /*
     442     * Get down to business.
     443     */
     444    int rc = pDbgMod->pDbgVt->pfnSymbolAdd(pDbgMod, pszSymbol, cchSymbol, iSeg, off, cb, fFlags);
     445
     446    RTDBGMOD_UNLOCK(pDbgMod);
     447    return rc;
     448}
     449
    386450
    387451RTDECL(uint32_t)    RTDbgModSymbolCount(RTDBGMOD hDbgMod)
     
    416480
    417481
     482/**
     483 * Adds a line number to the module.
     484 *
     485 * @returns IPRT status code.
     486 * @retval  VERR_INVALID_HANDLE if hDbgMod is invalid.
     487 * @retval  VERR_NOT_SUPPORTED if the module interpret doesn't support adding
     488 *          custom symbols.
     489 * @retval  VERR_DBG_FILE_NAME_OUT_OF_RANGE
     490 * @retval  VERR_DBG_INVALID_RVA
     491 * @retval  VERR_DBG_INVALID_SEGMENT_INDEX
     492 * @retval  VERR_DBG_INVALID_SEGMENT_OFFSET
     493 * @retval  VERR_INVALID_PARAMETER
     494 *
     495 * @param   hDbgMod         The module handle.
     496 * @param   pszFile         The file name.
     497 * @param   uLineNo         The line number.
     498 * @param   iSeg            The segment index.
     499 * @param   off             The segment offset.
     500 */
     501RTDECL(int) RTDbgModLineAdd(RTDBGMOD hDbgMod, const char *pszFile, uint32_t uLineNo, RTDBGSEGIDX iSeg, RTUINTPTR off)
     502{
     503    /*
     504     * Validate input.
     505     */
     506    PRTDBGMODINT pDbgMod = hDbgMod;
     507    RTDBGMOD_VALID_RETURN_RC(pDbgMod, VERR_INVALID_HANDLE);
     508    AssertPtr(pszFile);
     509    size_t cchFile = strlen(pszFile);
     510    AssertReturn(cchFile, VERR_DBG_FILE_NAME_OUT_OF_RANGE);
     511    AssertReturn(cchFile < RTDBG_FILE_NAME_LENGTH, VERR_DBG_FILE_NAME_OUT_OF_RANGE);
     512    AssertMsgReturn(   iSeg <= RTDBGSEGIDX_LAST
     513                    || iSeg == RTDBGSEGIDX_RVA,
     514                    ("%#x\n", iSeg),
     515                    VERR_DBG_INVALID_SEGMENT_INDEX);
     516    AssertReturn(uLineNo > 0 && uLineNo < UINT32_MAX, VERR_INVALID_PARAMETER);
     517
     518    RTDBGMOD_LOCK(pDbgMod);
     519
     520    /*
     521     * Convert RVAs.
     522     */
     523    if (iSeg == RTDBGSEGIDX_RVA)
     524    {
     525        iSeg = pDbgMod->pDbgVt->pfnRvaToSegOff(pDbgMod, off, &off);
     526        if (iSeg == NIL_RTDBGSEGIDX)
     527        {
     528            RTDBGMOD_UNLOCK(pDbgMod);
     529            return VERR_DBG_INVALID_RVA;
     530        }
     531    }
     532
     533    /*
     534     * Get down to business.
     535     */
     536    int rc = pDbgMod->pDbgVt->pfnLineAdd(pDbgMod, pszFile, cchFile, uLineNo, iSeg, off);
     537
     538    RTDBGMOD_UNLOCK(pDbgMod);
     539    return rc;
     540}
     541
     542
    418543RTDECL(int)         RTDbgModLineByAddr(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTINTPTR poffDisp, PRTDBGLINE pLine)
    419544{
  • trunk/src/VBox/Runtime/common/dbg/dbgmodcontainer.cpp

    r20739 r20740  
    2525    /** The name space core. */
    2626    RTSTRSPACECORE              NameCore;
    27     /** The segent offset. */
    28     RTUINTPTR                   off;
    2927    /** The segment index. */
    3028    RTDBGSEGIDX                 iSeg;
     29    /** The symbol flags. */
     30    uint32_t                    fFlags;
     31    /** The symbol size.
     32     * This may be zero while the range in AddrCore indicates 0. */
     33    RTUINTPTR                   cb;
    3134} RTDBGMODCONTAINERSYMBOL;
    3235/** Pointer to a symbol entry in the debug info container. */
    3336typedef RTDBGMODCONTAINERSYMBOL *PRTDBGMODCONTAINERSYMBOL;
     37/** Pointer to a const symbol entry in the debug info container. */
     38typedef RTDBGMODCONTAINERSYMBOL const *PCRTDBGMODCONTAINERSYMBOL;
     39
     40/**
     41 * Line number entry.
     42 */
     43typedef struct RTDBGMODCONTAINERLINE
     44{
     45    /** The address core.
     46     * The Key is the address of the line number. */
     47    AVLUINTPTRNODECORE  AddrCore;
     48    /** Pointer to the file name (in string cache). */
     49    const char         *pszFile;
     50    /** The line number. */
     51    uint32_t            uLineNo;
     52} RTDBGMODCONTAINERLINE;
     53/** Pointer to a line number entry. */
     54typedef RTDBGMODCONTAINERLINE *PRTDBGMODCONTAINERLINE;
     55/** Pointer to const a line number entry. */
     56typedef RTDBGMODCONTAINERLINE const *PCRTDBGMODCONTAINERLINE;
    3457
    3558/**
     
    3861typedef struct RTDBGMODCONTAINERSEGMENT
    3962{
     63    /** The symbol address space tree. */
     64    AVLRUINTPTRTREE             SymAddrTree;
     65    /** The line number address space tree. */
     66    AVLUINTPTRTREE              LineAddrTree;
    4067    /** The segment offset. */
    4168    RTUINTPTR                   off;
     
    4774/** Pointer to a segment entry in the debug info container. */
    4875typedef RTDBGMODCONTAINERSEGMENT *PRTDBGMODCONTAINERSEGMENT;
     76/** Pointer to a const segment entry in the debug info container. */
     77typedef RTDBGMODCONTAINERSEGMENT const *PCRTDBGMODCONTAINERSEGMENT;
    4978
    5079/**
     
    5584    /** The name space. */
    5685    RTSTRSPACE                  Names;
    57     /** The address space tree. */
    58     AVLRUINTPTRTREE             Addresses;
     86    /** Tree containing any absolute addresses. */
     87    AVLRUINTPTRTREE             AbsAddrTree;
    5988    /** Segment table. */
    6089    PRTDBGMODCONTAINERSEGMENT   paSegs;
     
    6897
    6998
     99/**
     100 * Fills in a RTDBGSYMBOL structure.
     101 *
     102 * @returns VINF_SUCCESS.
     103 * @param   pMySym          Our internal symbol representation.
     104 * @param   pExtSym         The external symbol representation.
     105 */
     106DECLINLINE(int) rtDbgModContainerReturnSymbol(PCRTDBGMODCONTAINERSYMBOL pMySym, PRTDBGSYMBOL pExtSym)
     107{
     108    pExtSym->Value  = pMySym->AddrCore.Key;
     109    pExtSym->offSeg = pMySym->AddrCore.Key;
     110    pExtSym->iSeg   = pMySym->iSeg;
     111    pExtSym->fFlags = pMySym->fFlags;
     112    pExtSym->cb     = pMySym->cb;
     113    Assert(pMySym->NameCore.cchString < sizeof(pExtSym->szName));
     114    memcpy(pExtSym->szName, pMySym->NameCore.pszString, pMySym->NameCore.cchString + 1);
     115    return VINF_SUCCESS;
     116}
     117
     118
    70119
    71120/** @copydoc RTDBGMODVTDBG::pfnLineByAddr */
    72 static DECLCALLBACK(int) rtDbgModContainer_LineByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTGCUINTPTR off, PRTGCINTPTR poffDisp, PRTDBGLINE pLine)
    73 {
    74     /** @todo Make it possible to add line numbers. */
    75     return VERR_DBG_NO_LINE_NUMBERS;
     121static DECLCALLBACK(int) rtDbgModContainer_LineByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off,
     122                                                      PRTINTPTR poffDisp, PRTDBGLINE pLine)
     123{
     124    PRTDBGMODCONTAINER pThis = (PRTDBGMODCONTAINER)pMod->pvDbgPriv;
     125
     126    /*
     127     * Validate the input address.
     128     */
     129    AssertMsgReturn(iSeg < pThis->cSegs,
     130                    ("iSeg=%#x cSegs=%#x\n", pThis->cSegs),
     131                    VERR_DBG_INVALID_SEGMENT_INDEX);
     132    AssertMsgReturn(pThis->paSegs[iSeg].cb < off,
     133                    ("off=%RTptr cbSeg=%RTptr\n", off, pThis->paSegs[iSeg].cb),
     134                    VERR_DBG_INVALID_SEGMENT_OFFSET);
     135
     136    /*
     137     * Lookup the nearest line number with an address less or equal to the specified address.
     138     */
     139    PAVLUINTPTRNODECORE pAvlCore = RTAvlUIntPtrGetBestFit(&pThis->paSegs[iSeg].LineAddrTree, off, false /*fAbove*/);
     140    if (!pAvlCore)
     141        return VERR_SYMBOL_NOT_FOUND;
     142    PCRTDBGMODCONTAINERLINE pMyLine = RT_FROM_MEMBER(pAvlCore, RTDBGMODCONTAINERLINE const, AddrCore);
     143    if (poffDisp)
     144        *poffDisp = off - pMyLine->AddrCore.Key;
     145    pLine->Address = pMyLine->AddrCore.Key;
     146    pLine->offSeg  = pMyLine->AddrCore.Key;
     147    pLine->iSeg    = iSeg;
     148    pLine->uLineNo = pMyLine->uLineNo;
     149    strcpy(pLine->szFilename, pMyLine->pszFile);
     150    return VINF_SUCCESS;
     151}
     152
     153
     154/** @copydoc RTDBGMODVTDBG::pfnLineAdd */
     155static DECLCALLBACK(int) rtDbgModContainer_LineAdd(PRTDBGMODINT pMod, const char *pszFile, size_t cchFile, uint32_t uLineNo,
     156                                                   uint32_t iSeg, RTUINTPTR off)
     157{
     158    PRTDBGMODCONTAINER pThis = (PRTDBGMODCONTAINER)pMod->pvDbgPriv;
     159
     160    /*
     161     * Validate the input address.
     162     */
     163    AssertMsgReturn(iSeg < pThis->cSegs,          ("iSeg=%#x cSegs=%#x\n", pThis->cSegs),
     164                    VERR_DBG_INVALID_SEGMENT_INDEX);
     165    AssertMsgReturn(pThis->paSegs[iSeg].cb < off, ("off=%RTptr cbSeg=%RTptr\n", off, pThis->paSegs[iSeg].cb),
     166                    VERR_DBG_INVALID_SEGMENT_OFFSET);
     167
     168    /*
     169     * Create a new entry.
     170     */
     171    PRTDBGMODCONTAINERLINE pLine = (PRTDBGMODCONTAINERLINE)RTMemAllocZ(sizeof(*pLine));
     172    if (!pLine)
     173        return VERR_NO_MEMORY;
     174    pLine->AddrCore.Key = off;
     175    pLine->uLineNo = uLineNo;
     176    pLine->pszFile = RTStrCacheEnterN(g_hDbgModStrCache, pszFile, cchFile);
     177    int rc;
     178    if (pLine->pszFile)
     179    {
     180        if (RTAvlUIntPtrInsert(&pThis->paSegs[iSeg].LineAddrTree, &pLine->AddrCore))
     181            return VINF_SUCCESS;
     182
     183        /* bail out */
     184        rc = VERR_DBG_ADDRESS_CONFLICT;
     185        RTStrCacheRelease(g_hDbgModStrCache, pLine->pszFile);
     186    }
     187    else
     188        rc = VERR_NO_MEMORY;
     189    RTMemFree(pLine);
     190    return rc;
    76191}
    77192
    78193
    79194/** @copydoc RTDBGMODVTDBG::pfnSymbolByAddr */
    80 static DECLCALLBACK(int) rtDbgModContainer_SymbolByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTGCUINTPTR off, PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol)
    81 {
    82     return VINF_SUCCESS;
     195static DECLCALLBACK(int) rtDbgModContainer_SymbolByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off,
     196                                                        PRTINTPTR poffDisp, PRTDBGSYMBOL pSymbol)
     197{
     198    PRTDBGMODCONTAINER pThis = (PRTDBGMODCONTAINER)pMod->pvDbgPriv;
     199
     200    /*
     201     * Validate the input address.
     202     */
     203    AssertMsgReturn(    iSeg == RTDBGSEGIDX_ABS
     204                    ||  iSeg < pThis->cSegs,
     205                    ("iSeg=%#x cSegs=%#x\n", pThis->cSegs),
     206                    VERR_DBG_INVALID_SEGMENT_INDEX);
     207    AssertMsgReturn(    iSeg >= RTDBGSEGIDX_SPECIAL_FIRST
     208                    ||  pThis->paSegs[iSeg].cb <= off,
     209                    ("off=%RTptr cbSeg=%RTptr\n", off, pThis->paSegs[iSeg].cb),
     210                    VERR_DBG_INVALID_SEGMENT_OFFSET);
     211
     212    /*
     213     * Lookup the nearest symbol with an address less or equal to the specified address.
     214     */
     215    PAVLRUINTPTRNODECORE pAvlCore = RTAvlrUIntPtrGetBestFit(  iSeg == RTDBGSEGIDX_ABS
     216                                                            ? &pThis->AbsAddrTree
     217                                                            : &pThis->paSegs[iSeg].SymAddrTree,
     218                                                            off,
     219                                                            false /*fAbove*/);
     220    if (!pAvlCore)
     221        return VERR_SYMBOL_NOT_FOUND;
     222    PCRTDBGMODCONTAINERSYMBOL pMySym = RT_FROM_MEMBER(pAvlCore, RTDBGMODCONTAINERSYMBOL const, AddrCore);
     223    if (poffDisp)
     224        *poffDisp = off - pMySym->AddrCore.Key;
     225    return rtDbgModContainerReturnSymbol(pMySym, pSymbol);
    83226}
    84227
     
    87230static DECLCALLBACK(int) rtDbgModContainer_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, PRTDBGSYMBOL pSymbol)
    88231{
    89     return VINF_SUCCESS;
     232    PRTDBGMODCONTAINER pThis = (PRTDBGMODCONTAINER)pMod->pvDbgPriv;
     233
     234    /*
     235     * Look it up in the name space.
     236     */
     237    PRTSTRSPACECORE pStrCore = RTStrSpaceGet(&pThis->Names, pszSymbol);
     238    if (!pStrCore)
     239        return VERR_SYMBOL_NOT_FOUND;
     240    PCRTDBGMODCONTAINERSYMBOL pMySym = RT_FROM_MEMBER(pStrCore, RTDBGMODCONTAINERSYMBOL const, NameCore);
     241    return rtDbgModContainerReturnSymbol(pMySym, pSymbol);
    90242}
    91243
    92244
    93245/** @copydoc RTDBGMODVTDBG::pfnSymbolAdd */
    94 static DECLCALLBACK(int) rtDbgModContainer_SymbolAdd(PRTDBGMODINT pMod, const char *pszSymbol, RTDBGSEGIDX iSeg, RTGCUINTPTR off, uint32_t cbSymbol)
     246static DECLCALLBACK(int) rtDbgModContainer_SymbolAdd(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
     247                                                     RTDBGSEGIDX iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags)
    95248{
    96249    PRTDBGMODCONTAINER pThis = (PRTDBGMODCONTAINER)pMod->pvDbgPriv;
     
    99252     * Address validation. The other arguments have already been validated.
    100253     */
    101     AssertMsgReturn(    (   iSeg >= RTDBGSEGIDX_SPECIAL_FIRST
    102                          && iSeg <= RTDBGSEGIDX_SPECIAL_LAST)
     254    AssertMsgReturn(    iSeg == RTDBGSEGIDX_ABS
    103255                    ||  iSeg < pThis->cSegs,
    104                     ("iSeg=%x cSegs=%x\n", pThis->cSegs),
     256                    ("iSeg=%#x cSegs=%#x\n", pThis->cSegs),
    105257                    VERR_DBG_INVALID_SEGMENT_INDEX);
    106258    AssertMsgReturn(    iSeg >= RTDBGSEGIDX_SPECIAL_FIRST
    107                     ||  pThis->paSegs[iSeg].cb <= off + cbSymbol,
    108                     ("off=%RTptr cbSymbol=%RTptr cbSeg=%RTptr\n", off, cbSymbol, pThis->paSegs[iSeg].cb),
     259                    ||  pThis->paSegs[iSeg].cb <= off + cb,
     260                    ("off=%RTptr cb=%RTptr cbSeg=%RTptr\n", off, cb, pThis->paSegs[iSeg].cb),
    109261                    VERR_DBG_INVALID_SEGMENT_OFFSET);
    110262
     
    116268        return VERR_NO_MEMORY;
    117269
    118 #if 0 /* continue on the workstation */
    119     pSymbol->AddrCore.Key     = iSeg < RTDBGSEGIDX_SPECIAL_FIRST
    120                               ? pThis->paSegs->off + off
    121                               : off;
    122     pSymbol->AddrCore.KeyLast = pSymbol->AddrCore.Key + cbSymbol;
    123     pSymbol->off  = off;
    124     pSymbol->iSeg = iSeg;
     270    pSymbol->AddrCore.Key       = off;
     271    pSymbol->AddrCore.KeyLast   = off + RT_MIN(cb, 1);
     272    pSymbol->iSeg               = iSeg;
     273    pSymbol->cb                 = cb;
     274    pSymbol->fFlags             = fFlags;
    125275    pSymbol->NameCore.pszString = RTStrCacheEnter(g_hDbgModStrCache, pszSymbol);
     276    int rc;
    126277    if (pSymbol->NameCore.pszString)
    127278    {
    128279        if (RTStrSpaceInsert(&pThis->Names, &pSymbol->NameCore))
    129280        {
    130             if (RTStrSpaceInsert(&pThis->Names, &pSymbol->NameCore))
     281            if (RTAvlrUIntPtrInsert(  iSeg == RTDBGSEGIDX_ABS
     282                                    ? &pThis->AbsAddrTree
     283                                    : &pThis->paSegs[iSeg].SymAddrTree,
     284                                    &pSymbol->AddrCore))
     285                return VINF_SUCCESS;
     286
     287            /* bail out */
     288            rc = VERR_DBG_ADDRESS_CONFLICT;
     289            RTStrSpaceRemove(&pThis->Names, pSymbol->NameCore.pszString);
     290        }
     291        else
     292            rc = VERR_DBG_DUPLICATE_SYMBOL;
     293        RTStrCacheRelease(g_hDbgModStrCache, pSymbol->NameCore.pszString);
     294    }
     295    else
     296        rc = VERR_NO_MEMORY;
     297    RTMemFree(pSymbol);
     298    return rc;
     299}
     300
     301
     302/** @copydoc RTDBGMODVTDBG::pfnRvaToSegOff */
     303static DECLCALLBACK(RTDBGSEGIDX) rtDbgModContainer_RvaToSegOff(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg)
     304{
     305    PRTDBGMODCONTAINER          pThis = (PRTDBGMODCONTAINER)pMod->pvDbgPriv;
     306    PCRTDBGMODCONTAINERSEGMENT  paSeg = pThis->paSegs;
     307    uint32_t const              cSegs = pThis->cSegs;
     308    if (cSegs <= 7)
     309    {
     310        /*
     311         * Linear search.
     312         */
     313        for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++)
     314        {
     315            RTUINTPTR offSeg = uRva - paSeg[iSeg].off;
     316            if (offSeg < paSeg[iSeg].cb)
    131317            {
    132 
     318                if (poffSeg)
     319                    *poffSeg = offSeg;
     320                return iSeg;
    133321            }
    134322        }
    135323    }
    136 #endif
    137 int rc = VERR_NOT_IMPLEMENTED;
    138 
    139     return rc;
     324    else
     325    {
     326        /*
     327         * Binary search.
     328         */
     329        uint32_t iFirst = 0;
     330        uint32_t iLast  = cSegs - 1;
     331        for (;;)
     332        {
     333            uint32_t    iSeg   = iFirst + (iFirst - iLast) / 2;
     334            RTUINTPTR   offSeg = uRva - paSeg[iSeg].off;
     335            if (offSeg < paSeg[iSeg].cb)
     336            {
     337                if (poffSeg)
     338                    *poffSeg = offSeg;
     339                return iSeg;
     340            }
     341
     342            /* advance */
     343            if (uRva < paSeg[iSeg].off)
     344            {
     345                /* between iFirst and iSeg. */
     346                if (iSeg == iFirst)
     347                    break;
     348                iLast = iSeg - 1;
     349            }
     350            else
     351            {
     352                /* between iSeg and iLast. */
     353                if (iSeg == iLast)
     354                    break;
     355                iFirst = iSeg + 1;
     356            }
     357        }
     358    }
     359
     360    /* Invalid. */
     361    return NIL_RTDBGSEGIDX;
    140362}
    141363
     
    146368    PRTDBGMODCONTAINERSYMBOL pSym = RT_FROM_MEMBER(pNode, RTDBGMODCONTAINERSYMBOL, AddrCore);
    147369    RTStrCacheRelease(g_hDbgModStrCache, pSym->NameCore.pszString);
     370    pSym->NameCore.pszString = NULL;
    148371    RTMemFree(pSym);
    149372    return 0;
     
    159382     * Destroy the symbols and instance data.
    160383     */
    161     RTAvlrUIntPtrDestroy(&pThis->Addresses, rtDbgModContainer_DestroyTreeNode, NULL);
     384    for (uint32_t iSeg = 0; iSeg < pThis->cSegs; iSeg++)
     385    {
     386        RTAvlrUIntPtrDestroy(&pThis->paSegs[iSeg].SymAddrTree, rtDbgModContainer_DestroyTreeNode, NULL);
     387        RTStrCacheRelease(g_hDbgModStrCache, pThis->paSegs[iSeg].pszName);
     388        pThis->paSegs[iSeg].pszName = NULL;
     389    }
     390    RTAvlrUIntPtrDestroy(&pThis->AbsAddrTree, rtDbgModContainer_DestroyTreeNode, NULL);
    162391    pThis->Names = NULL;
     392
    163393    RTMemFree(pThis->paSegs);
    164394    pThis->paSegs = NULL;
     
    185415    /*.pfnTryOpen = */          rtDbgModContainer_TryOpen,
    186416    /*.pfnClose = */            rtDbgModContainer_Close,
     417    /*.pfnRvaToSegOff = */      rtDbgModContainer_RvaToSegOff,
    187418    /*.pfnSymbolAdd = */        rtDbgModContainer_SymbolAdd,
    188419    /*.pfnSymbolByName = */     rtDbgModContainer_SymbolByName,
    189420    /*.pfnSymbolByAddr = */     rtDbgModContainer_SymbolByAddr,
     421    /*.pfnLineAdd = */          rtDbgModContainer_LineAdd,
    190422    /*.pfnLineByAddr = */       rtDbgModContainer_LineByAddr,
    191423    /*.u32EndMagic = */         RTDBGMODVTDBG_MAGIC
     
    208440
    209441    pThis->Names = NULL;
    210     pThis->Addresses = NULL;
     442    pThis->AbsAddrTree = NULL;
    211443    pThis->paSegs = NULL;
    212444    pThis->cSegs = 0;
  • trunk/src/VBox/Runtime/common/table/avluintptr.cpp

    • Property svn:keywords changed from Id to Author Date Id Revision
    r20739 r20740  
    11/* $Id$ */
    22/** @file
    3  * IPRT - AVL tree, RTUINTPTR, range, unique keys.
     3 * IPRT - AVL tree, RTUINTPTR, unique keys.
    44 */
    55
     
    3939 * AVL configuration.
    4040 */
    41 #define KAVL_FN(a)                  RTAvlrUIntPtr##a
     41#define KAVL_FN(a)                  RTAvlUIntPtr##a
    4242#define KAVL_MAX_STACK              27  /* Up to 2^24 nodes. */
    4343#define KAVL_CHECK_FOR_EQUAL_INSERT 1   /* No duplicate keys! */
    44 #define KAVLNODECORE                AVLRUINTPTRNODECORE
    45 #define PKAVLNODECORE               PAVLRUINTPTRNODECORE
    46 #define PPKAVLNODECORE              PPAVLRUINTPTRNODECORE
     44#define KAVLNODECORE                AVLUINTPTRNODECORE
     45#define PKAVLNODECORE               PAVLUINTPTRNODECORE
     46#define PPKAVLNODECORE              PPAVLUINTPTRNODECORE
    4747#define KAVLKEY                     RTUINTPTR
    4848#define PKAVLKEY                    PRTUINTPTR
    49 #define KAVLENUMDATA                AVLRUINTPTRENUMDATA
    50 #define PKAVLENUMDATA               PAVLRUINTPTRENUMDATA
    51 #define PKAVLCALLBACK               PAVLRUINTPTRCALLBACK
    52 #define KAVL_RANGE                  1
     49#define KAVLENUMDATA                AVLUINTPTRENUMDATA
     50#define PKAVLENUMDATA               PAVLUINTPTRENUMDATA
     51#define PKAVLCALLBACK               PAVLUINTPTRCALLBACK
    5352
    5453
     
    5958#define KAVL_E( key1, key2)         ( (RTGCUINTPTR)(key1) == (RTGCUINTPTR)(key2) )
    6059#define KAVL_NE(key1, key2)         ( (RTGCUINTPTR)(key1) != (RTGCUINTPTR)(key2) )
    61 #define KAVL_R_IS_IDENTICAL(key1B, key2B, key1E, key2E)     ( (RTGCUINTPTR)(key1B) == (RTGCUINTPTR)(key2B) && (RTGCUINTPTR)(key1E) == (RTGCUINTPTR)(key2E) )
    62 #define KAVL_R_IS_INTERSECTING(key1B, key2B, key1E, key2E)  ( (RTGCUINTPTR)(key1B) <= (RTGCUINTPTR)(key2E) && (RTGCUINTPTR)(key1E) >= (RTGCUINTPTR)(key2B) )
    63 #define KAVL_R_IS_IN_RANGE(key1B, key1E, key2)              KAVL_R_IS_INTERSECTING(key1B, key2, key1E, key2)
    64 
    6560
    6661
     
    7974#include "avl_Base.cpp.h"
    8075#include "avl_Get.cpp.h"
    81 #include "avl_Range.cpp.h"
    8276#include "avl_DoWithAll.cpp.h"
    8377#include "avl_Destroy.cpp.h"
  • trunk/src/VBox/Runtime/include/internal/dbgmod.h

    r20739 r20740  
    144144
    145145    /**
     146     * Converts an image relative virtual address address to a segmented address.
     147     *
     148     * @returns Segment index on success, NIL_RTDBGSEGIDX on failure.
     149     * @param   pMod        Pointer to the module structure.
     150     * @param   uRva        The image relative address to convert.
     151     * @param   poffSeg     Where to return the segment offset. Optional.
     152     */
     153    DECLCALLBACKMEMBER(RTDBGSEGIDX, pfnRvaToSegOff)(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg);
     154
     155    /**
    146156     * Adds a symbol to the module (optional).
    147157     *
    148      * This method is used to implement DBGFR3SymbolAdd.
    149      *
    150158     * @returns VBox status code.
    151159     * @retval  VERR_NOT_SUPPORTED if the interpreter doesn't support this feature.
     
    153161     * @param   pMod        Pointer to the module structure.
    154162     * @param   pszSymbol   The symbol name.
     163     * @param   cchSymbol   The length for the symbol name.
    155164     * @param   iSeg        The segment number (0-based). RTDBGMOD_SEG_RVA can be used.
    156165     * @param   off         The offset into the segment.
    157      * @param   cbSymbol    The area covered by the symbol. 0 is fine.
    158      */
    159     DECLCALLBACKMEMBER(int, pfnSymbolAdd)(PRTDBGMODINT pMod, const char *pszSymbol, uint32_t iSeg, RTGCUINTPTR off, RTUINT cbSymbol);
     166     * @param   cb          The area covered by the symbol. 0 is fine.
     167     */
     168    DECLCALLBACKMEMBER(int, pfnSymbolAdd)(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
     169                                          uint32_t iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags);
    160170
    161171    /**
     
    186196     *
    187197     * @param   pMod        Pointer to the module structure.
    188      * @param   iSeg        The segment number (0-based). RTDBGMOD_SEG_RVA can be used.
     198     * @param   iSeg        The segment number (0-based) or RTDBGSEGIDX_ABS.
    189199     * @param   off         The offset into the segment.
    190200     * @param   poffDisp    Where to store the distance between the specified address
     
    192202     * @param   pSymbol     Where to store the symbol information.
    193203     */
    194     DECLCALLBACKMEMBER(int, pfnSymbolByAddr)(PRTDBGMODINT pMod, uint32_t iSeg, RTGCUINTPTR off, PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol);
     204    DECLCALLBACKMEMBER(int, pfnSymbolByAddr)(PRTDBGMODINT pMod, uint32_t iSeg, RTUINTPTR off, PRTINTPTR poffDisp, PRTDBGSYMBOL pSymbol);
     205
     206    /**
     207     * Adds a line number to the module (optional).
     208     *
     209     * @returns VBox status code.
     210     * @retval  VERR_NOT_SUPPORTED if the interpreter doesn't support this feature.
     211     *
     212     * @param   pMod        Pointer to the module structure.
     213     * @param   pszFile     The filename.
     214     * @param   cchFile     The length of the filename.
     215     * @param   iSeg        The segment number (0-based).
     216     * @param   off         The offset into the segment.
     217     */
     218    DECLCALLBACKMEMBER(int, pfnLineAdd)(PRTDBGMODINT pMod, const char *pszFile, size_t cchFile, uint32_t uLineNo, uint32_t iSeg, RTUINTPTR off);
    195219
    196220    /**
     
    203227     *
    204228     * @param   pMod        Pointer to the module structure.
    205      * @param   iSeg        The segment number (0-based). RTDBGMOD_SEG_RVA can be used.
     229     * @param   iSeg        The segment number (0-based) or RTDBGSEGIDX_ABS.
    206230     * @param   off         The offset into the segment.
    207231     * @param   poffDisp    Where to store the distance between the specified address
     
    209233     * @param   pLine       Where to store the information about the closest line number.
    210234     */
    211     DECLCALLBACKMEMBER(int, pfnLineByAddr)(PRTDBGMODINT pMod, uint32_t iSeg, RTGCUINTPTR off, PRTGCINTPTR poffDisp, PRTDBGLINE pLine);
     235    DECLCALLBACKMEMBER(int, pfnLineByAddr)(PRTDBGMODINT pMod, uint32_t iSeg, RTUINTPTR off, PRTINTPTR poffDisp, PRTDBGLINE pLine);
    212236
    213237    /** For catching initialization errors (RTDBGMODVTDBG_MAGIC). */
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