Changeset 38581 in vbox for trunk/src/VBox/Runtime/common/dbg
- Timestamp:
- Aug 31, 2011 12:43:26 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 73772
- Location:
- trunk/src/VBox/Runtime/common/dbg
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/dbg/dbgmoddwarf.cpp
r38573 r38581 98 98 } krtDbgModDwarfSect; 99 99 100 100 101 /** 101 102 * The instance data of the DWARF reader. … … 125 126 126 127 /** 127 * Section reader instance.128 * DWARF cursor for reading byte data. 128 129 */ 129 130 typedef struct RTDWARFSECTRDR … … 147 148 * occurs. */ 148 149 int rc; 150 /** The start of the area covered by the cursor. 151 * Used for repositioning the cursor relative to the start of a section. */ 152 uint8_t const *pbStart; 149 153 } RTDWARFCURSOR; 150 154 /** Pointer to a DWARF section reader. */ 151 155 typedef RTDWARFCURSOR *PRTDWARFCURSOR; 152 153 154 /**155 * Loads a DWARF section from the image file.156 *157 * @returns IPRT status code.158 * @param pThis The DWARF instance.159 * @param enmSect The section to load.160 */161 static int rtDbgModDwarfLoadSection(PRTDBGMODDWARF pThis, krtDbgModDwarfSect enmSect)162 {163 /*164 * Don't load stuff twice.165 */166 if (pThis->aSections[enmSect].pv)167 return VINF_SUCCESS;168 169 /*170 * Sections that are not present cannot be loaded, treat them like they171 * are empty172 */173 if (!pThis->aSections[enmSect].fPresent)174 {175 Assert(pThis->aSections[enmSect].cb);176 return VINF_SUCCESS;177 }178 if (!pThis->aSections[enmSect].cb)179 return VINF_SUCCESS;180 181 /*182 * Sections must be readable with the current image interface.183 */184 if (pThis->aSections[enmSect].offFile < 0)185 return VERR_OUT_OF_RANGE;186 187 /*188 * Do the job.189 */190 return pThis->pMod->pImgVt->pfnMapPart(pThis->pMod, pThis->aSections[enmSect].offFile, pThis->aSections[enmSect].cb,191 &pThis->aSections[enmSect].pv);192 }193 194 195 /**196 * Unloads a DWARF section previously mapped by rtDbgModDwarfLoadSection.197 *198 * @returns IPRT status code.199 * @param pThis The DWARF instance.200 * @param enmSect The section to unload.201 */202 static int rtDbgModDwarfUnloadSection(PRTDBGMODDWARF pThis, krtDbgModDwarfSect enmSect)203 {204 if (!pThis->aSections[enmSect].pv)205 return VINF_SUCCESS;206 207 int rc = pThis->pMod->pImgVt->pfnUnmapPart(pThis->pMod, pThis->aSections[enmSect].cb, &pThis->aSections[enmSect].pv);208 AssertRC(rc);209 return rc;210 }211 212 213 /**214 * Converts to UTF-8 or otherwise makes sure it's valid UTF-8.215 *216 * @returns IPRT status code.217 * @param pThis The DWARF instance.218 * @param ppsz Pointer to the string pointer. May be219 * reallocated (RTStr*).220 */221 static int rtDbgModDwarfStringToUtf8(PRTDBGMODDWARF pThis, char **ppsz)222 {223 RTStrPurgeEncoding(*ppsz);224 return VINF_SUCCESS;225 }226 227 228 /**229 * Convers a link address into a segment+offset or RVA.230 *231 * @returns IPRT status code.232 * @param pThis The DWARF instance.233 * @param LinkAddress The address to convert..234 * @param piSeg The segment index.235 * @param poffSeg Where to return the segment offset.236 */237 static int rtDbgModDwarfLinkAddressToSegOffset(PRTDBGMODDWARF pThis, uint64_t LinkAddress,238 PRTDBGSEGIDX piSeg, PRTUINTPTR poffSeg)239 {240 /** @todo The image should be doing this conversion, not we. */241 *piSeg = RTDBGSEGIDX_RVA;242 *poffSeg = LinkAddress;243 return VINF_SUCCESS;244 }245 246 247 static uint8_t rtDwarfCursor_GetU8(PRTDWARFCURSOR pCursor, uint8_t uErrValue)248 {249 if (pCursor->cbUnitLeft < 1)250 {251 pCursor->rc = VERR_DWARF_UNEXPECTED_END;252 return uErrValue;253 }254 255 uint8_t u8 = pCursor->pb[0];256 pCursor->pb += 1;257 pCursor->cbUnitLeft -= 1;258 pCursor->cbLeft -= 1;259 return u8;260 }261 262 263 static uint16_t rtDwarfCursor_GetU16(PRTDWARFCURSOR pCursor, uint16_t uErrValue)264 {265 if (pCursor->cbUnitLeft < 2)266 {267 pCursor->pb += pCursor->cbUnitLeft;268 pCursor->cbLeft -= pCursor->cbUnitLeft;269 pCursor->cbUnitLeft = 0;270 pCursor->rc = VERR_DWARF_UNEXPECTED_END;271 return uErrValue;272 }273 274 uint16_t u16 = RT_MAKE_U16(pCursor->pb[0], pCursor->pb[1]);275 pCursor->pb += 2;276 pCursor->cbUnitLeft -= 2;277 pCursor->cbLeft -= 2;278 if (!pCursor->fNativEndian)279 u16 = RT_BSWAP_U16(u16);280 return u16;281 }282 283 284 static uint32_t rtDwarfCursor_GetU32(PRTDWARFCURSOR pCursor, uint32_t uErrValue)285 {286 if (pCursor->cbUnitLeft < 4)287 {288 pCursor->pb += pCursor->cbUnitLeft;289 pCursor->cbLeft -= pCursor->cbUnitLeft;290 pCursor->cbUnitLeft = 0;291 pCursor->rc = VERR_DWARF_UNEXPECTED_END;292 return uErrValue;293 }294 295 uint32_t u32 = RT_MAKE_U32_FROM_U8(pCursor->pb[0], pCursor->pb[1], pCursor->pb[2], pCursor->pb[3]);296 pCursor->pb += 4;297 pCursor->cbUnitLeft -= 4;298 pCursor->cbLeft -= 4;299 if (!pCursor->fNativEndian)300 u32 = RT_BSWAP_U32(u32);301 return u32;302 }303 304 305 static uint64_t rtDwarfCursor_GetU64(PRTDWARFCURSOR pCursor, uint64_t uErrValue)306 {307 if (pCursor->cbUnitLeft < 8)308 {309 pCursor->pb += pCursor->cbUnitLeft;310 pCursor->cbLeft -= pCursor->cbUnitLeft;311 pCursor->cbUnitLeft = 0;312 pCursor->rc = VERR_DWARF_UNEXPECTED_END;313 return uErrValue;314 }315 316 uint64_t u64 = RT_MAKE_U64_FROM_U8(pCursor->pb[0], pCursor->pb[1], pCursor->pb[2], pCursor->pb[3],317 pCursor->pb[4], pCursor->pb[5], pCursor->pb[6], pCursor->pb[7]);318 pCursor->pb += 8;319 pCursor->cbUnitLeft -= 8;320 pCursor->cbLeft -= 8;321 if (!pCursor->fNativEndian)322 u64 = RT_BSWAP_U64(u64);323 return u64;324 }325 326 327 /**328 * Gets a unsigned LEB128 encoded number.329 *330 * @returns unsigned number.331 * @param pCursor The cursor.332 * @param uErrValue The value to return on error.333 */334 static uint64_t rtDwarfCursor_GetULeb128(PRTDWARFCURSOR pCursor, uint64_t uErrValue)335 {336 if (pCursor->cbUnitLeft < 1)337 {338 pCursor->rc = VERR_DWARF_UNEXPECTED_END;339 return uErrValue;340 }341 342 /*343 * Special case - single byte.344 */345 uint8_t b = pCursor->pb[0];346 if (!(b & 0x80))347 {348 pCursor->pb += 1;349 pCursor->cbUnitLeft -= 1;350 pCursor->cbLeft -= 1;351 return b;352 }353 354 /*355 * Generic case.356 */357 /* Decode. */358 uint32_t off = 1;359 uint64_t u64Ret = b & 0x7f;360 do361 {362 if (off == pCursor->cbUnitLeft)363 {364 pCursor->rc = VERR_DWARF_UNEXPECTED_END;365 u64Ret = uErrValue;366 break;367 }368 b = pCursor->pb[off];369 u64Ret |= (b & 0x7f) << off * 7;370 off++;371 } while (b & 0x80);372 373 /* Update the cursor. */374 pCursor->pb += off;375 pCursor->cbUnitLeft -= off;376 pCursor->cbLeft -= off;377 378 /* Check the range. */379 uint32_t cBits = off * 7;380 if (cBits > 64)381 {382 pCursor->rc = VERR_DWARF_LEB_OVERFLOW;383 u64Ret = uErrValue;384 }385 386 return u64Ret;387 }388 389 390 /**391 * Gets a signed LEB128 encoded number.392 *393 * @returns signed number.394 * @param pCursor The cursor.395 * @param sErrValue The value to return on error.396 */397 static int64_t rtDwarfCursor_GetSLeb128(PRTDWARFCURSOR pCursor, int64_t sErrValue)398 {399 if (pCursor->cbUnitLeft < 1)400 {401 pCursor->rc = VERR_DWARF_UNEXPECTED_END;402 return sErrValue;403 }404 405 /*406 * Special case - single byte.407 */408 uint8_t b = pCursor->pb[0];409 if (!(b & 0x80))410 {411 pCursor->pb += 1;412 pCursor->cbUnitLeft -= 1;413 pCursor->cbLeft -= 1;414 if (b & 0x40)415 b |= 0x80;416 return (int8_t)b;417 }418 419 /*420 * Generic case.421 */422 /* Decode it. */423 uint32_t off = 1;424 uint64_t u64Ret = b & 0x7f;425 do426 {427 if (off == pCursor->cbUnitLeft)428 {429 pCursor->rc = VERR_DWARF_UNEXPECTED_END;430 u64Ret = (uint64_t)sErrValue;431 break;432 }433 b = pCursor->pb[off];434 u64Ret |= (b & 0x7f) << off * 7;435 off++;436 } while (b & 0x80);437 438 /* Update cursor. */439 pCursor->pb += off;440 pCursor->cbUnitLeft -= off;441 pCursor->cbLeft -= off;442 443 /* Check the range. */444 uint32_t cBits = off * 7;445 if (cBits > 64)446 {447 pCursor->rc = VERR_DWARF_LEB_OVERFLOW;448 u64Ret = (uint64_t)sErrValue;449 }450 /* Sign extend the value. */451 else if (u64Ret & RT_BIT_64(cBits - 1))452 u64Ret |= ~(RT_BIT_64(cBits - 1) - 1);453 454 return (int64_t)u64Ret;455 }456 457 458 /**459 * Gets a unsigned LEB128 encoded number, max 32-bit width.460 *461 * @returns unsigned number.462 * @param pCursor The cursor.463 * @param uErrValue The value to return on error.464 */465 static uint32_t rtDwarfCursor_GetULeb128AsU32(PRTDWARFCURSOR pCursor, uint32_t uErrValue)466 {467 uint64_t u64 = rtDwarfCursor_GetULeb128(pCursor, uErrValue);468 if (u64 > UINT32_MAX)469 {470 pCursor->rc = VERR_DWARF_LEB_OVERFLOW;471 return uErrValue;472 }473 return (uint32_t)u64;474 }475 476 477 /**478 * Gets a signed LEB128 encoded number, max 32-bit width.479 *480 * @returns unsigned number.481 * @param pCursor The cursor.482 * @param sErrValue The value to return on error.483 */484 static int32_t rtDwarfCursor_GetSLeb128AsS32(PRTDWARFCURSOR pCursor, int32_t sErrValue)485 {486 int64_t s64 = rtDwarfCursor_GetSLeb128(pCursor, sErrValue);487 if (s64 > INT32_MAX || s64 < INT32_MIN)488 {489 pCursor->rc = VERR_DWARF_LEB_OVERFLOW;490 return sErrValue;491 }492 return (int32_t)s64;493 }494 495 496 static int rtDwarfCursor_SkipLeb128(PRTDWARFCURSOR pCursor)497 {498 if (pCursor->cbUnitLeft < 1)499 return pCursor->rc = VERR_DWARF_UNEXPECTED_END;500 501 uint32_t offSkip = 1;502 if (pCursor->pb[0] & 0x80)503 do504 {505 if (offSkip == pCursor->cbUnitLeft)506 {507 pCursor->rc = VERR_DWARF_UNEXPECTED_END;508 break;509 }510 } while (pCursor->pb[offSkip++] & 0x80);511 512 pCursor->pb += offSkip;513 pCursor->cbUnitLeft -= offSkip;514 pCursor->cbLeft -= offSkip;515 return pCursor->rc;516 }517 518 519 520 /**521 * Reads a zero terminated string, advancing the cursor beyond the terminator.522 *523 * @returns Pointer to the string.524 * @param pCursor The cursor.525 * @param pszErrValue What to return if the string isn't terminated526 * before the end of the unit.527 */528 static const char *rtDwarfCursor_GetSZ(PRTDWARFCURSOR pCursor, const char *pszErrValue)529 {530 const char *pszRet = (const char *)pCursor->pb;531 for (;;)532 {533 if (!pCursor->cbUnitLeft)534 {535 pCursor->rc = VERR_DWARF_BAD_STRING;536 return pszErrValue;537 }538 pCursor->cbUnitLeft--;539 pCursor->cbLeft--;540 if (!*pCursor->pb++)541 break;542 }543 return pszRet;544 }545 546 547 548 static uint16_t rtDwarfCursor_GetUHalf(PRTDWARFCURSOR pCursor, uint16_t uErrValue)549 {550 return rtDwarfCursor_GetU16(pCursor, uErrValue);551 }552 553 554 static uint8_t rtDwarfCursor_GetUByte(PRTDWARFCURSOR pCursor, uint8_t uErrValue)555 {556 return rtDwarfCursor_GetU8(pCursor, uErrValue);557 }558 559 560 static int8_t rtDwarfCursor_GetSByte(PRTDWARFCURSOR pCursor, int8_t iErrValue)561 {562 return (int8_t)rtDwarfCursor_GetU8(pCursor, (uint8_t)iErrValue);563 }564 565 566 static uint64_t rtDwarfCursor_GetUOff(PRTDWARFCURSOR pCursor, uint64_t uErrValue)567 {568 if (pCursor->f64bitDwarf)569 return rtDwarfCursor_GetU64(pCursor, uErrValue);570 return rtDwarfCursor_GetU32(pCursor, (uint32_t)uErrValue);571 }572 573 574 /**575 * Gets the unit length, updating the unit length member and DWARF bitness576 * members of the cursor.577 *578 * @returns The unit length.579 * @param pCursor The cursor.580 */581 static uint64_t rtDwarfCursor_GetInitalLength(PRTDWARFCURSOR pCursor)582 {583 /*584 * Read the initial length.585 */586 pCursor->cbUnitLeft = pCursor->cbLeft;587 uint64_t cbUnit = rtDwarfCursor_GetU32(pCursor, 0);588 if (cbUnit != UINT32_C(0xffffffff))589 pCursor->f64bitDwarf = false;590 else591 {592 pCursor->f64bitDwarf = true;593 cbUnit = rtDwarfCursor_GetU64(pCursor, 0);594 }595 596 597 /*598 * Set the unit length, quitely fixing bad lengths.599 */600 pCursor->cbUnitLeft = (size_t)cbUnit;601 if ( pCursor->cbUnitLeft > pCursor->cbLeft602 || pCursor->cbUnitLeft != cbUnit)603 pCursor->cbUnitLeft = pCursor->cbLeft;604 605 return cbUnit;606 }607 608 609 /**610 * Calculates an absolute cursor position from one relative to the current611 * cursor position.612 *613 * @returns The absolute cursor position.614 * @param pCursor The cursor.615 * @param offRelative The relative position. Must be a positive616 * offset.617 */618 static uint8_t const *rtDwarfCursor_CalcPos(PRTDWARFCURSOR pCursor, size_t offRelative)619 {620 if (offRelative > pCursor->cbUnitLeft)621 {622 pCursor->rc = VERR_DWARF_BAD_POS;623 return NULL;624 }625 return pCursor->pb + offRelative;626 }627 628 629 /**630 * Advances the cursor to the given position.631 *632 * @returns IPRT status code.633 * @param pCursor The cursor.634 * @param pbNewPos The new position - returned by635 * rtDwarfCursor_CalcPos().636 */637 static int rtDwarfCursor_AdvanceToPos(PRTDWARFCURSOR pCursor, uint8_t const *pbNewPos)638 {639 if (RT_FAILURE(pCursor->rc))640 return pCursor->rc;641 AssertPtr(pbNewPos);642 if ((uintptr_t)pbNewPos < (uintptr_t)pCursor->pb)643 return pCursor->rc = VERR_DWARF_BAD_POS;644 645 uintptr_t cbAdj = (uintptr_t)pbNewPos - (uintptr_t)pCursor->pb;646 if (RT_UNLIKELY(cbAdj > pCursor->cbUnitLeft))647 {648 AssertFailed();649 pCursor->rc = VERR_DWARF_BAD_POS;650 cbAdj = pCursor->cbUnitLeft;651 }652 653 pCursor->cbUnitLeft -= cbAdj;654 pCursor->cbLeft -= cbAdj;655 pCursor->pb += cbAdj;656 return pCursor->rc;657 }658 659 660 static bool rtDwarfCursor_IsAtEndOfUnit(PRTDWARFCURSOR pCursor)661 {662 return !pCursor->cbUnitLeft;663 }664 665 666 static int rtDwarfCursor_SkipUnit(PRTDWARFCURSOR pCursor)667 {668 pCursor->pb += pCursor->cbUnitLeft;669 pCursor->cbLeft -= pCursor->cbUnitLeft;670 pCursor->cbUnitLeft = 0;671 return VINF_SUCCESS;672 }673 674 675 static bool rtDwarfCursor_IsAtEnd(PRTDWARFCURSOR pCursor)676 {677 return !pCursor->cbLeft;678 }679 680 681 /**682 * Initialize a section reader.683 *684 * @returns IPRT status code.685 * @param pCursor The section reader.686 * @param pThis The dwarf module.687 * @param enmSect .688 */689 static int rtDwarfCursor_Init(PRTDWARFCURSOR pCursor, PRTDBGMODDWARF pThis, krtDbgModDwarfSect enmSect)690 {691 int rc = rtDbgModDwarfLoadSection(pThis, enmSect);692 if (RT_FAILURE(rc))693 return rc;694 695 pCursor->pb = (uint8_t const *)pThis->aSections[enmSect].pv;696 pCursor->cbLeft = pThis->aSections[enmSect].cb;697 pCursor->cbUnitLeft = pCursor->cbLeft;698 pCursor->pDwarfMod = pThis;699 pCursor->fNativEndian = true; /** @todo endian */700 pCursor->f64bitDwarf = false;701 pCursor->cbNativeAddr = 4;702 pCursor->rc = VINF_SUCCESS;703 704 /** @todo ask the image about the endian used as well as the address705 * width. */706 707 return VINF_SUCCESS;708 }709 710 711 /**712 * Deletes a section reader initialized by rtDwarfCursor_Init.713 *714 * @param pCursor The section reader.715 */716 static void rtDwarfCursor_Delete(PRTDWARFCURSOR pCursor)717 {718 /* ... and a drop of poison. */719 pCursor->pb = NULL;720 pCursor->cbLeft = ~(size_t)0;721 pCursor->cbUnitLeft = ~(size_t)0;722 pCursor->pDwarfMod = NULL;723 pCursor->rc = VERR_INTERNAL_ERROR_4;724 }725 726 727 /** @interface_method_impl{RTDBGMODVTDBG,pfnLineByAddr} */728 static DECLCALLBACK(int) rtDbgModDwarf_LineByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off,729 PRTINTPTR poffDisp, PRTDBGLINE pLineInfo)730 {731 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;732 return RTDbgModLineByAddr(pThis->hCnt, iSeg, off, poffDisp, pLineInfo);733 }734 735 736 /** @interface_method_impl{RTDBGMODVTDBG,pfnLineByOrdinal} */737 static DECLCALLBACK(int) rtDbgModDwarf_LineByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo)738 {739 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;740 return RTDbgModLineByOrdinal(pThis->hCnt, iOrdinal, pLineInfo);741 }742 743 744 /** @interface_method_impl{RTDBGMODVTDBG,pfnLineCount} */745 static DECLCALLBACK(uint32_t) rtDbgModDwarf_LineCount(PRTDBGMODINT pMod)746 {747 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;748 return RTDbgModLineCount(pThis->hCnt);749 }750 751 752 /** @interface_method_impl{RTDBGMODVTDBG,pfnLineAdd} */753 static DECLCALLBACK(int) rtDbgModDwarf_LineAdd(PRTDBGMODINT pMod, const char *pszFile, size_t cchFile, uint32_t uLineNo,754 uint32_t iSeg, RTUINTPTR off, uint32_t *piOrdinal)755 {756 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;757 return RTDbgModLineAdd(pThis->hCnt, pszFile, uLineNo, iSeg, off, piOrdinal);758 }759 760 761 /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByAddr} */762 static DECLCALLBACK(int) rtDbgModDwarf_SymbolByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off,763 PRTINTPTR poffDisp, PRTDBGSYMBOL pSymInfo)764 {765 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;766 return RTDbgModSymbolByAddr(pThis->hCnt, iSeg, off, poffDisp, pSymInfo);767 }768 769 770 /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByName} */771 static DECLCALLBACK(int) rtDbgModDwarf_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,772 PRTDBGSYMBOL pSymInfo)773 {774 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;775 Assert(!pszSymbol[cchSymbol]);776 return RTDbgModSymbolByName(pThis->hCnt, pszSymbol/*, cchSymbol*/, pSymInfo);777 }778 779 780 /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByOrdinal} */781 static DECLCALLBACK(int) rtDbgModDwarf_SymbolByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo)782 {783 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;784 return RTDbgModSymbolByOrdinal(pThis->hCnt, iOrdinal, pSymInfo);785 }786 787 788 /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolCount} */789 static DECLCALLBACK(uint32_t) rtDbgModDwarf_SymbolCount(PRTDBGMODINT pMod)790 {791 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;792 return RTDbgModSymbolCount(pThis->hCnt);793 }794 795 796 /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolAdd} */797 static DECLCALLBACK(int) rtDbgModDwarf_SymbolAdd(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,798 RTDBGSEGIDX iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags,799 uint32_t *piOrdinal)800 {801 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;802 return RTDbgModSymbolAdd(pThis->hCnt, pszSymbol, iSeg, off, cb, fFlags, piOrdinal);803 }804 805 806 /** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentByIndex} */807 static DECLCALLBACK(int) rtDbgModDwarf_SegmentByIndex(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo)808 {809 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;810 return RTDbgModSegmentByIndex(pThis->hCnt, iSeg, pSegInfo);811 }812 813 814 /** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentCount} */815 static DECLCALLBACK(RTDBGSEGIDX) rtDbgModDwarf_SegmentCount(PRTDBGMODINT pMod)816 {817 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;818 return RTDbgModSegmentCount(pThis->hCnt);819 }820 821 822 /** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentAdd} */823 static DECLCALLBACK(int) rtDbgModDwarf_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName, size_t cchName,824 uint32_t fFlags, PRTDBGSEGIDX piSeg)825 {826 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;827 return RTDbgModSegmentAdd(pThis->hCnt, uRva, cb, pszName, fFlags, piSeg);828 }829 830 831 /** @interface_method_impl{RTDBGMODVTDBG,pfnImageSize} */832 static DECLCALLBACK(RTUINTPTR) rtDbgModDwarf_ImageSize(PRTDBGMODINT pMod)833 {834 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;835 RTUINTPTR cb1 = RTDbgModImageSize(pThis->hCnt);836 RTUINTPTR cb2 = pMod->pImgVt->pfnImageSize(pMod);837 return RT_MAX(cb1, cb2);838 }839 840 841 /** @interface_method_impl{RTDBGMODVTDBG,pfnRvaToSegOff} */842 static DECLCALLBACK(RTDBGSEGIDX) rtDbgModDwarf_RvaToSegOff(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg)843 {844 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;845 return RTDbgModRvaToSegOff(pThis->hCnt, uRva, poffSeg);846 }847 848 849 /** @interface_method_impl{RTDBGMODVTDBG,pfnClose} */850 static DECLCALLBACK(int) rtDbgModDwarf_Close(PRTDBGMODINT pMod)851 {852 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;853 854 for (unsigned iSect = 0; iSect < RT_ELEMENTS(pThis->aSections); iSect++)855 if (pThis->aSections[iSect].pv)856 pThis->pMod->pImgVt->pfnUnmapPart(pThis->pMod, pThis->aSections[iSect].cb, &pThis->aSections[iSect].pv);857 858 RTDbgModRelease(pThis->hCnt);859 RTMemFree(pThis);860 861 return VINF_SUCCESS;862 }863 156 864 157 … … 919 212 920 213 214 /** @callback_method_impl{FNRTLDRENUMSEGS} */ 215 static DECLCALLBACK(int) rtDbgModHlpAddSegmentCallback(RTLDRMOD hLdrMod, PCRTLDRSEG pSeg, void *pvUser) 216 { 217 PRTDBGMODINT pMod = (PRTDBGMODINT)pvUser; 218 Log(("Segment %.*s: LinkAddress=%#llx RVA=%#llx cb=%#llx\n", 219 pSeg->cchName, pSeg->pchName, (uint64_t)pSeg->LinkAddress, (uint64_t)pSeg->RVA, pSeg->cb)); 220 RTLDRADDR cb = RT_MAX(pSeg->cb, pSeg->cbMapped); 221 #if 1 222 return pMod->pDbgVt->pfnSegmentAdd(pMod, pSeg->RVA, cb, pSeg->pchName, pSeg->cchName, 0 /*fFlags*/, NULL); 223 #else 224 return pMod->pDbgVt->pfnSegmentAdd(pMod, pSeg->LinkAddress, cb, pSeg->pchName, pSeg->cchName, 0 /*fFlags*/, NULL); 225 #endif 226 } 227 228 229 /** 230 * Calls pfnSegmentAdd for each segment in the executable image. 231 * 232 * @returns IPRT status code. 233 * @param pMod The debug module. 234 */ 235 DECLHIDDEN(int) rtDbgModHlpAddSegmentsFromImage(PRTDBGMODINT pMod) 236 { 237 AssertReturn(pMod->pImgVt, VERR_INTERNAL_ERROR_2); 238 return pMod->pImgVt->pfnEnumSegments(pMod, rtDbgModHlpAddSegmentCallback, pMod); 239 } 240 241 242 243 244 /** 245 * Loads a DWARF section from the image file. 246 * 247 * @returns IPRT status code. 248 * @param pThis The DWARF instance. 249 * @param enmSect The section to load. 250 */ 251 static int rtDbgModDwarfLoadSection(PRTDBGMODDWARF pThis, krtDbgModDwarfSect enmSect) 252 { 253 /* 254 * Don't load stuff twice. 255 */ 256 if (pThis->aSections[enmSect].pv) 257 return VINF_SUCCESS; 258 259 /* 260 * Sections that are not present cannot be loaded, treat them like they 261 * are empty 262 */ 263 if (!pThis->aSections[enmSect].fPresent) 264 { 265 Assert(pThis->aSections[enmSect].cb); 266 return VINF_SUCCESS; 267 } 268 if (!pThis->aSections[enmSect].cb) 269 return VINF_SUCCESS; 270 271 /* 272 * Sections must be readable with the current image interface. 273 */ 274 if (pThis->aSections[enmSect].offFile < 0) 275 return VERR_OUT_OF_RANGE; 276 277 /* 278 * Do the job. 279 */ 280 return pThis->pMod->pImgVt->pfnMapPart(pThis->pMod, pThis->aSections[enmSect].offFile, pThis->aSections[enmSect].cb, 281 &pThis->aSections[enmSect].pv); 282 } 283 284 285 /** 286 * Unloads a DWARF section previously mapped by rtDbgModDwarfLoadSection. 287 * 288 * @returns IPRT status code. 289 * @param pThis The DWARF instance. 290 * @param enmSect The section to unload. 291 */ 292 static int rtDbgModDwarfUnloadSection(PRTDBGMODDWARF pThis, krtDbgModDwarfSect enmSect) 293 { 294 if (!pThis->aSections[enmSect].pv) 295 return VINF_SUCCESS; 296 297 int rc = pThis->pMod->pImgVt->pfnUnmapPart(pThis->pMod, pThis->aSections[enmSect].cb, &pThis->aSections[enmSect].pv); 298 AssertRC(rc); 299 return rc; 300 } 301 302 303 /** 304 * Converts to UTF-8 or otherwise makes sure it's valid UTF-8. 305 * 306 * @returns IPRT status code. 307 * @param pThis The DWARF instance. 308 * @param ppsz Pointer to the string pointer. May be 309 * reallocated (RTStr*). 310 */ 311 static int rtDbgModDwarfStringToUtf8(PRTDBGMODDWARF pThis, char **ppsz) 312 { 313 RTStrPurgeEncoding(*ppsz); 314 return VINF_SUCCESS; 315 } 316 317 318 /** 319 * Convers a link address into a segment+offset or RVA. 320 * 321 * @returns IPRT status code. 322 * @param pThis The DWARF instance. 323 * @param LinkAddress The address to convert.. 324 * @param piSeg The segment index. 325 * @param poffSeg Where to return the segment offset. 326 */ 327 static int rtDbgModDwarfLinkAddressToSegOffset(PRTDBGMODDWARF pThis, uint64_t LinkAddress, 328 PRTDBGSEGIDX piSeg, PRTLDRADDR poffSeg) 329 { 330 return pThis->pMod->pImgVt->pfnLinkAddressToSegOffset(pThis->pMod, LinkAddress, piSeg, poffSeg); 331 } 332 333 334 /* 335 * 336 * DWARF Cursor. 337 * DWARF Cursor. 338 * DWARF Cursor. 339 * 340 */ 341 342 343 /** 344 * Reads a 8-bit unsigned integer and advances the cursor. 345 * 346 * @returns 8-bit unsigned integer. On error RTDWARFCURSOR::rc is set and @a 347 * uErrValue is returned. 348 * @param pCursor The cursor. 349 * @param uErrValue What to return on read error. 350 */ 351 static uint8_t rtDwarfCursor_GetU8(PRTDWARFCURSOR pCursor, uint8_t uErrValue) 352 { 353 if (pCursor->cbUnitLeft < 1) 354 { 355 pCursor->rc = VERR_DWARF_UNEXPECTED_END; 356 return uErrValue; 357 } 358 359 uint8_t u8 = pCursor->pb[0]; 360 pCursor->pb += 1; 361 pCursor->cbUnitLeft -= 1; 362 pCursor->cbLeft -= 1; 363 return u8; 364 } 365 366 367 /** 368 * Reads a 16-bit unsigned integer and advances the cursor. 369 * 370 * @returns 16-bit unsigned integer. On error RTDWARFCURSOR::rc is set and @a 371 * uErrValue is returned. 372 * @param pCursor The cursor. 373 * @param uErrValue What to return on read error. 374 */ 375 static uint16_t rtDwarfCursor_GetU16(PRTDWARFCURSOR pCursor, uint16_t uErrValue) 376 { 377 if (pCursor->cbUnitLeft < 2) 378 { 379 pCursor->pb += pCursor->cbUnitLeft; 380 pCursor->cbLeft -= pCursor->cbUnitLeft; 381 pCursor->cbUnitLeft = 0; 382 pCursor->rc = VERR_DWARF_UNEXPECTED_END; 383 return uErrValue; 384 } 385 386 uint16_t u16 = RT_MAKE_U16(pCursor->pb[0], pCursor->pb[1]); 387 pCursor->pb += 2; 388 pCursor->cbUnitLeft -= 2; 389 pCursor->cbLeft -= 2; 390 if (!pCursor->fNativEndian) 391 u16 = RT_BSWAP_U16(u16); 392 return u16; 393 } 394 395 396 /** 397 * Reads a 32-bit unsigned integer and advances the cursor. 398 * 399 * @returns 32-bit unsigned integer. On error RTDWARFCURSOR::rc is set and @a 400 * uErrValue is returned. 401 * @param pCursor The cursor. 402 * @param uErrValue What to return on read error. 403 */ 404 static uint32_t rtDwarfCursor_GetU32(PRTDWARFCURSOR pCursor, uint32_t uErrValue) 405 { 406 if (pCursor->cbUnitLeft < 4) 407 { 408 pCursor->pb += pCursor->cbUnitLeft; 409 pCursor->cbLeft -= pCursor->cbUnitLeft; 410 pCursor->cbUnitLeft = 0; 411 pCursor->rc = VERR_DWARF_UNEXPECTED_END; 412 return uErrValue; 413 } 414 415 uint32_t u32 = RT_MAKE_U32_FROM_U8(pCursor->pb[0], pCursor->pb[1], pCursor->pb[2], pCursor->pb[3]); 416 pCursor->pb += 4; 417 pCursor->cbUnitLeft -= 4; 418 pCursor->cbLeft -= 4; 419 if (!pCursor->fNativEndian) 420 u32 = RT_BSWAP_U32(u32); 421 return u32; 422 } 423 424 425 /** 426 * Reads a 64-bit unsigned integer and advances the cursor. 427 * 428 * @returns 64-bit unsigned integer. On error RTDWARFCURSOR::rc is set and @a 429 * uErrValue is returned. 430 * @param pCursor The cursor. 431 * @param uErrValue What to return on read error. 432 */ 433 static uint64_t rtDwarfCursor_GetU64(PRTDWARFCURSOR pCursor, uint64_t uErrValue) 434 { 435 if (pCursor->cbUnitLeft < 8) 436 { 437 pCursor->pb += pCursor->cbUnitLeft; 438 pCursor->cbLeft -= pCursor->cbUnitLeft; 439 pCursor->cbUnitLeft = 0; 440 pCursor->rc = VERR_DWARF_UNEXPECTED_END; 441 return uErrValue; 442 } 443 444 uint64_t u64 = RT_MAKE_U64_FROM_U8(pCursor->pb[0], pCursor->pb[1], pCursor->pb[2], pCursor->pb[3], 445 pCursor->pb[4], pCursor->pb[5], pCursor->pb[6], pCursor->pb[7]); 446 pCursor->pb += 8; 447 pCursor->cbUnitLeft -= 8; 448 pCursor->cbLeft -= 8; 449 if (!pCursor->fNativEndian) 450 u64 = RT_BSWAP_U64(u64); 451 return u64; 452 } 453 454 455 /** 456 * Reads an unsigned LEB128 encoded number. 457 * 458 * @returns unsigned 64-bit number. On error RTDWARFCURSOR::rc is set and @a 459 * uErrValue is returned. 460 * @param pCursor The cursor. 461 * @param uErrValue The value to return on error. 462 */ 463 static uint64_t rtDwarfCursor_GetULeb128(PRTDWARFCURSOR pCursor, uint64_t uErrValue) 464 { 465 if (pCursor->cbUnitLeft < 1) 466 { 467 pCursor->rc = VERR_DWARF_UNEXPECTED_END; 468 return uErrValue; 469 } 470 471 /* 472 * Special case - single byte. 473 */ 474 uint8_t b = pCursor->pb[0]; 475 if (!(b & 0x80)) 476 { 477 pCursor->pb += 1; 478 pCursor->cbUnitLeft -= 1; 479 pCursor->cbLeft -= 1; 480 return b; 481 } 482 483 /* 484 * Generic case. 485 */ 486 /* Decode. */ 487 uint32_t off = 1; 488 uint64_t u64Ret = b & 0x7f; 489 do 490 { 491 if (off == pCursor->cbUnitLeft) 492 { 493 pCursor->rc = VERR_DWARF_UNEXPECTED_END; 494 u64Ret = uErrValue; 495 break; 496 } 497 b = pCursor->pb[off]; 498 u64Ret |= (b & 0x7f) << off * 7; 499 off++; 500 } while (b & 0x80); 501 502 /* Update the cursor. */ 503 pCursor->pb += off; 504 pCursor->cbUnitLeft -= off; 505 pCursor->cbLeft -= off; 506 507 /* Check the range. */ 508 uint32_t cBits = off * 7; 509 if (cBits > 64) 510 { 511 pCursor->rc = VERR_DWARF_LEB_OVERFLOW; 512 u64Ret = uErrValue; 513 } 514 515 return u64Ret; 516 } 517 518 519 /** 520 * Reads a signed LEB128 encoded number. 521 * 522 * @returns signed 64-bit number. On error RTDWARFCURSOR::rc is set and @a 523 * uErrValue is returned. 524 * @param pCursor The cursor. 525 * @param sErrValue The value to return on error. 526 */ 527 static int64_t rtDwarfCursor_GetSLeb128(PRTDWARFCURSOR pCursor, int64_t sErrValue) 528 { 529 if (pCursor->cbUnitLeft < 1) 530 { 531 pCursor->rc = VERR_DWARF_UNEXPECTED_END; 532 return sErrValue; 533 } 534 535 /* 536 * Special case - single byte. 537 */ 538 uint8_t b = pCursor->pb[0]; 539 if (!(b & 0x80)) 540 { 541 pCursor->pb += 1; 542 pCursor->cbUnitLeft -= 1; 543 pCursor->cbLeft -= 1; 544 if (b & 0x40) 545 b |= 0x80; 546 return (int8_t)b; 547 } 548 549 /* 550 * Generic case. 551 */ 552 /* Decode it. */ 553 uint32_t off = 1; 554 uint64_t u64Ret = b & 0x7f; 555 do 556 { 557 if (off == pCursor->cbUnitLeft) 558 { 559 pCursor->rc = VERR_DWARF_UNEXPECTED_END; 560 u64Ret = (uint64_t)sErrValue; 561 break; 562 } 563 b = pCursor->pb[off]; 564 u64Ret |= (b & 0x7f) << off * 7; 565 off++; 566 } while (b & 0x80); 567 568 /* Update cursor. */ 569 pCursor->pb += off; 570 pCursor->cbUnitLeft -= off; 571 pCursor->cbLeft -= off; 572 573 /* Check the range. */ 574 uint32_t cBits = off * 7; 575 if (cBits > 64) 576 { 577 pCursor->rc = VERR_DWARF_LEB_OVERFLOW; 578 u64Ret = (uint64_t)sErrValue; 579 } 580 /* Sign extend the value. */ 581 else if (u64Ret & RT_BIT_64(cBits - 1)) 582 u64Ret |= ~(RT_BIT_64(cBits - 1) - 1); 583 584 return (int64_t)u64Ret; 585 } 586 587 588 /** 589 * Reads an unsigned LEB128 encoded number, max 32-bit width. 590 * 591 * @returns unsigned 32-bit number. On error RTDWARFCURSOR::rc is set and @a 592 * uErrValue is returned. 593 * @param pCursor The cursor. 594 * @param uErrValue The value to return on error. 595 */ 596 static uint32_t rtDwarfCursor_GetULeb128AsU32(PRTDWARFCURSOR pCursor, uint32_t uErrValue) 597 { 598 uint64_t u64 = rtDwarfCursor_GetULeb128(pCursor, uErrValue); 599 if (u64 > UINT32_MAX) 600 { 601 pCursor->rc = VERR_DWARF_LEB_OVERFLOW; 602 return uErrValue; 603 } 604 return (uint32_t)u64; 605 } 606 607 608 /** 609 * Reads a signed LEB128 encoded number, max 32-bit width. 610 * 611 * @returns signed 32-bit number. On error RTDWARFCURSOR::rc is set and @a 612 * uErrValue is returned. 613 * @param pCursor The cursor. 614 * @param sErrValue The value to return on error. 615 */ 616 static int32_t rtDwarfCursor_GetSLeb128AsS32(PRTDWARFCURSOR pCursor, int32_t sErrValue) 617 { 618 int64_t s64 = rtDwarfCursor_GetSLeb128(pCursor, sErrValue); 619 if (s64 > INT32_MAX || s64 < INT32_MIN) 620 { 621 pCursor->rc = VERR_DWARF_LEB_OVERFLOW; 622 return sErrValue; 623 } 624 return (int32_t)s64; 625 } 626 627 628 /** 629 * Skips a LEB128 encoded number. 630 * 631 * @returns IPRT status code. 632 * @param pCursor The cursor. 633 */ 634 static int rtDwarfCursor_SkipLeb128(PRTDWARFCURSOR pCursor) 635 { 636 if (pCursor->cbUnitLeft < 1) 637 return pCursor->rc = VERR_DWARF_UNEXPECTED_END; 638 639 uint32_t offSkip = 1; 640 if (pCursor->pb[0] & 0x80) 641 do 642 { 643 if (offSkip == pCursor->cbUnitLeft) 644 { 645 pCursor->rc = VERR_DWARF_UNEXPECTED_END; 646 break; 647 } 648 } while (pCursor->pb[offSkip++] & 0x80); 649 650 pCursor->pb += offSkip; 651 pCursor->cbUnitLeft -= offSkip; 652 pCursor->cbLeft -= offSkip; 653 return pCursor->rc; 654 } 655 656 657 /** 658 * Reads a zero terminated string, advancing the cursor beyond the terminator. 659 * 660 * @returns Pointer to the string. 661 * @param pCursor The cursor. 662 * @param pszErrValue What to return if the string isn't terminated 663 * before the end of the unit. 664 */ 665 static const char *rtDwarfCursor_GetSZ(PRTDWARFCURSOR pCursor, const char *pszErrValue) 666 { 667 const char *pszRet = (const char *)pCursor->pb; 668 for (;;) 669 { 670 if (!pCursor->cbUnitLeft) 671 { 672 pCursor->rc = VERR_DWARF_BAD_STRING; 673 return pszErrValue; 674 } 675 pCursor->cbUnitLeft--; 676 pCursor->cbLeft--; 677 if (!*pCursor->pb++) 678 break; 679 } 680 return pszRet; 681 } 682 683 684 /** 685 * Reads an unsigned DWARF half number. 686 * 687 * @returns The number. On error RTDWARFCURSOR::rc is set and @a 688 * uErrValue is returned. 689 * @param pCursor The cursor. 690 * @param uErrValue What to return on error. 691 */ 692 static uint16_t rtDwarfCursor_GetUHalf(PRTDWARFCURSOR pCursor, uint16_t uErrValue) 693 { 694 return rtDwarfCursor_GetU16(pCursor, uErrValue); 695 } 696 697 698 /** 699 * Reads an unsigned DWARF byte number. 700 * 701 * @returns The number. On error RTDWARFCURSOR::rc is set and @a 702 * uErrValue is returned. 703 * @param pCursor The cursor. 704 * @param uErrValue What to return on error. 705 */ 706 static uint8_t rtDwarfCursor_GetUByte(PRTDWARFCURSOR pCursor, uint8_t uErrValue) 707 { 708 return rtDwarfCursor_GetU8(pCursor, uErrValue); 709 } 710 711 712 /** 713 * Reads a signed DWARF byte number. 714 * 715 * @returns The number. On error RTDWARFCURSOR::rc is set and @a 716 * uErrValue is returned. 717 * @param pCursor The cursor. 718 * @param uErrValue What to return on error. 719 */ 720 static int8_t rtDwarfCursor_GetSByte(PRTDWARFCURSOR pCursor, int8_t iErrValue) 721 { 722 return (int8_t)rtDwarfCursor_GetU8(pCursor, (uint8_t)iErrValue); 723 } 724 725 726 /** 727 * Reads a unsigned DWARF offset value. 728 * 729 * @returns The value. On error RTDWARFCURSOR::rc is set and @a 730 * uErrValue is returned. 731 * @param pCursor The cursor. 732 * @param uErrValue What to return on error. 733 */ 734 static uint64_t rtDwarfCursor_GetUOff(PRTDWARFCURSOR pCursor, uint64_t uErrValue) 735 { 736 if (pCursor->f64bitDwarf) 737 return rtDwarfCursor_GetU64(pCursor, uErrValue); 738 return rtDwarfCursor_GetU32(pCursor, (uint32_t)uErrValue); 739 } 740 741 742 /** 743 * Reads a unsigned DWARF native offset value. 744 * 745 * @returns The value. On error RTDWARFCURSOR::rc is set and @a 746 * uErrValue is returned. 747 * @param pCursor The cursor. 748 * @param uErrValue What to return on error. 749 */ 750 static uint64_t rtDwarfCursor_GetNativeUOff(PRTDWARFCURSOR pCursor, uint64_t uErrValue) 751 { 752 switch (pCursor->cbNativeAddr) 753 { 754 case 1: return rtDwarfCursor_GetU8(pCursor, (uint8_t )uErrValue); 755 case 2: return rtDwarfCursor_GetU16(pCursor, (uint16_t)uErrValue); 756 case 4: return rtDwarfCursor_GetU32(pCursor, (uint32_t)uErrValue); 757 case 8: return rtDwarfCursor_GetU64(pCursor, uErrValue); 758 default: 759 pCursor->rc = VERR_INTERNAL_ERROR_2; 760 return uErrValue; 761 } 762 } 763 764 765 /** 766 * Gets the unit length, updating the unit length member and DWARF bitness 767 * members of the cursor. 768 * 769 * @returns The unit length. 770 * @param pCursor The cursor. 771 */ 772 static uint64_t rtDwarfCursor_GetInitalLength(PRTDWARFCURSOR pCursor) 773 { 774 /* 775 * Read the initial length. 776 */ 777 pCursor->cbUnitLeft = pCursor->cbLeft; 778 uint64_t cbUnit = rtDwarfCursor_GetU32(pCursor, 0); 779 if (cbUnit != UINT32_C(0xffffffff)) 780 pCursor->f64bitDwarf = false; 781 else 782 { 783 pCursor->f64bitDwarf = true; 784 cbUnit = rtDwarfCursor_GetU64(pCursor, 0); 785 } 786 787 788 /* 789 * Set the unit length, quitely fixing bad lengths. 790 */ 791 pCursor->cbUnitLeft = (size_t)cbUnit; 792 if ( pCursor->cbUnitLeft > pCursor->cbLeft 793 || pCursor->cbUnitLeft != cbUnit) 794 pCursor->cbUnitLeft = pCursor->cbLeft; 795 796 return cbUnit; 797 } 798 799 800 /** 801 * Calculates an absolute cursor position from one relative to the current 802 * cursor position. 803 * 804 * @returns The absolute cursor position. 805 * @param pCursor The cursor. 806 * @param offRelative The relative position. Must be a positive 807 * offset. 808 */ 809 static uint8_t const *rtDwarfCursor_CalcPos(PRTDWARFCURSOR pCursor, size_t offRelative) 810 { 811 if (offRelative > pCursor->cbUnitLeft) 812 { 813 pCursor->rc = VERR_DWARF_BAD_POS; 814 return NULL; 815 } 816 return pCursor->pb + offRelative; 817 } 818 819 820 /** 821 * Advances the cursor to the given position. 822 * 823 * @returns IPRT status code. 824 * @param pCursor The cursor. 825 * @param pbNewPos The new position - returned by 826 * rtDwarfCursor_CalcPos(). 827 */ 828 static int rtDwarfCursor_AdvanceToPos(PRTDWARFCURSOR pCursor, uint8_t const *pbNewPos) 829 { 830 if (RT_FAILURE(pCursor->rc)) 831 return pCursor->rc; 832 AssertPtr(pbNewPos); 833 if ((uintptr_t)pbNewPos < (uintptr_t)pCursor->pb) 834 return pCursor->rc = VERR_DWARF_BAD_POS; 835 836 uintptr_t cbAdj = (uintptr_t)pbNewPos - (uintptr_t)pCursor->pb; 837 if (RT_UNLIKELY(cbAdj > pCursor->cbUnitLeft)) 838 { 839 AssertFailed(); 840 pCursor->rc = VERR_DWARF_BAD_POS; 841 cbAdj = pCursor->cbUnitLeft; 842 } 843 844 pCursor->cbUnitLeft -= cbAdj; 845 pCursor->cbLeft -= cbAdj; 846 pCursor->pb += cbAdj; 847 return pCursor->rc; 848 } 849 850 851 /** 852 * Check if the cursor is at the end of the current DWARF unit. 853 * 854 * @returns @c true if at the end, @c false if not. 855 * @param pCursor The cursor. 856 */ 857 static bool rtDwarfCursor_IsAtEndOfUnit(PRTDWARFCURSOR pCursor) 858 { 859 return !pCursor->cbUnitLeft; 860 } 861 862 863 /** 864 * Skips to the end of the current unit. 865 * 866 * @returns IPRT status code. 867 * @param pCursor The cursor. 868 */ 869 static int rtDwarfCursor_SkipUnit(PRTDWARFCURSOR pCursor) 870 { 871 pCursor->pb += pCursor->cbUnitLeft; 872 pCursor->cbLeft -= pCursor->cbUnitLeft; 873 pCursor->cbUnitLeft = 0; 874 return pCursor->rc; 875 } 876 877 878 /** 879 * Check if the cursor is at the end of the section (or whatever the cursor is 880 * processing). 881 * 882 * @returns @c true if at the end, @c false if not. 883 * @param pCursor The cursor. 884 */ 885 static bool rtDwarfCursor_IsAtEnd(PRTDWARFCURSOR pCursor) 886 { 887 return !pCursor->cbLeft; 888 } 889 890 891 /** 892 * Initialize a section reader cursor. 893 * 894 * @returns IPRT status code. 895 * @param pCursor The cursor. 896 * @param pThis The dwarf module. 897 * @param enmSect The name of the section to read. 898 */ 899 static int rtDwarfCursor_Init(PRTDWARFCURSOR pCursor, PRTDBGMODDWARF pThis, krtDbgModDwarfSect enmSect) 900 { 901 int rc = rtDbgModDwarfLoadSection(pThis, enmSect); 902 if (RT_FAILURE(rc)) 903 return rc; 904 905 pCursor->pbStart = (uint8_t const *)pThis->aSections[enmSect].pv; 906 pCursor->pb = pCursor->pbStart; 907 pCursor->cbLeft = pThis->aSections[enmSect].cb; 908 pCursor->cbUnitLeft = pCursor->cbLeft; 909 pCursor->pDwarfMod = pThis; 910 pCursor->f64bitDwarf = false; 911 /** @todo ask the image about the endian used as well as the address 912 * width. */ 913 pCursor->fNativEndian = true; 914 pCursor->cbNativeAddr = 4; 915 pCursor->rc = VINF_SUCCESS; 916 917 return VINF_SUCCESS; 918 } 919 920 921 /** 922 * Deletes a section reader initialized by rtDwarfCursor_Init. 923 * 924 * @param pCursor The section reader. 925 */ 926 static void rtDwarfCursor_Delete(PRTDWARFCURSOR pCursor) 927 { 928 /* ... and a drop of poison. */ 929 pCursor->pb = NULL; 930 pCursor->cbLeft = ~(size_t)0; 931 pCursor->cbUnitLeft = ~(size_t)0; 932 pCursor->pDwarfMod = NULL; 933 pCursor->rc = VERR_INTERNAL_ERROR_4; 934 } 935 936 937 /* 938 * 939 * DWARF Line Numbers. 940 * DWARF Line Numbers. 941 * DWARF Line Numbers. 942 * 943 */ 944 945 946 /** 947 * Defines a file name. 948 * 949 * @returns IPRT status code. 950 * @param pLnState The line number program state. 951 * @param pszFilename The name of the file. 952 * @param idxInc The include path index. 953 */ 921 954 static int rtDwarfLine_DefineFileName(PRTDWARFLINESTATE pLnState, const char *pszFilename, uint64_t idxInc) 922 955 { … … 957 990 958 991 959 static int rtDwarfLine_StdOp_Copy(PRTDWARFLINESTATE pLnState) 992 /** 993 * Adds a line to the table and resets parts of the state (DW_LNS_copy). 994 * 995 * @returns IPRT status code 996 * @param pLnState The line number program state. 997 */ 998 static int rtDwarfLine_AddLine(PRTDWARFLINESTATE pLnState) 960 999 { 961 1000 const char *pszFile = pLnState->Regs.iFile < pLnState->cFileNames … … 967 1006 if (RT_SUCCESS(rc)) 968 1007 { 969 Log2(("rtDwarfLine_ StdOp_Copy: %x:%08llx (%#llx) %s(%d)\n", iSeg, offSeg, pLnState->Regs.uAddress, pszFile, pLnState->Regs.uLine));1008 Log2(("rtDwarfLine_AddLine: %x:%08llx (%#llx) %s(%d)\n", iSeg, offSeg, pLnState->Regs.uAddress, pszFile, pLnState->Regs.uLine)); 970 1009 rc = RTDbgModLineAdd(pLnState->pDwarfMod->hCnt, pszFile, pLnState->Regs.uLine, iSeg, offSeg, NULL); 971 1010 … … 1044 1083 cOpIndexDelta, pLnState->Regs.idxOp)); 1045 1084 1046 rc = rtDwarfLine_ StdOp_Copy(pLnState);1085 rc = rtDwarfLine_AddLine(pLnState); 1047 1086 } 1048 1087 else … … 1055 1094 case DW_LNS_copy: 1056 1095 Log2(("DW_LNS_copy\n")); 1057 rc = rtDwarfLine_ StdOp_Copy(pLnState);1096 rc = rtDwarfLine_AddLine(pLnState); 1058 1097 break; 1059 1098 … … 1151 1190 { 1152 1191 case DW_LNE_end_sequence: 1153 #if 0 /* No need for this */1192 #if 0 /* No need for this, I think. */ 1154 1193 pLnState->Regs.fEndSequence = true; 1155 rc = rtDwarfLine_ StdOp_Copy(pLnState);1194 rc = rtDwarfLine_AddLine(pLnState); 1156 1195 #endif 1157 1196 rtDwarfLine_ResetState(pLnState); … … 1167 1206 default: 1168 1207 AssertMsgFailed(("%d\n", cbInstr)); 1169 pLnState->Regs.uAddress = rtDwarfCursor_Get UOff(pCursor, UINT64_MAX);1208 pLnState->Regs.uAddress = rtDwarfCursor_GetNativeUOff(pCursor, UINT64_MAX); 1170 1209 break; 1171 1210 } … … 1279 1318 1280 1319 1281 static int rtDbgModDwarfExplodeLineNumbersForUnit(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor) 1320 /** 1321 * Explodes the line number table for a compilation unit. 1322 * 1323 * @returns IPRT status code 1324 * @param pThis The DWARF instance. 1325 * @param pCursor The cursor to read the line number information 1326 * via. 1327 */ 1328 static int rtDwarfLine_ExplodeUnit(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor) 1282 1329 { 1283 1330 RTDWARFLINESTATE LnState; … … 1364 1411 * @param pThis The DWARF instance. 1365 1412 */ 1366 static int rtD bgModDwarfExplodeLineNumbers(PRTDBGMODDWARF pThis)1413 static int rtDwarfLine_ExplodeAll(PRTDBGMODDWARF pThis) 1367 1414 { 1368 1415 if (!pThis->aSections[krtDbgModDwarfSect_line].fPresent) … … 1376 1423 while ( !rtDwarfCursor_IsAtEnd(&Cursor) 1377 1424 && RT_SUCCESS(rc)) 1378 rc = rtDbgModDwarfExplodeLineNumbersForUnit(pThis, &Cursor); 1379 1425 rc = rtDwarfLine_ExplodeUnit(pThis, &Cursor); 1380 1426 1381 1427 rtDwarfCursor_Delete(&Cursor); … … 1431 1477 1432 1478 1433 /** @callback_method_impl{FNRTLDRENUMSEGS} */ 1434 static DECLCALLBACK(int) rtDbgModHlpAddSegmentCallback(RTLDRMOD hLdrMod, PCRTLDRSEG pSeg, void *pvUser) 1435 { 1436 PRTDBGMODINT pMod = (PRTDBGMODINT)pvUser; 1437 Log(("Segment %.*s: LinkAddress=%#llx RVA=%#llx cb=%#llx\n", 1438 pSeg->cchName, pSeg->pchName, (uint64_t)pSeg->LinkAddress, (uint64_t)pSeg->RVA, pSeg->cb)); 1439 #if 0 1440 return pMod->pDbgVt->pfnSegmentAdd(pMod, pSeg->RVA, pSeg->cb, pSeg->pchName, pSeg->cchName, 0 /*fFlags*/, NULL); 1441 #else 1442 return pMod->pDbgVt->pfnSegmentAdd(pMod, pSeg->LinkAddress, pSeg->cb, pSeg->pchName, pSeg->cchName, 0 /*fFlags*/, NULL); 1443 #endif 1444 } 1445 1446 1447 /** 1448 * Calls pfnSegmentAdd for each segment in the executable image. 1449 * 1450 * @returns IPRT status code. 1451 * @param pMod The debug module. 1452 */ 1453 DECLHIDDEN(int) rtDbgModHlpAddSegmentsFromImage(PRTDBGMODINT pMod) 1454 { 1455 AssertReturn(pMod->pImgVt, VERR_INTERNAL_ERROR_2); 1456 return pMod->pImgVt->pfnEnumSegments(pMod, rtDbgModHlpAddSegmentCallback, pMod); 1479 /* 1480 * 1481 * DWARF Debug module implementation. 1482 * DWARF Debug module implementation. 1483 * DWARF Debug module implementation. 1484 * 1485 */ 1486 1487 1488 /** @interface_method_impl{RTDBGMODVTDBG,pfnLineByAddr} */ 1489 static DECLCALLBACK(int) rtDbgModDwarf_LineByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, 1490 PRTINTPTR poffDisp, PRTDBGLINE pLineInfo) 1491 { 1492 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv; 1493 return RTDbgModLineByAddr(pThis->hCnt, iSeg, off, poffDisp, pLineInfo); 1494 } 1495 1496 1497 /** @interface_method_impl{RTDBGMODVTDBG,pfnLineByOrdinal} */ 1498 static DECLCALLBACK(int) rtDbgModDwarf_LineByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo) 1499 { 1500 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv; 1501 return RTDbgModLineByOrdinal(pThis->hCnt, iOrdinal, pLineInfo); 1502 } 1503 1504 1505 /** @interface_method_impl{RTDBGMODVTDBG,pfnLineCount} */ 1506 static DECLCALLBACK(uint32_t) rtDbgModDwarf_LineCount(PRTDBGMODINT pMod) 1507 { 1508 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv; 1509 return RTDbgModLineCount(pThis->hCnt); 1510 } 1511 1512 1513 /** @interface_method_impl{RTDBGMODVTDBG,pfnLineAdd} */ 1514 static DECLCALLBACK(int) rtDbgModDwarf_LineAdd(PRTDBGMODINT pMod, const char *pszFile, size_t cchFile, uint32_t uLineNo, 1515 uint32_t iSeg, RTUINTPTR off, uint32_t *piOrdinal) 1516 { 1517 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv; 1518 return RTDbgModLineAdd(pThis->hCnt, pszFile, uLineNo, iSeg, off, piOrdinal); 1519 } 1520 1521 1522 /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByAddr} */ 1523 static DECLCALLBACK(int) rtDbgModDwarf_SymbolByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, 1524 PRTINTPTR poffDisp, PRTDBGSYMBOL pSymInfo) 1525 { 1526 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv; 1527 return RTDbgModSymbolByAddr(pThis->hCnt, iSeg, off, poffDisp, pSymInfo); 1528 } 1529 1530 1531 /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByName} */ 1532 static DECLCALLBACK(int) rtDbgModDwarf_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol, 1533 PRTDBGSYMBOL pSymInfo) 1534 { 1535 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv; 1536 Assert(!pszSymbol[cchSymbol]); 1537 return RTDbgModSymbolByName(pThis->hCnt, pszSymbol/*, cchSymbol*/, pSymInfo); 1538 } 1539 1540 1541 /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByOrdinal} */ 1542 static DECLCALLBACK(int) rtDbgModDwarf_SymbolByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo) 1543 { 1544 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv; 1545 return RTDbgModSymbolByOrdinal(pThis->hCnt, iOrdinal, pSymInfo); 1546 } 1547 1548 1549 /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolCount} */ 1550 static DECLCALLBACK(uint32_t) rtDbgModDwarf_SymbolCount(PRTDBGMODINT pMod) 1551 { 1552 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv; 1553 return RTDbgModSymbolCount(pThis->hCnt); 1554 } 1555 1556 1557 /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolAdd} */ 1558 static DECLCALLBACK(int) rtDbgModDwarf_SymbolAdd(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol, 1559 RTDBGSEGIDX iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags, 1560 uint32_t *piOrdinal) 1561 { 1562 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv; 1563 return RTDbgModSymbolAdd(pThis->hCnt, pszSymbol, iSeg, off, cb, fFlags, piOrdinal); 1564 } 1565 1566 1567 /** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentByIndex} */ 1568 static DECLCALLBACK(int) rtDbgModDwarf_SegmentByIndex(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo) 1569 { 1570 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv; 1571 return RTDbgModSegmentByIndex(pThis->hCnt, iSeg, pSegInfo); 1572 } 1573 1574 1575 /** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentCount} */ 1576 static DECLCALLBACK(RTDBGSEGIDX) rtDbgModDwarf_SegmentCount(PRTDBGMODINT pMod) 1577 { 1578 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv; 1579 return RTDbgModSegmentCount(pThis->hCnt); 1580 } 1581 1582 1583 /** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentAdd} */ 1584 static DECLCALLBACK(int) rtDbgModDwarf_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName, size_t cchName, 1585 uint32_t fFlags, PRTDBGSEGIDX piSeg) 1586 { 1587 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv; 1588 return RTDbgModSegmentAdd(pThis->hCnt, uRva, cb, pszName, fFlags, piSeg); 1589 } 1590 1591 1592 /** @interface_method_impl{RTDBGMODVTDBG,pfnImageSize} */ 1593 static DECLCALLBACK(RTUINTPTR) rtDbgModDwarf_ImageSize(PRTDBGMODINT pMod) 1594 { 1595 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv; 1596 RTUINTPTR cb1 = RTDbgModImageSize(pThis->hCnt); 1597 RTUINTPTR cb2 = pMod->pImgVt->pfnImageSize(pMod); 1598 return RT_MAX(cb1, cb2); 1599 } 1600 1601 1602 /** @interface_method_impl{RTDBGMODVTDBG,pfnRvaToSegOff} */ 1603 static DECLCALLBACK(RTDBGSEGIDX) rtDbgModDwarf_RvaToSegOff(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg) 1604 { 1605 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv; 1606 return RTDbgModRvaToSegOff(pThis->hCnt, uRva, poffSeg); 1607 } 1608 1609 1610 /** @interface_method_impl{RTDBGMODVTDBG,pfnClose} */ 1611 static DECLCALLBACK(int) rtDbgModDwarf_Close(PRTDBGMODINT pMod) 1612 { 1613 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv; 1614 1615 for (unsigned iSect = 0; iSect < RT_ELEMENTS(pThis->aSections); iSect++) 1616 if (pThis->aSections[iSect].pv) 1617 pThis->pMod->pImgVt->pfnUnmapPart(pThis->pMod, pThis->aSections[iSect].cb, &pThis->aSections[iSect].pv); 1618 1619 RTDbgModRelease(pThis->hCnt); 1620 RTMemFree(pThis); 1621 1622 return VINF_SUCCESS; 1457 1623 } 1458 1624 … … 1563 1729 rc = rtDbgModDwarfExtractSymbols(pThis); 1564 1730 if (RT_SUCCESS(rc)) 1565 rc = rtD bgModDwarfExplodeLineNumbers(pThis);1731 rc = rtDwarfLine_ExplodeAll(pThis); 1566 1732 if (RT_SUCCESS(rc)) 1567 1733 { -
trunk/src/VBox/Runtime/common/dbg/dbgmodldr.cpp
r38547 r38581 99 99 100 100 101 /** @interface_method_impl{RTDBGMODVTIMG,pfnLinkAddressToSegOffset} */ 102 static DECLCALLBACK(int) rtDbgModLdr_LinkAddressToSegOffset(PRTDBGMODINT pMod, RTLDRADDR LinkAddress, 103 PRTDBGSEGIDX piSeg, PRTLDRADDR poffSeg) 104 { 105 PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv; 106 return RTLdrLinkAddressToSegOffset(pThis->hLdrMod, LinkAddress, piSeg, poffSeg); 107 } 108 109 101 110 /** @interface_method_impl{RTDBGMODVTIMG,pfnEnumSegments} */ 102 111 static DECLCALLBACK(int) rtDbgModLdr_EnumSegments(PRTDBGMODINT pMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser) … … 166 175 DECL_HIDDEN_CONST(RTDBGMODVTIMG) const g_rtDbgModVtImgLdr = 167 176 { 168 /*.u32Magic = */ RTDBGMODVTIMG_MAGIC, 169 /*.fReserved = */ 0, 170 /*.pszName = */ "RTLdr", 171 /*.pfnTryOpen = */ rtDbgModLdr_TryOpen, 172 /*.pfnClose = */ rtDbgModLdr_Close, 173 /*.pfnEnumDbgInfo = */ rtDbgModLdr_EnumDbgInfo, 174 /*.pfnEnumSegments = */ rtDbgModLdr_EnumSegments, 175 /*.pfnGetLoadedSize = */ rtDbgModLdr_GetLoadedSize, 176 /*.pfnMapPart = */ rtDbgModLdr_MapPart, 177 /*.pfnUnmapPart = */ rtDbgModLdr_UnmapPart, 177 /*.u32Magic = */ RTDBGMODVTIMG_MAGIC, 178 /*.fReserved = */ 0, 179 /*.pszName = */ "RTLdr", 180 /*.pfnTryOpen = */ rtDbgModLdr_TryOpen, 181 /*.pfnClose = */ rtDbgModLdr_Close, 182 /*.pfnEnumDbgInfo = */ rtDbgModLdr_EnumDbgInfo, 183 /*.pfnEnumSegments = */ rtDbgModLdr_EnumSegments, 184 /*.pfnGetLoadedSize = */ rtDbgModLdr_GetLoadedSize, 185 /*.pfnLinkAddressToSegOffset = */ rtDbgModLdr_LinkAddressToSegOffset, 186 /*.pfnMapPart = */ rtDbgModLdr_MapPart, 187 /*.pfnUnmapPart = */ rtDbgModLdr_UnmapPart, 178 188 179 /*.u32EndMagic = */ RTDBGMODVTIMG_MAGIC189 /*.u32EndMagic = */ RTDBGMODVTIMG_MAGIC 180 190 }; 181 191
Note:
See TracChangeset
for help on using the changeset viewer.