dbgmodcodeview.cpp revision 44f4668fd6b017b6d71e83a53d771d67f5e00ab7
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * IPRT - Debug Module Reader For Microsoft CodeView and COFF.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Based on the following documentation (plus guess work and googling):
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * - "Tools Interface Standard (TIS) Formats Specification for Windows",
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * dated February 1993, version 1.0.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * - "Visual C++ 5.0 Symbolic Debug Information Specification" chapter of
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * SPECS.CHM from MSDN Library October 2001.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * - "High Level Languages Debug Table Documentation", aka HLLDBG.HTML, aka
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * IBMHLL.HTML, last changed 1996-07-08.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Copyright (C) 2013 Oracle Corporation
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * available from http://www.virtualbox.org. This file is free software;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * you can redistribute it and/or modify it under the terms of the GNU
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * General Public License (GPL) as published by the Free Software
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync * The contents of this file may alternatively be used under the terms
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * of the Common Development and Distribution License Version 1.0
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * VirtualBox OSE distribution, in which case the provisions of the
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * CDDL are applicable instead of those of the GPL.
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * You may elect to license modified versions of this file under the
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * terms and conditions of either the GPL or the CDDL or both.
4569bf0ad094b40d2e177299a00d37e94d28616cvboxsync/*******************************************************************************
4569bf0ad094b40d2e177299a00d37e94d28616cvboxsync* Header Files *
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync*******************************************************************************/
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/*******************************************************************************
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync* Structures and Typedefs *
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync*******************************************************************************/
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * CodeView Header. There are two of this, base header at the start of the debug
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * information and a trailing header at the end.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsynctypedef struct RTCVHDR
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** The magic ('NBxx'), see RTCVHDR_MAGIC_XXX. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Base header: Subsection directory offset relative to this header (start).
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Trailing header: Offset of the base header relative to the end of the file.
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * Called lfoBase, lfaBase, lfoDirectory, lfoDir and probably other things in
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * the various specs/docs available. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/** Pointer to a CodeView header. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync/** @name CodeView magic values (RTCVHDR::u32Magic).
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync/** CodeView from Visual C++ 5.0. Specified in the 2001 MSDN specs.chm file. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync#define RTCVHDR_MAGIC_NB11 RT_MAKE_U32_FROM_U8('N', 'B', '1', '1')
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync/** External PDB reference (often referred to as PDB 2.0). */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#define RTCVHDR_MAGIC_NB10 RT_MAKE_U32_FROM_U8('N', 'B', '1', '0')
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/** CodeView v4.10, packed. Specified in the TIS document. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#define RTCVHDR_MAGIC_NB09 RT_MAKE_U32_FROM_U8('N', 'B', '0', '9')
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/** CodeView v4.00 thru v4.05. Specified in the TIS document? */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#define RTCVHDR_MAGIC_NB08 RT_MAKE_U32_FROM_U8('N', 'B', '0', '8')
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync/** Quick C for Windows 1.0 debug info. */
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync#define RTCVHDR_MAGIC_NB07 RT_MAKE_U32_FROM_U8('N', 'B', '0', '7')
0c4004948fca34f2db87e7b38013137e9472c306vboxsync/** Emitted by ILINK indicating incremental link. Comparable to NB05? */
0c4004948fca34f2db87e7b38013137e9472c306vboxsync#define RTCVHDR_MAGIC_NB06 RT_MAKE_U32_FROM_U8('N', 'B', '0', '6')
0c4004948fca34f2db87e7b38013137e9472c306vboxsync/** Emitted by LINK version 5.20 and later before packing. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#define RTCVHDR_MAGIC_NB05 RT_MAKE_U32_FROM_U8('N', 'B', '0', '5')
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/** Emitted by IBM ILINK for HLL (similar to NB02 in many ways). */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#define RTCVHDR_MAGIC_NB04 RT_MAKE_U32_FROM_U8('N', 'B', '0', '4')
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/** Emitted by LINK version 5.10 (or similar OMF linkers), as shipped with
44a2ecaf2d0fc196ab76cab13b3f909299e386d1vboxsync * Microsoft C v6.0 for example. More or less entirely 16-bit. */
44a2ecaf2d0fc196ab76cab13b3f909299e386d1vboxsync#define RTCVHDR_MAGIC_NB02 RT_MAKE_U32_FROM_U8('N', 'B', '0', '2')
4569bf0ad094b40d2e177299a00d37e94d28616cvboxsync/* No idea what NB03 might have been. */
4569bf0ad094b40d2e177299a00d37e94d28616cvboxsync/** AIX debugger format according to "IBM OS/2 16/32-bit Object Module Format
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * (OMF) and Linear eXecutable Module Format (LX)" revision 10 (LXOMF.PDF). */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#define RTCVHDR_MAGIC_NB01 RT_MAKE_U32_FROM_U8('N', 'B', '0', '1')
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync/** Ancient CodeView format according to LXOMF.PDF. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#define RTCVHDR_MAGIC_NB00 RT_MAKE_U32_FROM_U8('N', 'B', '0', '0')
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync/** @name CV directory headers.
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync * Really old CV directory header used with NB00 and NB02.
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync * Uses 16-bit directory entires (RTCVDIRENT16).
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsynctypedef struct RTCVDIRHDR16
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync /** The number of directory entries. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync/** Pointer to a old CV directory header. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Simple 32-bit CV directory base header, used by NB04 (aka IBM HLL).
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsynctypedef struct RTCVDIRHDR32
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** The number of bytes of this header structure. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** The number of bytes per entry. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** The number of directory entries. */
a9f41cb889f53e8407561a6155052c441eb0fc5fvboxsync/** Pointer to a 32-bit CV directory header. */
a9f41cb889f53e8407561a6155052c441eb0fc5fvboxsync * Extended 32-bit CV directory header as specified in the TIS doc.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * The two extra fields seems to never have been assigned any official purpose.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** This starts the same way as the NB04 header. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** Tentatively decleared as the offset to the next directory generated by
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync * the incremental linker. Haven't seen this used yet. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** Flags, non defined apparently, so MBZ. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync/** Pointer to an extended 32-bit CV directory header. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync * 16-bit CV directory entry used with NB00 and NB02.
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsynctypedef struct RTCVDIRENT16
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** Subsection type (RTCVSST). */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** Which module (1-based, 0xffff is special). */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** The lowe offset of this subsection relative to the base CV header. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** The high part of the subsection offset. */
93f91841f87620d1cb6d0238b3d0d5e52cd3b9a4vboxsync /** The size of the subsection. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync/** Pointer to a 16-bit CV directory entry. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync * 32-bit CV directory entry used starting with NB04.
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsynctypedef struct RTCVDIRENT32
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** Subsection type (RTCVSST). */
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync /** Which module (1-based, 0xffff is special). */
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync /** The offset of this subsection relative to the base CV header. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** The size of the subsection. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/** Pointer to a 32-bit CV directory entry. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/** Pointer to a const 32-bit CV directory entry. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * CodeView subsection types.
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** @name NB00, NB02 and NB04 subsection types.
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync * The actual format of each subsection varies between NB04 and the others,
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync * and it may further vary in NB04 depending on the module type.
7ccfefe49db4cd93c3701d7b60873ebf404b5b87vboxsync /** @name NB09, NB11 (and possibly NB05, NB06, NB07, and NB08) subsection types.
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync/** Pointer to a CV subsection type value. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/** Pointer to a const CV subsection type value. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync * CV4 module segment info.
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** The segment number. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** Explicit padding. */
fc78e01f665145ab3641c5f8095e9ae984ddcb84vboxsync /** Offset into the segment. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** The size of the contribution. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * CV4 segment map header.
4569bf0ad094b40d2e177299a00d37e94d28616cvboxsync /** Number of segments descriptors in the table. */
4569bf0ad094b40d2e177299a00d37e94d28616cvboxsync /** Number of logical segment descriptors. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync/** Pointer to a CV4 segment map header. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/** Pointer to a const CV4 segment map header. */
a9f41cb889f53e8407561a6155052c441eb0fc5fvboxsync * CV4 Segment map descriptor entry.
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** Segment flags. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** The overlay number. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** Group index into this segment descriptor array. 0 if not relevant.
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync * The group descriptors are found in the second half of the table. */
a9f41cb889f53e8407561a6155052c441eb0fc5fvboxsync /** Complicated. */
0dd6dfbebcda0af90da4413aaea5f3b9d1817556vboxsync /** Offset (byte) into the kCvSst_SegName table of the segment name, or
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * 0xffff. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** Offset (byte) into the kCvSst_SegName table of the class name, or 0xffff. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** Offset into the physical segment. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** Size of segment. */
0dd6dfbebcda0af90da4413aaea5f3b9d1817556vboxsync/** Pointer to a segment map descriptor entry. */
4569bf0ad094b40d2e177299a00d37e94d28616cvboxsync/** Pointer to a const segment map descriptor entry. */
4569bf0ad094b40d2e177299a00d37e94d28616cvboxsync/** @name RTCVSEGMAPDESC_F_XXX - RTCVSEGMAPDESC::fFlags values.
fc78e01f665145ab3641c5f8095e9ae984ddcb84vboxsync * CV4 segment map subsection.
fc78e01f665145ab3641c5f8095e9ae984ddcb84vboxsynctypedef struct RTCVSEGMAP
fc78e01f665145ab3641c5f8095e9ae984ddcb84vboxsync /** The header. */
fc78e01f665145ab3641c5f8095e9ae984ddcb84vboxsync /** Descriptor array. */
c2f2661efd8da5281e2a3af6ddd10e737d333909vboxsync/** Pointer to a segment map subsection. */
fc78e01f665145ab3641c5f8095e9ae984ddcb84vboxsync/** Pointer to a const segment map subsection. */
fc78e01f665145ab3641c5f8095e9ae984ddcb84vboxsync * Global symbol table header, used by kCvSst_GlobalSym and kCvSst_GlobalPub.
fc78e01f665145ab3641c5f8095e9ae984ddcb84vboxsync /** The symbol hash function. */
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync /** The address hash function. */
fc78e01f665145ab3641c5f8095e9ae984ddcb84vboxsync /** The amount of symbol information following immediately after the header. */
fc78e01f665145ab3641c5f8095e9ae984ddcb84vboxsync /** The amount of symbol hash tables following the symbols. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** The amount of address hash tables following the symbol hash tables. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync/** Pointer to a global symbol table header. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync/** Pointer to a const global symbol table header. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsynctypedef RTCVGLOBALSYMTABHDR const *PCRTCVGLOBALSYMTABHDR;
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync /** @name Symbols that doesn't change with compilation model or target machine.
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /** @name Symbols with 16:16 addresses.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** @name Symbols with 16:32 addresses.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** @name Symbols for MIPS.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** @name Symbols for Microsoft CodeView.
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync/** The $$SYMBOL table signature for CV4. */
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync#define RTCVSYMBOLS_SIGNATURE_CV4 UINT32_C(0x00000001)
8a339f91959bb7a3315b51a23461b68c7b0cb50evboxsync * File type.
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync /** Executable image. */
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync /** A DBG-file with a IMAGE_SEPARATE_DEBUG_HEADER. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** A PDB file. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** Some other kind of file with CV at the end. */
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync /** The end of the valid values. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** Type blowup. */
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync * CodeView debug info reader instance.
0c4004948fca34f2db87e7b38013137e9472c306vboxsynctypedef struct RTDBGMODCV
d7125f3a1b435761c393f9ec406e85a73ae2a3e7vboxsync /** Using a container for managing the debug info. */
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync /** @name Codeview details
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync /** The code view magic (used as format indicator). */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** The offset of the CV debug info in the file. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** The size of the CV debug info. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** The offset of the subsection directory (relative to offBase). */
b0db50948c349fa76655abf252f7946b515e8204vboxsync /** @name COFF details.
b0db50948c349fa76655abf252f7946b515e8204vboxsync /** Offset of the COFF header. */
b0db50948c349fa76655abf252f7946b515e8204vboxsync /** The size of the COFF debug info. */
b0db50948c349fa76655abf252f7946b515e8204vboxsync /** The COFF debug info header. */
b0db50948c349fa76655abf252f7946b515e8204vboxsync /** The file type. */
b0db50948c349fa76655abf252f7946b515e8204vboxsync /** The file handle (if external). */
b0db50948c349fa76655abf252f7946b515e8204vboxsync /** Pointer to the module (no reference retained). */
b0db50948c349fa76655abf252f7946b515e8204vboxsync /** The image size, if we know it. This is 0 if we don't know it. */
b0db50948c349fa76655abf252f7946b515e8204vboxsync /** Indicates that we've loaded segments intot he container already. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** @name Codeview Parsing state.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /** Number of directory entries. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** The directory (converted to 32-bit). */
b0db50948c349fa76655abf252f7946b515e8204vboxsync /** Current debugging style when parsing modules. */
b0db50948c349fa76655abf252f7946b515e8204vboxsync /** Current debugging style version (HLL only). */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** The segment map (if present). */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** Segment names. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** The size of the segment names. */
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync/** Pointer to a codeview debug info reader instance. */
faee255cc48bfbf17cb9f72fca70c8b9d3020ec4vboxsync/** Pointer to a const codeview debug info reader instance. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Subsection callback.
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * @returns IPRT status code.
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * @param pThis The CodeView debug info reader instance.
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * @param pvSubSect Pointer to the subsection data.
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * @param cbSubSect The size of the subsection data.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pDirEnt The directory entry.
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsynctypedef DECLCALLBACK(int) FNDBGMODCVSUBSECTCALLBACK(PRTDBGMODCV pThis, void const *pvSubSect, size_t cbSubSect,
a39ea3668b7019c23a68936259545f9b71bce1aavboxsync/** Pointer to a subsection callback. */
0db6a029780d9f9b347500e117320a8d5661efe5vboxsynctypedef FNDBGMODCVSUBSECTCALLBACK *PFNDBGMODCVSUBSECTCALLBACK;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/*******************************************************************************
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync* Defined Constants And Macros *
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync*******************************************************************************/
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync/** Light weight assert + return w/ fixed status code. */
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync#define RTDBGMODCV_CHECK_RET_BF(a_Expr, a_LogArgs) \
0c4004948fca34f2db87e7b38013137e9472c306vboxsync Log(("RTDbgCv: Check failed on line %d: " #a_Expr "\n", __LINE__)); \
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync } while (0)
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync/** Light weight assert + return w/ fixed status code. */
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync Log(("RTDbgCv: Check failed on line %d: " #a_Expr "\n", __LINE__)); \
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync } while (0)
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync * Reads CodeView information.
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync * @returns IPRT status.
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync * @param pThis The CodeView reader instance.
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync * @param off The offset to start reading at, relative to the
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync * CodeView base header.
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync * @param pvBuf The buffer to read into.
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync * @param cb How many bytes to read.
71f6a34b72f9cc873da208630959de49df1a28a5vboxsyncstatic int rtDbgModCvReadAt(PRTDBGMODCV pThis, uint32_t off, void *pvBuf, size_t cb)
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync rc = pThis->pMod->pImgVt->pfnReadAt(pThis->pMod, UINT32_MAX, off + pThis->offBase, pvBuf, cb);
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync rc = RTFileReadAt(pThis->hFile, off + pThis->offBase, pvBuf, cb, NULL);
0c4004948fca34f2db87e7b38013137e9472c306vboxsync * Reads CodeView information into an allocated buffer.
0c4004948fca34f2db87e7b38013137e9472c306vboxsync * @returns IPRT status.
0c4004948fca34f2db87e7b38013137e9472c306vboxsync * @param pThis The CodeView reader instance.
d4e9ccea0ea1ed303b5708ff94f6c202755f0dc6vboxsync * @param off The offset to start reading at, relative to the
0c4004948fca34f2db87e7b38013137e9472c306vboxsync * CodeView base header.
0c4004948fca34f2db87e7b38013137e9472c306vboxsync * @param ppvBuf Where to return the allocated buffer on success.
0c4004948fca34f2db87e7b38013137e9472c306vboxsync * @param cb How many bytes to read.
71f6a34b72f9cc873da208630959de49df1a28a5vboxsyncstatic int rtDbgModCvReadAtAlloc(PRTDBGMODCV pThis, uint32_t off, void **ppvBuf, size_t cb)
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync rc = pThis->pMod->pImgVt->pfnReadAt(pThis->pMod, UINT32_MAX, off + pThis->offBase, pvBuf, cb);
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync rc = RTFileReadAt(pThis->hFile, off + pThis->offBase, pvBuf, cb, NULL);
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync * Gets a name string for a subsection type.
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync * @returns Section name (read only).
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync * @param uSubSectType The subsection type.
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsyncstatic const char *rtDbgModCvGetSubSectionName(uint16_t uSubSectType)
0c4004948fca34f2db87e7b38013137e9472c306vboxsync case kCvSst_OldLibraries: return "sstOldLibraries";
0c4004948fca34f2db87e7b38013137e9472c306vboxsync case kCvSst_OldCompacted: return "sstOldCompacted";
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync case kCvSst_OldSrcLines3: return "sstOldSrcLines3";
8f0fc87a72dee210b62acc9dd859a4bebf8bfb33vboxsync RTStrPrintf(s_sz, sizeof(s_sz), "Unknown%#x", uSubSectType);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Adds a symbol to the container.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns IPRT status code
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pThis The CodeView debug info reader instance.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param iSeg Segment number.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param off Offset into the segment
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * @param pchName The symbol name (not necessarily terminated).
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param cchName The symbol name length.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param fFlags Flags reserved for future exploits, MBZ.
8cd2f2e64725096acb682f34a5568b7fb816eda7vboxsyncstatic int rtDbgModCvAddSymbol(PRTDBGMODCV pThis, uint32_t iSeg, uint64_t off, const char *pchName,
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync const char *pszName = RTStrCacheEnterN(g_hDbgModStrCache, pchName, cchName);
26947320577c481b4afefdb0afbb855181e5b2e8vboxsync Log(("Invalid segment index/offset %#06x:%08x for symbol %.*s\n", iSeg, off, cchName, pchName));
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (pThis->pSegMap->aDescs[iSeg - 1].fFlags & RTCVSEGMAPDESC_F_ABS)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync int rc = RTDbgModSymbolAdd(pThis->hCnt, pszName, iSeg, off, 0, 0 /*fFlags*/, NULL);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync Log(("Symbol: %04x:%08x %.*s [%Rrc]\n", iSeg, off, cchName, pchName, rc));
c28fa006ba669ad8f26ae31d00a338379c04ea1bvboxsync if (rc == VERR_DBG_ADDRESS_CONFLICT || rc == VERR_DBG_DUPLICATE_SYMBOL)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync Log(("Symbol: %04x:%08x %.*s\n", iSeg, off, cchName, pchName));
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync * Parses a CV4 symbol table, adding symbols to the container.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns IPRT status code
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pThis The CodeView debug info reader instance.
cba6719bd64ec749967bbe931230452664109857vboxsync * @param pbSymTab The symbol table.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param cbSymTab The size of the symbol table.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param fFlags Flags reserved for future exploits, MBZ.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsyncstatic int rtDbgModCvSsProcessV4SymTab(PRTDBGMODCV pThis, void const *pvSymTab, size_t cbSymTab, uint32_t fFlags)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync Log3((" %p: uSymType=%#06x LB %#x\n", pbRecStart - (uint8_t *)pvSymTab, uSymType, cbRec));
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTDBGMODCV_CHECK_RET_BF(cbRec >= 2 && cbRec <= cbSymTab, ("cbRec=%#x cbSymTab=%#x\n", cbRec, cbSymTab));
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTDBGMODCV_CHECK_NOMSG_RET_BF(cbRec > 2 + 2+2+2+1);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTDBGMODCV_CHECK_NOMSG_RET_BF(cbRec >= 2 + 2+2+2+1 + cchName);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync rc = rtDbgModCvAddSymbol(pThis, iSeg, off, uCursor.pch, cchName, 0);
9b789c281103a2489742bf32f6ab500e38b2ecd5vboxsync RTDBGMODCV_CHECK_NOMSG_RET_BF(cbRec > 2 + 4+2+2+1);
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync RTDBGMODCV_CHECK_NOMSG_RET_BF(cbRec >= 2 + 4+2+2+1 + cchName);
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync rc = rtDbgModCvAddSymbol(pThis, iSeg, off, uCursor.pch, cchName, 0);
ea779b55cc87f3e3fadddca4672c6697c82606edvboxsync /** @todo add GProc and LProc so we can gather sizes as well as just symbols. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /*else: shorter records can be used for alignment, I guess. */
44a2ecaf2d0fc196ab76cab13b3f909299e386d1vboxsync/** @callback_method_impl{FNDBGMODCVSUBSECTCALLBACK,
44a2ecaf2d0fc196ab76cab13b3f909299e386d1vboxsync * Parses kCvSst_GlobalPub, kCvSst_GlobalSym and kCvSst_StaticSym subsections,
44a2ecaf2d0fc196ab76cab13b3f909299e386d1vboxsync * adding symbols it finds to the container.} */
71f6a34b72f9cc873da208630959de49df1a28a5vboxsyncrtDbgModCvSs_GlobalPub_GlobalSym_StaticSym(PRTDBGMODCV pThis, void const *pvSubSect, size_t cbSubSect, PCRTCVDIRENT32 pDirEnt)
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync PCRTCVGLOBALSYMTABHDR pHdr = (PCRTCVGLOBALSYMTABHDR)pvSubSect;
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync * Quick data validation.
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync Log2(("RTDbgModCv: %s: uSymHash=%#x uAddrHash=%#x cbSymbols=%#x cbSymHash=%#x cbAddrHash=%#x\n",
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync rtDbgModCvGetSubSectionName(pDirEnt->uSubSectType), pHdr->uSymHash,
b0db50948c349fa76655abf252f7946b515e8204vboxsync pHdr->uAddrHash, pHdr->cbSymbols, pHdr->cbSymHash, pHdr->cbAddrHash));
b0db50948c349fa76655abf252f7946b515e8204vboxsync RTDBGMODCV_CHECK_NOMSG_RET_BF(cbSubSect >= sizeof(RTCVGLOBALSYMTABHDR));
71f6a34b72f9cc873da208630959de49df1a28a5vboxsync RTDBGMODCV_CHECK_NOMSG_RET_BF((uint64_t)pHdr->cbSymbols + pHdr->cbSymHash + pHdr->cbAddrHash <= cbSubSect - sizeof(*pHdr));
b0db50948c349fa76655abf252f7946b515e8204vboxsync RTDBGMODCV_CHECK_NOMSG_RET_BF(pHdr->uSymHash < 0x20);
b0db50948c349fa76655abf252f7946b515e8204vboxsync RTDBGMODCV_CHECK_NOMSG_RET_BF(pHdr->uAddrHash < 0x20);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Parse the symbols.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return rtDbgModCvSsProcessV4SymTab(pThis, pHdr + 1, pHdr->cbSymbols, 0);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/** @callback_method_impl{FNDBGMODCVSUBSECTCALLBACK,
5b465a7c1237993faf8bb50120d247f3f0319adavboxsync * Parses kCvSst_Module subsection, storing the debugging style in pThis.} */
ad77e3ec3cde24263bc7537575f5cae442bee3b1vboxsyncrtDbgModCvSs_Module(PRTDBGMODCV pThis, void const *pvSubSect, size_t cbSubSect, PCRTCVDIRENT32 pDirEnt)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTDBGMODCV_CHECK_NOMSG_RET_BF(cbSubSect >= 2 + 2 + 2 + 2 + 0 + 1);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTDBGMODCV_CHECK_NOMSG_RET_BF(cbSubSect >= 2 + 2 + 2 + 2 + cSegs * 12U + 1 + cchName);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync const char *pchName = (const char *)&uCursor.pu8[cSegs * 12 + 1];
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync Log2(("RTDbgModCv: Module: iOverlay=%#x iLib=%#x cSegs=%#x Style=%c%c (%#x) %.*s\n", iOverlay, iLib, cSegs,
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RT_BYTE1(pThis->uCurStyle), RT_BYTE2(pThis->uCurStyle), pThis->uCurStyle, cchName, pchName));
ad77e3ec3cde24263bc7537575f5cae442bee3b1vboxsync RTDBGMODCV_CHECK_NOMSG_RET_BF(pThis->uCurStyle == RT_MAKE_U16('C', 'V'));
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync PCRTCVMODSEGINFO32 paSegs = (PCRTCVMODSEGINFO32)uCursor.pv;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync Log2((" #%02u: %04x:%08x LB %08x\n", iSeg, paSegs[iSeg].iSeg, paSegs[iSeg].off, paSegs[iSeg].cb));
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/** @callback_method_impl{FNDBGMODCVSUBSECTCALLBACK,
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Parses kCvSst_Symbols, kCvSst_PublicSym and kCvSst_AlignSym subsections,
cba6719bd64ec749967bbe931230452664109857vboxsync * adding symbols it finds to the container.} */
cba6719bd64ec749967bbe931230452664109857vboxsyncrtDbgModCvSs_Symbols_PublicSym_AlignSym(PRTDBGMODCV pThis, void const *pvSubSect, size_t cbSubSect, PCRTCVDIRENT32 pDirEnt)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTDBGMODCV_CHECK_NOMSG_RET_BF(pThis->uCurStyle == RT_MAKE_U16('C', 'V'));
cba6719bd64ec749967bbe931230452664109857vboxsync uint32_t u32Signature = *(uint32_t const *)pvSubSect;
cba6719bd64ec749967bbe931230452664109857vboxsync RTDBGMODCV_CHECK_RET_BF(u32Signature == RTCVSYMBOLS_SIGNATURE_CV4,
cba6719bd64ec749967bbe931230452664109857vboxsync ("%#x, expected %#x\n", u32Signature, RTCVSYMBOLS_SIGNATURE_CV4));
44a2ecaf2d0fc196ab76cab13b3f909299e386d1vboxsync return rtDbgModCvSsProcessV4SymTab(pThis, (uint8_t const *)pvSubSect + 4, cbSubSect - 4, 0);
iSegMap = i;
iSegNames = i;
return VINF_SUCCESS;
return rc;
RTDBGMODCV_CHECK_NOMSG_RET_BF(!pThis->pszzSegNames || !pThis->pszzSegNames[pThis->cbSegNames - 1]); /* must be terminated */
Log2(("RTDbgModCv: SegMap: cSegs=%#x cLogSegs=%#x (cbSegNames=%#x)\n", pHdr->cSegs, pHdr->cLogSegs, pThis->cbSegNames));
RTDBGMODCV_CHECK_RET_BF(pThis->paDirEnts[iSegMap].cb >= sizeof(*pHdr) + pHdr->cSegs * sizeof(paDescs[0]),
Log2((" #%02u: %#010x LB %#010x flags=%#06x ovl=%#06x group=%#06x frame=%#06x iSegName=%#06x iClassName=%#06x %s\n",
RTDBGMODCV_CHECK_NOMSG_RET_BF(paDescs[i].offSegName == UINT16_MAX || paDescs[i].offSegName < pThis->cbSegNames);
RTDBGMODCV_CHECK_NOMSG_RET_BF(paDescs[i].offClassName == UINT16_MAX || paDescs[i].offClassName < pThis->cbSegNames);
: NULL;
: NULL;
RTDBGMODCV_CHECK_NOMSG_RET_BF(paDescs[i].iGroup == 0 || !(paDescs[i].fFlags & RTCVSEGMAPDESC_F_GROUP));
RTDBGMODCV_CHECK_NOMSG_RET_BF(!(paDescs[i].fFlags & RTCVSEGMAPDESC_F_GROUP) || paDescs[i].off == 0); /* assumed below */
if (fNoGroups)
if (!fNoGroups)
rc = RTDbgModSegmentAdd(pThis->hCnt, 0, cbGroup0, pszGroup0 ? pszGroup0 : "Seg00", 0 /*fFlags*/, NULL);
iSeg++;
iSeg++;
return rc;
return VINF_SUCCESS;
int rc;
while (cLeft--)
pDst--;
pSrc--;
Log(("Unexpected CV directory entry size: %#x (expected %#x)\n", DirHdr.Core.cbEntry, sizeof(RTCVDIRENT32)));
Log(("CV directory entry #%u is out of bounds: %#x LB %#x, max %#x\n", i, pDirEnt->off, pDirEnt->cb, cbDbgInfo));
Log(("CV directory entry #%u uses module index 0 (uSubSectType=%#x)\n", i, pDirEnt->iMod, pDirEnt->uSubSectType));
Log(("CV directory entry #%u is out of module order, this mod %u, prev mod %#u\n", i, pDirEnt->iMod, iMod));
if ( iMod != 0
return rc;
rc = VERR_CV_TODO; /** @todo Scan anything containing address, in particular sstSegMap and sstModule,
case kCvSst_GlobalPub:
case kCvSst_GlobalSym:
case kCvSst_StaticSym:
case kCvSst_Module:
case kCvSst_PublicSym:
case kCvSst_Symbols:
case kCvSst_AlignSym:
case kCvSst_OldModule:
case kCvSst_OldPublic:
case kCvSst_OldTypes:
case kCvSst_OldSymbols:
case kCvSst_OldSrcLines:
case kCvSst_OldLibraries:
case kCvSst_OldImports:
case kCvSst_OldCompacted:
case kCvSst_OldSrcLnSeg:
case kCvSst_OldSrcLines3:
case kCvSst_Types:
case kCvSst_Public:
case kCvSst_SrcLnSeg:
case kCvSst_SrcModule:
case kCvSst_Libraries:
case kCvSst_GlobalTypes:
case kCvSst_MPC:
case kCvSst_PreComp:
case kCvSst_PreCompMap:
case kCvSst_OffsetMap16:
case kCvSst_OffsetMap32:
case kCvSst_FileIndex:
case kCvSst_SegMap:
case kCvSst_SegName:
if (pfnCallback)
void *pvSubSect;
return rc;
switch (bStorageClass)
return s_szName;
while (cLines-- > 0)
int rc = RTDbgModLineAdd(pThis->hCnt, pszFile, pCur->Linenumber, RTDBGSEGIDX_RVA, pCur->Type.VirtualAddress, NULL);
pCur++;
static int rtDbgModCvAddCoffSymbol(PRTDBGMODCV pThis, uint32_t idxSeg, uint32_t uValue, const char *pszName)
Log(("Symbol: %s:%08x %s [%Rrc]\n", idxSeg == RTDBGSEGIDX_RVA ? "rva" : "abs", uValue, pszName, rc));
return rc;
const char *pszName;
case IMAGE_SYM_CLASS_NULL:
case IMAGE_SYM_CLASS_FILE:
rc = RTLatin1ToUtf8Ex(pszFile, Sym.NumberOfAuxSymbols * sizeof(IMAGE_SYMBOL), &pszDst, sizeof(szFile), NULL);
case IMAGE_SYM_CLASS_STATIC:
&& *pszName)
case IMAGE_SYM_CLASS_EXTERNAL:
&& *pszName )
case IMAGE_SYM_CLASS_FUNCTION:
case IMAGE_SYM_CLASS_REGISTER:
case IMAGE_SYM_CLASS_LABEL:
case IMAGE_SYM_CLASS_ARGUMENT:
case IMAGE_SYM_CLASS_ENUM_TAG:
case IMAGE_SYM_CLASS_BLOCK:
case IMAGE_SYM_CLASS_SECTION:
iLineSect++;
return rc;
int rc;
if (pbDbgSect)
rc = pThis->pMod->pImgVt->pfnReadAt(pThis->pMod, UINT32_MAX, pThis->offCoffDbgInfo, pbDbgSect, pThis->cbCoffDbgInfo);
uint32_t cbStrTab = (uint32_t)((uintptr_t)(pbDbgSect + pThis->cbCoffDbgInfo) - (uintptr_t)pszzStrTab);
return rc;
static DECLCALLBACK(int) rtDbgModCv_LineByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo)
static DECLCALLBACK(int) rtDbgModCv_LineAdd(PRTDBGMODINT pMod, const char *pszFile, size_t cchFile, uint32_t uLineNo,
static DECLCALLBACK(int) rtDbgModCv_SymbolByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags,
static DECLCALLBACK(int) rtDbgModCv_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
static DECLCALLBACK(int) rtDbgModCv_SymbolByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo)
static DECLCALLBACK(int) rtDbgModCv_SymbolAdd(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,
static DECLCALLBACK(int) rtDbgModCv_SegmentByIndex(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo)
static DECLCALLBACK(int) rtDbgModCv_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName, size_t cchName,
static DECLCALLBACK(RTDBGSEGIDX) rtDbgModCv_RvaToSegOff(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg)
return VINF_SUCCESS;
static DECLCALLBACK(int) rtDbgModCvAddSegmentsCallback(RTLDRMOD hLdrMod, PCRTLDRSEG pSeg, void *pvUser)
static int rtDbgModCvAddSegmentsFromDbg(PRTDBGMODCV pThis, PCIMAGE_SEPARATE_DEBUG_HEADER pDbgHdr, const char *pszFilename)
return VERR_CV_BAD_FORMAT;
return VERR_CV_BAD_FORMAT;
if (!paShs)
return VERR_NO_MEMORY;
Log(("RTDbgModCv: %s: Overlap or soring error, VirtualAddress=%#x uRvaPrev=%#x - section #%d '%.*s'!!!\n",
Log(("RTDbgModCv: %s: VirtualAddress=%#x VirtualSize=%#x (total %x) - beyond image size (%#x) - section #%d '%.*s'!!!\n",
pszFilename, paShs[i].VirtualAddress, pDbgHdr->SectionAlignment, i, sizeof(paShs[i].Name), paShs[i].Name));
if (uRvaPrev == 0)
return rc;
static int rtDbgModCvCreateInstance(PRTDBGMODINT pDbgMod, RTCVFILETYPE enmFileType, RTFILE hFile, PRTDBGMODCV *ppThis)
if (pThis)
return VINF_SUCCESS;
if (!pThis)
return VERR_NO_MEMORY;
return VINF_SUCCESS;
return rc;
return VERR_BAD_EXE_FORMAT;
return VERR_BAD_EXE_FORMAT;
int rc;
return rc;
Log(("RTDbgModCv: Bad COFF symbol count or/and offset: LvaToFirstSymbol=%#x, NumberOfSymbols=%#x cbCoff=%#x\n",
return VERR_BAD_EXE_FORMAT;
if ( (uint64_t)Hdr.LvaToFirstLinenumber + (uint64_t)Hdr.NumberOfLinenumbers * sizeof(IMAGE_LINENUMBER) > cb
Log(("RTDbgModCv: Bad COFF symbol count or/and offset: LvaToFirstSymbol=%#x, NumberOfSymbols=%#x cbCoff=%#x\n",
return VERR_BAD_EXE_FORMAT;
Log(("RTDbgModCv: The COFF symbol table is too short to be of any worth... (%u syms)\n", Hdr.NumberOfSymbols));
return VERR_NO_DATA;
return rc;
static int rtDbgModCvProbeCommon(PRTDBGMODINT pDbgMod, PRTCVHDR pCvHdr, RTCVFILETYPE enmFileType, RTFILE hFile,
RT_BYTE1(pCvHdr->u32Magic), RT_BYTE2(pCvHdr->u32Magic), RT_BYTE3(pCvHdr->u32Magic), RT_BYTE4(pCvHdr->u32Magic),
return VINF_SUCCESS;
return rc;
static DECLCALLBACK(int) rtDbgModCvEnumCallback(RTLDRMOD hLdrMod, PCRTLDRDBGINFO pDbgInfo, void *pvUser)
return VINF_SUCCESS;
int rc = pDbgMod->pImgVt->pfnReadAt(pDbgMod, pDbgInfo->iDbgInfo, pDbgInfo->offFile, &CvHdr, sizeof(CvHdr));
rc = rtDbgModCvProbeCommon(pDbgMod, &CvHdr, RTCVFILETYPE_IMAGE, NIL_RTFILE, pDbgInfo->offFile, pDbgInfo->cb,
rtDbgModCvProbeCoff(pDbgMod, RTCVFILETYPE_IMAGE, NIL_RTFILE, pDbgInfo->offFile, pDbgInfo->cb, pDbgMod->pszImgFile);
return VINF_SUCCESS;
static int rtDbgModCvProbeFile2(PRTDBGMODINT pThis, RTCVFILETYPE enmFileType, RTFILE hFile, uint32_t off, uint32_t cb,
return rc;
return rc;
switch (enmArch)
case RTLDRARCH_X86_32:
case RTLDRARCH_AMD64:
case RTLDRARCH_HOST:
AssertFailed();
case RTLDRARCH_WHATEVER:
return rc;
if (pThis)
return rc;
return rc;
if (!pThis)
return VINF_SUCCESS;
return rc;