VirtualBox

Ignore:
Timestamp:
Jun 21, 2009 2:09:28 AM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
48856
Message:

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

Location:
trunk/src/VBox/Runtime/common/dbg
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • 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;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette