VirtualBox

Ignore:
Timestamp:
Aug 31, 2011 12:43:26 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
73772
Message:

IPRT: More debug info & ldr stuff.

Location:
trunk/src/VBox/Runtime/common/dbg
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/dbg/dbgmoddwarf.cpp

    r38573 r38581  
    9898} krtDbgModDwarfSect;
    9999
     100
    100101/**
    101102 * The instance data of the DWARF reader.
     
    125126
    126127/**
    127  * Section reader instance.
     128 * DWARF cursor for reading byte data.
    128129 */
    129130typedef struct RTDWARFSECTRDR
     
    147148     *  occurs. */
    148149    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;
    149153} RTDWARFCURSOR;
    150154/** Pointer to a DWARF section reader. */
    151155typedef 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 they
    171      * are empty
    172      */
    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 be
    219  *                              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     do
    361     {
    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     do
    426     {
    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         do
    504         {
    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 terminated
    526  *                              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 bitness
    576  * 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     else
    591     {
    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->cbLeft
    602         || 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 current
    611  * cursor position.
    612  *
    613  * @returns The absolute cursor position.
    614  * @param   pCursor             The cursor.
    615  * @param   offRelative         The relative position.  Must be a positive
    616  *                              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 by
    635  *                              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 address
    705      *        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 }
    863156
    864157
     
    919212
    920213
     214/** @callback_method_impl{FNRTLDRENUMSEGS} */
     215static 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 */
     235DECLHIDDEN(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 */
     251static 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 */
     292static 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 */
     311static 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 */
     327static 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 */
     351static 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 */
     375static 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 */
     404static 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 */
     433static 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 */
     463static 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 */
     527static 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 */
     596static 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 */
     616static 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 */
     634static 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 */
     665static 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 */
     692static 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 */
     706static 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 */
     720static 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 */
     734static 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 */
     750static 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 */
     772static 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 */
     809static 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 */
     828static 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 */
     857static 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 */
     869static 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 */
     885static 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 */
     899static 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 */
     926static 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 */
    921954static int rtDwarfLine_DefineFileName(PRTDWARFLINESTATE pLnState, const char *pszFilename, uint64_t idxInc)
    922955{
     
    957990
    958991
    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 */
     998static int rtDwarfLine_AddLine(PRTDWARFLINESTATE pLnState)
    960999{
    9611000    const char *pszFile = pLnState->Regs.iFile < pLnState->cFileNames
     
    9671006    if (RT_SUCCESS(rc))
    9681007    {
    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));
    9701009        rc = RTDbgModLineAdd(pLnState->pDwarfMod->hCnt, pszFile, pLnState->Regs.uLine, iSeg, offSeg, NULL);
    9711010
     
    10441083                  cOpIndexDelta, pLnState->Regs.idxOp));
    10451084
    1046             rc = rtDwarfLine_StdOp_Copy(pLnState);
     1085            rc = rtDwarfLine_AddLine(pLnState);
    10471086        }
    10481087        else
     
    10551094                case DW_LNS_copy:
    10561095                    Log2(("DW_LNS_copy\n"));
    1057                     rc = rtDwarfLine_StdOp_Copy(pLnState);
     1096                    rc = rtDwarfLine_AddLine(pLnState);
    10581097                    break;
    10591098
     
    11511190                    {
    11521191                        case DW_LNE_end_sequence:
    1153 #if 0 /* No need for this */
     1192#if 0 /* No need for this, I think. */
    11541193                            pLnState->Regs.fEndSequence = true;
    1155                             rc = rtDwarfLine_StdOp_Copy(pLnState);
     1194                            rc = rtDwarfLine_AddLine(pLnState);
    11561195#endif
    11571196                            rtDwarfLine_ResetState(pLnState);
     
    11671206                                default:
    11681207                                    AssertMsgFailed(("%d\n", cbInstr));
    1169                                     pLnState->Regs.uAddress = rtDwarfCursor_GetUOff(pCursor, UINT64_MAX);
     1208                                    pLnState->Regs.uAddress = rtDwarfCursor_GetNativeUOff(pCursor, UINT64_MAX);
    11701209                                    break;
    11711210                            }
     
    12791318
    12801319
    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 */
     1328static int rtDwarfLine_ExplodeUnit(PRTDBGMODDWARF pThis, PRTDWARFCURSOR pCursor)
    12821329{
    12831330    RTDWARFLINESTATE LnState;
     
    13641411 * @param   pThis               The DWARF instance.
    13651412 */
    1366 static int rtDbgModDwarfExplodeLineNumbers(PRTDBGMODDWARF pThis)
     1413static int rtDwarfLine_ExplodeAll(PRTDBGMODDWARF pThis)
    13671414{
    13681415    if (!pThis->aSections[krtDbgModDwarfSect_line].fPresent)
     
    13761423    while (   !rtDwarfCursor_IsAtEnd(&Cursor)
    13771424           && RT_SUCCESS(rc))
    1378         rc = rtDbgModDwarfExplodeLineNumbersForUnit(pThis, &Cursor);
    1379 
     1425        rc = rtDwarfLine_ExplodeUnit(pThis, &Cursor);
    13801426
    13811427    rtDwarfCursor_Delete(&Cursor);
     
    14311477
    14321478
    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} */
     1489static 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} */
     1498static 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} */
     1506static 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} */
     1514static 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} */
     1523static 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} */
     1532static 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} */
     1542static 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} */
     1550static 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} */
     1558static 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} */
     1568static 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} */
     1576static 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} */
     1584static 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} */
     1593static 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} */
     1603static 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} */
     1611static 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;
    14571623}
    14581624
     
    15631729                    rc = rtDbgModDwarfExtractSymbols(pThis);
    15641730                if (RT_SUCCESS(rc))
    1565                     rc = rtDbgModDwarfExplodeLineNumbers(pThis);
     1731                    rc = rtDwarfLine_ExplodeAll(pThis);
    15661732                if (RT_SUCCESS(rc))
    15671733                {
  • trunk/src/VBox/Runtime/common/dbg/dbgmodldr.cpp

    r38547 r38581  
    9999
    100100
     101/** @interface_method_impl{RTDBGMODVTIMG,pfnLinkAddressToSegOffset} */
     102static 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
    101110/** @interface_method_impl{RTDBGMODVTIMG,pfnEnumSegments} */
    102111static DECLCALLBACK(int) rtDbgModLdr_EnumSegments(PRTDBGMODINT pMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser)
     
    166175DECL_HIDDEN_CONST(RTDBGMODVTIMG) const g_rtDbgModVtImgLdr =
    167176{
    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,
    178188
    179     /*.u32EndMagic = */         RTDBGMODVTIMG_MAGIC
     189    /*.u32EndMagic = */                 RTDBGMODVTIMG_MAGIC
    180190};
    181191
Note: See TracChangeset for help on using the changeset viewer.

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