VirtualBox

Ignore:
Timestamp:
May 26, 2013 3:27:31 PM (12 years ago)
Author:
vboxsync
Message:

dbgmodcodeview.cpp: More sane segment translation and more stuff.

File:
1 edited

Legend:

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

    r46266 r46269  
    22/** @file
    33 * IPRT - Debug Module Reader For Microsoft CodeView.
     4 *
     5 * Based on the following documentation (plus guess work and googling):
     6 *
     7 *  - "Tools Interface Standard (TIS) Formats Specification for Windows",
     8 *    dated February 1993, version 1.0.
     9 *
     10 *  - "Visual C++ 5.0 Symbolic Debug Information Specification" chapter of
     11 *     SPECS.CHM from MSDN Library October 2001.
     12 *
     13 *  - "High Level Languages Debug Table Documentation", aka HLLDBG.HTML, aka
     14 *     IBMHLL.HTML, last changed 1996-07-08.
    415 */
    516
     
    4354#include <iprt/path.h>
    4455#include <iprt/string.h>
     56#include <iprt/strcache.h>
    4557#include "internal/dbgmod.h"
    4658#include "internal/ldrPE.h"
     
    5769typedef struct RTCVHDR
    5870{
    59     /** The magic ('NBxx'). */
     71    /** The magic ('NBxx'), see RTCVHDR_MAGIC_XXX. */
    6072    uint32_t    u32Magic;
    6173    /**
     
    6981/** Pointer to a CodeView header. */
    7082typedef RTCVHDR *PRTCVHDR;
     83
     84/** @name CodeView magic values (RTCVHDR::u32Magic).
     85 * @{  */
     86/** CodeView from Visual C++ 5.0.  Specified in the 2001 MSDN specs.chm file. */
     87#define RTCVHDR_MAGIC_NB11  RT_MAKE_U32_FROM_U8('N', 'B', '1', '1')
     88/** External PDB reference (often referred to as PDB 2.0). */
     89#define RTCVHDR_MAGIC_NB10  RT_MAKE_U32_FROM_U8('N', 'B', '1', '0')
     90/** CodeView v4.10, packed. Specified in the TIS document. */
     91#define RTCVHDR_MAGIC_NB09  RT_MAKE_U32_FROM_U8('N', 'B', '0', '9')
     92/** CodeView v4.00 thru v4.05.  Specified in the TIS document?  */
     93#define RTCVHDR_MAGIC_NB08  RT_MAKE_U32_FROM_U8('N', 'B', '0', '8')
     94/** Quick C for Windows 1.0 debug info. */
     95#define RTCVHDR_MAGIC_NB07  RT_MAKE_U32_FROM_U8('N', 'B', '0', '7')
     96/** Emitted by ILINK indicating incremental link. Comparable to NB05?  */
     97#define RTCVHDR_MAGIC_NB06  RT_MAKE_U32_FROM_U8('N', 'B', '0', '6')
     98/** Emitted by LINK version 5.20 and later before packing. */
     99#define RTCVHDR_MAGIC_NB05  RT_MAKE_U32_FROM_U8('N', 'B', '0', '5')
     100/** Emitted by IBM ILINK for HLL (similar to NB02 in many ways). */
     101#define RTCVHDR_MAGIC_NB04  RT_MAKE_U32_FROM_U8('N', 'B', '0', '4')
     102/** Emitted by LINK version 5.10 (or similar OMF linkers), as shipped with
     103 * Microsoft C v6.0 for example.  More or less entirely 16-bit. */
     104#define RTCVHDR_MAGIC_NB02  RT_MAKE_U32_FROM_U8('N', 'B', '0', '2')
     105/* No idea what NB03 might have been. */
     106/** AIX debugger format according to "IBM OS/2 16/32-bit Object Module Format
     107 *  (OMF) and Linear eXecutable Module Format (LX)" revision 10 (LXOMF.PDF). */
     108#define RTCVHDR_MAGIC_NB01  RT_MAKE_U32_FROM_U8('N', 'B', '0', '1')
     109/** Ancient CodeView format according to LXOMF.PDF. */
     110#define RTCVHDR_MAGIC_NB00  RT_MAKE_U32_FROM_U8('N', 'B', '0', '0')
     111/** @} */
    71112
    72113
     
    216257
    217258
    218 /** @name CodeView magic values.
    219  * @{  */
    220 /** CodeView from Visual C++ 5.0.  Specified in the 2001 MSDN specs.chm file. */
    221 #define RTCVHDR_MAGIC_NB11  RT_MAKE_U32_FROM_U8('N', 'B', '1', '1')
    222 /** External PDB reference (often referred to as PDB 2.0). */
    223 #define RTCVHDR_MAGIC_NB10  RT_MAKE_U32_FROM_U8('N', 'B', '1', '0')
    224 /** CodeView v4.10, packed. Specified in the TIS document. */
    225 #define RTCVHDR_MAGIC_NB09  RT_MAKE_U32_FROM_U8('N', 'B', '0', '9')
    226 /** CodeView v4.00 thru v4.05.  Specified in the TIS document?  */
    227 #define RTCVHDR_MAGIC_NB08  RT_MAKE_U32_FROM_U8('N', 'B', '0', '8')
    228 /** Quick C for Windows 1.0 debug info. */
    229 #define RTCVHDR_MAGIC_NB07  RT_MAKE_U32_FROM_U8('N', 'B', '0', '7')
    230 /** Emitted by ILINK indicating incremental link. Comparable to NB05?  */
    231 #define RTCVHDR_MAGIC_NB06  RT_MAKE_U32_FROM_U8('N', 'B', '0', '6')
    232 /** Emitted by LINK version 5.20 and later before packing. */
    233 #define RTCVHDR_MAGIC_NB05  RT_MAKE_U32_FROM_U8('N', 'B', '0', '5')
    234 /** Emitted by IBM ILINK for HLL (similar to NB02 in many ways). */
    235 #define RTCVHDR_MAGIC_NB04  RT_MAKE_U32_FROM_U8('N', 'B', '0', '4')
    236 /** Emitted by LINK version 5.10 (or similar OMF linkers), as shipped with
    237  * Microsoft C v6.0 for example.  More or less entirely 16-bit. */
    238 #define RTCVHDR_MAGIC_NB02  RT_MAKE_U32_FROM_U8('N', 'B', '0', '2')
    239 /* No idea what NB03 might have been. */
    240 /** AIX debugger format according to "IBM OS/2 16/32-bit Object Module Format
    241  *  (OMF) and Linear eXecutable Module Format (LX)" revision 10 (LXOMF.PDF). */
    242 #define RTCVHDR_MAGIC_NB01  RT_MAKE_U32_FROM_U8('N', 'B', '0', '1')
    243 /** Ancient CodeView format according to LXOMF.PDF. */
    244 #define RTCVHDR_MAGIC_NB00  RT_MAKE_U32_FROM_U8('N', 'B', '0', '0')
     259/**
     260 * CV4 module segment info.
     261 */
     262typedef struct RTCVMODSEGINFO32
     263{
     264    /** The segment number. */
     265    uint16_t        iSeg;
     266    /** Explicit padding. */
     267    uint16_t        u16Padding;
     268    /** Offset into the segment. */
     269    uint32_t        off;
     270    /** The size of the contribution. */
     271    uint32_t        cb;
     272} RTCVMODSEGINFO32;
     273typedef RTCVMODSEGINFO32 *PRTCVMODSEGINFO32;
     274typedef RTCVMODSEGINFO32 const *PCRTCVMODSEGINFO32;
     275
     276
     277/**
     278 * CV4 segment map header.
     279 */
     280typedef struct RTCVSEGMAPHDR
     281{
     282    /** Number of segments descriptors in the table. */
     283    uint16_t        cSegs;
     284    /** Number of logical segment descriptors. */
     285    uint16_t        cLogSegs;
     286} RTCVSEGMAPHDR;
     287/** Pointer to a CV4 segment map header. */
     288typedef RTCVSEGMAPHDR *PRTCVSEGMAPHDR;
     289/** Pointer to a const CV4 segment map header. */
     290typedef RTCVSEGMAPHDR const *PCRTCVSEGMAPHDR;
     291
     292/**
     293 * CV4 Segment map descriptor entry.
     294 */
     295typedef struct RTCVSEGMAPDESC
     296{
     297    /** Segment flags. */
     298    uint16_t        fFlags;
     299    /** The overlay number. */
     300    uint16_t        iOverlay;
     301    /** Group index into this segment descriptor array. 0 if not relevant.
     302     * The group descriptors are found in the second half of the table.  */
     303    uint16_t        iGroup;
     304    /** Complicated. */
     305    uint16_t        iFrame;
     306    /** Offset (byte) into the kCvSst_SegName table of the segment name, or
     307     * 0xffff. */
     308    uint16_t        offSegName;
     309    /** Offset (byte) into the kCvSst_SegName table of the class name, or 0xffff. */
     310    uint16_t        offClassName;
     311    /** Offset into the physical segment. */
     312    uint32_t        off;
     313    /** Size of segment. */
     314    uint32_t        cb;
     315} RTCVSEGMAPDESC;
     316/** Pointer to a segment map descriptor entry. */
     317typedef RTCVSEGMAPDESC *PRTCVSEGMAPDESC;
     318/** Pointer to a const segment map descriptor entry. */
     319typedef RTCVSEGMAPDESC const *PCRTCVSEGMAPDESC;
     320
     321/** @name RTCVSEGMAPDESC_F_XXX - RTCVSEGMAPDESC::fFlags values.
     322 * @{ */
     323#define RTCVSEGMAPDESC_F_READ       UINT16_C(0x0001)
     324#define RTCVSEGMAPDESC_F_WRITE      UINT16_C(0x0002)
     325#define RTCVSEGMAPDESC_F_EXECUTE    UINT16_C(0x0004)
     326#define RTCVSEGMAPDESC_F_32BIT      UINT16_C(0x0008)
     327#define RTCVSEGMAPDESC_F_SEL        UINT16_C(0x0100)
     328#define RTCVSEGMAPDESC_F_ABS        UINT16_C(0x0200)
     329#define RTCVSEGMAPDESC_F_GROUP      UINT16_C(0x1000)
     330#define RTCVSEGMAPDESC_F_RESERVED   UINT16_C(0xecf0)
    245331/** @} */
     332
     333/**
     334 * CV4 segment map subsection.
     335 */
     336typedef struct RTCVSEGMAP
     337{
     338    /** The header. */
     339    RTCVSEGMAPHDR   Hdr;
     340    /** Descriptor array. */
     341    RTCVSEGMAPDESC  aDescs[1];
     342} RTCVSEGMAP;
     343/** Pointer to a segment map subsection. */
     344typedef RTCVSEGMAP *PRTCVSEGMAP;
     345/** Pointer to a const segment map subsection. */
     346typedef RTCVSEGMAP const *PCRTCVSEGMAP;
     347
     348
     349/**
     350 * Global symbol table header, used by kCvSst_GlobalSym and kCvSst_GlobalPub.
     351 */
     352typedef struct RTCVGLOBALSYMTABHDR
     353{
     354    /** The symbol hash function. */
     355    uint16_t        uSymHash;
     356    /** The address hash function. */
     357    uint16_t        uAddrHash;
     358    /** The amount of symbol information following immediately after the header. */
     359    uint32_t        cbSymbols;
     360    /** The amount of symbol hash tables following the symbols. */
     361    uint32_t        cbSymHash;
     362    /** The amount of address hash tables following the symbol hash tables. */
     363    uint32_t        cbAddrHash;
     364} RTCVGLOBALSYMTABHDR;
     365/** Pointer to a global symbol table header. */
     366typedef RTCVGLOBALSYMTABHDR *PRTCVGLOBALSYMTABHDR;
     367/** Pointer to a const global symbol table header. */
     368typedef RTCVGLOBALSYMTABHDR const *PCRTCVGLOBALSYMTABHDR;
     369
     370
     371typedef enum RTCVSYMTYPE
     372{
     373    /** @name Symbols that doesn't change with compilation model or target machine.
     374     * @{ */
     375    kCvSymType_Compile = 0x0001,
     376    kCvSymType_Register,
     377    kCvSymType_Constant,
     378    kCvSymType_UDT,
     379    kCvSymType_SSearch,
     380    kCvSymType_End,
     381    kCvSymType_Skip,
     382    kCvSymType_CVReserve,
     383    kCvSymType_ObjName,
     384    kCvSymType_EndArg,
     385    kCvSymType_CobolUDT,
     386    kCvSymType_ManyReg,
     387    kCvSymType_Return,
     388    kCvSymType_EntryThis,
     389    /** @}  */
     390
     391    /** @name Symbols with 16:16 addresses.
     392     * @{ */
     393    kCvSymType_BpRel16 = 0x0100,
     394    kCvSymType_LData16,
     395    kCvSymType_GData16,
     396    kCvSymType_Pub16,
     397    kCvSymType_LProc16,
     398    kCvSymType_GProc16,
     399    kCvSymType_Thunk16,
     400    kCvSymType_BLock16,
     401    kCvSymType_With16,
     402    kCvSymType_Label16,
     403    kCvSymType_CExModel16,
     404    kCvSymType_VftPath16,
     405    kCvSymType_RegRel16,
     406    /** @}  */
     407
     408    /** @name Symbols with 16:32 addresses.
     409     * @{ */
     410    kCvSymType_BpRel32 = 0x0200,
     411    kCvSymType_LData32,
     412    kCvSymType_GData32,
     413    kCvSymType_Pub32,
     414    kCvSymType_LProc32,
     415    kCvSymType_GProc32,
     416    kCvSymType_Thunk32,
     417    kCvSymType_Block32,
     418    kCvSymType_With32,
     419    kCvSymType_Label32,
     420    kCvSymType_CExModel32,
     421    kCvSymType_VftPath32,
     422    kCvSymType_RegRel32,
     423    kCvSymType_LThread32,
     424    kCvSymType_GThread32,
     425    /** @}  */
     426
     427    /** @name Symbols for MIPS.
     428     * @{ */
     429    kCvSymType_LProcMips = 0x0300,
     430    kCvSymType_GProcMips,
     431    /** @} */
     432
     433    /** @name Symbols for Microsoft CodeView.
     434     * @{ */
     435    kCvSymType_ProcRef,
     436    kCvSymType_DataRef,
     437    kCvSymType_Align,
     438    /** @} */
     439} RTCVSYMTYPE;
     440typedef RTCVSYMTYPE *PRTCVSYMTYPE;
     441typedef RTCVSYMTYPE const *PCRTCVSYMTYPE;
     442
     443
     444/** The $$SYMBOL table signature for CV4. */
     445#define RTCVSYMBOLS_SIGNATURE_CV4   UINT32_C(0x00000001)
     446
     447
    246448
    247449
     
    303505    /** The directory (converted to 32-bit). */
    304506    PRTCVDIRENT32   paDirEnts;
     507    /** Current debugging style when parsing modules. */
     508    uint16_t        uCurStyle;
     509    /** Current debugging style version (HLL only). */
     510    uint16_t        uCurStyleVer;
     511
     512    /** The segment map (if present). */
     513    PRTCVSEGMAP     pSegMap;
     514    /** Segment names. */
     515    char           *pszzSegNames;
     516    /** The size of the segment names. */
     517    uint32_t        cbSegNames;
    305518
    306519    /** @}  */
     
    313526
    314527
     528
     529/**
     530 * Subsection callback.
     531 *
     532 * @returns IPRT status code.
     533 * @param   pThis           The CodeView debug info reader instance.
     534 * @param   pvSubSect       Pointer to the subsection data.
     535 * @param   cbSubSect       The size of the subsection data.
     536 * @param   pDirEnt         The directory entry.
     537 */
     538typedef DECLCALLBACK(int) FNDBGMODCVSUBSECTCALLBACK(PRTDBGMODCV pThis, void const *pvSubSect, size_t cbSubSect,
     539                                                    PCRTCVDIRENT32 pDirEnt);
     540/** Pointer to a subsection callback. */
     541typedef FNDBGMODCVSUBSECTCALLBACK *PFNDBGMODCVSUBSECTCALLBACK;
     542
     543
     544
     545/*******************************************************************************
     546*   Defined Constants And Macros                                               *
     547*******************************************************************************/
     548/** Light weight assert + return w/ fixed status code. */
     549#define RTDBGMODCV_CHECK_RET_BF(a_Expr, a_LogArgs) \
     550    do { \
     551        if (!(a_Expr)) \
     552        { \
     553            Log(("RTDbgCv: Check failed on line %d: " #a_Expr "\n", __LINE__)); \
     554            Log(a_LogArgs); \
     555            return VERR_CV_BAD_FORMAT; \
     556        } \
     557    } while (0)
     558
     559
     560/** Light weight assert + return w/ fixed status code. */
     561#define RTDBGMODCV_CHECK_NOMSG_RET_BF(a_Expr) \
     562    do { \
     563        if (!(a_Expr)) \
     564        { \
     565            Log(("RTDbgCv: Check failed on line %d: " #a_Expr "\n", __LINE__)); \
     566            return VERR_CV_BAD_FORMAT; \
     567        } \
     568    } while (0)
     569
     570
     571
     572
     573
    315574static int rtDbgModCvReadAt(PRTDBGMODCV pThis, uint32_t off, void *pvBuf, size_t cb)
    316575{
    317576    int rc;
    318577    if (pThis->hFile == NIL_RTFILE)
    319         rc = pThis->pMod->pImgVt->pfnReadAt(pThis->pMod, UINT32_MAX, off, pvBuf, cb);
     578        rc = pThis->pMod->pImgVt->pfnReadAt(pThis->pMod, UINT32_MAX, off + pThis->offBase, pvBuf, cb);
    320579    else
    321         rc = RTFileReadAt(pThis->hFile, off, pvBuf, cb, NULL);
     580        rc = RTFileReadAt(pThis->hFile, off + pThis->offBase, pvBuf, cb, NULL);
    322581    return rc;
    323582}
    324583
     584
     585static int rtDbgModCvReadAtAlloc(PRTDBGMODCV pThis, uint32_t off, void **ppvBuf, size_t cb)
     586{
     587    int   rc;
     588    void *pvBuf = *ppvBuf = RTMemAlloc(cb);
     589    if (pvBuf)
     590    {
     591        if (pThis->hFile == NIL_RTFILE)
     592            rc = pThis->pMod->pImgVt->pfnReadAt(pThis->pMod, UINT32_MAX, off + pThis->offBase, pvBuf, cb);
     593        else
     594            rc = RTFileReadAt(pThis->hFile, off + pThis->offBase, pvBuf, cb, NULL);
     595        if (RT_SUCCESS(rc))
     596            return VINF_SUCCESS;
     597
     598        RTMemFree(pvBuf);
     599        *ppvBuf = NULL;
     600    }
     601    else
     602        rc = VERR_NO_MEMORY;
     603    return rc;
     604}
    325605
    326606
     
    375655
    376656/**
     657 * Adds a symbol to the container.
     658 *
     659 * @returns IPRT status code
     660 * @param   pThis               The CodeView debug info reader instance.
     661 * @param   iSeg                Segment number.
     662 * @param   off                 Offset into the segment
     663 * @param   pchName             The symbol name (not necessarily terminated).
     664 * @param   cchName             The symbol name length.
     665 * @param   fFlags              Flags reserved for future exploits, MBZ.
     666 */
     667static int rtDbgModCvAddSymbol(PRTDBGMODCV pThis, uint32_t iSeg, uint64_t off, const char *pchName,
     668                               uint8_t cchName, uint32_t fFlags)
     669{
     670    const char *pszName = RTStrCacheEnterN(g_hDbgModStrCache, pchName, cchName);
     671    if (!pszName)
     672        return VERR_NO_STR_MEMORY;
     673#if 1
     674    if (iSeg == 0)
     675        iSeg = RTDBGSEGIDX_ABS;
     676    else if (pThis->pSegMap)
     677    {
     678        if (   iSeg > pThis->pSegMap->Hdr.cSegs
     679            || iSeg == 0
     680            || off > pThis->pSegMap->aDescs[iSeg - 1].cb)
     681        {
     682            Log(("Invalid segment index/offset %#06x:%08x for symbol %.*s\n", iSeg, off, cchName, pchName));
     683            return VERR_CV_BAD_FORMAT;
     684        }
     685        off += pThis->pSegMap->aDescs[iSeg - 1].off;
     686        if (pThis->pSegMap->aDescs[iSeg - 1].fFlags & RTCVSEGMAPDESC_F_ABS)
     687            iSeg = RTDBGSEGIDX_ABS;
     688        else
     689            iSeg = pThis->pSegMap->aDescs[iSeg - 1].iGroup;
     690    }
     691
     692    int rc = RTDbgModSymbolAdd(pThis->hCnt, pszName, iSeg, off, 0, 0 /*fFlags*/, NULL);
     693    Log(("Symbol: %04x:%08x %.*s [%Rrc]\n", iSeg, off, cchName, pchName, rc));
     694    if (rc == VERR_DBG_ADDRESS_CONFLICT || rc == VERR_DBG_DUPLICATE_SYMBOL)
     695        rc = VINF_SUCCESS;
     696    RTStrCacheRelease(g_hDbgModStrCache, pszName);
     697    return rc;
     698#else
     699    Log(("Symbol: %04x:%08x %.*s\n", iSeg, off, cchName, pchName));
     700    return VINF_SUCCESS;
     701#endif
     702}
     703
     704
     705/**
     706 * Parses a CV4 symbol table, adding symbols to the container.
     707 *
     708 * @returns IPRT status code
     709 * @param   pThis               The CodeView debug info reader instance.
     710 * @param   pbSymTab            The symbol table.
     711 * @param   cbSymTab            The size of the symbol table.
     712 * @param   fFlags              Flags reserved for future exploits, MBZ.
     713 */
     714static int rtDbgModCvSsProcessV4SymTab(PRTDBGMODCV pThis, void const *pvSymTab, size_t cbSymTab, uint32_t fFlags)
     715{
     716    int         rc = VINF_SUCCESS;
     717    RTCPTRUNION uCursor;
     718    uCursor.pv = pvSymTab;
     719
     720    while (cbSymTab > 0 && RT_SUCCESS(rc))
     721    {
     722        uint8_t const * const pbRecStart = uCursor.pu8;
     723        uint16_t cbRec = *uCursor.pu16++;
     724        if (cbRec >= 2)
     725        {
     726            uint16_t uSymType = *uCursor.pu16++;
     727
     728            Log3(("    %p: uSymType=%#06x LB %#x\n", pbRecStart - (uint8_t *)pvSymTab, uSymType, cbRec));
     729            RTDBGMODCV_CHECK_RET_BF(cbRec >= 2 && cbRec <= cbSymTab, ("cbRec=%#x cbSymTab=%#x\n", cbRec, cbSymTab));
     730
     731            switch (uSymType)
     732            {
     733                case kCvSymType_LData16:
     734                case kCvSymType_GData16:
     735                case kCvSymType_Pub16:
     736                {
     737                    RTDBGMODCV_CHECK_NOMSG_RET_BF(cbRec > 2 + 2+2+2+1);
     738                    uint16_t off     = *uCursor.pu16++;
     739                    uint16_t iSeg    = *uCursor.pu16++;
     740                    /*uint16_t iType   =*/ *uCursor.pu16++;
     741                    uint8_t  cchName = *uCursor.pu8++;
     742                    RTDBGMODCV_CHECK_NOMSG_RET_BF(cchName > 0);
     743                    RTDBGMODCV_CHECK_NOMSG_RET_BF(cbRec >= 2 + 2+2+2+1 + cchName);
     744
     745                    rc = rtDbgModCvAddSymbol(pThis, iSeg, off, uCursor.pch, cchName, 0);
     746                    break;
     747                }
     748
     749                case kCvSymType_LData32:
     750                case kCvSymType_GData32:
     751                case kCvSymType_Pub32:
     752                {
     753                    RTDBGMODCV_CHECK_NOMSG_RET_BF(cbRec > 2 + 4+2+2+1);
     754                    uint32_t off     = *uCursor.pu32++;
     755                    uint16_t iSeg    = *uCursor.pu16++;
     756                    /*uint16_t iType   =*/ *uCursor.pu16++;
     757                    uint8_t  cchName = *uCursor.pu8++;
     758                    RTDBGMODCV_CHECK_NOMSG_RET_BF(cchName > 0);
     759                    RTDBGMODCV_CHECK_NOMSG_RET_BF(cbRec >= 2 + 4+2+2+1 + cchName);
     760
     761                    rc = rtDbgModCvAddSymbol(pThis, iSeg, off, uCursor.pch, cchName, 0);
     762                    break;
     763                }
     764
     765                /** @todo add GProc and LProc so we can gather sizes as well as just symbols. */
     766            }
     767        }
     768        /*else: shorter records can be used for alignment, I guess. */
     769
     770        /* next */
     771        uCursor.pu8 = pbRecStart + cbRec + 2;
     772        cbSymTab   -= cbRec + 2;
     773    }
     774    return rc;
     775}
     776
     777
     778/** @callback_method_impl{FNDBGMODCVSUBSECTCALLBACK,
     779 * Parses kCvSst_GlobalPub, kCvSst_GlobalSym and kCvSst_StaticSym subsections,
     780 * adding symbols it finds to the container.} */
     781static DECLCALLBACK(int)
     782rtDbgModCvSs_GlobalPub_GlobalSym_StaticSym(PRTDBGMODCV pThis, void const *pvSubSect, size_t cbSubSect, PCRTCVDIRENT32 pDirEnt)
     783{
     784    PCRTCVGLOBALSYMTABHDR pHdr = (PCRTCVGLOBALSYMTABHDR)pvSubSect;
     785
     786    /*
     787     * Quick data validation.
     788     */
     789    Log2(("RTDbgModCv: %s: uSymHash=%#x uAddrHash=%#x cbSymbols=%#x cbSymHash=%#x cbAddrHash=%#x\n",
     790          rtDbgModCvGetSubSectionName(pDirEnt->uSubSectType), pHdr->uSymHash,
     791          pHdr->uAddrHash, pHdr->cbSymbols, pHdr->cbSymHash, pHdr->cbAddrHash));
     792    RTDBGMODCV_CHECK_NOMSG_RET_BF(cbSubSect >= sizeof(RTCVGLOBALSYMTABHDR));
     793    RTDBGMODCV_CHECK_NOMSG_RET_BF((uint64_t)pHdr->cbSymbols + pHdr->cbSymHash + pHdr->cbAddrHash <= cbSubSect - sizeof(*pHdr));
     794    RTDBGMODCV_CHECK_NOMSG_RET_BF(pHdr->uSymHash  < 0x20);
     795    RTDBGMODCV_CHECK_NOMSG_RET_BF(pHdr->uAddrHash < 0x20);
     796    if (!pHdr->cbSymbols)
     797        return VINF_SUCCESS;
     798
     799    /*
     800     * Parse the symbols.
     801     */
     802    return rtDbgModCvSsProcessV4SymTab(pThis, pHdr + 1, pHdr->cbSymbols, 0);
     803}
     804
     805
     806/** @callback_method_impl{FNDBGMODCVSUBSECTCALLBACK,
     807 * Parses kCvSst_Module subsection, storing the debugging style in pThis.} */
     808static DECLCALLBACK(int)
     809rtDbgModCvSs_Module(PRTDBGMODCV pThis, void const *pvSubSect, size_t cbSubSect, PCRTCVDIRENT32 pDirEnt)
     810{
     811    RTCPTRUNION uCursor;
     812    uCursor.pv = pvSubSect;
     813    RTDBGMODCV_CHECK_NOMSG_RET_BF(cbSubSect >= 2 + 2 + 2 + 2 + 0 + 1);
     814    uint16_t iOverlay = *uCursor.pu16++;
     815    uint16_t iLib     = *uCursor.pu16++;
     816    uint16_t cSegs    = *uCursor.pu16++;
     817    pThis->uCurStyle  = *uCursor.pu16++;
     818    if (pThis->uCurStyle == 0)
     819        pThis->uCurStyle = RT_MAKE_U16('C', 'V');
     820    pThis->uCurStyleVer = 0;
     821    uint8_t cchName   = uCursor.pu8[cSegs * 12];
     822    RTDBGMODCV_CHECK_NOMSG_RET_BF(cbSubSect >= 2 + 2 + 2 + 2 + cSegs * 12U + 1 + cchName);
     823
     824    const char *pchName = (const char *)&uCursor.pu8[cSegs * 12 + 1];
     825    Log2(("RTDbgModCv: Module: iOverlay=%#x iLib=%#x cSegs=%#x Style=%c%c (%#x) %.*s\n", iOverlay, iLib, cSegs,
     826          RT_BYTE1(pThis->uCurStyle), RT_BYTE2(pThis->uCurStyle), pThis->uCurStyle, cchName, pchName));
     827    RTDBGMODCV_CHECK_NOMSG_RET_BF(pThis->uCurStyle == RT_MAKE_U16('C', 'V'));
     828
     829    PCRTCVMODSEGINFO32 paSegs = (PCRTCVMODSEGINFO32)uCursor.pv;
     830    for (uint16_t iSeg = 0; iSeg < cSegs; iSeg++)
     831        Log2(("    #%02u: %04x:%08x LB %08x\n", iSeg, paSegs[iSeg].iSeg, paSegs[iSeg].off, paSegs[iSeg].cb));
     832
     833    return VINF_SUCCESS;
     834}
     835
     836
     837/** @callback_method_impl{FNDBGMODCVSUBSECTCALLBACK,
     838 * Parses kCvSst_Symbols, kCvSst_PublicSym and kCvSst_AlignSym subsections,
     839 * adding symbols it finds to the container.} */
     840static DECLCALLBACK(int)
     841rtDbgModCvSs_Symbols_PublicSym_AlignSym(PRTDBGMODCV pThis, void const *pvSubSect, size_t cbSubSect, PCRTCVDIRENT32 pDirEnt)
     842{
     843    RTDBGMODCV_CHECK_NOMSG_RET_BF(pThis->uCurStyle == RT_MAKE_U16('C', 'V'));
     844    RTDBGMODCV_CHECK_NOMSG_RET_BF(cbSubSect >= 8);
     845
     846    uint32_t u32Signature = *(uint32_t const *)pvSubSect;
     847    RTDBGMODCV_CHECK_RET_BF(u32Signature == RTCVSYMBOLS_SIGNATURE_CV4,
     848                            ("%#x, expected %#x\n", u32Signature, RTCVSYMBOLS_SIGNATURE_CV4));
     849
     850    return rtDbgModCvSsProcessV4SymTab(pThis, (uint8_t const *)pvSubSect + 4, cbSubSect - 4, 0);
     851}
     852
     853
     854static int rtDbgModCvLoadSegmentMap(PRTDBGMODCV pThis)
     855{
     856    /*
     857     * Search for the segment map and segment names. They will be at the end of the directory.
     858     */
     859    uint32_t iSegMap   = UINT32_MAX;
     860    uint32_t iSegNames = UINT32_MAX;
     861    uint32_t i = pThis->cDirEnts;
     862    while (i-- > 0)
     863    {
     864        if (   pThis->paDirEnts[i].iMod != 0xffff
     865            && pThis->paDirEnts[i].iMod != 0x0000)
     866            break;
     867        if (pThis->paDirEnts[i].uSubSectType == kCvSst_SegMap)
     868            iSegMap = i;
     869        else if (pThis->paDirEnts[i].uSubSectType == kCvSst_SegName)
     870            iSegNames = i;
     871    }
     872    if (iSegMap == UINT32_MAX)
     873    {
     874        Log(("RTDbgModCv: No segment map present, using segment indexes as is then...\n"));
     875        return VINF_SUCCESS;
     876    }
     877    RTDBGMODCV_CHECK_RET_BF(pThis->paDirEnts[iSegMap].cb >= sizeof(RTCVSEGMAPHDR),
     878                            ("Bad sstSegMap entry: cb=%#x\n", pThis->paDirEnts[iSegMap].cb));
     879    RTDBGMODCV_CHECK_NOMSG_RET_BF(iSegNames == UINT32_MAX || pThis->paDirEnts[iSegNames].cb > 0);
     880
     881    /*
     882     * Read them into memory.
     883     */
     884    int rc = rtDbgModCvReadAtAlloc(pThis, pThis->paDirEnts[iSegMap].off, (void **)&pThis->pSegMap,
     885                                   pThis->paDirEnts[iSegMap].cb);
     886    if (iSegNames != UINT32_MAX && RT_SUCCESS(rc))
     887    {
     888        pThis->cbSegNames = pThis->paDirEnts[iSegNames].cb;
     889        rc = rtDbgModCvReadAtAlloc(pThis, pThis->paDirEnts[iSegNames].off, (void **)&pThis->pszzSegNames,
     890                                   pThis->paDirEnts[iSegNames].cb);
     891    }
     892    if (RT_FAILURE(rc))
     893        return rc;
     894    RTDBGMODCV_CHECK_NOMSG_RET_BF(!pThis->pszzSegNames || !pThis->pszzSegNames[pThis->cbSegNames - 1]); /* must be terminated */
     895
     896    /* Use local pointers to avoid lots of indirection and typing. */
     897    PCRTCVSEGMAPHDR  pHdr    = &pThis->pSegMap->Hdr;
     898    PRTCVSEGMAPDESC  paDescs = &pThis->pSegMap->aDescs[0];
     899
     900    /*
     901     * If there are only logical segments, assume a direct mapping.
     902     * PE images, like the NT4 kernel, does it like this.
     903     */
     904    bool const fNoGroups = pHdr->cSegs == pHdr->cLogSegs;
     905
     906    /*
     907     * Validate and display it all.
     908     */
     909    Log2(("RTDbgModCv: SegMap: cSegs=%#x cLogSegs=%#x (cbSegNames=%#x)\n", pHdr->cSegs, pHdr->cLogSegs, pThis->cbSegNames));
     910    RTDBGMODCV_CHECK_RET_BF(pThis->paDirEnts[iSegMap].cb >= sizeof(*pHdr) + pHdr->cSegs * sizeof(paDescs[0]),
     911                            ("SegMap is out of bounds: cbSubSect=%#x cSegs=%#x\n", pThis->paDirEnts[iSegMap].cb, pHdr->cSegs));
     912    RTDBGMODCV_CHECK_NOMSG_RET_BF(pHdr->cSegs >= pHdr->cLogSegs);
     913
     914    Log2(("Logical segment descriptors: %u\n", pHdr->cLogSegs));
     915    for (uint16_t i = 0; i < pHdr->cSegs; i++)
     916    {
     917        if (i == pHdr->cLogSegs)
     918            Log2(("Group/Physical descriptors: %u\n", pHdr->cSegs - pHdr->cLogSegs));
     919        uint16_t idx = i < pHdr->cLogSegs ? i : i - pHdr->cLogSegs;
     920        char szFlags[16];
     921        memset(szFlags, '-', sizeof(szFlags));
     922        if (paDescs[i].fFlags & RTCVSEGMAPDESC_F_READ)
     923            szFlags[0] = 'R';
     924        if (paDescs[i].fFlags & RTCVSEGMAPDESC_F_WRITE)
     925            szFlags[1] = 'W';
     926        if (paDescs[i].fFlags & RTCVSEGMAPDESC_F_EXECUTE)
     927            szFlags[2] = 'X';
     928        if (paDescs[i].fFlags & RTCVSEGMAPDESC_F_32BIT)
     929            szFlags[3] = '3', szFlags[4]  = '2';
     930        if (paDescs[i].fFlags & RTCVSEGMAPDESC_F_SEL)
     931            szFlags[5] = 'S';
     932        if (paDescs[i].fFlags & RTCVSEGMAPDESC_F_ABS)
     933            szFlags[6] = 'A';
     934        if (paDescs[i].fFlags & RTCVSEGMAPDESC_F_GROUP)
     935            szFlags[7] = 'G';
     936        szFlags[8] = '\0';
     937        if (paDescs[i].fFlags & RTCVSEGMAPDESC_F_RESERVED)
     938            szFlags[8]  = '!', szFlags[9] = '\0';
     939        Log2(("    #%02u: %#010x LB %#010x flags=%#06x ovl=%#06x group=%#06x frame=%#06x iSegName=%#06x iClassName=%#06x %s\n",
     940              idx, paDescs[i].off, paDescs[i].cb, paDescs[i].fFlags, paDescs[i].iOverlay, paDescs[i].iGroup,
     941              paDescs[i].iFrame, paDescs[i].offSegName, paDescs[i].offClassName, szFlags));
     942
     943        RTDBGMODCV_CHECK_NOMSG_RET_BF(paDescs[i].offSegName == UINT16_MAX || paDescs[i].offSegName < pThis->cbSegNames);
     944        RTDBGMODCV_CHECK_NOMSG_RET_BF(paDescs[i].offClassName == UINT16_MAX || paDescs[i].offClassName < pThis->cbSegNames);
     945        const char *pszName  = paDescs[i].offSegName   != UINT16_MAX
     946                             ? pThis->pszzSegNames + paDescs[i].offSegName
     947                             : NULL;
     948        const char *pszClass = paDescs[i].offClassName != UINT16_MAX
     949                             ? pThis->pszzSegNames + paDescs[i].offClassName
     950                             : NULL;
     951        if (pszName || pszClass)
     952            Log2(("              pszName=%s pszClass=%s\n", pszName, pszClass));
     953
     954        /* Validate the group link. */
     955        RTDBGMODCV_CHECK_NOMSG_RET_BF(paDescs[i].iGroup == 0 || !(paDescs[i].fFlags & RTCVSEGMAPDESC_F_GROUP));
     956        RTDBGMODCV_CHECK_NOMSG_RET_BF(   paDescs[i].iGroup == 0
     957                                      || (   paDescs[i].iGroup >= pHdr->cLogSegs
     958                                          && paDescs[i].iGroup <  pHdr->cSegs));
     959        RTDBGMODCV_CHECK_NOMSG_RET_BF(   paDescs[i].iGroup == 0
     960                                      || (paDescs[paDescs[i].iGroup].fFlags & RTCVSEGMAPDESC_F_GROUP));
     961        RTDBGMODCV_CHECK_NOMSG_RET_BF(!(paDescs[i].fFlags & RTCVSEGMAPDESC_F_GROUP) || paDescs[i].off == 0); /* assumed below */
     962
     963        if (fNoGroups)
     964        {
     965            RTDBGMODCV_CHECK_NOMSG_RET_BF(paDescs[i].iGroup == 0);
     966            RTDBGMODCV_CHECK_NOMSG_RET_BF(paDescs[i].off == 0);
     967        }
     968    }
     969
     970    /*
     971     * Modify the groups index to be the loader segment index instead, also
     972     * add the segments to the container if we haven't done that already.
     973     */
     974
     975    /* Guess work: Group can be implicit if used.  Observed Visual C++ v1.5,
     976       omitting the CODE group. */
     977    const char *pszGroup0 = NULL;
     978    uint64_t    cbGroup0  = 0;
     979    if (!fNoGroups)
     980    {
     981        for (uint16_t i = 0; i < pHdr->cSegs; i++)
     982            if (   !(paDescs[i].fFlags & (RTCVSEGMAPDESC_F_GROUP | RTCVSEGMAPDESC_F_ABS))
     983                && paDescs[i].iGroup == 0)
     984            {
     985                if (pszGroup0 == NULL && paDescs[i].offClassName != UINT16_MAX)
     986                    pszGroup0 = pThis->pszzSegNames + paDescs[i].offClassName;
     987                uint64_t offEnd = (uint64_t)paDescs[i].off + paDescs[i].cb;
     988                if (offEnd > cbGroup0)
     989                    cbGroup0 = offEnd;
     990            }
     991    }
     992
     993    /* Add the segments.
     994       Note! The RVAs derived from this exercise are all wrong. :-/
     995       Note! We don't have an image loader, so we cannot add any fake sections. */
     996    /** @todo Try see if we can figure something out from the frame value later. */
     997    if (!pThis->fHaveLoadedSegments)
     998    {
     999        Assert(!pThis->pMod->pImgVt); Assert(pThis->enmType != RTCVFILETYPE_DBG);
     1000        uint16_t iSeg = 0;
     1001        uint64_t uRva = 0;
     1002        if (cbGroup0 && !fNoGroups)
     1003        {
     1004            rc = RTDbgModSegmentAdd(pThis->hCnt, 0, cbGroup0, pszGroup0 ? pszGroup0 : "Seg00", 0 /*fFlags*/, NULL);
     1005            uRva += cbGroup0;
     1006            iSeg++;
     1007        }
     1008
     1009        for (uint32_t i = 0; RT_SUCCESS(rc) && i < pHdr->cSegs; i++)
     1010            if ((paDescs[i].fFlags & RTCVSEGMAPDESC_F_GROUP) || fNoGroups)
     1011            {
     1012                char szName[16];
     1013                char *pszName = szName;
     1014                if (paDescs[i].offSegName != UINT16_MAX)
     1015                    pszName = pThis->pszzSegNames + paDescs[i].offSegName;
     1016                else
     1017                    RTStrPrintf(szName, sizeof(szName), "Seg%02u", iSeg);
     1018                rc = RTDbgModSegmentAdd(pThis->hCnt, uRva, paDescs[i].cb, pszName, 0 /*fFlags*/, NULL);
     1019                uRva += paDescs[i].cb;
     1020                iSeg++;
     1021            }
     1022
     1023        if (RT_FAILURE(rc))
     1024        {
     1025            Log(("RTDbgModCv: %Rrc while adding segments from SegMap\n", rc));
     1026            return rc;
     1027        }
     1028
     1029        pThis->fHaveLoadedSegments = true;
     1030    }
     1031
     1032    /* The PE image has an extra section/segment for the headers, the others doesn't. */
     1033    RTLDRFMT enmImgFmt = RTLDRFMT_INVALID;
     1034    if (pThis->pMod->pImgVt)
     1035        enmImgFmt = pThis->pMod->pImgVt->pfnGetFormat(pThis->pMod);
     1036
     1037    /* Pass one: Fixate the group segment indexes. */
     1038    uint16_t iSeg0 = enmImgFmt == RTLDRFMT_PE || pThis->enmType == RTCVFILETYPE_DBG ? 1 : 0;
     1039    uint16_t iSeg = iSeg0 + cbGroup0 > 0;
     1040    for (uint16_t i = 0; i < pHdr->cSegs; i++)
     1041        if (paDescs[i].fFlags & RTCVSEGMAPDESC_F_ABS)
     1042            paDescs[i].iGroup = (uint16_t)RTDBGSEGIDX_ABS;
     1043        else if ((paDescs[i].fFlags & RTCVSEGMAPDESC_F_GROUP) || fNoGroups)
     1044            paDescs[i].iGroup = iSeg++;
     1045
     1046    /* Pass two: Resolve group references in to segment indexes. */
     1047    Log2(("Mapped segments (both kinds):\n"));
     1048    for (uint16_t i = 0; i < pHdr->cSegs; i++)
     1049    {
     1050        if (!fNoGroups && !(paDescs[i].fFlags & (RTCVSEGMAPDESC_F_GROUP | RTCVSEGMAPDESC_F_ABS)))
     1051            paDescs[i].iGroup = paDescs[i].iGroup == 0 ? iSeg0 : paDescs[paDescs[i].iGroup].iGroup;
     1052
     1053        Log2(("    #%02u: %#010x LB %#010x -> %#06x (flags=%#06x ovl=%#06x frame=%#06x)\n",
     1054              i, paDescs[i].off, paDescs[i].cb, paDescs[i].iGroup,
     1055              paDescs[i].fFlags, paDescs[i].iOverlay, paDescs[i].iFrame));
     1056    }
     1057
     1058    return VINF_SUCCESS;
     1059}
     1060
     1061
     1062/**
    3771063 * Loads the directory into memory (RTDBGMODCV::paDirEnts and
    3781064 * RTDBGMODCV::cDirEnts).
     
    3981084         */
    3991085        RTCVDIRHDR16 DirHdr;
    400         rc = rtDbgModCvReadAt(pThis, pThis->offBase + pThis->offDir, &DirHdr, sizeof(DirHdr));
     1086        rc = rtDbgModCvReadAt(pThis, pThis->offDir, &DirHdr, sizeof(DirHdr));
    4011087        if (RT_SUCCESS(rc))
    4021088        {
     
    4071093                if (pThis->paDirEnts)
    4081094                {
    409                     rc = rtDbgModCvReadAt(pThis, pThis->offBase + pThis->offDir + sizeof(DirHdr),
     1095                    rc = rtDbgModCvReadAt(pThis, pThis->offDir + sizeof(DirHdr),
    4101096                                          pThis->paDirEnts, DirHdr.cEntries * sizeof(RTCVDIRENT16));
    4111097                    if (RT_SUCCESS(rc))
     
    4431129         */
    4441130        RTCVDIRHDR32EX DirHdr;
    445         rc = rtDbgModCvReadAt(pThis, pThis->offBase + pThis->offDir, &DirHdr, sizeof(DirHdr));
     1131        rc = rtDbgModCvReadAt(pThis, pThis->offDir, &DirHdr, sizeof(DirHdr));
    4461132        if (RT_SUCCESS(rc))
    4471133        {
     
    4751161                pThis->paDirEnts = (PRTCVDIRENT32)RTMemAlloc(DirHdr.Core.cEntries * sizeof(pThis->paDirEnts[0]));
    4761162                if (pThis->paDirEnts)
    477                     rc = rtDbgModCvReadAt(pThis, pThis->offBase + pThis->offDir + DirHdr.Core.cbHdr,
     1163                    rc = rtDbgModCvReadAt(pThis, pThis->offDir + DirHdr.Core.cbHdr,
    4781164                                          pThis->paDirEnts, DirHdr.Core.cEntries * sizeof(RTCVDIRENT32));
    4791165                else
     
    4881174    if (RT_SUCCESS(rc))
    4891175    {
     1176        uint16_t       iMod      = 0;
    4901177        uint32_t const cbDbgInfo = pThis->cbDbgInfo;
    4911178        uint32_t const cDirEnts  = pThis->cDirEnts;
     
    5131200                rc = VERR_CV_BAD_FORMAT;
    5141201            }
     1202            if (   pDirEnt->iMod < iMod
     1203                && (   pDirEnt->iMod != 0
     1204                    || (   pThis->u32CvMagic != RTCVHDR_MAGIC_NB00 /* May be first, maybe last. */
     1205                        && pThis->u32CvMagic != RTCVHDR_MAGIC_NB02
     1206                        && pThis->u32CvMagic != RTCVHDR_MAGIC_NB04) ) )
     1207            {
     1208                Log(("CV directory entry #%u is out of module order, this mod %u, prev mod %#u\n", i, pDirEnt->iMod, iMod));
     1209                rc = VERR_CV_BAD_FORMAT;
     1210            }
     1211            if (pDirEnt->iMod != iMod)
     1212            {
     1213                iMod = pDirEnt->iMod;
     1214                if (   iMod != 0
     1215                    && iMod != 0xffff
     1216                    && pDirEnt->uSubSectType != kCvSst_Module
     1217                    && pDirEnt->uSubSectType != kCvSst_OldModule)
     1218                {
     1219                    Log(("CV directory entry #%u: expected module subsection first, found %s (%#x)\n",
     1220                         i, rtDbgModCvGetSubSectionName(pDirEnt->uSubSectType), pDirEnt->uSubSectType));
     1221                    rc = VERR_CV_BAD_FORMAT;
     1222                }
     1223            }
    5151224        }
    5161225    }
     
    5201229
    5211230
    522 
    5231231static int rtDbgModCvLoadInfo(PRTDBGMODCV pThis)
    5241232{
    5251233    /*
    526      * Load the directory and segments.
     1234     * Load the directory, the segment map (if any) and then scan for segments
     1235     * if necessary.
    5271236     */
    5281237    int rc = rtDbgModCvLoadDirectory(pThis);
     1238    if (RT_SUCCESS(rc))
     1239        rc = rtDbgModCvLoadSegmentMap(pThis);
    5291240    if (RT_SUCCESS(rc) && !pThis->fHaveLoadedSegments)
     1241    {
    5301242        rc = VERR_CV_TODO; /** @todo Scan anything containing address, in particular sstSegMap and sstModule,
    5311243                            * and reconstruct the segments from that information. */
    532 
    533     /*
    534      * Load segment map, if present.
    535      */
    536     //if (RT_SUCCESS(rc))
    537     //    rc = rtDbgModCvLoadGlobals(pThis);
     1244        pThis->cbImage = 0x1000;
     1245        rc = VINF_SUCCESS;
     1246    }
    5381247
    5391248    /*
    5401249     * Process the directory.
    5411250     */
    542     uint32_t i = pThis->cDirEnts;
    543     while (i-- > 0)
    544     {
    545 #if 0
    546         if (   pThis->paDirEnts[i].uSubSectType == kCvSst_OldPublic
    547             || pThis->paDirEnts[i].uSubSectType == kCvSst_Public
    548             )
     1251    for (uint32_t i = 0; RT_SUCCESS(rc) && i < pThis->cDirEnts; i++)
     1252    {
     1253        PCRTCVDIRENT32              pDirEnt     = &pThis->paDirEnts[i];
     1254        Log3(("Processing subsection %#u %s\n", i, rtDbgModCvGetSubSectionName(pDirEnt->uSubSectType)));
     1255        PFNDBGMODCVSUBSECTCALLBACK  pfnCallback = NULL;
     1256        switch (pDirEnt->uSubSectType)
    5491257        {
     1258            case kCvSst_GlobalPub:
     1259            case kCvSst_GlobalSym:
     1260            case kCvSst_StaticSym:
     1261                pfnCallback = rtDbgModCvSs_GlobalPub_GlobalSym_StaticSym;
     1262                break;
     1263            case kCvSst_Module:
     1264                pfnCallback = rtDbgModCvSs_Module;
     1265                break;
     1266            case kCvSst_PublicSym:
     1267            case kCvSst_Symbols:
     1268            case kCvSst_AlignSym:
     1269                pfnCallback = rtDbgModCvSs_Symbols_PublicSym_AlignSym;
     1270                break;
     1271
     1272            case kCvSst_OldModule:
     1273            case kCvSst_OldPublic:
     1274            case kCvSst_OldTypes:
     1275            case kCvSst_OldSymbols:
     1276            case kCvSst_OldSrcLines:
     1277            case kCvSst_OldLibraries:
     1278            case kCvSst_OldImports:
     1279            case kCvSst_OldCompacted:
     1280            case kCvSst_OldSrcLnSeg:
     1281            case kCvSst_OldSrcLines3:
     1282
     1283            case kCvSst_Types:
     1284            case kCvSst_Public:
     1285            case kCvSst_SrcLnSeg:
     1286            case kCvSst_SrcModule:
     1287            case kCvSst_Libraries:
     1288            case kCvSst_GlobalTypes:
     1289            case kCvSst_MPC:
     1290            case kCvSst_PreComp:
     1291            case kCvSst_PreCompMap:
     1292            case kCvSst_OffsetMap16:
     1293            case kCvSst_OffsetMap32:
     1294            case kCvSst_FileIndex:
     1295
     1296            default:
     1297                /** @todo implement more. */
     1298                break;
     1299
     1300            /* Skip because we've already processed them: */
     1301            case kCvSst_SegMap:
     1302            case kCvSst_SegName:
     1303                pfnCallback = NULL;
     1304                break;
    5501305        }
    551 #endif
     1306
     1307        if (pfnCallback)
     1308        {
     1309            void *pvSubSect;
     1310            rc = rtDbgModCvReadAtAlloc(pThis, pDirEnt->off, &pvSubSect, pDirEnt->cb);
     1311            if (RT_SUCCESS(rc))
     1312            {
     1313                rc = pfnCallback(pThis, pvSubSect, pDirEnt->cb, pDirEnt);
     1314                RTMemFree(pvSubSect);
     1315            }
     1316        }
    5521317    }
    5531318
     
    9051670                    pThis->offDir     = pCvHdr->off;
    9061671                    pThis->hFile      = hFile;
     1672                    pThis->pMod       = pDbgMod;
    9071673                    return VINF_CALLBACK_RETURN;
    9081674                }
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