Changeset 20740 in vbox for trunk/src/VBox/Runtime/common/dbg
- Timestamp:
- Jun 21, 2009 2:09:28 AM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 48856
- 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 62 62 AVLPVNODECORE Core; 63 63 /** Pointer to the first mapping of the module or a segment within it. */ 64 RTDBGASMAP *pMapHead;64 PRTDBGASMAP pMapHead; 65 65 /** Pointer to the next module with an identical name. */ 66 66 PRTDBGASMOD pNextName; … … 1029 1029 * @param piSeg where to return the segment index. 1030 1030 * @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 */ 1033 DECLINLINE(RTDBGMOD) rtDbgAsModuleByAddr(PRTDBGASINT pDbgAs, RTUINTPTR Addr, PRTDBGSEGIDX piSeg, PRTUINTPTR poffSeg, PRTUINTPTR pMapAddr) 1033 1034 { 1034 1035 RTDBGMOD hMod = NIL_RTDBGMOD; … … 1040 1041 hMod = (RTDBGMOD)pMap->pMod->Core.Key; 1041 1042 RTDbgModRetain(hMod); 1042 *piSeg = pMap->iSeg ;1043 *piSeg = pMap->iSeg != NIL_RTDBGSEGIDX ? pMap->iSeg : RTDBGSEGIDX_RVA; 1043 1044 *poffSeg = Addr - pMap->Core.Key; 1045 if (pMapAddr) 1046 *pMapAddr = pMap->Core.Key; 1044 1047 } 1045 1048 RTDBGAS_UNLOCK_READ(pDbgAs); 1046 1049 1047 1050 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 */ 1064 DECLINLINE(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 */ 1110 DECLINLINE(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 */ 1127 DECLINLINE(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); 1048 1132 } 1049 1133 … … 1055 1139 * @retval VERR_INVALID_HANDLE if hDbgAs is invalid. 1056 1140 * @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. 1057 1143 * 1058 1144 * @param hDbgAs The address space handle. … … 1060 1146 * @param Addr The address of the symbol. 1061 1147 * @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 */ 1150 RTDECL(int) RTDbgAsSymbolAdd(RTDBGAS hDbgAs, const char *pszSymbol, RTUINTPTR Addr, RTUINTPTR cb, uint32_t fFlags) 1064 1151 { 1065 1152 /* … … 1071 1158 RTDBGSEGIDX iSeg; 1072 1159 RTUINTPTR offSeg; 1073 RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg );1160 RTDBGMOD hMod = rtDbgAsModuleByAddr(pDbgAs, Addr, &iSeg, &offSeg, NULL); 1074 1161 if (hMod == NIL_RTDBGMOD) 1075 1162 return VERR_NOT_FOUND; … … 1078 1165 * Forward the call. 1079 1166 */ 1080 int rc = RTDbgModSymbolAdd(hMod, pszSymbol, iSeg, offSeg, cb );1167 int rc = RTDbgModSymbolAdd(hMod, pszSymbol, iSeg, offSeg, cb, fFlags); 1081 1168 RTDbgModRelease(hMod); 1082 1169 return rc; … … 1106 1193 1107 1194 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); 1110 1198 if (hMod == NIL_RTDBGMOD) 1111 1199 return VERR_NOT_FOUND; … … 1115 1203 */ 1116 1204 int rc = RTDbgModSymbolByAddr(hMod, iSeg, offSeg, poffDisp, pSymbol); 1205 if (RT_SUCCESS(rc)) 1206 rtDbgAsAdjustSymbolValue(pSymbol, hMod, MapAddr, iSeg); 1117 1207 RTDbgModRelease(hMod); 1118 1208 return rc; … … 1143 1233 1144 1234 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); 1147 1238 if (hMod == NIL_RTDBGMOD) 1148 1239 return VERR_NOT_FOUND; … … 1152 1243 */ 1153 1244 int rc = RTDbgModSymbolByAddrA(hMod, iSeg, offSeg, poffDisp, ppSymbol); 1245 if (RT_SUCCESS(rc)) 1246 rtDbgAsAdjustSymbolValue(*ppSymbol, hMod, MapAddr, iSeg); 1154 1247 RTDbgModRelease(hMod); 1155 1248 return rc; … … 1189 1282 1190 1283 /** 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 */ 1292 static 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 /** 1191 1351 * Query a symbol by name. 1192 1352 * … … 1219 1379 { 1220 1380 int rc = RTDbgModSymbolByName(paModules[i], pszSymbol, pSymbol); 1221 RTDbgModRelease(paModules[i]);1222 1381 if (RT_SUCCESS(rc)) 1223 1382 { 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 } 1228 1390 } 1391 RTDbgModRelease(paModules[i]); 1229 1392 } 1230 1393 … … 1267 1430 { 1268 1431 int rc = RTDbgModSymbolByNameA(paModules[i], pszSymbol, ppSymbol); 1269 RTDbgModRelease(paModules[i]);1270 1432 if (RT_SUCCESS(rc)) 1271 1433 { 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; 1276 1444 } 1445 RTDbgModRelease(paModules[i]); 1277 1446 } 1278 1447 1279 1448 RTMemTmpFree(paModules); 1280 1449 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 */ 1467 RTDECL(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; 1281 1487 } 1282 1488 … … 1304 1510 1305 1511 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); 1308 1515 if (hMod == NIL_RTDBGMOD) 1309 1516 return VERR_NOT_FOUND; … … 1313 1520 */ 1314 1521 int rc = RTDbgModLineByAddr(hMod, iSeg, offSeg, poffDisp, pLine); 1522 if (RT_SUCCESS(rc)) 1523 rtDbgAsAdjustLineAddress(pLine, hMod, MapAddr, iSeg); 1315 1524 RTDbgModRelease(hMod); 1316 1525 return rc; … … 1341 1550 1342 1551 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); 1345 1555 if (hMod == NIL_RTDBGMOD) 1346 1556 return VERR_NOT_FOUND; … … 1350 1560 */ 1351 1561 int rc = RTDbgModLineByAddrA(hMod, iSeg, offSeg, poffDisp, ppLine); 1562 if (RT_SUCCESS(rc)) 1563 rtDbgAsAdjustLineAddress(*ppLine, hMod, MapAddr, iSeg); 1352 1564 RTDbgModRelease(hMod); 1353 1565 return rc; -
trunk/src/VBox/Runtime/common/dbg/dbgmod.cpp
r20739 r20740 375 375 } 376 376 377 RTDECL(RTUINTPTR) RTDbgModSegmentRva(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg) 378 { 379 return 0; 380 } 381 377 382 RTDECL(RTDBGSEGIDX) RTDbgModSegmentCount(RTDBGMOD hDbgMod) 378 383 { … … 380 385 } 381 386 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 */ 408 RTDECL(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 386 450 387 451 RTDECL(uint32_t) RTDbgModSymbolCount(RTDBGMOD hDbgMod) … … 416 480 417 481 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 */ 501 RTDECL(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 418 543 RTDECL(int) RTDbgModLineByAddr(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTINTPTR poffDisp, PRTDBGLINE pLine) 419 544 { -
trunk/src/VBox/Runtime/common/dbg/dbgmodcontainer.cpp
r20739 r20740 25 25 /** The name space core. */ 26 26 RTSTRSPACECORE NameCore; 27 /** The segent offset. */28 RTUINTPTR off;29 27 /** The segment index. */ 30 28 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; 31 34 } RTDBGMODCONTAINERSYMBOL; 32 35 /** Pointer to a symbol entry in the debug info container. */ 33 36 typedef RTDBGMODCONTAINERSYMBOL *PRTDBGMODCONTAINERSYMBOL; 37 /** Pointer to a const symbol entry in the debug info container. */ 38 typedef RTDBGMODCONTAINERSYMBOL const *PCRTDBGMODCONTAINERSYMBOL; 39 40 /** 41 * Line number entry. 42 */ 43 typedef 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. */ 54 typedef RTDBGMODCONTAINERLINE *PRTDBGMODCONTAINERLINE; 55 /** Pointer to const a line number entry. */ 56 typedef RTDBGMODCONTAINERLINE const *PCRTDBGMODCONTAINERLINE; 34 57 35 58 /** … … 38 61 typedef struct RTDBGMODCONTAINERSEGMENT 39 62 { 63 /** The symbol address space tree. */ 64 AVLRUINTPTRTREE SymAddrTree; 65 /** The line number address space tree. */ 66 AVLUINTPTRTREE LineAddrTree; 40 67 /** The segment offset. */ 41 68 RTUINTPTR off; … … 47 74 /** Pointer to a segment entry in the debug info container. */ 48 75 typedef RTDBGMODCONTAINERSEGMENT *PRTDBGMODCONTAINERSEGMENT; 76 /** Pointer to a const segment entry in the debug info container. */ 77 typedef RTDBGMODCONTAINERSEGMENT const *PCRTDBGMODCONTAINERSEGMENT; 49 78 50 79 /** … … 55 84 /** The name space. */ 56 85 RTSTRSPACE Names; 57 /** T he address space tree. */58 AVLRUINTPTRTREE A ddresses;86 /** Tree containing any absolute addresses. */ 87 AVLRUINTPTRTREE AbsAddrTree; 59 88 /** Segment table. */ 60 89 PRTDBGMODCONTAINERSEGMENT paSegs; … … 68 97 69 98 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 */ 106 DECLINLINE(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 70 119 71 120 /** @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; 121 static 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 */ 155 static 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; 76 191 } 77 192 78 193 79 194 /** @copydoc RTDBGMODVTDBG::pfnSymbolByAddr */ 80 static DECLCALLBACK(int) rtDbgModContainer_SymbolByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTGCUINTPTR off, PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol) 81 { 82 return VINF_SUCCESS; 195 static 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); 83 226 } 84 227 … … 87 230 static DECLCALLBACK(int) rtDbgModContainer_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, PRTDBGSYMBOL pSymbol) 88 231 { 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); 90 242 } 91 243 92 244 93 245 /** @copydoc RTDBGMODVTDBG::pfnSymbolAdd */ 94 static DECLCALLBACK(int) rtDbgModContainer_SymbolAdd(PRTDBGMODINT pMod, const char *pszSymbol, RTDBGSEGIDX iSeg, RTGCUINTPTR off, uint32_t cbSymbol) 246 static DECLCALLBACK(int) rtDbgModContainer_SymbolAdd(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol, 247 RTDBGSEGIDX iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags) 95 248 { 96 249 PRTDBGMODCONTAINER pThis = (PRTDBGMODCONTAINER)pMod->pvDbgPriv; … … 99 252 * Address validation. The other arguments have already been validated. 100 253 */ 101 AssertMsgReturn( ( iSeg >= RTDBGSEGIDX_SPECIAL_FIRST 102 && iSeg <= RTDBGSEGIDX_SPECIAL_LAST) 254 AssertMsgReturn( iSeg == RTDBGSEGIDX_ABS 103 255 || iSeg < pThis->cSegs, 104 ("iSeg=% x cSegs=%x\n", pThis->cSegs),256 ("iSeg=%#x cSegs=%#x\n", pThis->cSegs), 105 257 VERR_DBG_INVALID_SEGMENT_INDEX); 106 258 AssertMsgReturn( iSeg >= RTDBGSEGIDX_SPECIAL_FIRST 107 || pThis->paSegs[iSeg].cb <= off + cb Symbol,108 ("off=%RTptr cb Symbol=%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), 109 261 VERR_DBG_INVALID_SEGMENT_OFFSET); 110 262 … … 116 268 return VERR_NO_MEMORY; 117 269 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; 125 275 pSymbol->NameCore.pszString = RTStrCacheEnter(g_hDbgModStrCache, pszSymbol); 276 int rc; 126 277 if (pSymbol->NameCore.pszString) 127 278 { 128 279 if (RTStrSpaceInsert(&pThis->Names, &pSymbol->NameCore)) 129 280 { 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 */ 303 static 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) 131 317 { 132 318 if (poffSeg) 319 *poffSeg = offSeg; 320 return iSeg; 133 321 } 134 322 } 135 323 } 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; 140 362 } 141 363 … … 146 368 PRTDBGMODCONTAINERSYMBOL pSym = RT_FROM_MEMBER(pNode, RTDBGMODCONTAINERSYMBOL, AddrCore); 147 369 RTStrCacheRelease(g_hDbgModStrCache, pSym->NameCore.pszString); 370 pSym->NameCore.pszString = NULL; 148 371 RTMemFree(pSym); 149 372 return 0; … … 159 382 * Destroy the symbols and instance data. 160 383 */ 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); 162 391 pThis->Names = NULL; 392 163 393 RTMemFree(pThis->paSegs); 164 394 pThis->paSegs = NULL; … … 185 415 /*.pfnTryOpen = */ rtDbgModContainer_TryOpen, 186 416 /*.pfnClose = */ rtDbgModContainer_Close, 417 /*.pfnRvaToSegOff = */ rtDbgModContainer_RvaToSegOff, 187 418 /*.pfnSymbolAdd = */ rtDbgModContainer_SymbolAdd, 188 419 /*.pfnSymbolByName = */ rtDbgModContainer_SymbolByName, 189 420 /*.pfnSymbolByAddr = */ rtDbgModContainer_SymbolByAddr, 421 /*.pfnLineAdd = */ rtDbgModContainer_LineAdd, 190 422 /*.pfnLineByAddr = */ rtDbgModContainer_LineByAddr, 191 423 /*.u32EndMagic = */ RTDBGMODVTDBG_MAGIC … … 208 440 209 441 pThis->Names = NULL; 210 pThis->A ddresses= NULL;442 pThis->AbsAddrTree = NULL; 211 443 pThis->paSegs = NULL; 212 444 pThis->cSegs = 0;
Note:
See TracChangeset
for help on using the changeset viewer.