- Timestamp:
- Nov 2, 2018 9:12:17 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 126335
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 3 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/VBox/Runtime/Makefile.kmk ¶
r75129 r75237 425 425 common/dbg/dbgmodcodeview.cpp \ 426 426 common/dbg/dbgmoddwarf.cpp \ 427 common/dbg/dbgmodmapsym.cpp \ 427 428 common/dbg/dbgmodnm.cpp \ 428 429 common/dvm/dvm.cpp \ … … 1600 1601 common/dbg/dbgmodexports.cpp \ 1601 1602 common/dbg/dbgmodldr.cpp \ 1603 common/dbg/dbgmodmapsym.cpp \ 1602 1604 common/dbg/dbgmodnm.cpp \ 1603 1605 common/err/errinfo-alloc.cpp \ -
TabularUnified trunk/src/VBox/Runtime/common/dbg/dbgmod.cpp ¶
r75130 r75237 279 279 */ 280 280 rc = rtDbgModDebugInterpreterRegister(&g_rtDbgModVtDbgNm); 281 if (RT_SUCCESS(rc)) 282 rc = rtDbgModDebugInterpreterRegister(&g_rtDbgModVtDbgMapSym); 281 283 if (RT_SUCCESS(rc)) 282 284 rc = rtDbgModDebugInterpreterRegister(&g_rtDbgModVtDbgDwarf); -
TabularUnified trunk/src/VBox/Runtime/common/dbg/dbgmodmapsym.cpp ¶
r75204 r75237 1 1 /* $Id$ */ 2 2 /** @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. 4 9 */ 5 10 … … 29 34 * Header Files * 30 35 *********************************************************************************************************************************/ 36 #define LOG_GROUP RTLOGGROUP_DBG 31 37 #include <iprt/dbg.h> 32 38 #include "internal/iprt.h" … … 34 40 #include <iprt/err.h> 35 41 #include <iprt/ctype.h> 42 #include <iprt/file.h> 43 #include <iprt/log.h> 36 44 #include <iprt/mem.h> 37 45 #include <iprt/stream.h> … … 43 51 * Structures and Typedefs * 44 52 *********************************************************************************************************************************/ 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. */ 57 typedef 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. */ 73 typedef 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. */ 81 typedef 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 */ 101 typedef 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 */ 109 typedef 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. */ 117 typedef 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. */ 128 typedef 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 55 142 56 143 57 144 58 145 /** @interface_method_impl{RTDBGMODVTDBG,pfnUnwindFrame} */ 59 static DECLCALLBACK(int) rtDbgMod Nm_UnwindFrame(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTDBGUNWINDSTATE pState)146 static DECLCALLBACK(int) rtDbgModMapSym_UnwindFrame(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTDBGUNWINDSTATE pState) 60 147 { 61 148 RT_NOREF(pMod, iSeg, off, pState); … … 65 152 66 153 /** @interface_method_impl{RTDBGMODVTDBG,pfnLineByAddr} */ 67 static DECLCALLBACK(int) rtDbgMod Nm_LineByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off,154 static DECLCALLBACK(int) rtDbgModMapSym_LineByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, 68 155 PRTINTPTR poffDisp, PRTDBGLINE pLineInfo) 69 156 { 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); 72 159 } 73 160 74 161 75 162 /** @interface_method_impl{RTDBGMODVTDBG,pfnLineByOrdinal} */ 76 static DECLCALLBACK(int) rtDbgMod Nm_LineByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo)77 { 78 PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;79 return RTDbgModLineByOrdinal( pThis->hCnt, iOrdinal, pLineInfo);163 static DECLCALLBACK(int) rtDbgModMapSym_LineByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo) 164 { 165 RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv; 166 return RTDbgModLineByOrdinal(hCnt, iOrdinal, pLineInfo); 80 167 } 81 168 82 169 83 170 /** @interface_method_impl{RTDBGMODVTDBG,pfnLineCount} */ 84 static DECLCALLBACK(uint32_t) rtDbgMod Nm_LineCount(PRTDBGMODINT pMod)85 { 86 PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;87 return RTDbgModLineCount( pThis->hCnt);171 static DECLCALLBACK(uint32_t) rtDbgModMapSym_LineCount(PRTDBGMODINT pMod) 172 { 173 RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv; 174 return RTDbgModLineCount(hCnt); 88 175 } 89 176 90 177 91 178 /** @interface_method_impl{RTDBGMODVTDBG,pfnLineAdd} */ 92 static DECLCALLBACK(int) rtDbgMod Nm_LineAdd(PRTDBGMODINT pMod, const char *pszFile, size_t cchFile, uint32_t uLineNo,179 static DECLCALLBACK(int) rtDbgModMapSym_LineAdd(PRTDBGMODINT pMod, const char *pszFile, size_t cchFile, uint32_t uLineNo, 93 180 uint32_t iSeg, RTUINTPTR off, uint32_t *piOrdinal) 94 181 { 95 PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;182 RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv; 96 183 Assert(!pszFile[cchFile]); NOREF(cchFile); 97 return RTDbgModLineAdd( pThis->hCnt, pszFile, uLineNo, iSeg, off, piOrdinal);184 return RTDbgModLineAdd(hCnt, pszFile, uLineNo, iSeg, off, piOrdinal); 98 185 } 99 186 100 187 101 188 /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByAddr} */ 102 static DECLCALLBACK(int) rtDbgMod Nm_SymbolByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags,189 static DECLCALLBACK(int) rtDbgModMapSym_SymbolByAddr(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags, 103 190 PRTINTPTR poffDisp, PRTDBGSYMBOL pSymInfo) 104 191 { 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); 107 194 } 108 195 109 196 110 197 /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByName} */ 111 static DECLCALLBACK(int) rtDbgMod Nm_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol,198 static DECLCALLBACK(int) rtDbgModMapSym_SymbolByName(PRTDBGMODINT pMod, const char *pszSymbol, size_t cchSymbol, 112 199 PRTDBGSYMBOL pSymInfo) 113 200 { 114 PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;201 RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv; 115 202 Assert(!pszSymbol[cchSymbol]); NOREF(cchSymbol); 116 return RTDbgModSymbolByName( pThis->hCnt, pszSymbol, pSymInfo);203 return RTDbgModSymbolByName(hCnt, pszSymbol, pSymInfo); 117 204 } 118 205 119 206 120 207 /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolByOrdinal} */ 121 static DECLCALLBACK(int) rtDbgMod Nm_SymbolByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo)122 { 123 PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;124 return RTDbgModSymbolByOrdinal( pThis->hCnt, iOrdinal, pSymInfo);208 static DECLCALLBACK(int) rtDbgModMapSym_SymbolByOrdinal(PRTDBGMODINT pMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo) 209 { 210 RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv; 211 return RTDbgModSymbolByOrdinal(hCnt, iOrdinal, pSymInfo); 125 212 } 126 213 127 214 128 215 /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolCount} */ 129 static DECLCALLBACK(uint32_t) rtDbgMod Nm_SymbolCount(PRTDBGMODINT pMod)130 { 131 PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;132 return RTDbgModSymbolCount( pThis->hCnt);216 static DECLCALLBACK(uint32_t) rtDbgModMapSym_SymbolCount(PRTDBGMODINT pMod) 217 { 218 RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv; 219 return RTDbgModSymbolCount(hCnt); 133 220 } 134 221 135 222 136 223 /** @interface_method_impl{RTDBGMODVTDBG,pfnSymbolAdd} */ 137 static DECLCALLBACK(int) rtDbgMod Nm_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;224 static 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; 142 229 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); 144 231 } 145 232 146 233 147 234 /** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentByIndex} */ 148 static DECLCALLBACK(int) rtDbgMod Nm_SegmentByIndex(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo)149 { 150 PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;151 return RTDbgModSegmentByIndex( pThis->hCnt, iSeg, pSegInfo);235 static DECLCALLBACK(int) rtDbgModMapSym_SegmentByIndex(PRTDBGMODINT pMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo) 236 { 237 RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv; 238 return RTDbgModSegmentByIndex(hCnt, iSeg, pSegInfo); 152 239 } 153 240 154 241 155 242 /** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentCount} */ 156 static DECLCALLBACK(RTDBGSEGIDX) rtDbgMod Nm_SegmentCount(PRTDBGMODINT pMod)157 { 158 PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;159 return RTDbgModSegmentCount( pThis->hCnt);243 static DECLCALLBACK(RTDBGSEGIDX) rtDbgModMapSym_SegmentCount(PRTDBGMODINT pMod) 244 { 245 RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv; 246 return RTDbgModSegmentCount(hCnt); 160 247 } 161 248 162 249 163 250 /** @interface_method_impl{RTDBGMODVTDBG,pfnSegmentAdd} */ 164 static DECLCALLBACK(int) rtDbgMod Nm_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName,251 static DECLCALLBACK(int) rtDbgModMapSym_SegmentAdd(PRTDBGMODINT pMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName, 165 252 size_t cchName, uint32_t fFlags, PRTDBGSEGIDX piSeg) 166 253 { 167 PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;254 RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv; 168 255 Assert(!pszName[cchName]); NOREF(cchName); 169 return RTDbgModSegmentAdd( pThis->hCnt, uRva, cb, pszName, fFlags, piSeg);256 return RTDbgModSegmentAdd(hCnt, uRva, cb, pszName, fFlags, piSeg); 170 257 } 171 258 172 259 173 260 /** @interface_method_impl{RTDBGMODVTDBG,pfnImageSize} */ 174 static DECLCALLBACK(RTUINTPTR) rtDbgMod Nm_ImageSize(PRTDBGMODINT pMod)175 { 176 PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;177 return RTDbgModImageSize( pThis->hCnt);261 static DECLCALLBACK(RTUINTPTR) rtDbgModMapSym_ImageSize(PRTDBGMODINT pMod) 262 { 263 RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv; 264 return RTDbgModImageSize(hCnt); 178 265 } 179 266 180 267 181 268 /** @interface_method_impl{RTDBGMODVTDBG,pfnRvaToSegOff} */ 182 static DECLCALLBACK(RTDBGSEGIDX) rtDbgMod Nm_RvaToSegOff(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg)183 { 184 PRTDBGMODNM pThis = (PRTDBGMODNM)pMod->pvDbgPriv;185 return RTDbgModRvaToSegOff( pThis->hCnt, uRva, poffSeg);269 static DECLCALLBACK(RTDBGSEGIDX) rtDbgModMapSym_RvaToSegOff(PRTDBGMODINT pMod, RTUINTPTR uRva, PRTUINTPTR poffSeg) 270 { 271 RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv; 272 return RTDbgModRvaToSegOff(hCnt, uRva, poffSeg); 186 273 } 187 274 188 275 189 276 /** @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); 277 static DECLCALLBACK(int) rtDbgModMapSym_Close(PRTDBGMODINT pMod) 278 { 279 RTDBGMOD hCnt = (RTDBGMOD)pMod->pvDbgPriv; 280 RTDbgModRelease(hCnt); 281 pMod->pvDbgPriv = NULL; 196 282 return VINF_SUCCESS; 197 283 } … … 199 285 200 286 /** 201 * Scans a NM-like map file.287 * Validate the module header. 202 288 * 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 */ 294 static 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. 204 332 * 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. 209 336 */ 210 static int rtDbgModNmScanFile(PRTDBGMODNM pThis, PRTSTREAM pStrm, bool fAddSymbols) 337 static 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 */ 383 static int rtDbgModMapSymReadIt(RTDBGMOD hCnt, uint8_t const *pbFile, size_t cbFile) 211 384 { 212 385 /* 213 * Try parse the stream.386 * Revalidate the header. 214 387 */ 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++) 226 401 { 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++) 229 424 { 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) 251 427 { 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; 258 431 } 259 432 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) 260 459 { 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) 279 464 { 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; 295 467 } 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)); 307 490 else 308 491 { 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; 436 495 } 437 496 } 438 497 } 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; 464 501 } 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; 484 503 } 485 504 486 505 487 506 /** @interface_method_impl{RTDBGMODVTDBG,pfnTryOpen} */ 488 static DECLCALLBACK(int) rtDbgMod Nm_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch)507 static DECLCALLBACK(int) rtDbgModMapSym_TryOpen(PRTDBGMODINT pMod, RTLDRARCH enmArch) 489 508 { 490 509 NOREF(enmArch); … … 496 515 || pMod->pImgVt) 497 516 return VERR_DBG_NO_MATCHING_INTERPRETER; 517 pMod->pvDbgPriv = NULL; 498 518 499 519 /* 500 * Try open the file and c reate an instance.520 * Try open the file and check out the first header. 501 521 */ 502 PRTSTREAM pStrm;503 int rc = RT StrmOpen(pMod->pszDbgFile, "r", &pStrm);522 RTFILE hFile; 523 int rc = RTFileOpen(&hFile, pMod->pszDbgFile, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 504 524 if (RT_SUCCESS(rc)) 505 525 { 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) 508 530 { 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); 510 538 if (RT_SUCCESS(rc)) 511 539 { 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)) 522 541 { 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 } 526 565 } 527 566 } 528 RTDbgModRelease(pThis->hCnt);529 567 } 530 else 531 rc = VERR_NO_MEMORY; 532 RTStrmClose(pStrm); 568 RTFileClose(hFile); 533 569 } 570 Log(("rtDbgModMapSym_TryOpen: %s -> %Rrc, %p\n", pMod->pszDbgFile, rc, pMod->pvDbgPriv)); 534 571 return rc; 535 572 } … … 537 574 538 575 539 /** Virtual function table for the NM-like mapfile reader. */540 DECL_HIDDEN_CONST(RTDBGMODVTDBG) const g_rtDbgModVtDbg Nm =576 /** Virtual function table for the MAPSYM file reader. */ 577 DECL_HIDDEN_CONST(RTDBGMODVTDBG) const g_rtDbgModVtDbgMapSym = 541 578 { 542 579 /*.u32Magic = */ RTDBGMODVTDBG_MAGIC, 543 /*.fSupports = */ RT_DBGTYPE_ MAP,544 /*.pszName = */ " nm",545 /*.pfnTryOpen = */ rtDbgMod Nm_TryOpen,546 /*.pfnClose = */ rtDbgMod Nm_Close,547 548 /*.pfnRvaToSegOff = */ rtDbgMod Nm_RvaToSegOff,549 /*.pfnImageSize = */ rtDbgMod Nm_ImageSize,550 551 /*.pfnSegmentAdd = */ rtDbgMod Nm_SegmentAdd,552 /*.pfnSegmentCount = */ rtDbgMod Nm_SegmentCount,553 /*.pfnSegmentByIndex = */ rtDbgMod Nm_SegmentByIndex,554 555 /*.pfnSymbolAdd = */ rtDbgMod Nm_SymbolAdd,556 /*.pfnSymbolCount = */ rtDbgMod Nm_SymbolCount,557 /*.pfnSymbolByOrdinal = */ rtDbgMod Nm_SymbolByOrdinal,558 /*.pfnSymbolByName = */ rtDbgMod Nm_SymbolByName,559 /*.pfnSymbolByAddr = */ rtDbgMod Nm_SymbolByAddr,560 561 /*.pfnLineAdd = */ rtDbgMod Nm_LineAdd,562 /*.pfnLineCount = */ rtDbgMod Nm_LineCount,563 /*.pfnLineByOrdinal = */ rtDbgMod Nm_LineByOrdinal,564 /*.pfnLineByAddr = */ rtDbgMod Nm_LineByAddr,565 566 /*.pfnUnwindFrame = */ rtDbgMod Nm_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, 567 604 568 605 /*.u32EndMagic = */ RTDBGMODVTDBG_MAGIC -
TabularUnified trunk/src/VBox/Runtime/include/internal/dbgmod.h ¶
r75235 r75237 688 688 extern DECLHIDDEN(RTDBGMODVTDBG const) g_rtDbgModVtDbgDwarf; 689 689 extern DECLHIDDEN(RTDBGMODVTDBG const) g_rtDbgModVtDbgNm; 690 extern DECLHIDDEN(RTDBGMODVTDBG const) g_rtDbgModVtDbgMapSym; 690 691 #ifdef RT_OS_WINDOWS 691 692 extern DECLHIDDEN(RTDBGMODVTDBG const) g_rtDbgModVtDbgDbgHelp;
Note:
See TracChangeset
for help on using the changeset viewer.