Changeset 59231 in vbox for trunk/src/VBox/Runtime/common/dbg/dbgmodcodeview.cpp
- Timestamp:
- Dec 31, 2015 12:24:57 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/dbg/dbgmodcodeview.cpp
r58742 r59231 450 450 451 451 452 /** 453 * Adds a string to the g_hDbgModStrCache after sanitizing it. 454 * 455 * IPRT only deals with UTF-8 strings, so the string will be forced to UTF-8 456 * encoding. Also, codeview generally have length prefixed 457 * 458 * @returns String cached copy of the string. 459 * @param pch The string to copy to the cache. 460 * @param cch The length of the string. RTSTR_MAX if zero 461 * terminated. 462 */ 463 static const char *rtDbgModCvAddSanitizedStringToCache(const char *pch, size_t cch) 464 { 465 /* 466 * If the string is valid UTF-8 and or the right length, we're good. 467 * This is usually the case. 468 */ 469 const char *pszRet; 470 int rc; 471 if (cch != RTSTR_MAX) 472 rc = RTStrValidateEncodingEx(pch, cch, RTSTR_VALIDATE_ENCODING_EXACT_LENGTH); 473 else 474 rc = RTStrValidateEncodingEx(pch, cch, 0); 475 if (RT_SUCCESS(rc)) 476 pszRet = RTStrCacheEnterN(g_hDbgModStrCache, pch, cch); 477 else 478 { 479 /* 480 * Need to sanitize the string, so make a copy of it. 481 */ 482 char *pszCopy = (char *)RTMemDupEx(pch, cch, 1); 483 AssertPtrReturn(pszCopy, NULL); 484 485 /* Deal with anyembedded zero chars. */ 486 char *psz = RTStrEnd(pszCopy, cch); 487 while (psz) 488 { 489 *psz = '_'; 490 psz = RTStrEnd(psz, cch - (psz - pszCopy)); 491 } 492 493 /* Force valid UTF-8 encoding. */ 494 size_t cchTmp = RTStrPurgeEncoding(pszCopy); 495 NOREF(cchTmp); Assert(cchTmp == cch); 496 497 /* Enter it into the cache and free the temp copy. */ 498 pszRet = RTStrCacheEnterN(g_hDbgModStrCache, pszCopy, cch); 499 RTMemFree(pszCopy); 500 } 501 return pszRet; 502 } 503 504 505 /** 506 * Translates a codeview segment and offset into our segment layout. 507 * 508 * @returns 509 * @param pThis . 510 * @param piSeg . 511 * @param poff . 512 */ 513 DECLINLINE(int) rtDbgModCvAdjustSegAndOffset(PRTDBGMODCV pThis, uint32_t *piSeg, uint64_t *poff) 514 { 515 uint32_t iSeg = *piSeg; 516 if (iSeg == 0) 517 iSeg = RTDBGSEGIDX_ABS; 518 else if (pThis->pSegMap) 519 { 520 if (pThis->fHaveDosFrames) 521 { 522 if ( iSeg > pThis->pSegMap->Hdr.cSegs 523 || iSeg == 0) 524 return VERR_CV_BAD_FORMAT; 525 if (*poff <= pThis->pSegMap->aDescs[iSeg - 1].cb + pThis->pSegMap->aDescs[iSeg - 1].off) 526 *poff -= pThis->pSegMap->aDescs[iSeg - 1].off; 527 else 528 { 529 /* Workaround for VGABIOS where _DATA symbols like vgafont8 are 530 reported in the VGAROM segment. */ 531 uint64_t uAddrSym = *poff + ((uint32_t)pThis->pSegMap->aDescs[iSeg - 1].iFrame << 4); 532 uint16_t j = pThis->pSegMap->Hdr.cSegs; 533 while (j-- > 0) 534 { 535 uint64_t uAddrFirst = (uint64_t)pThis->pSegMap->aDescs[j].off 536 + ((uint32_t)pThis->pSegMap->aDescs[j].iFrame << 4); 537 if (uAddrSym - uAddrFirst < pThis->pSegMap->aDescs[j].cb) 538 { 539 Log(("CV addr fix: %04x:%08x -> %04x:%08x\n", iSeg, *poff, j + 1, uAddrSym - uAddrFirst)); 540 *poff = uAddrSym - uAddrFirst; 541 iSeg = j + 1; 542 break; 543 } 544 } 545 if (j == UINT16_MAX) 546 return VERR_CV_BAD_FORMAT; 547 } 548 } 549 else 550 { 551 if ( iSeg > pThis->pSegMap->Hdr.cSegs 552 || iSeg == 0 553 || *poff > pThis->pSegMap->aDescs[iSeg - 1].cb) 554 return VERR_CV_BAD_FORMAT; 555 *poff += pThis->pSegMap->aDescs[iSeg - 1].off; 556 } 557 if (pThis->pSegMap->aDescs[iSeg - 1].fFlags & RTCVSEGMAPDESC_F_ABS) 558 iSeg = RTDBGSEGIDX_ABS; 559 else 560 iSeg = pThis->pSegMap->aDescs[iSeg - 1].iGroup; 561 } 562 *piSeg = iSeg; 563 return VINF_SUCCESS; 564 } 565 452 566 453 567 /** … … 466 580 uint32_t cchName, uint32_t fFlags, uint32_t cbSym) 467 581 { 468 const char *pszName = RTStrCacheEnterN(g_hDbgModStrCache, pchName, cchName); 469 if (!pszName) 470 return VERR_NO_STR_MEMORY; 582 const char *pszName = rtDbgModCvAddSanitizedStringToCache(pchName, cchName); 583 int rc; 584 if (pszName) 585 { 471 586 #if 1 472 Log2(("CV Sym: %04x:%08x %.*s\n", iSeg, off, cchName, pchName)); 473 if (iSeg == 0) 474 iSeg = RTDBGSEGIDX_ABS; 475 else if (pThis->pSegMap) 476 { 477 if (pThis->fHaveDosFrames) 478 { 479 if ( iSeg > pThis->pSegMap->Hdr.cSegs 480 || iSeg == 0) 481 { 482 Log(("Invalid segment index/offset %#06x:%08x for symbol %.*s\n", iSeg, off, cchName, pchName)); 483 return VERR_CV_BAD_FORMAT; 484 } 485 if (off <= pThis->pSegMap->aDescs[iSeg - 1].cb + pThis->pSegMap->aDescs[iSeg - 1].off) 486 off -= pThis->pSegMap->aDescs[iSeg - 1].off; 487 else 488 { 489 /* Workaround for VGABIOS where _DATA symbols like vgafont8 are 490 reported in the VGAROM segment. */ 491 uint64_t uAddrSym = off + ((uint32_t)pThis->pSegMap->aDescs[iSeg - 1].iFrame << 4); 492 uint16_t j = pThis->pSegMap->Hdr.cSegs; 493 while (j-- > 0) 587 Log2(("CV Sym: %04x:%08x %.*s\n", iSeg, off, cchName, pchName)); 588 rc = rtDbgModCvAdjustSegAndOffset(pThis, &iSeg, &off); 589 if (RT_SUCCESS(rc)) 590 { 591 rc = RTDbgModSymbolAdd(pThis->hCnt, pszName, iSeg, off, cbSym, 0 /*fFlags*/, NULL); 592 593 /* Simple duplicate symbol mangling, just to get more details. */ 594 if (rc == VERR_DBG_DUPLICATE_SYMBOL && cchName < _2K) 595 { 596 char szTmpName[_2K + 96]; 597 memcpy(szTmpName, pszName, cchName); 598 szTmpName[cchName] = '_'; 599 for (uint32_t i = 1; i < 32; i++) 494 600 { 495 uint64_t uAddrFirst = (uint64_t)pThis->pSegMap->aDescs[j].off 496 + ((uint32_t)pThis->pSegMap->aDescs[j].iFrame << 4); 497 if (uAddrSym - uAddrFirst < pThis->pSegMap->aDescs[j].cb) 498 { 499 Log(("CV addr fix: %04x:%08x -> %04x:%08x\n", iSeg, off, j + 1, uAddrSym - uAddrFirst)); 500 off = uAddrSym - uAddrFirst; 501 iSeg = j + 1; 601 RTStrFormatU32(&szTmpName[cchName + 1], 80, i, 10, 0, 0, 0); 602 rc = RTDbgModSymbolAdd(pThis->hCnt, szTmpName, iSeg, off, cbSym, 0 /*fFlags*/, NULL); 603 if (rc != VERR_DBG_DUPLICATE_SYMBOL) 502 604 break; 503 }504 605 } 505 if (j == UINT16_MAX) 506 {507 Log(("Invalid segment index/offset %#06x:%08x for symbol %.*s [2]\n", iSeg, off, cchName, pchName)); 508 return VERR_CV_BAD_FORMAT;509 }510 }606 607 } 608 609 Log(("Symbol: %04x:%08x %.*s [%Rrc]\n", iSeg, off, cchName, pchName, rc)); 610 if (rc == VERR_DBG_ADDRESS_CONFLICT || rc == VERR_DBG_DUPLICATE_SYMBOL) 611 rc = VINF_SUCCESS; 511 612 } 512 613 else 513 { 514 if ( iSeg > pThis->pSegMap->Hdr.cSegs 515 || iSeg == 0 516 || off > pThis->pSegMap->aDescs[iSeg - 1].cb) 517 { 518 Log(("Invalid segment index/offset %#06x:%08x for symbol %.*s\n", iSeg, off, cchName, pchName)); 519 return VERR_CV_BAD_FORMAT; 520 } 521 off += pThis->pSegMap->aDescs[iSeg - 1].off; 522 } 523 if (pThis->pSegMap->aDescs[iSeg - 1].fFlags & RTCVSEGMAPDESC_F_ABS) 524 iSeg = RTDBGSEGIDX_ABS; 525 else 526 iSeg = pThis->pSegMap->aDescs[iSeg - 1].iGroup; 527 } 528 529 int rc = RTDbgModSymbolAdd(pThis->hCnt, pszName, iSeg, off, cbSym, 0 /*fFlags*/, NULL); 530 531 /* Simple duplicate symbol mangling, just to get more details. */ 532 if (rc == VERR_DBG_DUPLICATE_SYMBOL && cchName < _2K) 533 { 534 char szTmpName[_2K + 96]; 535 memcpy(szTmpName, pszName, cchName); 536 szTmpName[cchName] = '_'; 537 for (uint32_t i = 1; i < 32; i++) 538 { 539 RTStrFormatU32(&szTmpName[cchName + 1], 80, i, 10, 0, 0, 0); 540 pszName = RTStrCacheEnterN(g_hDbgModStrCache, szTmpName, cchName + 1 + 1 + (i >= 10)); 541 rc = RTDbgModSymbolAdd(pThis->hCnt, pszName, iSeg, off, cbSym, 0 /*fFlags*/, NULL); 542 if (rc != VERR_DBG_DUPLICATE_SYMBOL) 543 break; 544 } 545 546 } 547 548 Log(("Symbol: %04x:%08x %.*s [%Rrc]\n", iSeg, off, cchName, pchName, rc)); 549 if (rc == VERR_DBG_ADDRESS_CONFLICT || rc == VERR_DBG_DUPLICATE_SYMBOL) 614 Log(("Invalid segment index/offset %#06x:%08x for symbol %.*s\n", iSeg, off, cchName, pchName)); 615 616 #else 617 Log(("Symbol: %04x:%08x %.*s\n", iSeg, off, cchName, pchName)); 550 618 rc = VINF_SUCCESS; 551 RTStrCacheRelease(g_hDbgModStrCache, pszName); 619 #endif 620 RTStrCacheRelease(g_hDbgModStrCache, pszName); 621 } 622 else 623 rc = VERR_NO_STR_MEMORY; 552 624 return rc; 553 #else554 Log(("Symbol: %04x:%08x %.*s\n", iSeg, off, cchName, pchName));555 return VINF_SUCCESS;556 #endif557 625 } 558 626 … … 834 902 return rtDbgModCvSsProcessV8SymTab(pThis, (uint8_t const *)pvSubSect + 4, cbSubSect - 4, 0); 835 903 return rtDbgModCvSsProcessV4PlusSymTab(pThis, (uint8_t const *)pvSubSect + 4, cbSubSect - 4, 0); 904 } 905 906 907 /** @callback_method_impl{FNDBGMODCVSUBSECTCALLBACK, 908 * Parses kCvSst_SrcModule adding line numbers it finds to the container.} 909 */ 910 static DECLCALLBACK(int) 911 rtDbgModCvSs_SrcModule(PRTDBGMODCV pThis, void const *pvSubSect, size_t cbSubSect, PCRTCVDIRENT32 pDirEnt) 912 { 913 Log(("rtDbgModCvSs_SrcModule: uCurStyle=%#x\n%.*Rhxd\n", pThis->uCurStyle, cbSubSect, pvSubSect)); 914 915 /* Check the header. */ 916 PCRTCVSRCMODULE pHdr = (PCRTCVSRCMODULE)pvSubSect; 917 AssertReturn(cbSubSect >= RT_OFFSETOF(RTCVSRCMODULE, aoffSrcFiles), VERR_CV_BAD_FORMAT); 918 size_t cbHdr = sizeof(RTCVSRCMODULE) 919 + pHdr->cFiles * sizeof(uint32_t) 920 + pHdr->cSegs * sizeof(uint32_t) * 2 921 + pHdr->cSegs * sizeof(uint16_t); 922 Log2(("RTDbgModCv: SrcModule: cFiles=%u cSegs=%u\n", pHdr->cFiles, pHdr->cFiles)); 923 RTDBGMODCV_CHECK_RET_BF(cbSubSect >= cbHdr, ("cbSubSect=%#x cbHdr=%zx\n", cbSubSect, cbHdr)); 924 if (LogIs2Enabled()) 925 { 926 for (uint32_t i = 0; i < pHdr->cFiles; i++) 927 Log2(("RTDbgModCv: source file #%u: %#x\n", i, pHdr->aoffSrcFiles[i])); 928 PCRTCVSRCRANGE paSegRanges = (PCRTCVSRCRANGE)&pHdr->aoffSrcFiles[pHdr->cFiles]; 929 uint16_t const *paidxSegs = (uint16_t const *)&paSegRanges[pHdr->cSegs]; 930 for (uint32_t i = 0; i < pHdr->cSegs; i++) 931 Log2(("RTDbgModCv: seg #%u: %#010x-%#010x\n", paidxSegs[i], paSegRanges[i].offStart, paSegRanges[i].offEnd)); 932 } 933 934 /* 935 * Work over the source files. 936 */ 937 for (uint32_t i = 0; i < pHdr->cFiles; i++) 938 { 939 uint32_t const offSrcFile = pHdr->aoffSrcFiles[i]; 940 RTDBGMODCV_CHECK_RET_BF(cbSubSect - RT_OFFSETOF(RTCVSRCFILE, aoffSrcLines) >= offSrcFile, 941 ("cbSubSect=%#x (- %#x) aoffSrcFiles[%u]=%#x\n", 942 cbSubSect, RT_OFFSETOF(RTCVSRCFILE, aoffSrcLines), i, offSrcFile)); 943 PCRTCVSRCFILE pSrcFile = (PCRTCVSRCFILE)((uint8_t const *)pvSubSect + offSrcFile); 944 size_t cbSrcFileHdr = RT_OFFSETOF(RTCVSRCFILE, aoffSrcLines[pSrcFile->cSegs]) 945 + sizeof(RTCVSRCRANGE) * pSrcFile->cSegs 946 + sizeof(uint8_t); 947 RTDBGMODCV_CHECK_RET_BF(cbSubSect >= offSrcFile + cbSrcFileHdr && cbSubSect > cbSrcFileHdr, 948 ("cbSubSect=%#x aoffSrcFiles[%u]=%#x cbSrcFileHdr=%#x\n", cbSubSect, offSrcFile, i, cbSrcFileHdr)); 949 PCRTCVSRCRANGE paSegRanges = (PCRTCVSRCRANGE)&pSrcFile->aoffSrcLines[pSrcFile->cSegs]; 950 uint8_t const *pcchName = (uint8_t const *)&paSegRanges[pSrcFile->cSegs]; /** @todo TIS NB09 docs say 16-bit length... */ 951 const char *pchName = (const char *)(pcchName + 1); 952 RTDBGMODCV_CHECK_RET_BF(cbSubSect >= offSrcFile + cbSrcFileHdr + *pcchName, 953 ("cbSubSect=%#x offSrcFile=%#x cbSubSect=%#x *pcchName=%#x\n", 954 cbSubSect, offSrcFile, cbSubSect, *pcchName)); 955 Log2(("RTDbgModCv: source file #%u/%#x: cSegs=%#x '%.*s'\n", i, offSrcFile, pSrcFile->cSegs, *pcchName, pchName)); 956 const char *pszName = rtDbgModCvAddSanitizedStringToCache(pchName, *pcchName); 957 958 /* 959 * Work the segments this source file contributes code to. 960 */ 961 for (uint32_t iSeg = 0; iSeg < pSrcFile->cSegs; iSeg++) 962 { 963 uint32_t const offSrcLine = pSrcFile->aoffSrcLines[iSeg]; 964 RTDBGMODCV_CHECK_RET_BF(cbSubSect - RT_OFFSETOF(RTCVSRCLINE, aoffLines) >= offSrcLine, 965 ("cbSubSect=%#x (- %#x) aoffSrcFiles[%u]=%#x\n", 966 cbSubSect, RT_OFFSETOF(RTCVSRCLINE, aoffLines), iSeg, offSrcLine)); 967 PCRTCVSRCLINE pSrcLine = (PCRTCVSRCLINE)((uint8_t const *)pvSubSect + offSrcLine); 968 size_t cbSrcLine = RT_OFFSETOF(RTCVSRCLINE, aoffLines[pSrcLine->cPairs]) 969 + pSrcLine->cPairs * sizeof(uint16_t); 970 RTDBGMODCV_CHECK_RET_BF(cbSubSect >= offSrcLine + cbSrcLine, 971 ("cbSubSect=%#x aoffSrcFiles[%u]=%#x cbSrcLine=%#x\n", 972 cbSubSect, iSeg, offSrcLine, cbSrcLine)); 973 uint16_t const *paiLines = (uint16_t const *)&pSrcLine->aoffLines[pSrcLine->cPairs]; 974 Log2(("RTDbgModCv: seg #%u, %u pairs (off %#x)\n", pSrcLine->idxSeg, pSrcLine->cPairs, offSrcLine)); 975 for (uint32_t iPair = 0; iPair < pSrcLine->cPairs; iPair++) 976 { 977 978 uint32_t idxSeg = pSrcLine->idxSeg; 979 uint64_t off = pSrcLine->aoffLines[iPair]; 980 int rc = rtDbgModCvAdjustSegAndOffset(pThis, &idxSeg, &off); 981 if (RT_SUCCESS(rc)) 982 rc = RTDbgModLineAdd(pThis->hCnt, pszName, paiLines[iPair], idxSeg, off, NULL); 983 if (RT_SUCCESS(rc)) 984 Log3(("RTDbgModCv: %#x:%#010llx %0u\n", idxSeg, off, paiLines[iPair])); 985 /* Note! Wlink produces the sstSrcModule subsections from LINNUM records, however the 986 CVGenLines() function assumes there is only one segment contributing to the 987 line numbers. So, when we do assembly that jumps between segments, it emits 988 the wrong addresses for some line numbers and we end up here, typically with 989 VERR_DBG_ADDRESS_CONFLICT. */ 990 else 991 Log(( "RTDbgModCv: %#x:%#010llx %0u - rc=%Rrc!! (org: idxSeg=%#x off=%#x)\n", 992 idxSeg, off, paiLines[iPair], rc, pSrcLine->idxSeg, pSrcLine->aoffLines[iPair])); 993 } 994 } 995 } 996 997 return VINF_SUCCESS; 836 998 } 837 999 … … 1099 1261 else 1100 1262 RTStrPrintf(szName, sizeof(szName), "Seg%02u", iSeg); 1101 Log(("CV: %#010x LB %#010x %s uRVA=%#010x iBest=%u cOverlaps=%u\n", 1102 uBestAddr, paDescs[iBest].cb, szName, uBestAddr - uImageBase, iBest, cOverlaps)); 1103 rc = RTDbgModSegmentAdd(pThis->hCnt, uBestAddr - uImageBase, paDescs[iBest].cb, pszName, 0 /*fFlags*/, NULL); 1263 RTDBGSEGIDX idxDbgSeg = NIL_RTDBGSEGIDX; 1264 rc = RTDbgModSegmentAdd(pThis->hCnt, uBestAddr - uImageBase, paDescs[iBest].cb, pszName, 0 /*fFlags*/, &idxDbgSeg); 1265 Log(("CV: %#010x LB %#010x %s uRVA=%#010x iBest=%u cOverlaps=%u [idxDbgSeg=%#x iSeg=%#x]\n", 1266 uBestAddr, paDescs[iBest].cb, szName, uBestAddr - uImageBase, iBest, cOverlaps, idxDbgSeg, idxDbgSeg)); 1104 1267 1105 1268 /* Update translations. */ … … 1544 1707 case kCvSst_OldSrcLnSeg: 1545 1708 case kCvSst_OldSrcLines3: 1709 /** @todo implement more. */ 1710 break; 1546 1711 1547 1712 case kCvSst_Types: 1548 1713 case kCvSst_Public: 1549 1714 case kCvSst_SrcLnSeg: 1715 /** @todo implement more. */ 1716 break; 1550 1717 case kCvSst_SrcModule: 1718 pfnCallback = rtDbgModCvSs_SrcModule; 1719 break; 1551 1720 case kCvSst_Libraries: 1552 1721 case kCvSst_GlobalTypes:
Note:
See TracChangeset
for help on using the changeset viewer.