VirtualBox

Changeset 38547 in vbox


Ignore:
Timestamp:
Aug 26, 2011 12:58:47 PM (13 years ago)
Author:
vboxsync
Message:

IPRT: More debug info hacking.

Location:
trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/ldr.h

    r38515 r38547  
    3838
    3939RT_C_DECLS_BEGIN
     40
     41/** Loader address (unsigned integer). */
     42typedef RTUINTPTR           RTLDRADDR;
     43/** Pointer to a loader address. */
     44typedef RTLDRADDR          *PRTLDRADDR;
     45/** Pointer to a const loader address. */
     46typedef RTLDRADDR const    *PCRTLDRADDR;
     47/** The max loader address value. */
     48#define RTLDRADDR_MAX       RTUINTPTR_MAX
     49/** NIL loader address value. */
     50#define NIL_RTLDRADDR       RTLDRADDR_MAX
    4051
    4152
     
    237248 * @param   pValue          Where to store the symbol value.
    238249 */
    239 RTDECL(int) RTLdrGetSymbolEx(RTLDRMOD hLdrMod, const void *pvBits, RTUINTPTR BaseAddress, const char *pszSymbol, RTUINTPTR *pValue);
     250RTDECL(int) RTLdrGetSymbolEx(RTLDRMOD hLdrMod, const void *pvBits, RTLDRADDR BaseAddress, const char *pszSymbol,
     251                             PRTLDRADDR pValue);
    240252
    241253/**
     
    261273 * @param   pvUser          User argument.
    262274 */
    263 typedef DECLCALLBACK(int) RTLDRIMPORT(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol, unsigned uSymbol, RTUINTPTR *pValue, void *pvUser);
     275typedef DECLCALLBACK(int) RTLDRIMPORT(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol, unsigned uSymbol,
     276                                      PRTLDRADDR pValue, void *pvUser);
    264277/** Pointer to a FNRTLDRIMPORT() callback function. */
    265278typedef RTLDRIMPORT *PFNRTLDRIMPORT;
     
    278291 * @remark  Not supported for RTLdrLoad() images.
    279292 */
    280 RTDECL(int) RTLdrGetBits(RTLDRMOD hLdrMod, void *pvBits, RTUINTPTR BaseAddress, PFNRTLDRIMPORT pfnGetImport, void *pvUser);
     293RTDECL(int) RTLdrGetBits(RTLDRMOD hLdrMod, void *pvBits, RTLDRADDR BaseAddress, PFNRTLDRIMPORT pfnGetImport, void *pvUser);
    281294
    282295/**
     
    294307 * @remark  Not supported for RTLdrLoad() images.
    295308 */
    296 RTDECL(int) RTLdrRelocate(RTLDRMOD hLdrMod, void *pvBits, RTUINTPTR NewBaseAddress, RTUINTPTR OldBaseAddress,
     309RTDECL(int) RTLdrRelocate(RTLDRMOD hLdrMod, void *pvBits, RTLDRADDR NewBaseAddress, RTLDRADDR OldBaseAddress,
    297310                          PFNRTLDRIMPORT pfnGetImport, void *pvUser);
    298311
     
    307320 * @param   pvUser          The user argument specified to RTLdrEnumSymbols().
    308321 */
    309 typedef DECLCALLBACK(int) RTLDRENUMSYMS(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol, RTUINTPTR Value, void *pvUser);
     322typedef DECLCALLBACK(int) RTLDRENUMSYMS(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol, RTLDRADDR Value, void *pvUser);
    310323/** Pointer to a RTLDRENUMSYMS() callback function. */
    311324typedef RTLDRENUMSYMS *PFNRTLDRENUMSYMS;
     
    324337 * @remark  Not supported for RTLdrLoad() images.
    325338 */
    326 RTDECL(int) RTLdrEnumSymbols(RTLDRMOD hLdrMod, unsigned fFlags, const void *pvBits, RTUINTPTR BaseAddress, PFNRTLDRENUMSYMS pfnCallback, void *pvUser);
     339RTDECL(int) RTLdrEnumSymbols(RTLDRMOD hLdrMod, unsigned fFlags, const void *pvBits, RTLDRADDR BaseAddress, PFNRTLDRENUMSYMS pfnCallback, void *pvUser);
    327340
    328341/** @name RTLdrEnumSymbols flags.
     
    377390 *                          if there isn't any specific file location.
    378391 * @param   LinkAddress     The link address of the debug info if it's
    379  *                          loadable. RTUINTPTR_MAX if not loadable.
     392 *                          loadable. NIL_RTLDRADDR if not loadable.
    380393 * @param   cb              The size of the debug information. -1 is used if
    381394 *                          this isn't applicable.
     
    387400typedef DECLCALLBACK(int) FNRTLDRENUMDBG(RTLDRMOD hLdrMod, uint32_t iDbgInfo, RTLDRDBGINFOTYPE enmType,
    388401                                         uint16_t iMajorVer, uint16_t iMinorVer, const char *pszPartNm,
    389                                          RTFOFF offFile, RTUINTPTR LinkAddress, RTUINTPTR cb,
     402                                         RTFOFF offFile, RTLDRADDR LinkAddress, RTLDRADDR cb,
    390403                                         const char *pszExtFile, void *pvUser);
    391404/** Pointer to a debug info enumerator callback. */
    392405typedef FNRTLDRENUMDBG *PFNRTLDRENUMDBG;
    393 
    394406
    395407/**
     
    407419RTDECL(int) RTLdrEnumDbgInfo(RTLDRMOD hLdrMod, const void *pvBits, PFNRTLDRENUMDBG pfnCallback, void *pvUser);
    408420
     421
     422/**
     423 * Loader segment.
     424 */
     425typedef struct RTLDRSEG
     426{
     427    /** The segment name. (Might not be zero terminated!) */
     428    const char     *pchName;
     429    /** The length of the segment name. */
     430    uint32_t        cchName;
     431    /** The flat selector to use for the segment (i.e. data/code).
     432     * Primarily a way for the user to specify selectors for the LX/LE and NE interpreters. */
     433    uint16_t        SelFlat;
     434    /** The 16-bit selector to use for the segment.
     435     * Primarily a way for the user to specify selectors for the LX/LE and NE interpreters. */
     436    uint16_t        Sel16bit;
     437    /** Segment flags. */
     438    uint32_t        fFlags;
     439    /** The segment protection (RTMEM_PROT_XXX). */
     440    uint32_t        fProt;
     441    /** The size of the segment. */
     442    RTLDRADDR       cb;
     443    /** The required segment alignment.
     444     * The to 0 if the segment isn't supposed to be mapped. */
     445    RTLDRADDR       Alignment;
     446    /** The link address.
     447     * Set to NIL_RTLDRADDR if the segment isn't supposed to be mapped or if
     448     * the image doesn't have link addresses. */
     449    RTLDRADDR       LinkAddress;
     450    /** File offset of the segment.
     451     * Set to -1 if no file backing (like BSS). */
     452    RTFOFF          offFile;
     453    /** Size of the file bits of the segment.
     454     * Set to -1 if no file backing (like BSS). */
     455    RTFOFF          cbFile;
     456    /** The relative virtual address when mapped.
     457     * Set to NIL_RTLDRADDR if the segment isn't supposed to be mapped. */
     458    RTLDRADDR       RVA;
     459    /** The size of the segment including the alignment gap up to the next segment when mapped.
     460     * This is set to NIL_RTLDRADDR if not implemented. */
     461    RTLDRADDR       cbMapped;
     462} RTLDRSEG;
     463/** Pointer to a loader segment. */
     464typedef RTLDRSEG *PRTLDRSEG;
     465/** Pointer to a read only loader segment. */
     466typedef RTLDRSEG const *PCRTLDRSEG;
     467
     468
     469/** @name Segment flags
     470 * @{ */
     471/** The segment is 16-bit. When not set the default of the target architecture is assumed. */
     472#define RTLDRSEG_FLAG_16BIT         UINT32_C(1)
     473/** The segment requires a 16-bit selector alias. (OS/2) */
     474#define RTLDRSEG_FLAG_OS2_ALIAS16   UINT32_C(2)
     475/** Conforming segment (x86 weirdness). (OS/2) */
     476#define RTLDRSEG_FLAG_OS2_CONFORM   UINT32_C(4)
     477/** IOPL (ring-2) segment. (OS/2) */
     478#define RTLDRSEG_FLAG_OS2_IOPL      UINT32_C(8)
     479/** @} */
     480
     481/**
     482 * Segment enumerator callback.
     483 *
     484 * @returns VINF_SUCCESS to continue the enumeration.  Any other status code
     485 *          will cause RTLdrEnumSegments to immediately return with that
     486 *          status.
     487 *
     488 * @param   hLdrMod         The module handle.
     489 * @param   pSeg            The segment information.
     490 * @param   pvUser          The user parameter specified to RTLdrEnumSegments.
     491 */
     492typedef DECLCALLBACK(int) FNRTLDRENUMSEGS(RTLDRMOD hLdrMod, PCRTLDRSEG pSeg, void *pvUser);
     493/** Pointer to a segment enumerator callback. */
     494typedef FNRTLDRENUMSEGS *PFNRTLDRENUMSEGS;
     495
     496/**
     497 * Enumerate the debug info contained in the executable image.
     498 *
     499 * @returns IPRT status code or whatever pfnCallback returns.
     500 *
     501 * @param   hLdrMod         The module handle.
     502 * @param   pfnCallback     The callback function.
     503 * @param   pvUser          The user argument.
     504 */
     505RTDECL(int) RTLdrEnumSegments(RTLDRMOD hLdrMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser);
     506
     507
    409508RT_C_DECLS_END
    410509
  • trunk/include/iprt/mangling.h

    r38539 r38547  
    552552# define RTLdrClose                                     RT_MANGLER(RTLdrClose)
    553553# define RTLdrEnumDbgInfo                               RT_MANGLER(RTLdrEnumDbgInfo)
     554# define RTLdrEnumSegments                              RT_MANGLER(RTLdrEnumSegments)
    554555# define RTLdrEnumSymbols                               RT_MANGLER(RTLdrEnumSymbols)
    555556# define RTLdrGetBits                                   RT_MANGLER(RTLdrGetBits)
  • trunk/src/VBox/Runtime/common/dbg/dbgmoddwarf.cpp

    r38531 r38547  
    7575    PRTDBGMODINT        pMod;
    7676
    77     /** Total line number count. */
    78     uint32_t            cLines;
    79     /** Total symbol count. */
    80     uint32_t            cSymbols;
    81 
    8277    /** DWARF debug info sections. */
    8378    struct
     
    151146        return VINF_SUCCESS;
    152147
    153     return pThis->pMod->pImgVt->pfnUnmapPart(pThis->pMod, pThis->aSections[enmSect].cb, &pThis->aSections[enmSect].pv);
     148    int rc =  pThis->pMod->pImgVt->pfnUnmapPart(pThis->pMod, pThis->aSections[enmSect].cb, &pThis->aSections[enmSect].pv);
     149    AssertRC(rc);
     150    return rc;
    154151}
    155152
     
    192189/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByAddr} */
    193190static DECLCALLBACK(int) rtDbgModDwarf_SymbolByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off,
    194                                                  PRTINTPTR poffDisp, PRTDBGSYMBOL pSymInfo)
    195 {
    196     PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;
    197     return VERR_DBG_NO_SYMBOLS;
     191                                                    PRTINTPTR poffDisp, PRTDBGSYMBOL pSymInfo)
     192{
     193    PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;
     194    return RTDbgModSymbolByAddr(pThis->hCnt, iSeg, off, poffDisp, pSymInfo);
    198195}
    199196
     
    204201{
    205202    PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;
    206     return VERR_DBG_NO_SYMBOLS;
     203    Assert(!pszSymbol[cchSymbol]);
     204    return RTDbgModSymbolByName(pThis->hCnt, pszSymbol/*, cchSymbol*/, pSymInfo);
    207205}
    208206
     
    212210{
    213211    PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;
    214     return VERR_DBG_NO_SYMBOLS;
     212    return RTDbgModSymbolByOrdinal(pThis->hCnt, iOrdinal, pSymInfo);
    215213}
    216214
     
    220218{
    221219    PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;
    222     return pThis->cSymbols;
     220    return RTDbgModSymbolCount(pThis->hCnt);
    223221}
    224222
     
    226224/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolAdd} */
    227225static DECLCALLBACK(int) rtDbgModDwarf_SymbolAdd(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
    228                                               RTDBGSEGIDX iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags,
    229                                               uint32_t *piOrdinal)
    230 {
    231     return VERR_NOT_SUPPORTED;
     226                                                 RTDBGSEGIDX iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags,
     227                                                 uint32_t *piOrdinal)
     228{
     229    PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;
     230    return RTDbgModSymbolAdd(pThis->hCnt, pszSymbol, iSeg, off, cb, fFlags, piOrdinal);
    232231}
    233232
     
    237236{
    238237    PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;
    239     return VERR_DBG_INVALID_SEGMENT_INDEX;
     238    return RTDbgModSegmentByIndex(pThis->hCnt, iSeg, pSegInfo);
    240239}
    241240
     
    245244{
    246245    PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;
    247     return 0; /** @todo defer to image reader if present? */
     246    return RTDbgModSegmentCount(pThis->hCnt);
    248247}
    249248
     
    251250/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentAdd} */
    252251static DECLCALLBACK(int) rtDbgModDwarf_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName, size_t cchName,
    253                                                uint32_t fFlags, PRTDBGSEGIDX piSeg)
    254 {
    255     return VERR_NOT_SUPPORTED;
     252                                                  uint32_t fFlags, PRTDBGSEGIDX piSeg)
     253{
     254    PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;
     255    return RTDbgModSegmentAdd(pThis->hCnt, uRva, cb, pszName, fFlags, piSeg);
    256256}
    257257
     
    261261{
    262262    PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;
    263     return 0; /** @todo defer to image reader if present? */
     263    RTUINTPTR cb1 = RTDbgModImageSize(pThis->hCnt);
     264    RTUINTPTR cb2 = pMod->pImgVt->pfnImageSize(pMod);
     265    return RT_MAX(cb1, cb2);
    264266}
    265267
     
    269271{
    270272    PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pMod->pvDbgPriv;
    271     /** @todo defer to image reader if present? */
    272     *poffSeg = uRva;
    273     return 0;
     273    return RTDbgModRvaToSegOff(pThis->hCnt, uRva, poffSeg);
    274274}
    275275
     
    291291
    292292
     293/**
     294 * Explodes the line number table.
     295 *
     296 * The line numbers are insered into the debug info container.
     297 *
     298 * @returns IPRT status code
     299 * @param   pThis               The DWARF instance.
     300 */
    293301static int rtDbgModDwarfExplodeLineNumbers(PRTDBGMODDWARF pThis)
    294302{
    295     if (!pThis->aSections[krtDbgModDwarfSect_line].fPresent)
    296         return VINF_SUCCESS;
    297303    int rc = rtDbgModDwarfLoadSection(pThis, krtDbgModDwarfSect_line);
    298304    if (RT_FAILURE(rc))
    299305        return rc;
    300306
    301 
    302     int rc2 = rtDbgModDwarfUnloadSection(pThis, krtDbgModDwarfSect_line);
    303     return RT_SUCCESS(rc2) || RT_FAILURE(rc) ? rc : rc2;
    304 }
    305 
    306 
     307#if 0 /** @todo  */
     308    size_t          cbLeft = pThis->aSections[krtDbgModDwarfSect_line].cb;
     309    uint8_t const  *pb     = (uint8_t const *)pThis->aSections[krtDbgModDwarfSect_line].pv;
     310    while (cbLeft > 0)
     311    {
     312
     313    }
     314#endif
     315
     316    rtDbgModDwarfUnloadSection(pThis, krtDbgModDwarfSect_line);
     317    return rc;
     318}
     319
     320
     321/**
     322 * Extracts the symbols.
     323 *
     324 * The symbols are insered into the debug info container.
     325 *
     326 * @returns IPRT status code
     327 * @param   pThis               The DWARF instance.
     328 */
    307329static int rtDbgModDwarfExtractSymbols(PRTDBGMODDWARF pThis)
    308330{
     
    311333        return rc;
    312334
    313 
    314     return VERR_NOT_IMPLEMENTED;
     335    /** @todo  */
     336
     337    rtDbgModDwarfUnloadSection(pThis, krtDbgModDwarfSect_info);
     338    return rc;
     339}
     340
     341
     342/**
     343 * Loads the abbreviations used to parse the info section.
     344 *
     345 * @returns IPRT status code
     346 * @param   pThis               The DWARF instance.
     347 */
     348static int rtDbgModDwarfLoadAbbreviations(PRTDBGMODDWARF pThis)
     349{
     350    int rc = rtDbgModDwarfLoadSection(pThis, krtDbgModDwarfSect_abbrev);
     351    if (RT_FAILURE(rc))
     352        return rc;
     353
     354#if 0 /** @todo  */
     355    size_t          cbLeft = pThis->aSections[krtDbgModDwarfSect_abbrev].cb;
     356    uint8_t const  *pb     = (uint8_t const *)pThis->aSections[krtDbgModDwarfSect_abbrev].pv;
     357    while (cbLeft > 0)
     358    {
     359
     360    }
     361#endif
     362
     363    rtDbgModDwarfUnloadSection(pThis, krtDbgModDwarfSect_abbrev);
     364    return rc;
     365}
     366
     367
     368/** @callback_method_impl{FNRTLDRENUMSEGS} */
     369static DECLCALLBACK(int) rtDbgModHlpAddSegmentCallback(RTLDRMOD hLdrMod, PCRTLDRSEG pSeg, void *pvUser)
     370{
     371    PRTDBGMODINT pMod = (PRTDBGMODINT)pvUser;
     372    return pMod->pDbgVt->pfnSegmentAdd(pMod, pSeg->RVA, pSeg->cb, pSeg->pchName, pSeg->cchName, 0 /*fFlags*/, NULL);
     373}
     374
     375
     376/**
     377 * Calls pfnSegmentAdd for each segment in the executable image.
     378 *
     379 * @returns IPRT status code.
     380 * @param   pMod                The debug module.
     381 */
     382DECLHIDDEN(int) rtDbgModHlpAddSegmentsFromImage(PRTDBGMODINT pMod)
     383{
     384    AssertReturn(pMod->pImgVt, VERR_INTERNAL_ERROR_2);
     385    return pMod->pImgVt->pfnEnumSegments(pMod, rtDbgModHlpAddSegmentCallback, pMod);
    315386}
    316387
     
    319390static DECLCALLBACK(int) rtDbgModDwarfEnumCallback(RTLDRMOD hLdrMod, uint32_t iDbgInfo, RTLDRDBGINFOTYPE enmType,
    320391                                                   uint16_t iMajorVer, uint16_t iMinorVer, const char *pszPartNm,
    321                                                    RTFOFF offFile, RTUINTPTR LinkAddress, RTUINTPTR cb,
     392                                                   RTFOFF offFile, RTLDRADDR LinkAddress, RTLDRADDR cb,
    322393                                                   const char *pszExtFile, void *pvUser)
    323394{
     
    334405     * or underscores.
    335406     */
    336     if (!strncmp(pszPartNm, ".debug_", sizeof(".debug_") - 1))
     407    if (!strncmp(pszPartNm, ".debug_", sizeof(".debug_") - 1))        /* ELF */
    337408        pszPartNm += sizeof(".debug_") - 1;
    338     else if (!strncmp(pszPartNm, "__debug_", sizeof("__debug_") - 1))
     409    else if (!strncmp(pszPartNm, "__debug_", sizeof("__debug_") - 1)) /* Mach-O */
    339410        pszPartNm += sizeof("__debug_") - 1;
    340411    else
     
    413484            if (RT_SUCCESS(rc))
    414485            {
    415                 rc = rtDbgModDwarfExtractSymbols(pThis);
     486                pMod->pvDbgPriv = pThis;
     487
     488                rc = rtDbgModHlpAddSegmentsFromImage(pMod);
     489                if (RT_SUCCESS(rc))
     490                    rc = rtDbgModDwarfLoadAbbreviations(pThis);
     491                if (RT_SUCCESS(rc))
     492                    rc = rtDbgModDwarfExtractSymbols(pThis);
    416493                if (RT_SUCCESS(rc))
    417494                    rc = rtDbgModDwarfExplodeLineNumbers(pThis);
    418495                if (RT_SUCCESS(rc))
    419496                {
    420                     pMod->pvDbgPriv = pThis;
    421497                    return VINF_SUCCESS;
    422498                }
     
    424500                /* bail out. */
    425501                RTDbgModRelease(pThis->hCnt);
     502                pMod->pvDbgPriv = NULL;
    426503            }
    427504        }
  • trunk/src/VBox/Runtime/common/dbg/dbgmodldr.cpp

    r38531 r38547  
    3434#include <iprt/assert.h>
    3535#include <iprt/err.h>
     36#include <iprt/file.h>
    3637#include <iprt/ldr.h>
    3738#include <iprt/mem.h>
     
    5354    /** The loader handle. */
    5455    RTLDRMOD        hLdrMod;
     56    /** File handle for the image. */
     57    RTFILE          hFile;
    5558} RTDBGMODLDR;
    5659/** Pointer to instance data NM map reader. */
    5760typedef RTDBGMODLDR *PRTDBGMODLDR;
     61
     62
     63/** @interface_method_impl{RTDBGMODVTIMG,pfnUnmapPart} */
     64static DECLCALLBACK(int) rtDbgModLdr_UnmapPart(PRTDBGMODINT pMod, size_t cb, void const **ppvMap)
     65{
     66    RTMemFree((void *)*ppvMap);
     67    *ppvMap = NULL;
     68    return VINF_SUCCESS;
     69}
     70
     71
     72/** @interface_method_impl{RTDBGMODVTIMG,pfnMapPart} */
     73static DECLCALLBACK(int) rtDbgModLdr_MapPart(PRTDBGMODINT pMod, RTFOFF off, size_t cb, void const **ppvMap)
     74{
     75    PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv;
     76
     77    void *pvMap = RTMemAlloc(cb);
     78    if (!pvMap)
     79        return VERR_NO_MEMORY;
     80
     81    int rc = RTFileReadAt(pThis->hFile, off, pvMap, cb, NULL);
     82    if (RT_SUCCESS(rc))
     83        *ppvMap = pvMap;
     84    else
     85    {
     86        RTMemFree(pvMap);
     87        *ppvMap = NULL;
     88    }
     89    return rc;
     90}
     91
     92
     93/** @interface_method_impl{RTDBGMODVTIMG,pfnGetLoadedSize} */
     94static DECLCALLBACK(RTUINTPTR) rtDbgModLdr_GetLoadedSize(PRTDBGMODINT pMod)
     95{
     96    PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv;
     97    return RTLdrSize(pThis->hLdrMod);
     98}
     99
     100
     101/** @interface_method_impl{RTDBGMODVTIMG,pfnEnumSegments} */
     102static DECLCALLBACK(int) rtDbgModLdr_EnumSegments(PRTDBGMODINT pMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser)
     103{
     104    PRTDBGMODLDR pThis = (PRTDBGMODLDR)pMod->pvImgPriv;
     105    return RTLdrEnumSegments(pThis->hLdrMod, pfnCallback, pvUser);
     106}
    58107
    59108
     
    74123    int rc = RTLdrClose(pThis->hLdrMod); AssertRC(rc);
    75124    pThis->hLdrMod = NIL_RTLDRMOD;
     125
     126    rc = RTFileClose(pThis->hFile); AssertRC(rc);
     127    pThis->hFile = NIL_RTFILE;
     128
    76129    RTMemFree(pThis);
    77130
     
    83136static DECLCALLBACK(int) rtDbgModLdr_TryOpen(PRTDBGMODINT pMod)
    84137{
    85     RTLDRMOD hLdrMod;
    86     int rc = RTLdrOpen(pMod->pszImgFile, 0 /*fFlags*/, RTLDRARCH_WHATEVER, &hLdrMod);
    87     if (RT_FAILURE(rc))
    88         return rc;
     138    RTFILE hFile;
     139    int rc = RTFileOpen(&hFile, pMod->pszImgFile, RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN);
     140    if (RT_SUCCESS(rc))
     141    {
     142        RTLDRMOD hLdrMod;
     143        rc = RTLdrOpen(pMod->pszImgFile, 0 /*fFlags*/, RTLDRARCH_WHATEVER, &hLdrMod);
     144        if (RT_SUCCESS(rc))
     145        {
     146            PRTDBGMODLDR pThis = (PRTDBGMODLDR)RTMemAllocZ(sizeof(RTDBGMODLDR));
     147            if (pThis)
     148            {
     149                pThis->hLdrMod  = hLdrMod;
     150                pThis->hFile    = hFile;
     151                pMod->pvImgPriv = pThis;
     152                return VINF_SUCCESS;
     153            }
    89154
    90     PRTDBGMODLDR pThis = (PRTDBGMODLDR)RTMemAllocZ(sizeof(RTDBGMODLDR));
    91     if (!pThis)
    92     {
    93         RTLdrClose(hLdrMod);
    94         return VERR_NO_MEMORY;
     155            rc = VERR_NO_MEMORY;
     156            RTLdrClose(hLdrMod);
     157        }
     158
     159        RTFileClose(hFile);
    95160    }
    96 
    97     pThis->hLdrMod = hLdrMod;
    98     pMod->pvImgPriv = pThis;
    99     return VINF_SUCCESS;
     161    return rc;
    100162}
    101163
     
    110172    /*.pfnClose = */            rtDbgModLdr_Close,
    111173    /*.pfnEnumDbgInfo = */      rtDbgModLdr_EnumDbgInfo,
    112     /*.pfnMapPart = */          NULL /** @todo*/,
    113     /*.pfnUnmapPart = */        NULL /** @todo*/,
     174    /*.pfnEnumSegments = */     rtDbgModLdr_EnumSegments,
     175    /*.pfnGetLoadedSize = */    rtDbgModLdr_GetLoadedSize,
     176    /*.pfnMapPart = */          rtDbgModLdr_MapPart,
     177    /*.pfnUnmapPart = */        rtDbgModLdr_UnmapPart,
    114178
    115179    /*.u32EndMagic = */         RTDBGMODVTIMG_MAGIC
  • trunk/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h

    r38515 r38547  
    696696
    697697
     698/** @copydoc RTLDROPS::pfnEnumSegments. */
     699static DECLCALLBACK(int) RTLDRELF_NAME(EnumSegments)(PRTLDRMODINTERNAL pMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser)
     700{
     701    PRTLDRMODELF pModElf = (PRTLDRMODELF)pMod;
     702
     703    return VERR_NOT_IMPLEMENTED;
     704}
     705
     706
     707
    698708/**
    699709 * The ELF module operations.
     
    716726    RTLDRELF_NAME(GetSymbolEx),
    717727    RTLDRELF_NAME(EnumDbgInfo),
     728    RTLDRELF_NAME(EnumSegments),
    718729    42
    719730};
  • trunk/src/VBox/Runtime/common/ldr/ldrEx.cpp

    r38515 r38547  
    209209 * @remark  Not supported for RTLdrLoad() images.
    210210 */
    211 RTDECL(int) RTLdrGetBits(RTLDRMOD hLdrMod, void *pvBits, RTUINTPTR BaseAddress, PFNRTLDRIMPORT pfnGetImport, void *pvUser)
     211RTDECL(int) RTLdrGetBits(RTLDRMOD hLdrMod, void *pvBits, RTLDRADDR BaseAddress, PFNRTLDRIMPORT pfnGetImport, void *pvUser)
    212212{
    213213    LogFlow(("RTLdrGetBits: hLdrMod=%RTldrm pvBits=%p BaseAddress=%RTptr pfnGetImport=%p pvUser=%p\n",
     
    247247 * @remark  Not supported for RTLdrLoad() images.
    248248 */
    249 RTDECL(int) RTLdrRelocate(RTLDRMOD hLdrMod, void *pvBits, RTUINTPTR NewBaseAddress, RTUINTPTR OldBaseAddress,
     249RTDECL(int) RTLdrRelocate(RTLDRMOD hLdrMod, void *pvBits, RTLDRADDR NewBaseAddress, RTLDRADDR OldBaseAddress,
    250250                          PFNRTLDRIMPORT pfnGetImport, void *pvUser)
    251251{
     
    289289 * @param   pValue          Where to store the symbol value.
    290290 */
    291 RTDECL(int) RTLdrGetSymbolEx(RTLDRMOD hLdrMod, const void *pvBits, RTUINTPTR BaseAddress, const char *pszSymbol, RTUINTPTR *pValue)
     291RTDECL(int) RTLdrGetSymbolEx(RTLDRMOD hLdrMod, const void *pvBits, RTLDRADDR BaseAddress, const char *pszSymbol,
     292                             PRTLDRADDR pValue)
    292293{
    293294    LogFlow(("RTLdrGetSymbolEx: hLdrMod=%RTldrm pvBits=%p BaseAddress=%RTptr pszSymbol=%p:{%s} pValue\n",
     
    338339 * @remark  Not supported for RTLdrLoad() images.
    339340 */
    340 RTDECL(int) RTLdrEnumSymbols(RTLDRMOD hLdrMod, unsigned fFlags, const void *pvBits, RTUINTPTR BaseAddress, PFNRTLDRENUMSYMS pfnCallback, void *pvUser)
     341RTDECL(int) RTLdrEnumSymbols(RTLDRMOD hLdrMod, unsigned fFlags, const void *pvBits, RTLDRADDR BaseAddress,
     342                             PFNRTLDRENUMSYMS pfnCallback, void *pvUser)
    341343{
    342344    LogFlow(("RTLdrEnumSymbols: hLdrMod=%RTldrm fFlags=%#x pvBits=%p BaseAddress=%RTptr pfnCallback=%p pvUser=%p\n",
     
    390392RT_EXPORT_SYMBOL(RTLdrEnumDbgInfo);
    391393
     394
     395RTDECL(int) RTLdrEnumSegments(RTLDRMOD hLdrMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser)
     396{
     397    LogFlow(("RTLdrEnumSegments: hLdrMod=%RTldrm pfnCallback=%p pvUser=%p\n",
     398             hLdrMod, pfnCallback, pvUser));
     399
     400    /*
     401     * Validate input.
     402     */
     403    AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), VERR_INVALID_HANDLE);
     404    AssertMsgReturn(RT_VALID_PTR(pfnCallback), ("pfnCallback=%p\n", pfnCallback), VERR_INVALID_PARAMETER);
     405    PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod;
     406    //AssertMsgReturn(pMod->eState == LDR_STATE_OPENED, ("eState=%d\n", pMod->eState), VERR_WRONG_ORDER);
     407
     408    /*
     409     * Do it.
     410     */
     411    int rc;
     412    if (pMod->pOps->pfnEnumSegments)
     413        rc = pMod->pOps->pfnEnumSegments(pMod, pfnCallback, pvUser);
     414    else
     415        rc = VERR_NOT_SUPPORTED;
     416
     417    LogFlow(("RTLdrEnumSegments: returns %Rrc\n", rc));
     418    return rc;
     419
     420}
     421RT_EXPORT_SYMBOL(RTLdrEnumSegments);
     422
  • trunk/src/VBox/Runtime/common/ldr/ldrNative.cpp

    r38515 r38547  
    6969    rtldrNativeEnumSymbols,
    7070    /* ext: */
     71    NULL,
    7172    NULL,
    7273    NULL,
  • trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp

    r38515 r38547  
    776776
    777777
     778/** @copydoc RTLDROPS::pfnEnumSegments. */
     779static DECLCALLBACK(int) rtldrPE_EnumSegments(PRTLDRMODINTERNAL pMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser)
     780{
     781    return VINF_NOT_SUPPORTED;
     782}
     783
     784
    778785/** @copydoc RTLDROPS::pfnDone */
    779786static DECLCALLBACK(int) rtldrPEDone(PRTLDRMODINTERNAL pMod)
     
    835842        rtldrPEGetSymbolEx,
    836843        rtldrPE_EnumDbgInfo,
     844        rtldrPE_EnumSegments,
    837845        42
    838846    },
     
    859867        rtldrPEGetSymbolEx,
    860868        rtldrPE_EnumDbgInfo,
     869        rtldrPE_EnumSegments,
    861870        42
    862871    },
  • trunk/src/VBox/Runtime/common/ldr/ldrkStuff.cpp

    r38531 r38547  
    629629
    630630
     631/** @copydoc RTLDROPS::pfnEnumSegments. */
     632static DECLCALLBACK(int) rtkldr_EnumSegments(PRTLDRMODINTERNAL pMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser)
     633{
     634    PRTLDRMODKLDR   pThis      = (PRTLDRMODKLDR)pMod;
     635    uint32_t const  cSegments  = pThis->pMod->cSegments;
     636    PCKLDRSEG       paSegments = &pThis->pMod->aSegments[0];
     637
     638    for (uint32_t iSeg = 0; iSeg < cSegments; iSeg++)
     639    {
     640        RTLDRSEG Seg;
     641
     642        Seg.pchName     = paSegments[iSeg].pchName;
     643        Seg.cchName     = paSegments[iSeg].cchName;
     644        Seg.SelFlat     = paSegments[iSeg].SelFlat;
     645        Seg.Sel16bit    = paSegments[iSeg].Sel16bit;
     646        Seg.fFlags      = paSegments[iSeg].fFlags;
     647        AssertCompile(KLDRSEG_FLAG_16BIT          == RTLDRSEG_FLAG_16BIT      );
     648        AssertCompile(KLDRSEG_FLAG_OS2_ALIAS16    == RTLDRSEG_FLAG_OS2_ALIAS16);
     649        AssertCompile(KLDRSEG_FLAG_OS2_CONFORM    == RTLDRSEG_FLAG_OS2_CONFORM);
     650        AssertCompile(KLDRSEG_FLAG_OS2_IOPL       == RTLDRSEG_FLAG_OS2_IOPL   );
     651
     652        switch (paSegments[iSeg].enmProt)
     653        {
     654            default:
     655                AssertMsgFailed(("%d\n", paSegments[iSeg].enmProt));
     656            case KPROT_NOACCESS:
     657                Seg.fProt = 0;
     658                break;
     659
     660            case KPROT_READONLY:            Seg.fProt = RTMEM_PROT_READ; break;
     661            case KPROT_READWRITE:           Seg.fProt = RTMEM_PROT_READ | RTMEM_PROT_WRITE; break;
     662            case KPROT_WRITECOPY:           Seg.fProt = RTMEM_PROT_WRITE; break;
     663            case KPROT_EXECUTE:             Seg.fProt = RTMEM_PROT_EXEC; break;
     664            case KPROT_EXECUTE_READ:        Seg.fProt = RTMEM_PROT_EXEC | RTMEM_PROT_READ; break;
     665            case KPROT_EXECUTE_READWRITE:   Seg.fProt = RTMEM_PROT_EXEC | RTMEM_PROT_READ | RTMEM_PROT_WRITE; break;
     666            case KPROT_EXECUTE_WRITECOPY:   Seg.fProt = RTMEM_PROT_EXEC | RTMEM_PROT_WRITE; break;
     667        }
     668        Seg.cb          = paSegments[iSeg].cb;
     669        Seg.Alignment   = paSegments[iSeg].Alignment;
     670        Seg.LinkAddress = paSegments[iSeg].LinkAddress;
     671        Seg.offFile     = paSegments[iSeg].offFile;
     672        Seg.cbFile      = paSegments[iSeg].cbFile;
     673        Seg.RVA         = paSegments[iSeg].RVA;
     674        Seg.cbMapped    = paSegments[iSeg].cbMapped;
     675
     676        int rc = pfnCallback(pMod, &Seg, pvUser);
     677        if (rc != VINF_SUCCESS)
     678            return rc;
     679    }
     680
     681    return VINF_SUCCESS;
     682}
     683
     684
    631685/**
    632686 * Operations for a kLdr module.
     
    645699    rtkldr_GetSymbolEx,
    646700    rtkldr_EnumDbgInfo,
     701    rtkldr_EnumSegments,
    647702    42
    648703};
  • trunk/src/VBox/Runtime/include/internal/dbgmod.h

    r38531 r38547  
    9696     *
    9797     * @param   pMod            Pointer to the module structure.
    98      * @param   pvBits          Optional pointer to bits returned by
    99      *                          RTLdrGetBits().  This can be used by some module
    100      *                          interpreters to reduce memory consumption.
    10198     * @param   pfnCallback     The callback function.  Ignore the module
    10299     *                          handle argument!
     
    104101     */
    105102    DECLCALLBACKMEMBER(int, pfnEnumDbgInfo)(PRTDBGMODINT pMod, PFNRTLDRENUMDBG pfnCallback, void *pvUser);
     103
     104    /**
     105     * Enumerate the segments in the executable image.
     106     *
     107     * Identical to RTLdrEnumSegments.
     108     *
     109     * @returns IPRT status code or whatever pfnCallback returns.
     110     *
     111     * @param   pMod            Pointer to the module structure.
     112     * @param   pfnCallback     The callback function.  Ignore the module
     113     *                          handle argument!
     114     * @param   pvUser          The user argument.
     115     */
     116    DECLCALLBACKMEMBER(int, pfnEnumSegments)(PRTDBGMODINT pMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser);
     117
     118    /**
     119     * Gets the size of the loaded image.
     120     *
     121     * Identical to RTLdrSize.
     122     *
     123     * @returns The size in bytes, RTUINTPTR_MAX on failure.
     124     *
     125     * @param   pMod            Pointer to the module structure.
     126     */
     127    DECLCALLBACKMEMBER(RTUINTPTR, pfnImageSize)(PRTDBGMODINT pMod);
    106128
    107129    /**
  • trunk/src/VBox/Runtime/include/internal/ldr.h

    r38515 r38547  
    240240                                            PFNRTLDRENUMDBG pfnCallback, void *pvUser);
    241241
     242    /**
     243     * Enumerates the segments in the module.
     244     *
     245     * @returns iprt status code, which might have been returned by pfnCallback.
     246     * @param   pMod        Pointer to the loader module structure.
     247     * @param   pfnCallback The callback function which each debug info part is
     248     *                      to be fed to.
     249     * @param   pvUser      User argument to pass to the enumerator.
     250     * @remark  This is an optional entry point that can be NULL.
     251     */
     252    DECLCALLBACKMEMBER(int, pfnEnumSegments)(PRTLDRMODINTERNAL pMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser);
     253
    242254
    243255    /** Dummy entry to make sure we've initialized it all. */
  • trunk/src/VBox/Runtime/tools/RTLdrFlt.cpp

    r38515 r38547  
    125125     * as we parse the parameters.
    126126     */
    127     RTDBGAS hAs;
    128     rc = RTDbgAsCreate(&hAs, 0, RTUINTPTR_MAX, "");
     127    RTDBGAS hDbgAs;
     128    rc = RTDbgAsCreate(&hDbgAs, 0, RTUINTPTR_MAX, "");
    129129    if (RT_FAILURE(rc))
    130         return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDBgAsCreate -> %Rrc\n", rc);
     130        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDBgAsCreate -> %Rrc", rc);
    131131
    132132
     
    136136    static const RTGETOPTDEF s_aOptions[] =
    137137    {
    138         { "--later", 'l', RTGETOPT_REQ_STRING },
     138        { "--input",   'i', RTGETOPT_REQ_STRING },
     139        { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
    139140    };
     141
     142    PRTSTREAM       pInput   = g_pStdIn;
     143    bool            fVerbose = false;
    140144
    141145    RTGETOPTUNION   ValueUnion;
     
    146150        switch (rc)
    147151        {
     152            case 'i':
     153                rc = RTStrmOpen(ValueUnion.psz, "r", &pInput);
     154                if (RT_FAILURE(rc))
     155                    return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to open '%s' for reading: %Rrc", ValueUnion.psz, rc);
     156                break;
     157
     158            case 'v':
     159                fVerbose = true;
     160                break;
     161
    148162            case 'h':
    149163                RTPrintf("Usage: %s [options] <module> <address> [<module> <address> [..]]\n"
    150164                         "\n"
    151165                         "Options:\n"
     166                         "  -i,--input=file\n"
     167                         "      Specify a input file instead of standard input.\n"
     168                         "  -v, --verbose\n"
     169                         "      Display the address space before doing the filtering.\n"
    152170                         "  -h, -?, --help\n"
    153171                         "      Display this help text and exit successfully.\n"
     
    174192                rc = RTDbgModCreateFromImage(&hMod, pszModule, NULL, 0 /*fFlags*/);
    175193                if (RT_FAILURE(rc))
    176                     return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDbgModCreateFromImage(,%s,,) -> %Rrc\n", pszModule, rc);
    177 
    178                 rc = RTDbgAsModuleLink(hAs, hMod, u64Address, 0 /* fFlags */);
     194                    return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDbgModCreateFromImage(,%s,,) -> %Rrc", pszModule, rc);
     195
     196                rc = RTDbgAsModuleLink(hDbgAs, hMod, u64Address, 0 /* fFlags */);
    179197                if (RT_FAILURE(rc))
    180                     return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDbgAsModuleLink(,%s,%llx,) -> %Rrc\n", pszModule, u64Address, rc);
     198                    return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDbgAsModuleLink(,%s,%llx,) -> %Rrc", pszModule, u64Address, rc);
    181199                break;
    182200            }
     
    188206
    189207    /*
     208     * Display the address space.
     209     */
     210    if (fVerbose)
     211    {
     212        RTPrintf("*** Address Space Dump ***\n");
     213        uint32_t cModules = RTDbgAsModuleCount(hDbgAs);
     214        for (uint32_t iModule = 0; iModule < cModules; iModule++)
     215        {
     216            RTDBGMOD        hDbgMod = RTDbgAsModuleByIndex(hDbgAs, iModule);
     217            RTPrintf("Module #%u: %s\n", iModule, RTDbgModName(hDbgMod));
     218
     219            RTDBGASMAPINFO  aMappings[128];
     220            uint32_t        cMappings = RT_ELEMENTS(aMappings);
     221            rc = RTDbgAsModuleQueryMapByIndex(hDbgAs, iModule, &aMappings[0], &cMappings, 0 /*fFlags*/);
     222            if (RT_SUCCESS(rc))
     223            {
     224                for (uint32_t iMapping = 0; iMapping < cMappings; iMapping++)
     225                {
     226                    if (aMappings[iMapping].iSeg == NIL_RTDBGSEGIDX)
     227                        RTPrintf("  mapping #%u: %RTptr-%RTptr\n",
     228                                 iMapping,
     229                                 aMappings[iMapping].Address,
     230                                 aMappings[iMapping].Address + RTDbgModImageSize(hDbgMod) - 1);
     231                    else
     232                    {
     233                        RTDBGSEGMENT SegInfo;
     234                        rc = RTDbgModSegmentByIndex(hDbgMod, aMappings[iMapping].iSeg, &SegInfo);
     235                        if (RT_SUCCESS(rc))
     236                            RTPrintf("  mapping #%u: %RTptr-%RTptr (segment #%u - '%s')",
     237                                     iMapping,
     238                                     aMappings[iMapping].Address,
     239                                     aMappings[iMapping].Address + SegInfo.cb,
     240                                     SegInfo.iSeg, SegInfo.szName);
     241                        else
     242                            RTPrintf("  mapping #%u: %RTptr-???????? (segment #%u)", iMapping, aMappings[iMapping].Address);
     243                    }
     244                }
     245            }
     246            else
     247                RTMsgError("RTDbgAsModuleQueryMapByIndex failed: %Rrc", rc);
     248            RTDbgModRelease(hDbgMod);
     249        }
     250        RTPrintf("*** End of Address Space Dump ***\n");
     251    }
     252
     253    /*
    190254     * Read text from standard input and see if there is anything we can translate.
    191255     */
     
    194258        /* Get a line. */
    195259        char szLine[_64K];
    196         rc = RTStrmGetLine(g_pStdIn, szLine, sizeof(szLine));
     260        rc = RTStrmGetLine(pInput, szLine, sizeof(szLine));
    197261        if (rc == VERR_EOF)
    198262            break;
     
    219283               )
    220284            {
     285                /* Print. */
     286                psz += cchAddress;
    221287                if (pszStart != psz)
    222288                    RTStrmWrite(g_pStdOut, pszStart, psz - pszStart);
    223289                pszStart = psz;
    224290
    225                 RTDBGSYMBOL Symbol;
    226                 RTINTPTR    off;
    227                 rc = RTDbgAsSymbolByAddr(hAs, u64Address, &off, &Symbol, NULL);
     291                /* Try get the module. */
     292                RTUINTPTR   uAddr;
     293                RTDBGSEGIDX iSeg;
     294                RTDBGMOD    hDbgMod;
     295                rc = RTDbgAsModuleByAddr(hDbgAs, u64Address, &hDbgMod, &uAddr, &iSeg);
    228296                if (RT_SUCCESS(rc))
    229297                {
    230                     if (!off)
    231                         RTStrmPrintf(g_pStdOut, "%.*s=[%s]", cchAddress, psz, Symbol.szName);
    232                     else if (off > 0)
    233                         RTStrmPrintf(g_pStdOut, "%.*s=[%s+%#llx]", cchAddress, psz, Symbol.szName, off);
     298                    if (iSeg != UINT32_MAX)
     299                        RTStrmPrintf(g_pStdOut, "=[%s:%u", RTDbgModName(hDbgMod), iSeg);
    234300                    else
    235                         RTStrmPrintf(g_pStdOut, "%.*s=[%s-%#llx]", cchAddress, psz, Symbol.szName, -off);
    236                     psz += cchAddress;
    237                     pszStart = psz;
     301                        RTStrmPrintf(g_pStdOut, "=[%s", RTDbgModName(hDbgMod), iSeg);
     302
     303                    /*
     304                     * Do we have symbols?
     305                     */
     306                    RTDBGSYMBOL Symbol;
     307                    RTINTPTR    offSym;
     308                    rc = RTDbgAsSymbolByAddr(hDbgAs, u64Address, &offSym, &Symbol, NULL);
     309                    if (RT_SUCCESS(rc))
     310                    {
     311                        if (!offSym)
     312                            RTStrmPrintf(g_pStdOut, "!%s", Symbol.szName);
     313                        else if (offSym > 0)
     314                            RTStrmPrintf(g_pStdOut, "!%s+%#llx", Symbol.szName, offSym);
     315                        else
     316                            RTStrmPrintf(g_pStdOut, "!%s-%#llx", Symbol.szName, -offSym);
     317                    }
     318                    else
     319                        RTStrmPrintf(g_pStdOut, "+%#llx", u64Address - uAddr);
     320
     321                    /*
     322                     * Do we have line numbers?
     323                     */
     324                    RTDBGLINE   Line;
     325                    RTINTPTR    offLine;
     326                    rc = RTDbgAsLineByAddr(hDbgAs, u64Address, &offLine, &Line);
     327                    if (RT_SUCCESS(rc))
     328                        RTStrmPrintf(g_pStdOut, " %Rbn(%u)", Line.szFilename, Line.uLineNo);
     329
     330                    RTStrmPrintf(g_pStdOut, "]");
     331                    RTDbgModRelease(hDbgMod);
    238332                }
    239                 else
    240                     psz += cchAddress;
    241333            }
    242334            else
Note: See TracChangeset for help on using the changeset viewer.

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