VirtualBox

Changeset 75237 in vbox for trunk/src


Ignore:
Timestamp:
Nov 2, 2018 9:12:17 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
126335
Message:

IPRT: Added support for reading MAPSYM output.

Location:
trunk/src/VBox/Runtime
Files:
3 edited
1 copied

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/src/VBox/Runtime/Makefile.kmk

    r75129 r75237  
    425425        common/dbg/dbgmodcodeview.cpp \
    426426        common/dbg/dbgmoddwarf.cpp \
     427        common/dbg/dbgmodmapsym.cpp \
    427428        common/dbg/dbgmodnm.cpp \
    428429        common/dvm/dvm.cpp \
     
    16001601        common/dbg/dbgmodexports.cpp \
    16011602        common/dbg/dbgmodldr.cpp \
     1603        common/dbg/dbgmodmapsym.cpp \
    16021604        common/dbg/dbgmodnm.cpp \
    16031605        common/err/errinfo-alloc.cpp \
  • TabularUnified trunk/src/VBox/Runtime/common/dbg/dbgmod.cpp

    r75130 r75237  
    279279         */
    280280        rc = rtDbgModDebugInterpreterRegister(&g_rtDbgModVtDbgNm);
     281        if (RT_SUCCESS(rc))
     282            rc = rtDbgModDebugInterpreterRegister(&g_rtDbgModVtDbgMapSym);
    281283        if (RT_SUCCESS(rc))
    282284            rc = rtDbgModDebugInterpreterRegister(&g_rtDbgModVtDbgDwarf);
  • TabularUnified trunk/src/VBox/Runtime/common/dbg/dbgmodmapsym.cpp

    r75204 r75237  
    11/* $Id$ */
    22/** @file
    3  * IPRT - Debug Map Reader For NM Like Mapfiles.
     3 * IPRT - Debug Map Reader for MAPSYM files (used by SYMDBG from old MASM).
     4 *
     5 * MAPSYM is was the tool producing these files from linker map files for
     6 * use with SYMDBG (which shipped with MASM 3.0 (possibly earlier)), the OS/2
     7 * kernel debugger, and other tools.  The format is very limited and they had
     8 * to strip down the os2krnl.map file in later years to keep MAPSYM happy.
    49 */
    510
     
    2934*   Header Files                                                                                                                 *
    3035*********************************************************************************************************************************/
     36#define LOG_GROUP RTLOGGROUP_DBG
    3137#include <iprt/dbg.h>
    3238#include "internal/iprt.h"
     
    3440#include <iprt/err.h>
    3541#include <iprt/ctype.h>
     42#include <iprt/file.h>
     43#include <iprt/log.h>
    3644#include <iprt/mem.h>
    3745#include <iprt/stream.h>
     
    4351*   Structures and Typedefs                                                                                                      *
    4452*********************************************************************************************************************************/
    45 /**
    46  * Instance data.
    47  */
    48 typedef struct RTDBGMODNM
    49 {
    50     /** The debug container containing doing the real work. */
    51     RTDBGMOD                    hCnt;
    52 } RTDBGMODNM;
    53 /** Pointer to instance data NM map reader. */
    54 typedef RTDBGMODNM *PRTDBGMODNM;
     53/** @name MAPSYM structures and constants.
     54 * @{ */
     55
     56/** MAPSYM: Header structure.   */
     57typedef struct MAPSYMHDR
     58{
     59    uint16_t    off16NextMap;                   /**< 0x00: Offset of the next map divided by 16. */
     60    uint8_t     bFlags;                         /**< 0x02: Who really knows... */
     61    uint8_t     bReserved;                      /**< 0x03: Reserved / unknown. */
     62    uint16_t    uSegEntry;                      /**< 0x04: Some entrypoint/segment thing we don't care about. */
     63    uint16_t    cConsts;                        /**< 0x06: Constants referenced by offConstDef. */
     64    uint16_t    offConstDef;                    /**< 0x08: Offset to head of constant chain.  Not div 16? */
     65    uint16_t    cSegs;                          /**< 0x0a: Number of segments in the map. */
     66    uint16_t    off16SegDef;                    /**< 0x0c: Offset of the segment defintions divided by 16. */
     67    uint8_t     cchMaxSym;                      /**< 0x0e: Maximum symbol-name length. */
     68    uint8_t     cchModule;                      /**< 0x0f: Length of the module name. */
     69    char        achModule[RT_FLEXIBLE_ARRAY];   /**< 0x10: Module name, length given by cchModule. */
     70} MAPSYMHDR;
     71
     72/** MAPSYM: Tail structure.   */
     73typedef struct MAPSYMTAIL
     74{
     75    uint16_t    offNextMap;                     /**< 0x00: Always zero (it's the tail, see). */
     76    uint8_t     bRelease;                       /**< 0x02: Minor version number. */
     77    uint8_t     bVersion;                       /**< 0x03: Major version number. */
     78} MAPSYMTAIL;
     79
     80/** MAPSYM: Segment defintion.   */
     81typedef struct MAPSYMSEGDEF
     82{
     83    uint16_t    off16NextSeg;                  /**< 0x00: Offset of the next segment divided by 16. */
     84    uint16_t    cSymbols;                      /**< 0x02: Number of symbol offsets . */
     85    uint16_t    offSymbolOffsets;              /**< 0x04: Offset of the symbol offset table. Each entry is a 16-bit value giving
     86                                                *         the offset symbol relative to this structure. */
     87    uint16_t    au16Reserved0[4];              /**< 0x06: Reserved / unknown.
     88                                                * First byte/word seems to be 1-based segment number. */
     89    uint8_t     bFlags;                        /**< 0x0e: MAPSYMSEGDEF_F_32BIT or zero. */
     90    uint8_t     bReserved1;                    /**< 0x0f: Reserved / unknown. */
     91    uint16_t    offLineDef;                    /**< 0x10: Offset to the line defintions. */
     92    uint16_t    u16Reserved2;                  /**< 0x12: Reserved / unknown.  Often seen holding 0xff00. */
     93    uint8_t     cchSegName;                    /**< 0x14: Segment name length. */
     94    char        achSegName[RT_FLEXIBLE_ARRAY]; /**< 0x15: Segment name, length given by cchSegName. */
     95} MAPSYMSEGDEF;
     96
     97#define MAPSYMSEGDEF_F_32BIT    UINT8_C(0x01)  /**< Indicates 32-bit segment rather than 16-bit, relevant for symbols. */
     98#define MAPSYMSEGDEF_F_UNKNOWN  UINT8_C(0x02)  /**< Set on all segments in os2krnlr.sym from ACP2. */
     99
     100/** MAPSYM: 16-bit symbol   */
     101typedef struct MAPSYMSYMDEF16
     102{
     103    uint16_t    uValue;                        /**< 0x00: The symbol value (address). */
     104    uint8_t     cchName;                       /**< 0x02: Symbol name length. */
     105    char        achName[1];                    /**< 0x03: The symbol name, length give by cchName. */
     106} MAPSYMSYMDEF16;
     107
     108/** MAPSYM: 16-bit symbol   */
     109typedef struct MAPSYMSYMDEF32
     110{
     111    uint32_t    uValue;                        /**< 0x00: The symbol value (address). */
     112    uint8_t     cchName;                       /**< 0x04: Symbol name length. */
     113    char        achName[1];                    /**< 0x05: The symbol name, length give by cchName. */
     114} MAPSYMSYMDEF32;
     115
     116/** MAPSYM: Line number defintions. */
     117typedef struct MAPSYMLINEDEF
     118{
     119    uint16_t    off16NextLine;                 /**< 0x00: Offset to the next line defintion divided by 16. */
     120    uint16_t    uSegment;                      /**< 0x02: Guessing this must be segment number. */
     121    uint16_t    offLines;                      /**< 0x04: Offset to the line number array, relative to this structure. */
     122    uint16_t    cLines;                        /**< 0x08: Number of line numbers in the array. */
     123    uint8_t     cchSrcFile;                    /**< 0x0a: Length of source filename. */
     124    char        achSrcFile[RT_FLEXIBLE_ARRAY]; /**< 0x0b: Source filename, length given by cchSrcFile. */
     125} MAPSYMLINEDEF;
     126
     127/** MAPSYM: 16-bit line numbers. */
     128typedef struct MAPSYMLINENO16
     129{
     130    uint16_t    offSeg;
     131    uint16_t    uLineNo;
     132} MAPSYMLINENO16;
     133
     134/** @} */
     135
     136
     137/*********************************************************************************************************************************
     138*   Defined Constants And Macros                                                                                                 *
     139*********************************************************************************************************************************/
     140/** Maximum number of segments we expect in a MAPSYM file. */
     141#define RTDBGMODMAPSYM_MAX_SEGMENTS 256
    55142
    56143
    57144
    58145/** @interface_method_impl{RTDBGMODVTDBG,pfnUnwindFrame} */
    59 static DECLCALLBACK(int) rtDbgModNm_UnwindFrame(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTDBGUNWINDSTATE pState)
     146static DECLCALLBACK(int) rtDbgModMapSym_UnwindFrame(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTDBGUNWINDSTATE pState)
    60147{
    61148    RT_NOREF(pMod, iSeg, off, pState);
     
    65152
    66153/** @interface_method_impl{RTDBGMODVTDBG,pfnLineByAddr} */
    67 static DECLCALLBACK(int) rtDbgModNm_LineByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off,
     154static DECLCALLBACK(int) rtDbgModMapSym_LineByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off,
    68155                                               PRTINTPTR poffDisp, PRTDBGLINE pLineInfo)
    69156{
    70     PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
    71     return RTDbgModLineByAddr(pThis->hCnt, iSeg, off, poffDisp, pLineInfo);
     157    RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
     158    return RTDbgModLineByAddr(hCnt, iSeg, off, poffDisp, pLineInfo);
    72159}
    73160
    74161
    75162/** @interface_method_impl{RTDBGMODVTDBG,pfnLineByOrdinal} */
    76 static DECLCALLBACK(int) rtDbgModNm_LineByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo)
    77 {
    78     PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
    79     return RTDbgModLineByOrdinal(pThis->hCnt, iOrdinal, pLineInfo);
     163static DECLCALLBACK(int) rtDbgModMapSym_LineByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo)
     164{
     165    RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
     166    return RTDbgModLineByOrdinal(hCnt, iOrdinal, pLineInfo);
    80167}
    81168
    82169
    83170/** @interface_method_impl{RTDBGMODVTDBG,pfnLineCount} */
    84 static DECLCALLBACK(uint32_t) rtDbgModNm_LineCount(PRTDBGMODINT pMod)
    85 {
    86     PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
    87     return RTDbgModLineCount(pThis->hCnt);
     171static DECLCALLBACK(uint32_t) rtDbgModMapSym_LineCount(PRTDBGMODINT pMod)
     172{
     173    RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
     174    return RTDbgModLineCount(hCnt);
    88175}
    89176
    90177
    91178/** @interface_method_impl{RTDBGMODVTDBG,pfnLineAdd} */
    92 static DECLCALLBACK(int) rtDbgModNm_LineAdd(PRTDBGMODINT pMod, const char *pszFile, size_t cchFile, uint32_t uLineNo,
     179static DECLCALLBACK(int) rtDbgModMapSym_LineAdd(PRTDBGMODINT pMod, const char *pszFile, size_t cchFile, uint32_t uLineNo,
    93180                                            uint32_t iSeg, RTUINTPTR off, uint32_t *piOrdinal)
    94181{
    95     PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
     182    RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
    96183    Assert(!pszFile[cchFile]); NOREF(cchFile);
    97     return RTDbgModLineAdd(pThis->hCnt, pszFile, uLineNo, iSeg, off, piOrdinal);
     184    return RTDbgModLineAdd(hCnt, pszFile, uLineNo, iSeg, off, piOrdinal);
    98185}
    99186
    100187
    101188/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByAddr} */
    102 static DECLCALLBACK(int) rtDbgModNm_SymbolByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags,
     189static DECLCALLBACK(int) rtDbgModMapSym_SymbolByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags,
    103190                                                 PRTINTPTR poffDisp, PRTDBGSYMBOL pSymInfo)
    104191{
    105     PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
    106     return RTDbgModSymbolByAddr(pThis->hCnt, iSeg, off, fFlags, poffDisp, pSymInfo);
     192    RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
     193    return RTDbgModSymbolByAddr(hCnt, iSeg, off, fFlags, poffDisp, pSymInfo);
    107194}
    108195
    109196
    110197/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByName} */
    111 static DECLCALLBACK(int) rtDbgModNm_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
     198static DECLCALLBACK(int) rtDbgModMapSym_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
    112199                                                 PRTDBGSYMBOL pSymInfo)
    113200{
    114     PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
     201    RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
    115202    Assert(!pszSymbol[cchSymbol]); NOREF(cchSymbol);
    116     return RTDbgModSymbolByName(pThis->hCnt, pszSymbol, pSymInfo);
     203    return RTDbgModSymbolByName(hCnt, pszSymbol, pSymInfo);
    117204}
    118205
    119206
    120207/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByOrdinal} */
    121 static DECLCALLBACK(int) rtDbgModNm_SymbolByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo)
    122 {
    123     PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
    124     return RTDbgModSymbolByOrdinal(pThis->hCnt, iOrdinal, pSymInfo);
     208static DECLCALLBACK(int) rtDbgModMapSym_SymbolByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo)
     209{
     210    RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
     211    return RTDbgModSymbolByOrdinal(hCnt, iOrdinal, pSymInfo);
    125212}
    126213
    127214
    128215/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolCount} */
    129 static DECLCALLBACK(uint32_t) rtDbgModNm_SymbolCount(PRTDBGMODINT pMod)
    130 {
    131     PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
    132     return RTDbgModSymbolCount(pThis->hCnt);
     216static DECLCALLBACK(uint32_t) rtDbgModMapSym_SymbolCount(PRTDBGMODINT pMod)
     217{
     218    RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
     219    return RTDbgModSymbolCount(hCnt);
    133220}
    134221
    135222
    136223/** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolAdd} */
    137 static DECLCALLBACK(int) rtDbgModNm_SymbolAdd(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
    138                                               RTDBGSEGIDX iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags,
    139                                               uint32_t *piOrdinal)
    140 {
    141     PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
     224static DECLCALLBACK(int) rtDbgModMapSym_SymbolAdd(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
     225                                                  RTDBGSEGIDX iSeg, RTUINTPTR off, RTUINTPTR cb, uint32_t fFlags,
     226                                                  uint32_t *piOrdinal)
     227{
     228    RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
    142229    Assert(!pszSymbol[cchSymbol]); NOREF(cchSymbol);
    143     return RTDbgModSymbolAdd(pThis->hCnt, pszSymbol, iSeg, off, cb, fFlags, piOrdinal);
     230    return RTDbgModSymbolAdd(hCnt, pszSymbol, iSeg, off, cb, fFlags, piOrdinal);
    144231}
    145232
    146233
    147234/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentByIndex} */
    148 static DECLCALLBACK(int) rtDbgModNm_SegmentByIndex(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo)
    149 {
    150     PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
    151     return RTDbgModSegmentByIndex(pThis->hCnt, iSeg, pSegInfo);
     235static DECLCALLBACK(int) rtDbgModMapSym_SegmentByIndex(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo)
     236{
     237    RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
     238    return RTDbgModSegmentByIndex(hCnt, iSeg, pSegInfo);
    152239}
    153240
    154241
    155242/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentCount} */
    156 static DECLCALLBACK(RTDBGSEGIDX) rtDbgModNm_SegmentCount(PRTDBGMODINT pMod)
    157 {
    158     PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
    159     return RTDbgModSegmentCount(pThis->hCnt);
     243static DECLCALLBACK(RTDBGSEGIDX) rtDbgModMapSym_SegmentCount(PRTDBGMODINT pMod)
     244{
     245    RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
     246    return RTDbgModSegmentCount(hCnt);
    160247}
    161248
    162249
    163250/** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentAdd} */
    164 static DECLCALLBACK(int) rtDbgModNm_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName,
     251static DECLCALLBACK(int) rtDbgModMapSym_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName,
    165252                                               size_t cchName, uint32_t fFlags, PRTDBGSEGIDX piSeg)
    166253{
    167     PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
     254    RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
    168255    Assert(!pszName[cchName]); NOREF(cchName);
    169     return RTDbgModSegmentAdd(pThis->hCnt, uRva, cb, pszName, fFlags, piSeg);
     256    return RTDbgModSegmentAdd(hCnt, uRva, cb, pszName, fFlags, piSeg);
    170257}
    171258
    172259
    173260/** @interface_method_impl{RTDBGMODVTDBG,pfnImageSize} */
    174 static DECLCALLBACK(RTUINTPTR) rtDbgModNm_ImageSize(PRTDBGMODINT pMod)
    175 {
    176     PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
    177     return RTDbgModImageSize(pThis->hCnt);
     261static DECLCALLBACK(RTUINTPTR) rtDbgModMapSym_ImageSize(PRTDBGMODINT pMod)
     262{
     263    RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
     264    return RTDbgModImageSize(hCnt);
    178265}
    179266
    180267
    181268/** @interface_method_impl{RTDBGMODVTDBG,pfnRvaToSegOff} */
    182 static DECLCALLBACK(RTDBGSEGIDX) rtDbgModNm_RvaToSegOff(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg)
    183 {
    184     PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
    185     return RTDbgModRvaToSegOff(pThis->hCnt, uRva, poffSeg);
     269static DECLCALLBACK(RTDBGSEGIDX) rtDbgModMapSym_RvaToSegOff(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg)
     270{
     271    RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
     272    return RTDbgModRvaToSegOff(hCnt, uRva, poffSeg);
    186273}
    187274
    188275
    189276/** @interface_method_impl{RTDBGMODVTDBG,pfnClose} */
    190 static DECLCALLBACK(int) rtDbgModNm_Close(PRTDBGMODINT pMod)
    191 {
    192     PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;
    193     RTDbgModRelease(pThis->hCnt);
    194     pThis->hCnt = NIL_RTDBGMOD;
    195     RTMemFree(pThis);
     277static DECLCALLBACK(int) rtDbgModMapSym_Close(PRTDBGMODINT pMod)
     278{
     279    RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv;
     280    RTDbgModRelease(hCnt);
     281    pMod->pvDbgPriv = NULL;
    196282    return VINF_SUCCESS;
    197283}
     
    199285
    200286/**
    201  * Scans a NM-like map file.
     287 * Validate the module header.
    202288 *
    203  * This implements both passes to avoid code duplication.
     289 * @returns true if valid, false if not.
     290 * @param   pHdr        The header.
     291 * @param   cbAvail     How much we've actually read.
     292 * @param   cbFile      The file size (relative to module header).
     293 */
     294static bool rtDbgModMapSymIsValidHeader(MAPSYMHDR const *pHdr, size_t cbAvail, uint64_t cbFile)
     295{
     296    if (cbAvail <= RT_UOFFSETOF(MAPSYMHDR, achModule))
     297        return false;
     298
     299    if (pHdr->cSegs == 0)
     300        return false;
     301    if (pHdr->cSegs > RTDBGMODMAPSYM_MAX_SEGMENTS)
     302        return false;
     303
     304    if (pHdr->off16SegDef == 0)
     305        return false;
     306    if (pHdr->off16SegDef * (uint32_t)16 >= cbFile)
     307        return false;
     308
     309    if (pHdr->cchModule == 0)
     310        return false;
     311    if (pHdr->cchModule > 128) /* Note must be smaller than abPadding below in caller */
     312        return false;
     313
     314    size_t cchMaxName = cbAvail - RT_UOFFSETOF(MAPSYMHDR, achModule);
     315    if (pHdr->cchModule > cchMaxName)
     316        return false;
     317
     318    for (uint32_t i = 0; i < pHdr->cchModule; i++)
     319    {
     320        unsigned char const uch = pHdr->achModule[i];
     321        if (   uch <  0x20
     322            || uch >= 0x7f)
     323            return false;
     324    }
     325
     326    return true;
     327}
     328
     329
     330/**
     331 * Validate the given segment definition.
    204332 *
    205  * @returns IPRT status code.
    206  * @param   pThis               The instance data.
    207  * @param   pStrm               The stream.
    208  * @param   fAddSymbols         false in the first pass, true in the second.
     333 * @returns true if valid, false if not.
     334 * @param   pSegDef     The segment definition structure.
     335 * @param   cbMax       Host many bytes are available starting with pSegDef.
    209336 */
    210 static int rtDbgModNmScanFile(PRTDBGMODNM pThis, PRTSTREAM pStrm, bool fAddSymbols)
     337static bool rtDbgModMapSymIsValidSegDef(MAPSYMSEGDEF const *pSegDef, size_t cbMax)
     338{
     339    if (RT_UOFFSETOF(MAPSYMSEGDEF, achSegName) > cbMax)
     340        return false;
     341    if (pSegDef->cSymbols)
     342    {
     343        if (pSegDef->cSymbols > _32K)
     344        {
     345            Log(("rtDbgModMapSymIsValidSegDef: Too many symbols: %#x\n", pSegDef->cSymbols));
     346            return false;
     347        }
     348
     349        if (pSegDef->offSymbolOffsets + (uint32_t)2 * pSegDef->cSymbols > cbMax)
     350        {
     351            Log(("rtDbgModMapSymIsValidSegDef: Bad symbol offset/count: %#x/%#x\n", pSegDef->offSymbolOffsets, pSegDef->cSymbols));
     352            return false;
     353        }
     354    }
     355
     356    size_t cchMaxName = cbMax - RT_UOFFSETOF(MAPSYMHDR, achModule);
     357    if (pSegDef->cchSegName > cchMaxName)
     358    {
     359        Log(("rtDbgModMapSymIsValidSegDef: Bad segment name length\n"));
     360        return false;
     361    }
     362
     363    for (uint32_t i = 0; i < pSegDef->cchSegName; i++)
     364    {
     365        unsigned char uch = pSegDef->achSegName[i];
     366        if (   uch <  0x20
     367            || uch >= 0x7f)
     368        {
     369            Log(("rtDbgModMapSymIsValidSegDef: Bad segment name: %.*Rhxs\n", pSegDef->cchSegName, pSegDef->achSegName));
     370            return false;
     371        }
     372    }
     373
     374    return true;
     375}
     376
     377
     378/**
     379 * Fills @a hCnt with segments and symbols from the MAPSYM file.
     380 *
     381 * @note  We only support reading the first module, right now.
     382 */
     383static int rtDbgModMapSymReadIt(RTDBGMOD hCnt, uint8_t const *pbFile, size_t cbFile)
    211384{
    212385    /*
    213      * Try parse the stream.
     386     * Revalidate the header.
    214387     */
    215     RTUINTPTR   SegZeroRva = fAddSymbols ? RTDbgModSegmentRva(pThis->hCnt, 0/*iSeg*/) : 0;
    216     char        szSym[RTDBG_SYMBOL_NAME_LENGTH] = "";
    217     size_t      cchMod    = 0;
    218     size_t      offSym    = 0;
    219     unsigned    cchAddr   = 0;
    220     uint64_t    u64Low    = UINT64_MAX;
    221     uint64_t    u64High   = 0;
    222     int         fWithType = -1;
    223     char        szLine[512];
    224     int         rc;
    225     while (RT_SUCCESS(rc = RTStrmGetLine(pStrm, szLine, sizeof(szLine))))
     388    MAPSYMHDR const *pHdr = (MAPSYMHDR const *)pbFile;
     389    if (!rtDbgModMapSymIsValidHeader(pHdr, cbFile, cbFile))
     390        return VERR_DBG_NO_MATCHING_INTERPRETER;
     391    Log(("rtDbgModMapSymReadIt: szModule='%.*s' cSegs=%u off16NextMap=%#x\n",
     392         pHdr->cchModule, pHdr->achModule, pHdr->cSegs, pHdr->off16NextMap));
     393
     394    /*
     395     * Load each segment.
     396     */
     397    uint32_t       uRva       = 0;
     398    uint32_t const cSegs      = pHdr->cSegs;
     399    uint32_t       offSegment = pHdr->off16SegDef * (uint32_t)16;
     400    for (uint32_t iSeg = 0; iSeg < cSegs; iSeg++)
    226401    {
    227         char    chType;
    228         if (RT_C_IS_XDIGIT(szLine[0]))
     402        if (offSegment >= cbFile)
     403            return VERR_DBG_NO_MATCHING_INTERPRETER;
     404
     405        size_t const cbMax = cbFile - offSegment;
     406        MAPSYMSEGDEF const *pSegDef = (MAPSYMSEGDEF const *)&pbFile[offSegment];
     407        if (!rtDbgModMapSymIsValidSegDef(pSegDef, cbMax))
     408            return VERR_DBG_NO_MATCHING_INTERPRETER;
     409
     410        Log(("rtDbgModMapSymReadIt:  Segment #%u: flags=%#x name='%.*s' symbols=%#x @ %#x next=%#x lines=@%#x (reserved: %#x %#x %#x %#x %#x %#x)\n",
     411             iSeg, pSegDef->bFlags, pSegDef->cchSegName, pSegDef->achSegName, pSegDef->cSymbols, pSegDef->offSymbolOffsets,
     412             pSegDef->off16NextSeg, pSegDef->offLineDef, pSegDef->au16Reserved0[0], pSegDef->au16Reserved0[1],
     413             pSegDef->au16Reserved0[2], pSegDef->au16Reserved0[3], pSegDef->bReserved1, pSegDef->u16Reserved2));
     414
     415        /*
     416         * First symbol pass finds the largest symbol and uses that as the segment size.
     417         */
     418        uint32_t               cbSegmentEst = 0;
     419        uint32_t const         cSymbols     = pSegDef->cSymbols;
     420        uint16_t const * const paoffSymbols = (uint16_t const *)&pbFile[offSegment + pSegDef->offSymbolOffsets];
     421        bool const             fIs32Bit     = RT_BOOL(pSegDef->bFlags & MAPSYMSEGDEF_F_32BIT);
     422        uint32_t const         cbSymDef     = fIs32Bit ? 4 + 1 : 2 + 1;
     423        for (uint32_t iSymbol = 0; iSymbol < cSymbols; iSymbol++)
    229424        {
    230             /*
    231              * This is really what C was made for, string parsing.
    232              */
    233             /* The symbol value (address). */
    234             uint64_t u64Addr;
    235             char    *psz;
    236             rc = RTStrToUInt64Ex(szLine, &psz, 16, &u64Addr);
    237             if (rc != VWRN_TRAILING_CHARS)
    238                 return VERR_DBG_NOT_NM_MAP_FILE;
    239 
    240             /* Check the address width. */
    241             if (cchAddr == 0)
    242                 cchAddr = psz == &szLine[8] ? 8 : 16;
    243             if (psz != &szLine[cchAddr])
    244                 return VERR_DBG_NOT_NM_MAP_FILE;
    245 
    246             /* Get the type and check for single space before symbol. */
    247             char *pszName;
    248             if (fWithType < 0)
    249                 fWithType = RT_C_IS_BLANK(szLine[cchAddr + 2]) ? 1 : 0; /* have type? Linux 2.4 /proc/ksyms doesn't. */
    250             if (fWithType)
     425            uint32_t off = paoffSymbols[iSymbol] + offSegment;
     426            if (off + cbSymDef <= cbFile)
    251427            {
    252                 chType  = szLine[cchAddr + 1];
    253                 pszName = &szLine[cchAddr + 3];
    254                 if (    RT_C_IS_BLANK(chType)
    255                     ||  !RT_C_IS_BLANK(szLine[cchAddr + 2])
    256                     ||  RT_C_IS_BLANK(szLine[cchAddr + 3]))
    257                     return VERR_DBG_NOT_NM_MAP_FILE;
     428                uint32_t uValue = fIs32Bit ? *(uint32_t const *)&pbFile[off] : (uint32_t)*(uint16_t const *)&pbFile[off];
     429                if (uValue > cbSegmentEst)
     430                    cbSegmentEst = uValue;
    258431            }
    259432            else
     433                Log(("rtDbgModMapSymReadIt:  Bad symbol offset %#x\n", off));
     434        }
     435
     436        /*
     437         * Add the segment.
     438         */
     439        char szName[256];
     440        memcpy(szName, pSegDef->achSegName, pSegDef->cchSegName);
     441        szName[pSegDef->cchSegName] = '\0';
     442        if (!pSegDef->cchSegName)
     443            RTStrPrintf(szName, sizeof(szName), "seg%02u", iSeg);
     444
     445        RTDBGSEGIDX idxDbgSeg = iSeg;
     446        int rc = RTDbgModSegmentAdd(hCnt, uRva, cbSegmentEst, szName, 0 /*fFlags*/, &idxDbgSeg);
     447        if (RT_FAILURE(rc))
     448            return rc;
     449
     450        uRva += cbSegmentEst;
     451
     452        /*
     453         * The second symbol pass loads the symbol values and names.
     454         */
     455        for (uint32_t iSymbol = 0; iSymbol < cSymbols; iSymbol++)
     456        {
     457            uint32_t off = paoffSymbols[iSymbol] + offSegment;
     458            if (off + cbSymDef <= cbFile)
    260459            {
    261                 chType = 'T';
    262                 pszName = &szLine[cchAddr + 1];
    263             }
    264 
    265             /* Find the end of the symbol name. */
    266             char *pszNameEnd = pszName;
    267             char ch;
    268             while ((ch = *pszNameEnd) != '\0' && !RT_C_IS_SPACE(ch))
    269                 pszNameEnd++;
    270 
    271             /* Any module name (linux /proc/kallsyms) following in brackets? */
    272             char *pszModName    = pszNameEnd;
    273             char *pszModNameEnd = pszModName;
    274             if (*pszModName)
    275             {
    276                 *pszModName++ = '\0';
    277                 pszModNameEnd = pszModName = RTStrStripL(pszModName);
    278                 if (*pszModName != '\0')
     460                /* Get value: */
     461                uint32_t uValue = RT_MAKE_U16(pbFile[off], pbFile[off + 1]);
     462                off += 2;
     463                if (fIs32Bit)
    279464                {
    280                     if (*pszModName != '[')
    281                         return VERR_DBG_NOT_LINUX_KALLSYMS;
    282                     pszModNameEnd = ++pszModName;
    283                     while ((ch = *pszModNameEnd) != '\0' && ch != ']')
    284                         pszModNameEnd++;
    285                     if (ch != ']')
    286                         return VERR_DBG_NOT_LINUX_KALLSYMS;
    287                     char *pszEnd = pszModNameEnd + 1;
    288                     if ((size_t)(pszModNameEnd - pszModName) >= 128) /* lazy bird */
    289                         return VERR_DBG_NOT_LINUX_KALLSYMS;
    290                     *pszModNameEnd = '\0';
    291                     if (*pszEnd)
    292                         pszEnd = RTStrStripL(pszEnd);
    293                     if (*pszEnd)
    294                         return VERR_DBG_NOT_LINUX_KALLSYMS;
     465                    uValue |= RT_MAKE_U32_FROM_U8(0, 0, pbFile[off], pbFile[off + 1]);
     466                    off += 2;
    295467                }
    296             }
    297 
    298             /*
    299              * Did the module change? Then update the symbol prefix.
    300              */
    301             if (    cchMod != (size_t)(pszModNameEnd - pszModName)
    302                 ||  memcmp(pszModName, szSym, cchMod))
    303             {
    304                 cchMod = pszModNameEnd - pszModName;
    305                 if (cchMod == 0)
    306                     offSym = 0;
     468
     469                /* Get name: */
     470                uint8_t cchName = pbFile[off++];
     471                if (off + cchName <= cbFile)
     472                {
     473                    memcpy(szName, &pbFile[off], cchName);
     474                    szName[cchName] = '\0';
     475                    RTStrPurgeEncoding(szName);
     476                }
     477                else
     478                    cchName = 0;
     479                if (cchName == 0)
     480                    RTStrPrintf(szName, sizeof(szName), "unknown_%u_%u", iSeg, iSymbol);
     481
     482                /* Try add it: */
     483                rc = RTDbgModSymbolAdd(hCnt, szName, idxDbgSeg, uValue, 0 /*cb*/, 0 /*fFlags*/, NULL /*piOrdinal*/);
     484                if (RT_SUCCESS(rc))
     485                    Log7(("rtDbgModMapSymReadIt: %02x:%06x %s\n", idxDbgSeg, uValue, szName));
     486                else if (   rc == VERR_DBG_DUPLICATE_SYMBOL
     487                         || rc == VERR_DBG_ADDRESS_CONFLICT
     488                         || rc == VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE)
     489                    Log(("rtDbgModMapSymReadIt: %02x:%06x %s\n", idxDbgSeg, uValue, szName));
    307490                else
    308491                {
    309                     memcpy(szSym, pszModName, cchMod);
    310                     szSym[cchMod] = '.';
    311                     offSym = cchMod + 1;
    312                 }
    313                 szSym[offSym] = '\0';
    314             }
    315 
    316             /*
    317              * Validate the type and add the symbol if it's a type we care for.
    318              */
    319             uint32_t    fFlags  = 0;
    320             RTDBGSEGIDX iSegSym = 0;
    321             switch (chType)
    322             {
    323                 /* absolute */
    324                 case 'a':
    325                 case '?': /* /proc/kallsyms */
    326                     iSegSym = RTDBGSEGIDX_ABS;
    327                     /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL;
    328                     break;
    329                 case 'A':
    330                     iSegSym = RTDBGSEGIDX_ABS;
    331                     /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC;
    332                     break;
    333 
    334                 case 'b':
    335                     /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL;
    336                     break;
    337                 case 'B':
    338                     /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC;
    339                     break;
    340 
    341                 case 'c':
    342                     /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL | RTDBG_SYM_FLAGS_COMMON;
    343                     break;
    344                 case 'C':
    345                     /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC | RTDBG_SYM_FLAGS_COMMON;
    346                     break;
    347 
    348                 case 'd':
    349                     /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL;
    350                     break;
    351                 case 'D':
    352                     /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC;
    353                     break;
    354 
    355                 case 'g':
    356                     /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL;
    357                     break;
    358                 case 'G':
    359                     /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC;
    360                     break;
    361 
    362                 case 'i':
    363                     /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL;
    364                     break;
    365                 case 'I':
    366                     /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC;
    367                     break;
    368 
    369                 case 'r':
    370                     /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL | RTDBG_SYM_FLAGS_CONST;
    371                     break;
    372                 case 'R':
    373                     /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC | RTDBG_SYM_FLAGS_CONST;
    374                     break;
    375 
    376                 case 's':
    377                     /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL;
    378                     break;
    379                 case 'S':
    380                     /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC;
    381                     break;
    382 
    383                 case 't':
    384                     /// @todo fFlags |= RTDBG_SYM_FLAGS_LOCAL | RTDBG_SYM_FLAGS_TEXT;
    385                     break;
    386                 case 'T':
    387                     /// @todo fFlags |= RTDBG_SYM_FLAGS_PUBLIC | RTDBG_SYM_FLAGS_TEXT;
    388                     break;
    389 
    390                 case 'w':
    391                     /// @todo fFlags |= RTDBG_SYM_FLAGS_WEAK | RTDBG_SYM_FLAGS_LOCAL; //???
    392                     break;
    393                 case 'W':
    394                     /// @todo fFlags |= RTDBG_SYM_FLAGS_WEAK | RTDBG_SYM_FLAGS_PUBLIC;
    395                     break;
    396 
    397                 case 'N': /* debug */
    398                 case 'n':
    399                 case '-': /* stabs */
    400                 case 'u': /* undefined (/proc/kallsyms) */
    401                 case 'U':
    402                 case 'v': /* weakext */
    403                 case 'V':
    404                     iSegSym = NIL_RTDBGSEGIDX;
    405                     break;
    406 
    407                 default:
    408                     return VERR_DBG_NOT_NM_MAP_FILE;
    409             }
    410 
    411             if (iSegSym != NIL_RTDBGSEGIDX)
    412             {
    413                 if (fAddSymbols)
    414                 {
    415                     size_t cchName = pszNameEnd - pszName;
    416                     if (cchName >= sizeof(szSym) - offSym)
    417                         cchName = sizeof(szSym) - offSym - 1;
    418                     memcpy(&szSym[offSym], pszName, cchName + 1);
    419                     if (iSegSym == 0)
    420                         rc = RTDbgModSymbolAdd(pThis->hCnt, szSym, iSegSym, u64Addr - SegZeroRva, 0/*cb*/, fFlags, NULL);
    421                     else
    422                         rc = RTDbgModSymbolAdd(pThis->hCnt, szSym, iSegSym, u64Addr, 0/*cb*/, fFlags, NULL);
    423                     if (    RT_FAILURE(rc)
    424                         &&  rc != VERR_DBG_DUPLICATE_SYMBOL
    425                         &&  rc != VERR_DBG_ADDRESS_CONFLICT) /* (don't be too strict) */
    426                         return rc;
    427                 }
    428 
    429                 /* Track segment span. */
    430                 if (iSegSym == 0)
    431                 {
    432                     if (u64Low > u64Addr)
    433                         u64Low = u64Addr;
    434                     if (u64High < u64Addr)
    435                         u64High = u64Addr;
     492                    Log(("rtDbgModMapSymReadIt: Unexpected RTDbgModSymbolAdd failure: %Rrc - %02x:%06x %s\n",
     493                         rc, idxDbgSeg, uValue, szName));
     494                    return rc;
    436495                }
    437496            }
    438497        }
    439         else
    440         {
    441             /*
    442              * This is either a blank line or a symbol without an address.
    443              */
    444             RTStrStripR(szLine);
    445             if (szLine[0])
    446             {
    447                 size_t cch = strlen(szLine);
    448                 if (cchAddr == 0)
    449                     cchAddr = cch < 16+3 || szLine[8+1] != ' ' ? 8 : 16;
    450                 if (cch < cchAddr+3+1)
    451                     return VERR_DBG_NOT_NM_MAP_FILE;
    452                 chType = szLine[cchAddr + 1];
    453                 if (    chType != 'U'
    454                     &&  chType != 'w')
    455                     return VERR_DBG_NOT_NM_MAP_FILE;
    456                 char *pszType = RTStrStripL(szLine);
    457                 if (pszType != &szLine[cchAddr + 1])
    458                     return VERR_DBG_NOT_NM_MAP_FILE;
    459                 if (!RT_C_IS_BLANK(szLine[cchAddr + 2]))
    460                     return VERR_DBG_NOT_NM_MAP_FILE;
    461             }
    462             /* else: blank - ignored */
    463         }
     498
     499        /* Next segment */
     500        offSegment = pSegDef->off16NextSeg * (uint32_t)16;
    464501    }
    465 
    466     /*
    467      * The final segment.
    468      */
    469     if (rc == VERR_EOF)
    470     {
    471         if (fAddSymbols)
    472             rc = VINF_SUCCESS;
    473         else
    474         {
    475             if (    u64Low  != UINT64_MAX
    476                  || u64High != 0)
    477                 rc = RTDbgModSegmentAdd(pThis->hCnt, u64Low, u64High - u64Low + 1, "main", 0, NULL);
    478             else /* No sensible symbols... throw an error instead? */
    479                 rc = RTDbgModSegmentAdd(pThis->hCnt, 0, 0, "main", 0, NULL);
    480         }
    481     }
    482 
    483     return rc;
     502    return VINF_SUCCESS;
    484503}
    485504
    486505
    487506/** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */
    488 static DECLCALLBACK(int) rtDbgModNm_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
     507static DECLCALLBACK(int) rtDbgModMapSym_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)
    489508{
    490509    NOREF(enmArch);
     
    496515        || pMod->pImgVt)
    497516        return VERR_DBG_NO_MATCHING_INTERPRETER;
     517    pMod->pvDbgPriv = NULL;
    498518
    499519    /*
    500      * Try open the file and create an instance.
     520     * Try open the file and check out the first header.
    501521     */
    502     PRTSTREAM pStrm;
    503     int rc = RTStrmOpen(pMod->pszDbgFile, "r", &pStrm);
     522    RTFILE hFile;
     523    int rc = RTFileOpen(&hFile, pMod->pszDbgFile, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
    504524    if (RT_SUCCESS(rc))
    505525    {
    506         PRTDBGMODNM pThis = (PRTDBGMODNM)RTMemAlloc(sizeof(*pThis));
    507         if (pThis)
     526        uint64_t cbFile = 0;
     527        rc = RTFileGetSize(hFile, &cbFile);
     528        if (   RT_SUCCESS(rc)
     529            && cbFile < _2M)
    508530        {
    509             rc = RTDbgModCreate(&pThis->hCnt, pMod->pszName, 0 /*cbSeg*/, 0 /*fFlags*/);
     531            union
     532            {
     533                MAPSYMHDR Hdr;
     534                char      abPadding[sizeof(MAPSYMHDR) + 257]; /* rtDbgModMapSymIsValidHeader makes size assumptions.  */
     535            } uBuf;
     536            size_t cbToRead = (size_t)RT_MIN(cbFile, sizeof(uBuf));
     537            rc = RTFileReadAt(hFile, 0, &uBuf, RT_MIN(cbFile, sizeof(uBuf)), NULL);
    510538            if (RT_SUCCESS(rc))
    511539            {
    512                 /*
    513                  * Scan the file twice, first to figure the segment
    514                  * sizes, then to add the symbol.
    515                  */
    516                 rc = rtDbgModNmScanFile(pThis, pStrm, false /*fAddSymbols*/);
    517                 if (RT_SUCCESS(rc))
    518                     rc = RTStrmRewind(pStrm);
    519                 if (RT_SUCCESS(rc))
    520                     rc = rtDbgModNmScanFile(pThis, pStrm, true /*fAddSymbols*/);
    521                 if (RT_SUCCESS(rc))
     540                if (rtDbgModMapSymIsValidHeader(&uBuf.Hdr, cbToRead, cbFile))
    522541                {
    523                     RTStrmClose(pStrm);
    524                     pMod->pvDbgPriv = pThis;
    525                     return rc;
     542                    uBuf.Hdr.achModule[uBuf.Hdr.cchModule] = '\0';
     543
     544                    /*
     545                     * Read the whole thing into memory, create an
     546                     * instance/container and load it with symbols.
     547                     */
     548                    void  *pvFile  = NULL;
     549                    size_t cbFile2 = 0;
     550                    rc = RTFileReadAllByHandle(hFile, &pvFile, &cbFile2);
     551                    if (RT_SUCCESS(rc))
     552                    {
     553                        RTDBGMOD hCnt;
     554                        rc = RTDbgModCreate(&hCnt, uBuf.Hdr.achModule, 0 /*cbSeg*/, 0 /*fFlags*/);
     555                        if (RT_SUCCESS(rc))
     556                        {
     557                            rc = rtDbgModMapSymReadIt(hCnt, (uint8_t const *)pvFile, cbFile2);
     558                            if (RT_SUCCESS(rc))
     559                                pMod->pvDbgPriv = hCnt;
     560                            else
     561                                RTDbgModRelease(hCnt);
     562                        }
     563                        RTFileReadAllFree(pvFile, cbFile2);
     564                    }
    526565                }
    527566            }
    528             RTDbgModRelease(pThis->hCnt);
    529567        }
    530         else
    531             rc = VERR_NO_MEMORY;
    532         RTStrmClose(pStrm);
     568        RTFileClose(hFile);
    533569    }
     570    Log(("rtDbgModMapSym_TryOpen: %s -> %Rrc, %p\n", pMod->pszDbgFile, rc, pMod->pvDbgPriv));
    534571    return rc;
    535572}
     
    537574
    538575
    539 /** Virtual function table for the NM-like map file reader. */
    540 DECL_HIDDEN_CONST(RTDBGMODVTDBG) const g_rtDbgModVtDbgNm =
     576/** Virtual function table for the MAPSYM file reader. */
     577DECL_HIDDEN_CONST(RTDBGMODVTDBG) const g_rtDbgModVtDbgMapSym =
    541578{
    542579    /*.u32Magic = */            RTDBGMODVTDBG_MAGIC,
    543     /*.fSupports = */           RT_DBGTYPE_MAP,
    544     /*.pszName = */             "nm",
    545     /*.pfnTryOpen = */          rtDbgModNm_TryOpen,
    546     /*.pfnClose = */            rtDbgModNm_Close,
    547 
    548     /*.pfnRvaToSegOff = */      rtDbgModNm_RvaToSegOff,
    549     /*.pfnImageSize = */        rtDbgModNm_ImageSize,
    550 
    551     /*.pfnSegmentAdd = */       rtDbgModNm_SegmentAdd,
    552     /*.pfnSegmentCount = */     rtDbgModNm_SegmentCount,
    553     /*.pfnSegmentByIndex = */   rtDbgModNm_SegmentByIndex,
    554 
    555     /*.pfnSymbolAdd = */        rtDbgModNm_SymbolAdd,
    556     /*.pfnSymbolCount = */      rtDbgModNm_SymbolCount,
    557     /*.pfnSymbolByOrdinal = */  rtDbgModNm_SymbolByOrdinal,
    558     /*.pfnSymbolByName = */     rtDbgModNm_SymbolByName,
    559     /*.pfnSymbolByAddr = */     rtDbgModNm_SymbolByAddr,
    560 
    561     /*.pfnLineAdd = */          rtDbgModNm_LineAdd,
    562     /*.pfnLineCount = */        rtDbgModNm_LineCount,
    563     /*.pfnLineByOrdinal = */    rtDbgModNm_LineByOrdinal,
    564     /*.pfnLineByAddr = */       rtDbgModNm_LineByAddr,
    565 
    566     /*.pfnUnwindFrame = */      rtDbgModNm_UnwindFrame,
     580    /*.fSupports = */           RT_DBGTYPE_SYM,
     581    /*.pszName = */             "mapsym",
     582    /*.pfnTryOpen = */          rtDbgModMapSym_TryOpen,
     583    /*.pfnClose = */            rtDbgModMapSym_Close,
     584
     585    /*.pfnRvaToSegOff = */      rtDbgModMapSym_RvaToSegOff,
     586    /*.pfnImageSize = */        rtDbgModMapSym_ImageSize,
     587
     588    /*.pfnSegmentAdd = */       rtDbgModMapSym_SegmentAdd,
     589    /*.pfnSegmentCount = */     rtDbgModMapSym_SegmentCount,
     590    /*.pfnSegmentByIndex = */   rtDbgModMapSym_SegmentByIndex,
     591
     592    /*.pfnSymbolAdd = */        rtDbgModMapSym_SymbolAdd,
     593    /*.pfnSymbolCount = */      rtDbgModMapSym_SymbolCount,
     594    /*.pfnSymbolByOrdinal = */  rtDbgModMapSym_SymbolByOrdinal,
     595    /*.pfnSymbolByName = */     rtDbgModMapSym_SymbolByName,
     596    /*.pfnSymbolByAddr = */     rtDbgModMapSym_SymbolByAddr,
     597
     598    /*.pfnLineAdd = */          rtDbgModMapSym_LineAdd,
     599    /*.pfnLineCount = */        rtDbgModMapSym_LineCount,
     600    /*.pfnLineByOrdinal = */    rtDbgModMapSym_LineByOrdinal,
     601    /*.pfnLineByAddr = */       rtDbgModMapSym_LineByAddr,
     602
     603    /*.pfnUnwindFrame = */      rtDbgModMapSym_UnwindFrame,
    567604
    568605    /*.u32EndMagic = */         RTDBGMODVTDBG_MAGIC
  • TabularUnified trunk/src/VBox/Runtime/include/internal/dbgmod.h

    r75235 r75237  
    688688extern DECLHIDDEN(RTDBGMODVTDBG const)  g_rtDbgModVtDbgDwarf;
    689689extern DECLHIDDEN(RTDBGMODVTDBG const)  g_rtDbgModVtDbgNm;
     690extern DECLHIDDEN(RTDBGMODVTDBG const)  g_rtDbgModVtDbgMapSym;
    690691#ifdef RT_OS_WINDOWS
    691692extern DECLHIDDEN(RTDBGMODVTDBG const)  g_rtDbgModVtDbgDbgHelp;
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