Changeset 3528 for trunk/kDbg/kDbgModPE-win.cpp
- Timestamp:
- Aug 20, 2007, 4:43:13 AM (18 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/kDbg/kDbgModPE-win.cpp
-
Property svn:eol-style
set to
native
-
Property svn:keywords
set to
Id
r3526 r3528 1 /* $Id :$ */1 /* $Id$ */ 2 2 /** @file 3 * 4 * kProfile Mark 2 - Debug Info Reader, DbgHelp Base Reader.5 * 6 * Copyright (c) 2006 knut st. osmundsen <bird-src-spam@anduin.net.de> 7 * 3 * kDbg - The Debug Info Reader, DbgHelp Based Reader. 4 */ 5 6 /* 7 * Copyright (c) 2006-2007 knut st. osmundsen <bird-src-spam@anduin.net> 8 8 * 9 9 * This file is part of kLIBC. … … 33 33 #include <DbgHelp.h> 34 34 35 #include <iprt/file.h> 36 #include <iprt/string.h> 37 #include <iprt/alloc.h> 38 #include <iprt/assert.h> 39 #include <iprt/asm.h> 40 #include <iprt/err.h> 41 #include <iprt/thread.h> 42 #include <iprt/alloca.h> 43 #include "kDbgBase.h" 44 #include "DBGInternal.h" 45 46 47 //#include "internal/ldrPE.h" 35 #include "kDbgInternal.h" 36 48 37 49 38 /******************************************************************************* … … 73 62 * A dbghelp based PE debug reader. 74 63 */ 75 typedef struct RTDBGMODPE64 typedef struct KDBGMODPE 76 65 { 77 66 /** The common module core. */ 78 RTDBGMOD Core;67 KDBGMOD Core; 79 68 /** The image base. */ 80 69 DWORD64 ImageBase; … … 88 77 * implicit header section.*/ 89 78 IMAGE_SECTION_HEADER aSections[1]; 90 } RTDBGMODPE, *PRTDBGMODPE;79 } KDBGMODPE, *PKDBGMODPE; 91 80 92 81 … … 101 90 * @param puRVA Where to store the RVA on success. 102 91 */ 103 static int rtDbgModPeSegOffToRVA(P RTDBGMODPE pModPe, int32_t iSegment, RTUINTPTR off, uint32_t *puRVA)92 static int rtDbgModPeSegOffToRVA(PKDBGMODPE pModPe, int32_t iSegment, KDBGADDR off, uint32_t *puRVA) 104 93 { 105 94 if (iSegment >= 0) 106 95 { 107 AssertMsgReturn(iSegment < pModPe->cSections, ("iSegment=%RX32 cSections=%RX32\n", iSegment, pModPe->cSections),108 VERR_DBGMOD_INVALID_ADDRESS);109 AssertMsgReturn(off < pModPe->aSections[iSegment].Misc.VirtualSize,110 ("off=%RTptr VirtualSize=%RX32\n", off, pModPe->aSections[iSegment].Misc.VirtualSize),111 VERR_DBGMOD_INVALID_ADDRESS);96 kDbgAssertMsgReturn(iSegment < pModPe->cSections, ("iSegment=%x cSections=%x\n", iSegment, pModPe->cSections), 97 KDBG_ERR_INVALID_ADDRESS); 98 kDbgAssertMsgReturn(off < pModPe->aSections[iSegment].Misc.VirtualSize, 99 ("off=" PRI_KDBGADDR " VirtualSize=%x\n", off, pModPe->aSections[iSegment].Misc.VirtualSize), 100 KDBG_ERR_INVALID_ADDRESS); 112 101 *puRVA = pModPe->aSections[iSegment].VirtualAddress + off; 113 return VINF_SUCCESS;114 } 115 116 if (iSegment == RTDBGSEG_RVA)117 { 118 AssertMsgReturn(off < pModPe->cbImage, ("off=%RTptr, cbImage=%RX32\n", off, pModPe->cbImage),119 VERR_DBGMOD_INVALID_ADDRESS);102 return 0; 103 } 104 105 if (iSegment == KDBGSEG_RVA) 106 { 107 kDbgAssertMsgReturn(off < pModPe->cbImage, ("off=" PRI_KDBGADDR ", cbImage=%x\n", off, pModPe->cbImage), 108 KDBG_ERR_INVALID_ADDRESS); 120 109 *puRVA = off; 121 return VINF_SUCCESS;122 } 123 AssertMsgFailedReturn(("iSegment=%RI32\n", iSegment), VERR_DBGMOD_INVALID_ADDRESS);110 return 0; 111 } 112 AssertMsgFailedReturn(("iSegment=%RI32\n", iSegment), KDBG_ERR_INVALID_ADDRESS); 124 113 } 125 114 … … 135 124 * @param poff Where to store the segment offset. 136 125 */ 137 static int rtDbgModPeRVAToSegOff(P RTDBGMODPE pModPe, uint32_t uRVA, int32_t *piSegment, RTUINTPTR *poff)138 { 139 AssertMsgReturn(uRVA < pModPe->cbImage, ("uRVA=%RX32, cbImage=%RX32\n", uRVA, pModPe->cbImage),140 VERR_DBGMOD_INVALID_ADDRESS);126 static int rtDbgModPeRVAToSegOff(PKDBGMODPE pModPe, uint32_t uRVA, int32_t *piSegment, KDBGADDR *poff) 127 { 128 kDbgAssertMsgReturn(uRVA < pModPe->cbImage, ("uRVA=%x, cbImage=%x\n", uRVA, pModPe->cbImage), 129 KDBG_ERR_INVALID_ADDRESS); 141 130 for (int32_t iSegment = 0; iSegment < pModPe->cSections; iSegment++) 142 131 { … … 147 136 *poff = off; 148 137 *piSegment = iSegment; 149 return VINF_SUCCESS;150 } 151 } 152 AssertMsgFailedReturn(("uRVA=% RX32\n", uRVA), VERR_DBGMOD_INVALID_ADDRESS);153 } 154 155 156 /** 157 * @copydoc RTDBGMODOPS::pfnQueryLine158 */ 159 static DECLCALLBACK(int) rtDbgModPEQueryLine(P RTDBGMOD pMod, int32_t iSegment, RTUINTPTR off, PRTDBGLINE pLine)160 { 161 P RTDBGMODPE pModPe = (PRTDBGMODPE)pMod;138 return 0; 139 } 140 } 141 AssertMsgFailedReturn(("uRVA=%x\n", uRVA), KDBG_ERR_INVALID_ADDRESS); 142 } 143 144 145 /** 146 * @copydoc KDBGMODOPS::pfnQueryLine 147 */ 148 static DECLCALLBACK(int) rtDbgModPEQueryLine(PKDBGMOD pMod, int32_t iSegment, KDBGADDR off, PKDBGLINE pLine) 149 { 150 PKDBGMODPE pModPe = (PKDBGMODPE)pMod; 162 151 163 152 /* … … 166 155 uint32_t uRVA; 167 156 int rc = rtDbgModPeSegOffToRVA(pModPe, iSegment, off, &uRVA); 168 if ( RT_SUCCESS(rc))157 if (!rc) 169 158 { 170 159 DWORD64 off; … … 173 162 if (g_pfnSymGetLineFromAddr64(pModPe->hSymInst, pModPe->ImageBase + uRVA, &off, &Line)) 174 163 { 175 pLine->RVA = ( RTUINTPTR)(Line.Address - pModPe->ImageBase);164 pLine->RVA = (KDBGADDR)(Line.Address - pModPe->ImageBase); 176 165 rc = rtDbgModPeRVAToSegOff(pModPe, pLine->RVA, &pLine->iSegment, &pLine->offSegment); 177 166 pLine->iLine = Line.LineNumber; … … 192 181 193 182 /** 194 * @copydoc RTDBGMODOPS::pfnQuerySymbol195 */ 196 static DECLCALLBACK(int) rtDbgModPEQuerySymbol(P RTDBGMOD pMod, int32_t iSegment, RTUINTPTR off, PRTDBGSYMBOL pSym)197 { 198 P RTDBGMODPE pModPe = (PRTDBGMODPE)pMod;183 * @copydoc KDBGMODOPS::pfnQuerySymbol 184 */ 185 static DECLCALLBACK(int) rtDbgModPEQuerySymbol(PKDBGMOD pMod, int32_t iSegment, KDBGADDR off, PKDBGSYMBOL pSym) 186 { 187 PKDBGMODPE pModPe = (PKDBGMODPE)pMod; 199 188 200 189 /* … … 203 192 uint32_t uRVA; 204 193 int rc = rtDbgModPeSegOffToRVA(pModPe, iSegment, off, &uRVA); 205 if ( RT_SUCCESS(rc))194 if (!rc) 206 195 { 207 196 DWORD64 off; … … 209 198 { 210 199 SYMBOL_INFO Sym; 211 char achBuffer[sizeof(SYMBOL_INFO) + RTDBG_SYMBOL_MAX];200 char achBuffer[sizeof(SYMBOL_INFO) + KDBG_SYMBOL_MAX]; 212 201 } Buf; 213 202 Buf.Sym.SizeOfStruct = sizeof(SYMBOL_INFO); 214 Buf.Sym.MaxNameLen = RTDBG_SYMBOL_MAX;203 Buf.Sym.MaxNameLen = KDBG_SYMBOL_MAX; 215 204 if (g_pfnSymFromAddr(pModPe->hSymInst, pModPe->ImageBase + uRVA, &off, &Buf.Sym)) 216 205 { … … 218 207 pSym->fFlags = 0; 219 208 if (Buf.Sym.Flags & SYMFLAG_FUNCTION) 220 pSym->fFlags |= RTDBGSYM_FLAGS_CODE;209 pSym->fFlags |= KDBGSYM_FLAGS_CODE; 221 210 else if (Buf.Sym.Flags & SYMFLAG_CONSTANT) 222 pSym->fFlags |= RTDBGSYM_FLAGS_ABS; /** @todo SYMFLAG_CONSTANT must be tested - documentation is too brief to say what is really meant here.*/211 pSym->fFlags |= KDBGSYM_FLAGS_ABS; /** @todo SYMFLAG_CONSTANT must be tested - documentation is too brief to say what is really meant here.*/ 223 212 else 224 pSym->fFlags |= RTDBGSYM_FLAGS_DATA;213 pSym->fFlags |= KDBGSYM_FLAGS_DATA; 225 214 if (Buf.Sym.Flags & SYMFLAG_EXPORT) 226 pSym->fFlags |= RTDBGSYM_FLAGS_EXPORTED;215 pSym->fFlags |= KDBGSYM_FLAGS_EXPORTED; 227 216 if ((Buf.Sym.Flags & (SYMFLAG_VALUEPRESENT | SYMFLAG_CONSTANT)) == (SYMFLAG_VALUEPRESENT | SYMFLAG_CONSTANT)) 228 217 { 229 pSym->iSegment = RTDBGSEG_ABS;230 pSym->offSegment = ( RTUINTPTR)Buf.Sym.Value;231 pSym->RVA = ( RTUINTPTR)Buf.Sym.Value;218 pSym->iSegment = KDBGSEG_ABS; 219 pSym->offSegment = (KDBGADDR)Buf.Sym.Value; 220 pSym->RVA = (KDBGADDR)Buf.Sym.Value; 232 221 } 233 222 else 234 223 { 235 pSym->RVA = ( RTUINTPTR)(Buf.Sym.Address - pModPe->ImageBase);224 pSym->RVA = (KDBGADDR)(Buf.Sym.Address - pModPe->ImageBase); 236 225 rc = rtDbgModPeRVAToSegOff(pModPe, pSym->RVA, &pSym->iSegment, &pSym->offSegment); 237 226 } … … 253 242 254 243 /** 255 * @copydoc RTDBGMODOPS::pfnClose256 */ 257 static DECLCALLBACK(int) rtDbgModPEClose(P RTDBGMOD pMod)258 { 259 P RTDBGMODPE pModPe = (PRTDBGMODPE)pMod;244 * @copydoc KDBGMODOPS::pfnClose 245 */ 246 static DECLCALLBACK(int) rtDbgModPEClose(PKDBGMOD pMod) 247 { 248 PKDBGMODPE pModPe = (PKDBGMODPE)pMod; 260 249 261 250 if (g_pfnSymCleanup(pModPe->hSymInst)) 262 return VINF_SUCCESS;251 return 0; 263 252 264 253 DWORD Err = GetLastError(); … … 272 261 * Methods for a PE module. 273 262 */ 274 static const RTDBGMODOPS g_rtDbgModPEOps =263 static const KDBGMODOPS g_rtDbgModPEOps = 275 264 { 276 265 "PE (dbghelp)", … … 310 299 } 311 300 if (pFileInfo->dwFileVersionMS >= 0x60004) 312 rc = VINF_SUCCESS;301 rc = 0; 313 302 else 314 303 rc = VERR_VERSION_MISMATCH; … … 355 344 strcat(strrchr(pszPath, '\\'), s_szDbgHelp); 356 345 int rc2 = rtDbgModPETryDbgHelp(pszPath, &FileVersionMS, &FileVersionLS); 357 if ( RT_SUCCESS(rc))346 if (!rc) 358 347 return rc2; 359 348 if (rc != VERR_VERSION_MISMATCH) … … 442 431 { 443 432 if (g_hDbgHelp) 444 return VINF_SUCCESS;433 return 0; 445 434 446 435 /* primitive locking - make some useful API for this kind of spinning! */ … … 452 441 { 453 442 ASMAtomicXchgU32(&s_u32Lock, 0); 454 return VINF_SUCCESS;443 return 0; 455 444 } 456 445 … … 460 449 char szPath[260]; 461 450 int rc = rtDbgModPEFindDbgHelp(szPath, sizeof(szPath)); 462 if ( RT_FAILURE(rc))451 if (rc) 463 452 { 464 453 ASMAtomicXchgU32(&s_u32Lock, 0); … … 520 509 *s_aFunctions[i].ppfn = pfn; 521 510 } 522 if ( RT_SUCCESS(rc))511 if (!rc) 523 512 { 524 513 ASMAtomicXchgSize(&g_hDbgHelp, hmod); 525 514 ASMAtomicXchgU32(&s_u32Lock, 0); 526 return VINF_SUCCESS;515 return 0; 527 516 } 528 517 } … … 556 545 * 557 546 */ 558 int rtDbgModPEOpen(RTFILE File, RTFOFF offHdr, const char *pszModulePath, PRTDBGMOD *ppDbgMod)547 int kdbgModPEOpen(RTFILE File, int64_t offHdr, const char *pszModulePath, PKDBGMOD *ppDbgMod) 559 548 { 560 549 /* … … 562 551 */ 563 552 IMAGE_FILE_HEADER FHdr; 564 int rc = RTFileReadAt(File, offHdr + KDBG_OFFSETOF(IMAGE_NT_HEADERS32, FileHeader), &FHdr, sizeof(FHdr), NULL);553 int rc = kDbgHlpReadAt(File, offHdr + KDBG_OFFSETOF(IMAGE_NT_HEADERS32, FileHeader), &FHdr, sizeof(FHdr), NULL); 565 554 AssertRCReturn(rc, rc); 566 555 567 556 uint32_t cbImage; 568 557 if (FHdr.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32)) 569 rc = RTFileReadAt(File, offHdr + KDBG_OFFSETOF(IMAGE_NT_HEADERS32, OptionalHeader.SizeOfImage),558 rc = kDbgHlpReadAt(File, offHdr + KDBG_OFFSETOF(IMAGE_NT_HEADERS32, OptionalHeader.SizeOfImage), 570 559 &cbImage, sizeof(cbImage), NULL); 571 560 else if (FHdr.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER64)) 572 rc = RTFileReadAt(File, offHdr + KDBG_OFFSETOF(IMAGE_NT_HEADERS64, OptionalHeader.SizeOfImage),561 rc = kDbgHlpReadAt(File, offHdr + KDBG_OFFSETOF(IMAGE_NT_HEADERS64, OptionalHeader.SizeOfImage), 573 562 &cbImage, sizeof(cbImage), NULL); 574 563 else … … 580 569 */ 581 570 rc = rtDbgModPELoadDbgHelp(); 582 if ( RT_FAILURE(rc))571 if (rc) 583 572 return rc; 584 573 … … 586 575 * Allocate the module and read/construct the section headers. 587 576 */ 588 P RTDBGMODPE pModPe = (PRTDBGMODPE)RTMemAlloc(KDBG_OFFSETOF(RTDBGMODPE, aSections[FHdr.NumberOfSections + 2]));589 AssertReturn(pModPe, VERR_NO_MEMORY);590 pModPe->Core.u32Magic = RTDBGMOD_MAGIC;577 PKDBGMODPE pModPe = (PKDBGMODPE)RTMemAlloc(KDBG_OFFSETOF(KDBGMODPE, aSections[FHdr.NumberOfSections + 2])); 578 AssertReturn(pModPe, KDBG_ERR_NO_MEMORY); 579 pModPe->Core.u32Magic = KDBGMOD_MAGIC; 591 580 pModPe->Core.pOps = &g_rtDbgModPEOps; 592 581 pModPe->Core.File = File; 593 582 pModPe->cbImage = cbImage; 594 583 pModPe->cSections = 1 + FHdr.NumberOfSections; 595 rc = RTFileReadAt(File, offHdr + KDBG_OFFSETOF(IMAGE_NT_HEADERS32, OptionalHeader) + FHdr.SizeOfOptionalHeader,584 rc = kDbgHlpReadAt(File, offHdr + KDBG_OFFSETOF(IMAGE_NT_HEADERS32, OptionalHeader) + FHdr.SizeOfOptionalHeader, 596 585 &pModPe->aSections[1], sizeof(pModPe->aSections[0]) * FHdr.NumberOfSections, NULL); 597 if ( RT_SUCCESS(rc))586 if (!rc) 598 587 { 599 588 PIMAGE_SECTION_HEADER pSH = &pModPe->aSections[0]; … … 671 660 AssertRC(rc); 672 661 673 RTMemFree(pModPe);662 kDbgHlpFree(pModPe); 674 663 return rc; 675 664 } -
Property svn:eol-style
set to
Note:
See TracChangeset
for help on using the changeset viewer.