Changeset 46101 in vbox
- Timestamp:
- May 15, 2013 3:36:43 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 85787
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/dbg.h
r46083 r46101 972 972 973 973 /** 974 * Gets the name of the debug info file we're using. 975 * 976 * @returns Pointer to a read only string containing the filename, NULL if we 977 * don't use one. 978 * 979 * @param hDbgMod The module handle. 980 */ 981 RTDECL(const char *) RTDbgModDebugFile(RTDBGMOD hDbgMod); 982 983 /** 984 * Gets the image filename (as specified by the user). 985 * 986 * @returns Pointer to a read only string containing the filename. 987 * 988 * @param hDbgMod The module handle. 989 */ 990 RTDECL(const char *) RTDbgModImageFile(RTDBGMOD hDbgMod); 991 992 /** 993 * Gets the image filename actually used if it differs from RTDbgModImageFile. 994 * 995 * @returns Pointer to a read only string containing the filename, NULL if same 996 * as RTDBgModImageFile. 997 * 998 * @param hDbgMod The module handle. 999 */ 1000 RTDECL(const char *) RTDbgModImageFileUsed(RTDBGMOD hDbgMod); 1001 1002 /** 974 1003 * Converts an image relative address to a segment:offset address. 975 1004 * -
trunk/include/iprt/mangling.h
r46080 r46101 401 401 # define RTDbgModLineCount RT_MANGLER(RTDbgModLineCount) 402 402 # define RTDbgModName RT_MANGLER(RTDbgModName) 403 # define RTDbgModDebugFile RT_MANGLER(RTDbgModDebugFile) 404 # define RTDbgModImageFile RT_MANGLER(RTDbgModImageFile) 405 # define RTDbgModImageFileUsed RT_MANGLER(RTDbgModImageFileUsed) 403 406 # define RTDbgModRelease RT_MANGLER(RTDbgModRelease) 404 407 # define RTDbgModRetain RT_MANGLER(RTDbgModRetain) -
trunk/include/iprt/strcache.h
r44529 r46101 88 88 89 89 /** 90 * Enters a string into the cache in lower cased form. 91 * 92 * @returns Pointer to a read-only lower cased copy of the string. 93 * 94 * @param hStrCache Handle to the string cache. 95 * @param pchString Pointer to a string. This does not need to be 96 * zero terminated, but must not contain any zero 97 * characters. 98 * @param cchString The number of characters (bytes) to enter. 99 * 100 * @remarks It is implementation dependent whether the returned string pointer 101 * differs when entering the same string twice. 102 */ 103 RTDECL(const char *) RTStrCacheEnterLowerN(RTSTRCACHE hStrCache, const char *pchString, size_t cchString); 104 105 /** 106 * Enters a string into the cache in lower cased form. 107 * 108 * @returns Pointer to a read-only lower cased copy of the string. 109 * 110 * @param hStrCache Handle to the string cache. 111 * @param psz Pointer to a zero terminated string. 112 * 113 * @remarks See RTStrCacheEnterN. 114 */ 115 RTDECL(const char *) RTStrCacheEnterLower(RTSTRCACHE hStrCache, const char *psz); 116 117 118 /** 90 119 * Retains a reference to a string. 91 120 * -
trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp
r46078 r46101 342 342 { "kh", 0, 0, NULL, 0, 0, dbgcCmdStack, "", "Callstack - hypervisor." }, 343 343 { "lm", 0, ~0U, &g_aArgListMods[0], RT_ELEMENTS(g_aArgListMods), 0, dbgcCmdListModules, "[module [..]]", "List modules." }, 344 { "lmv", 0, ~0U, &g_aArgListMods[0], RT_ELEMENTS(g_aArgListMods), 0, dbgcCmdListModules, "[module [..]]", "List modules, verbose." }, 344 345 { "lmo", 0, ~0U, &g_aArgListMods[0], RT_ELEMENTS(g_aArgListMods), 0, dbgcCmdListModules, "[module [..]]", "List modules and their segments." }, 346 { "lmov", 0, ~0U, &g_aArgListMods[0], RT_ELEMENTS(g_aArgListMods), 0, dbgcCmdListModules, "[module [..]]", "List modules and their segments, verbose." }, 345 347 { "ln", 0, ~0U, &g_aArgListNear[0], RT_ELEMENTS(g_aArgListNear), 0, dbgcCmdListNear, "[addr/sym [..]]", "List symbols near to the address. Default address is CS:EIP." }, 346 348 { "ls", 0, 1, &g_aArgListSource[0],RT_ELEMENTS(g_aArgListSource), 0, dbgcCmdListSource, "[addr]", "Source." }, … … 3892 3894 { 3893 3895 bool const fMappings = pCmd->pszCmd[2] == 'o'; 3896 bool const fVerbose = pCmd->pszCmd[strlen(pCmd->pszCmd) - 1] == 'v'; 3894 3897 PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp); 3895 3898 … … 3905 3908 if (hMod != NIL_RTDBGMOD) 3906 3909 { 3907 uint32_t const cSegs = RTDbgModSegmentCount(hMod); 3908 const char * const pszName = RTDbgModName(hMod); 3910 uint32_t const cSegs = RTDbgModSegmentCount(hMod); 3911 const char * const pszName = RTDbgModName(hMod); 3912 const char * const pszImgFile = RTDbgModImageFile(hMod); 3913 const char * const pszImgFileUsed = RTDbgModImageFileUsed(hMod); 3914 const char * const pszDbgFile = RTDbgModDebugFile(hMod); 3909 3915 if ( cArgs == 0 3910 3916 || dbgcCmdListModuleMatch(pszName, paArgs, cArgs)) … … 3926 3932 || aMappings[iMap].iSeg == NIL_RTDBGSEGIDX)) 3927 3933 uMin = aMappings[iMap].Address; 3928 DBGCCmdHlpPrintf(pCmdHlp, "%RGv %04x %s\n", (RTGCUINTPTR)uMin, cSegs, pszName); 3934 if (!fVerbose || !pszImgFile) 3935 DBGCCmdHlpPrintf(pCmdHlp, "%RGv %04x %s\n", (RTGCUINTPTR)uMin, cSegs, pszName); 3936 else 3937 DBGCCmdHlpPrintf(pCmdHlp, "%RGv %04x %-12s %s\n", (RTGCUINTPTR)uMin, cSegs, pszName, pszImgFile); 3938 if (fVerbose && pszImgFileUsed) 3939 DBGCCmdHlpPrintf(pCmdHlp, " Local image: %s\n", pszImgFileUsed); 3940 if (fVerbose && pszDbgFile) 3941 DBGCCmdHlpPrintf(pCmdHlp, " Debug file: %s\n", pszDbgFile); 3929 3942 3930 3943 if (fMappings) -
trunk/src/VBox/Debugger/DBGPlugInWinNt.cpp
r46083 r46101 162 162 } NTPRODUCTTYPE; 163 163 164 /** 165 * PDB v2.0 in image debug info. 166 * The URL is constructed from the timestamp and the %02x age? 167 */ 168 typedef struct CV_INFO_PDB20 169 { 170 uint32_t Signature; /**< CV_SIGNATURE_PDB70. */ 171 int32_t Offset; /**< Always 0. Used to be the offset to the real debug info. */ 172 uint32_t TimeDateStamp; 173 uint32_t Age; 174 uint8_t PdbFilename[4]; 175 } CV_INFO_PDB20; 176 /** The CV_INFO_PDB20 signature. */ 177 #define CV_SIGNATURE_PDB20 RT_MAKE_U32_FROM_U8('N','B','1','0') 178 179 /** 180 * PDB v7.0 in image debug info. 181 * The URL is constructed from the signature and the %02x age. 182 */ 183 #pragma pack(4) 184 typedef struct CV_INFO_PDB70 185 { 186 uint32_t CvSignature; /**< CV_SIGNATURE_PDB70. */ 187 RTUUID Signature; 188 uint32_t Age; 189 uint8_t PdbFilename[4]; 190 } CV_INFO_PDB70; 191 #pragma pack() 192 AssertCompileMemberOffset(CV_INFO_PDB70, Signature, 4); 193 AssertCompileMemberOffset(CV_INFO_PDB70, Age, 4 + 16); 194 /** The CV_INFO_PDB70 signature. */ 195 #define CV_SIGNATURE_PDB70 RT_MAKE_U32_FROM_U8('R','S','D','S') 164 165 /** NT image header union. */ 166 typedef union NTHDRSU 167 { 168 IMAGE_NT_HEADERS32 vX_32; 169 IMAGE_NT_HEADERS64 vX_64; 170 } NTHDRS; 171 /** Pointer to NT image header union. */ 172 typedef NTHDRS *PNTHDRS; 173 /** Pointer to const NT image header union. */ 174 typedef NTHDRS const *PCNTHDRS; 196 175 197 176 /** @} */ 177 198 178 199 179 … … 251 231 /** The image size. */ 252 232 uint32_t cbImage; 233 /** The file offset of the SizeOfImage field in the optional header if it 234 * needs patching, otherwise set to UINT32_MAX. */ 235 uint32_t offSizeOfImage; 236 /** The correct image size. */ 237 uint32_t cbCorrectImageSize; 253 238 /** Number of entries in the aMappings table. */ 254 239 uint32_t cMappings; … … 310 295 { 311 296 PDBGDIGGERWINNTRDR pThis = (PDBGDIGGERWINNTRDR)pvUser; 297 uint32_t offFile = (uint32_t)off; 298 AssertReturn(offFile == off, VERR_INVALID_PARAMETER); 312 299 313 300 uint32_t i = pThis->iHint; 314 if (pThis->aMappings[i].offFile > off )301 if (pThis->aMappings[i].offFile > offFile) 315 302 { 316 303 i = pThis->cMappings; 317 304 while (i-- > 0) 318 if (off >= pThis->aMappings[i].offFile)305 if (offFile >= pThis->aMappings[i].offFile) 319 306 break; 320 307 pThis->iHint = i; … … 324 311 { 325 312 uint32_t offNextMap = i + 1 < pThis->cMappings ? pThis->aMappings[i + 1].offFile : pThis->cbImage; 326 uint32_t offMap = (uint32_t)off- pThis->aMappings[i].offFile;313 uint32_t offMap = offFile - pThis->aMappings[i].offFile; 327 314 328 315 /* Read file bits backed by memory. */ 329 if (off < pThis->aMappings[i].cbMem)316 if (offMap < pThis->aMappings[i].cbMem) 330 317 { 331 318 uint32_t cbToRead = pThis->aMappings[i].cbMem - offMap; … … 339 326 if (RT_FAILURE(rc)) 340 327 return rc; 328 329 /* Patch it? */ 330 if ( pThis->offSizeOfImage != UINT32_MAX 331 && offFile < pThis->offSizeOfImage + 4 332 && offFile + cbToRead > pThis->offSizeOfImage) 333 { 334 uint32_t SizeOfImage = pThis->cbCorrectImageSize; 335 int32_t offPatch = pThis->offSizeOfImage - offFile; 336 uint8_t *pbPatch = (uint8_t *)pvBuf + offPatch; 337 uint32_t cbPatch = sizeof(uint32_t); 338 if (offFile + cbToRead < pThis->offSizeOfImage + cbPatch) 339 cbPatch = offFile + cbToRead - pThis->offSizeOfImage; 340 while (cbPatch-- > 0) 341 { 342 if (offPatch >= 0) 343 *pbPatch = (uint8_t)SizeOfImage; 344 offPatch++; 345 pbPatch++; 346 SizeOfImage >>= 8; 347 } 348 } 349 350 /* Done? */ 341 351 if (cbToRead == cb) 342 352 break; 343 353 344 off 345 cb -= cbToRead;346 pvBuf = (char *)pvBuf + cbToRead;354 offFile += cbToRead; 355 cb -= cbToRead; 356 pvBuf = (char *)pvBuf + cbToRead; 347 357 } 348 358 349 359 /* Mind the gap. */ 350 if (offNextMap > off )351 { 352 uint32_t cbZero = offNextMap - (uint32_t)off;360 if (offNextMap > offFile) 361 { 362 uint32_t cbZero = offNextMap - offFile; 353 363 if (cbZero > cb) 354 364 { … … 358 368 359 369 RT_BZERO(pvBuf, cbZero); 360 off 361 cb -= cbZero;362 pvBuf = (char *)pvBuf + cbZero;370 offFile += cbZero; 371 cb -= cbZero; 372 pvBuf = (char *)pvBuf + cbZero; 363 373 } 364 374 … … 378 388 pThis->pUVM = NULL; 379 389 RTMemFree(pvUser); 390 } 391 392 393 /** 394 * Checks if the section headers look okay. 395 * 396 * @returns true / false. 397 * @param paShs Pointer to the section headers. 398 * @param cShs Number of headers. 399 * @param cbImage The image size. 400 */ 401 static bool dbgDiggerWinNtIsSectionHeaderOk(PCIMAGE_SECTION_HEADER paShs, uint32_t cShs, uint32_t cbImage) 402 { 403 for (uint32_t i = 0; i < cShs; i++) 404 { 405 if (!paShs[i].Name[0]) 406 { 407 Log(("DigWinNt: Section header #%u has no name\n", i)); 408 return false; 409 } 410 411 if (paShs[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD) 412 continue; 413 if (paShs[i].VirtualAddress >= cbImage) 414 { 415 Log(("DigWinNt: Section header #%u has a virtual address beyond the image: %#x cbImage=%#x\n", 416 i, paShs[i].VirtualAddress, cbImage)); 417 return false; 418 } 419 if (paShs[i].Misc.VirtualSize >= cbImage) /* we don't check too strictly here becuase NT4 SP1 ntfs.sys. */ 420 { 421 Log(("DigWinNt: Section header #%u has a end beyond the image: VirtualAddress=%#x VirtualSize=%#x cbImage=%#x\n", 422 i, paShs[i].VirtualAddress, paShs[i].Misc.VirtualSize, cbImage)); 423 return false; 424 } 425 } 426 return true; 427 } 428 429 430 /** 431 * Create a loader module for the in-guest-memory PE module. 432 */ 433 static int dbgDiggerWinNtCreateLdrMod(PDBGDIGGERWINNT pThis, PUVM pUVM, const char *pszName, PCDBGFADDRESS pImageAddr, 434 uint32_t cbImage, uint8_t *pbBuf, size_t cbBuf, 435 uint32_t offHdrs, PCNTHDRS pHdrs, PRTLDRMOD phLdrMod) 436 { 437 /* 438 * Allocate and create a reader instance. 439 */ 440 uint32_t const cShs = WINNT_UNION(pThis, pHdrs, FileHeader.NumberOfSections); 441 PDBGDIGGERWINNTRDR pRdr = (PDBGDIGGERWINNTRDR)RTMemAlloc(RT_OFFSETOF(DBGDIGGERWINNTRDR, aMappings[cShs + 2])); 442 if (!pRdr) 443 return VERR_NO_MEMORY; 444 445 VMR3RetainUVM(pUVM); 446 pRdr->pUVM = pUVM; 447 pRdr->ImageAddr = *pImageAddr; 448 pRdr->cbImage = cbImage; 449 pRdr->cbCorrectImageSize = cbImage; 450 pRdr->offSizeOfImage = UINT32_MAX; 451 pRdr->iHint = 0; 452 453 /* 454 * Use the section table to construct a more accurate view of the file/ 455 * image if it's in the buffer (it should be). 456 */ 457 uint32_t offShs = offHdrs 458 + ( pThis->f32Bit 459 ? pHdrs->vX_32.FileHeader.SizeOfOptionalHeader + RT_OFFSETOF(IMAGE_NT_HEADERS32, OptionalHeader) 460 : pHdrs->vX_64.FileHeader.SizeOfOptionalHeader + RT_OFFSETOF(IMAGE_NT_HEADERS64, OptionalHeader)); 461 uint32_t cbShs = cShs * sizeof(IMAGE_SECTION_HEADER); 462 PCIMAGE_SECTION_HEADER paShs = (PCIMAGE_SECTION_HEADER)(pbBuf + offShs); 463 if ( offShs + cbShs <= RT_MIN(cbImage, cbBuf) 464 && dbgDiggerWinNtIsSectionHeaderOk(paShs, cShs, cbImage)) 465 { 466 pRdr->cMappings = 0; 467 468 for (uint32_t i = 0; i < cShs; i++) 469 if ( paShs[i].SizeOfRawData > 0 470 && paShs[i].PointerToRawData > 0) 471 { 472 uint32_t j = 1; 473 if (!pRdr->cMappings) 474 pRdr->cMappings++; 475 else 476 { 477 while (j < pRdr->cMappings && pRdr->aMappings[j].offFile < paShs[i].PointerToRawData) 478 j++; 479 if (j < pRdr->cMappings) 480 memmove(&pRdr->aMappings[j + 1], &pRdr->aMappings[j], (pRdr->cMappings - j) * sizeof(pRdr->aMappings)); 481 } 482 pRdr->aMappings[j].offFile = paShs[i].PointerToRawData; 483 pRdr->aMappings[j].offMem = paShs[i].VirtualAddress; 484 pRdr->aMappings[j].cbMem = i + 1 < cShs 485 ? paShs[i + 1].VirtualAddress - paShs[i].VirtualAddress 486 : paShs[i].Misc.VirtualSize; 487 if (j == pRdr->cMappings) 488 pRdr->cbImage = paShs[i].PointerToRawData + paShs[i].SizeOfRawData; 489 pRdr->cMappings++; 490 } 491 492 /* Insert the mapping of the headers that isn't covered by the section table. */ 493 pRdr->aMappings[0].offFile = 0; 494 pRdr->aMappings[0].offMem = 0; 495 pRdr->aMappings[0].cbMem = pRdr->cMappings ? pRdr->aMappings[1].offFile : pRdr->cbImage; 496 497 int j = pRdr->cMappings - 1; 498 while (j-- > 0) 499 { 500 uint32_t cbFile = pRdr->aMappings[j + 1].offFile - pRdr->aMappings[j].offFile; 501 if (pRdr->aMappings[j].cbMem > cbFile) 502 pRdr->aMappings[j].cbMem = cbFile; 503 } 504 } 505 else 506 { 507 /* 508 * Fallback, fake identity mapped file data. 509 */ 510 pRdr->cMappings = 1; 511 pRdr->aMappings[0].offFile = 0; 512 pRdr->aMappings[0].offMem = 0; 513 pRdr->aMappings[0].cbMem = pRdr->cbImage; 514 } 515 516 /* 517 * Call the loader to open the PE image for debugging. 518 * Note! It always calls pfnDtor. 519 */ 520 RTLDRMOD hLdrMod; 521 int rc = RTLdrOpenInMemory(pszName, RTLDR_O_FOR_DEBUG, RTLDRARCH_WHATEVER, pRdr->cbImage, 522 dbgDiggerWinNtRdr_Read, dbgDiggerWinNtRdr_Dtor, pRdr, 523 &hLdrMod); 524 if (RT_SUCCESS(rc)) 525 *phLdrMod = hLdrMod; 526 else 527 *phLdrMod = NIL_RTLDRMOD; 528 return rc; 380 529 } 381 530 … … 413 562 /* Dig out the NT/PE headers. */ 414 563 IMAGE_DOS_HEADER const *pMzHdr = (IMAGE_DOS_HEADER const *)pbBuf; 415 typedef union NTHDRSU 416 { 417 IMAGE_NT_HEADERS32 vX_32; 418 IMAGE_NT_HEADERS64 vX_64; 419 } NTHDRS; 420 NTHDRS const *pHdrs; 564 PCNTHDRS pHdrs; 421 565 uint32_t offHdrs; 422 566 if (pMzHdr->e_magic != IMAGE_DOS_SIGNATURE) 423 567 { 424 568 offHdrs = 0; 425 pHdrs = ( NTHDRS const *)pbBuf;569 pHdrs = (PCNTHDRS)pbBuf; 426 570 } 427 571 else if ( pMzHdr->e_lfanew >= cbImage … … 460 604 return; 461 605 } 606 if (WINNT_UNION(pThis, pHdrs, FileHeader.NumberOfSections) > 64) 607 { 608 Log(("DigWinNt: %s: Too many sections: %#x\n", pszName, WINNT_UNION(pThis, pHdrs, FileHeader.NumberOfSections))); 609 return; 610 } 611 462 612 const uint32_t TimeDateStamp = pHdrs->vX_32.FileHeader.TimeDateStamp; 463 613 … … 480 630 } 481 631 482 uint32_t uRvaDebugDir = 0;483 uint32_t cbDebugDir = 0;484 IMAGE_DATA_DIRECTORY const *pDir = &WINNT_UNION(pThis, pHdrs, OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]);485 if ( pDir->VirtualAddress > offHdrs486 && pDir->VirtualAddress < cbImage487 && pDir->Size >= sizeof(IMAGE_DEBUG_DIRECTORY)488 && pDir->Size < cbImage489 && pDir->VirtualAddress + pDir->Size <= cbImage490 )491 {492 uRvaDebugDir = pDir->VirtualAddress;493 cbDebugDir = pDir->Size;494 }495 632 496 633 /* 497 * Create the module. 634 * Create the module using the in memory image first, falling back 635 * on cached image. 498 636 */ 637 RTLDRMOD hLdrMod; 638 int rc = dbgDiggerWinNtCreateLdrMod(pThis, pUVM, pszName, pImageAddr, cbImage, pbBuf, cbBuf, offHdrs, pHdrs, 639 &hLdrMod); 640 if (RT_FAILURE(rc)) 641 hLdrMod = NIL_RTLDRMOD; 642 499 643 RTDBGMOD hMod; 500 int rc = RTDbgModCreateFromPeImage(&hMod, pszName, NULL, NIL_RTLDRMOD,501 644 rc = RTDbgModCreateFromPeImage(&hMod, pszName, NULL, hLdrMod, 645 cbImageFromHdr, TimeDateStamp, DBGFR3AsGetConfig(pUVM)); 502 646 if (RT_FAILURE(rc)) 503 647 { 504 648 /* 505 * Probably didn't find the image any where, try fake an image 506 * from guest memory. 649 * Final fallback is a container module. 507 650 */ 508 uint32_t cMappings = WINNT_UNION(pThis, pHdrs, FileHeader.NumberOfSections) + 3; 509 PDBGDIGGERWINNTRDR pRdr = (PDBGDIGGERWINNTRDR)RTMemAlloc(RT_OFFSETOF(DBGDIGGERWINNTRDR, aMappings[cMappings])); 510 if (!pRdr) 651 rc = RTDbgModCreate(&hMod, pszName, cbImage, 0); 652 if (RT_FAILURE(rc)) 511 653 return; 512 654 513 VMR3RetainUVM(pUVM); 514 pRdr->pUVM = pUVM; 515 pRdr->ImageAddr = *pImageAddr; 516 pRdr->cbImage = cbImageFromHdr; 517 pRdr->cMappings = 1; 518 pRdr->iHint = 0; 519 pRdr->aMappings[0].offFile = 0; 520 pRdr->aMappings[0].offMem = 0; 521 pRdr->aMappings[0].cbMem = cbImageFromHdr; 522 523 RTLDRMOD hLdrMod; 524 rc = RTLdrOpenInMemory(pszName, RTLDR_O_FOR_DEBUG, RTLDRARCH_WHATEVER, pRdr->cbImage, 525 dbgDiggerWinNtRdr_Read, dbgDiggerWinNtRdr_Dtor, pRdr, 526 &hLdrMod); 527 if (RT_SUCCESS(rc)) 528 { 529 rc = RTDbgModCreateFromPeImage(&hMod, pszName, NULL, hLdrMod, 530 cbImageFromHdr, TimeDateStamp, DBGFR3AsGetConfig(pUVM)); 531 if (RT_FAILURE(rc)) 532 RTLdrClose(hLdrMod); 533 } 534 if (RT_FAILURE(rc)) 535 { 536 /* 537 * Final fallback is a container module. 538 */ 539 rc = RTDbgModCreate(&hMod, pszName, cbImage, 0); 540 if (RT_FAILURE(rc)) 541 return; 542 543 rc = RTDbgModSymbolAdd(hMod, "Headers", 0 /*iSeg*/, 0, cbImage, 0 /*fFlags*/, NULL); AssertRC(rc); 544 } 545 } 546 rc = RTDbgModSetTag(hMod, DIG_WINNT_MOD_TAG); AssertRC(rc); 547 548 #if 0 549 /* 550 * Dig out debug info if possible. What we're after is the CODEVIEW part. 551 */ 552 /** @todo do we really need this? */ 553 if (uRvaDebugDir != 0) 554 { 555 DBGFADDRESS Addr = *pImageAddr; 556 DBGFR3AddrAdd(&Addr, uRvaDebugDir); 557 rc = DBGFR3MemRead(pUVM, 0 /*idCpu*/, &Addr, pbBuf, RT_MIN(cbDebugDir, cbBuf)); 558 if (RT_SUCCESS(rc)) 559 { 560 IMAGE_DEBUG_DIRECTORY const *pa = (IMAGE_DEBUG_DIRECTORY const *)pbBuf; 561 size_t c = RT_MIN(RT_MIN(cbDebugDir, cbBuf) / sizeof(*pa), 10); 562 for (uint32_t i = 0; i < c; i++) 563 if ( pa[i].AddressOfRawData > offHdrs 564 && pa[i].AddressOfRawData < cbImage 565 && pa[i].SizeOfData < cbImage 566 && pa[i].AddressOfRawData + pa[i].SizeOfData <= cbImage 567 && pa[i].TimeDateStamp == TimeDateStamp /* too paranoid? */ 568 && pa[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW 569 ) 570 { 571 } 572 } 573 } 574 #endif 655 rc = RTDbgModSymbolAdd(hMod, "Headers", 0 /*iSeg*/, 0, cbImage, 0 /*fFlags*/, NULL); 656 AssertRC(rc); 657 } 658 659 /* Tag the module. */ 660 rc = RTDbgModSetTag(hMod, DIG_WINNT_MOD_TAG); 661 AssertRC(rc); 575 662 576 663 /* -
trunk/src/VBox/Runtime/common/dbg/dbgmod.cpp
r46083 r46101 33 33 #include "internal/iprt.h" 34 34 35 #include <iprt/alloca.h> 35 36 #include <iprt/asm.h> 36 37 #include <iprt/assert.h> … … 302 303 303 304 305 /** 306 * Performs lazy init of our global variables. 307 * @returns IPRT status code. 308 */ 304 309 DECLINLINE(int) rtDbgModLazyInit(void) 305 310 { … … 308 313 309 314 310 /**311 * Creates a module based on the default debug info container.312 *313 * This can be used to manually load a module and its symbol. The primary user314 * group is the debug info interpreters, which use this API to create an315 * efficient debug info container behind the scenes and forward all queries to316 * it once the info has been loaded.317 *318 * @returns IPRT status code.319 *320 * @param phDbgMod Where to return the module handle.321 * @param pszName The name of the module (mandatory).322 * @param cbSeg The size of initial segment. If zero, segments will323 * have to be added manually using RTDbgModSegmentAdd.324 * @param fFlags Flags reserved for future extensions, MBZ for now.325 */326 315 RTDECL(int) RTDbgModCreate(PRTDBGMOD phDbgMod, const char *pszName, RTUINTPTR cbSeg, uint32_t fFlags) 327 316 { … … 350 339 if (RT_SUCCESS(rc)) 351 340 { 352 pDbgMod->pszName = RTStrCacheEnter(g_hDbgModStrCache, pszName); 341 pDbgMod->pszImgFileSpecified = RTStrCacheEnter(g_hDbgModStrCache, pszName); 342 pDbgMod->pszName = RTStrCacheEnterLower(g_hDbgModStrCache, RTPathFilename(pszName)); 353 343 if (pDbgMod->pszName) 354 344 { … … 359 349 return rc; 360 350 } 351 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile); 361 352 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName); 362 353 } … … 399 390 if (RT_SUCCESS(rc)) 400 391 { 401 pDbgMod->pszName = RTStrCacheEnter (g_hDbgModStrCache, pszName);392 pDbgMod->pszName = RTStrCacheEnterLower(g_hDbgModStrCache, pszName); 402 393 if (pDbgMod->pszName) 403 394 { … … 405 396 if (pDbgMod->pszImgFile) 406 397 { 398 RTStrCacheRetain(pDbgMod->pszImgFile); 399 pDbgMod->pszImgFileSpecified = pDbgMod->pszImgFile; 400 407 401 /* 408 402 * Find an image reader which groks the file. … … 488 482 RTSemRWReleaseRead(g_hDbgModRWSem); 489 483 } 490 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName); 484 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFileSpecified); 485 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile); 491 486 } 492 487 else 493 488 rc = VERR_NO_STR_MEMORY; 494 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->psz ImgFile);489 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName); 495 490 } 496 491 else … … 537 532 if (RT_SUCCESS(rc)) 538 533 { 539 pDbgMod->pszName = RTStrCacheEnter (g_hDbgModStrCache, pszName);534 pDbgMod->pszName = RTStrCacheEnterLower(g_hDbgModStrCache, pszName); 540 535 if (pDbgMod->pszName) 541 536 { … … 700 695 rtDbgModOpenDebugInfoExternalToImageCallback(RTLDRMOD hLdrMod, PCRTLDRDBGINFO pDbgInfo, void *pvUser) 701 696 { 702 if (!pDbgInfo->pszExtFile) 703 return VINF_SUCCESS; 704 697 RTDBGMODOPENDIETI *pArgs = (RTDBGMODOPENDIETI *)pvUser; 698 699 Assert(pDbgInfo->enmType > RTLDRDBGINFOTYPE_INVALID && pDbgInfo->enmType < RTLDRDBGINFOTYPE_END); 700 const char *pszExtFile = pDbgInfo->pszExtFile; 701 if (!pszExtFile) 702 { 703 /* 704 * If a external debug type comes without a file name, calculate a 705 * likely debug filename for it. (Hack for NT4 drivers.) 706 */ 707 const char *pszExt = NULL; 708 if (pDbgInfo->enmType == RTLDRDBGINFOTYPE_CODEVIEW_DBG) 709 pszExt = ".dbg"; 710 else if ( pDbgInfo->enmType == RTLDRDBGINFOTYPE_CODEVIEW_PDB20 711 || pDbgInfo->enmType == RTLDRDBGINFOTYPE_CODEVIEW_PDB70) 712 pszExt = ".pdb"; 713 if (pszExt && pArgs->pDbgMod->pszName) 714 { 715 size_t cchName = strlen(pArgs->pDbgMod->pszName); 716 char *psz = (char *)alloca(cchName + strlen(pszExt) + 1); 717 if (psz) 718 { 719 memcpy(psz, pArgs->pDbgMod->pszName, cchName + 1); 720 RTPathStripExt(psz); 721 pszExtFile = strcat(psz, pszExt); 722 } 723 } 724 725 if (!pszExtFile) 726 { 727 Log2(("rtDbgModOpenDebugInfoExternalToImageCallback: enmType=%d\n", pDbgInfo->enmType)); 728 return VINF_SUCCESS; 729 } 730 } 731 732 /* 733 * Switch on type and call the appropriate search function. 734 */ 705 735 int rc; 706 RTDBGMODOPENDIETI *pArgs = (RTDBGMODOPENDIETI *)pvUser;707 736 switch (pDbgInfo->enmType) 708 737 { 709 738 case RTLDRDBGINFOTYPE_CODEVIEW_PDB70: 710 rc = RTDbgCfgOpenPdb70(pArgs->hDbgCfg, p DbgInfo->pszExtFile,739 rc = RTDbgCfgOpenPdb70(pArgs->hDbgCfg, pszExtFile, 711 740 &pDbgInfo->u.Pdb70.Uuid, 712 741 pDbgInfo->u.Pdb70.uAge, … … 715 744 716 745 case RTLDRDBGINFOTYPE_CODEVIEW_PDB20: 717 rc = RTDbgCfgOpenPdb20(pArgs->hDbgCfg, p DbgInfo->pszExtFile,746 rc = RTDbgCfgOpenPdb20(pArgs->hDbgCfg, pszExtFile, 718 747 pDbgInfo->u.Pdb20.cbImage, 719 748 pDbgInfo->u.Pdb20.uTimestamp, … … 723 752 724 753 case RTLDRDBGINFOTYPE_CODEVIEW_DBG: 725 rc = RTDbgCfgOpenDbg(pArgs->hDbgCfg, p DbgInfo->pszExtFile,754 rc = RTDbgCfgOpenDbg(pArgs->hDbgCfg, pszExtFile, 726 755 pDbgInfo->u.Dbg.cbImage, 727 756 pDbgInfo->u.Dbg.uTimestamp, … … 730 759 731 760 case RTLDRDBGINFOTYPE_DWARF_DWO: 732 rc = RTDbgCfgOpenDwo(pArgs->hDbgCfg, p DbgInfo->pszExtFile,761 rc = RTDbgCfgOpenDwo(pArgs->hDbgCfg, pszExtFile, 733 762 pDbgInfo->u.Dwo.uCrc32, 734 763 rtDbgModExtDbgInfoOpenCallback, pArgs->pDbgMod, (void *)pDbgInfo); … … 737 766 default: 738 767 Log(("rtDbgModOpenDebugInfoExternalToImageCallback: Don't know how to handle enmType=%d and pszFileExt=%s\n", 739 pDbgInfo->enmType, p DbgInfo->pszExtFile));768 pDbgInfo->enmType, pszExtFile)); 740 769 return VERR_DBG_TODO; 741 770 } … … 747 776 } 748 777 Log(("rtDbgModOpenDebugInfoExternalToImageCallback: '%s' (enmType=%d) for '%s' -> %Rrc\n", 749 p DbgInfo->pszExtFile, pDbgInfo->enmType, pArgs->pDbgMod->pszImgFile, rc));778 pszExtFile, pDbgInfo->enmType, pArgs->pDbgMod->pszImgFile, rc)); 750 779 return rc; 751 780 } … … 761 790 static int rtDbgModOpenDebugInfoExternalToImage(PRTDBGMODINT pDbgMod, RTDBGCFG hDbgCfg) 762 791 { 792 Assert(!pDbgMod->pDbgVt); 793 763 794 RTDBGMODOPENDIETI Args; 764 795 Args.pDbgMod = pDbgMod; … … 767 798 if (RT_SUCCESS(rc) && pDbgMod->pDbgVt) 768 799 return VINF_SUCCESS; 800 801 LogFlow(("rtDbgModOpenDebugInfoExternalToImage: rc=%Rrc\n", rc)); 769 802 return VERR_NOT_FOUND; 770 803 } … … 944 977 if (pDbgMod->pszImgFile) 945 978 { 979 RTStrCacheRetain(pDbgMod->pszImgFile); 980 pDbgMod->pszImgFileSpecified = pDbgMod->pszImgFile; 981 946 982 /* 947 983 * If we have a loader module, we must instantiate the loader … … 993 1029 else 994 1030 rc = VERR_NO_STR_MEMORY; 1031 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFileSpecified); 995 1032 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile); 996 1033 } … … 1038 1075 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName); 1039 1076 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile); 1077 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFileSpecified); 1040 1078 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszDbgFile); 1041 1079 RTCritSectLeave(&pDbgMod->CritSect); /* paranoia */ … … 1045 1083 1046 1084 1047 /**1048 * Retains another reference to the module.1049 *1050 * @returns New reference count, UINT32_MAX on invalid handle (asserted).1051 *1052 * @param hDbgMod The module handle.1053 *1054 * @remarks Will not take any locks.1055 */1056 1085 RTDECL(uint32_t) RTDbgModRetain(RTDBGMOD hDbgMod) 1057 1086 { … … 1063 1092 1064 1093 1065 /**1066 * Release a reference to the module.1067 *1068 * When the reference count reaches zero, the module is destroyed.1069 *1070 * @returns New reference count, UINT32_MAX on invalid handle (asserted).1071 *1072 * @param hDbgMod The module handle. The NIL handle is quietly ignored1073 * and 0 is returned.1074 *1075 * @remarks Will not take any locks.1076 */1077 1094 RTDECL(uint32_t) RTDbgModRelease(RTDBGMOD hDbgMod) 1078 1095 { … … 1090 1107 1091 1108 1092 /**1093 * Gets the module name.1094 *1095 * @returns Pointer to a read only string containing the name.1096 *1097 * @param hDbgMod The module handle.1098 */1099 1109 RTDECL(const char *) RTDbgModName(RTDBGMOD hDbgMod) 1100 1110 { … … 1106 1116 1107 1117 1108 /** 1109 * Converts an image relative address to a segment:offset address. 1110 * 1111 * @returns Segment index on success. 1112 * NIL_RTDBGSEGIDX is returned if the module handle or the RVA are 1113 * invalid. 1114 * 1115 * @param hDbgMod The module handle. 1116 * @param uRva The image relative address to convert. 1117 * @param poffSeg Where to return the segment offset. Optional. 1118 */ 1118 RTDECL(const char *) RTDbgModDebugFile(RTDBGMOD hDbgMod) 1119 { 1120 PRTDBGMODINT pDbgMod = hDbgMod; 1121 RTDBGMOD_VALID_RETURN_RC(pDbgMod, NULL); 1122 if (pDbgMod->fDeferred || pDbgMod->fExports) 1123 return NULL; 1124 return pDbgMod->pszDbgFile; 1125 } 1126 RT_EXPORT_SYMBOL(RTDbgModDebugFile); 1127 1128 1129 RTDECL(const char *) RTDbgModImageFile(RTDBGMOD hDbgMod) 1130 { 1131 PRTDBGMODINT pDbgMod = hDbgMod; 1132 RTDBGMOD_VALID_RETURN_RC(pDbgMod, NULL); 1133 return pDbgMod->pszImgFileSpecified; 1134 } 1135 RT_EXPORT_SYMBOL(RTDbgModImageFile); 1136 1137 1138 RTDECL(const char *) RTDbgModImageFileUsed(RTDBGMOD hDbgMod) 1139 { 1140 PRTDBGMODINT pDbgMod = hDbgMod; 1141 RTDBGMOD_VALID_RETURN_RC(pDbgMod, NULL); 1142 return pDbgMod->pszImgFile == pDbgMod->pszImgFileSpecified ? NULL : pDbgMod->pszImgFile; 1143 } 1144 RT_EXPORT_SYMBOL(RTDbgModImageFileUsed); 1145 1146 1119 1147 RTDECL(RTDBGSEGIDX) RTDbgModRvaToSegOff(RTDBGMOD hDbgMod, RTUINTPTR uRva, PRTUINTPTR poffSeg) 1120 1148 { … … 1131 1159 1132 1160 1133 /**1134 * Image size when mapped if segments are mapped adjacently.1135 *1136 * For ELF, PE, and Mach-O images this is (usually) a natural query, for LX and1137 * NE and such it's a bit odder and the answer may not make much sense for them.1138 *1139 * @returns Image mapped size.1140 * RTUINTPTR_MAX is returned if the handle is invalid.1141 *1142 * @param hDbgMod The module handle.1143 */1144 1161 RTDECL(RTUINTPTR) RTDbgModImageSize(RTDBGMOD hDbgMod) 1145 1162 { … … 1156 1173 1157 1174 1158 /**1159 * Gets the module tag value if any.1160 *1161 * @returns The tag. 0 if hDbgMod is invalid.1162 *1163 * @param hDbgMod The module handle.1164 */1165 1175 RTDECL(uint64_t) RTDbgModGetTag(RTDBGMOD hDbgMod) 1166 1176 { … … 1172 1182 1173 1183 1174 /**1175 * Tags or untags the module.1176 *1177 * @returns IPRT status code.1178 * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.1179 *1180 * @param hDbgMod The module handle.1181 * @param uTag The tag value. The convention is that 0 is no tag1182 * and any other value means it's tagged. It's adviced1183 * to use some kind of unique number like an address1184 * (global or string cache for instance) to avoid1185 * collisions with other users1186 */1187 1184 RTDECL(int) RTDbgModSetTag(RTDBGMOD hDbgMod, uint64_t uTag) 1188 1185 { … … 1199 1196 1200 1197 1201 /**1202 * Adds a segment to the module. Optional feature.1203 *1204 * This method is intended used for manually constructing debug info for a1205 * module. The main usage is from other debug info interpreters that want to1206 * avoid writing a debug info database and instead uses the standard container1207 * behind the scenes.1208 *1209 * @returns IPRT status code.1210 * @retval VERR_NOT_SUPPORTED if this feature isn't support by the debug info1211 * interpreter. This is a common return code.1212 * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.1213 * @retval VERR_DBG_ADDRESS_WRAP if uRva+cb wraps around.1214 * @retval VERR_DBG_SEGMENT_NAME_OUT_OF_RANGE if pszName is too short or long.1215 * @retval VERR_INVALID_PARAMETER if fFlags contains undefined flags.1216 * @retval VERR_DBG_SPECIAL_SEGMENT if *piSeg is a special segment.1217 * @retval VERR_DBG_INVALID_SEGMENT_INDEX if *piSeg doesn't meet expectations.1218 *1219 * @param hDbgMod The module handle.1220 * @param uRva The image relative address of the segment.1221 * @param cb The size of the segment.1222 * @param pszName The segment name. Does not normally need to be1223 * unique, although this is somewhat up to the1224 * debug interpreter to decide.1225 * @param fFlags Segment flags. Reserved for future used, MBZ.1226 * @param piSeg The segment index or NIL_RTDBGSEGIDX on input.1227 * The assigned segment index on successful return.1228 * Optional.1229 */1230 1198 RTDECL(int) RTDbgModSegmentAdd(RTDBGMOD hDbgMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName, 1231 1199 uint32_t fFlags, PRTDBGSEGIDX piSeg) … … 1258 1226 1259 1227 1260 /**1261 * Gets the number of segments in the module.1262 *1263 * This is can be used to determine the range which can be passed to1264 * RTDbgModSegmentByIndex and derivatives.1265 *1266 * @returns The segment relative address.1267 * NIL_RTDBGSEGIDX if the handle is invalid.1268 *1269 * @param hDbgMod The module handle.1270 */1271 1228 RTDECL(RTDBGSEGIDX) RTDbgModSegmentCount(RTDBGMOD hDbgMod) 1272 1229 { … … 1283 1240 1284 1241 1285 /**1286 * Query information about a segment.1287 *1288 * This can be used together with RTDbgModSegmentCount to enumerate segments.1289 * The index starts a 0 and stops one below RTDbgModSegmentCount.1290 *1291 * @returns IPRT status code.1292 * @retval VERR_DBG_INVALID_SEGMENT_INDEX if iSeg is too high.1293 * @retval VERR_DBG_SPECIAL_SEGMENT if iSeg indicates a special segment.1294 * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.1295 *1296 * @param hDbgMod The module handle.1297 * @param iSeg The segment index. No special segments.1298 * @param pSegInfo Where to return the segment info. The1299 * RTDBGSEGMENT::Address member will be set to1300 * RTUINTPTR_MAX or the load address used at link time.1301 */1302 1242 RTDECL(int) RTDbgModSegmentByIndex(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo) 1303 1243 { … … 1315 1255 1316 1256 1317 /**1318 * Gets the size of a segment.1319 *1320 * This is a just a wrapper around RTDbgModSegmentByIndex.1321 *1322 * @returns The segment size.1323 * RTUINTPTR_MAX is returned if either the handle and segment index are1324 * invalid.1325 *1326 * @param hDbgMod The module handle.1327 * @param iSeg The segment index. RTDBGSEGIDX_ABS is not allowed.1328 * If RTDBGSEGIDX_RVA is used, the functions returns1329 * the same value as RTDbgModImageSize.1330 */1331 1257 RTDECL(RTUINTPTR) RTDbgModSegmentSize(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg) 1332 1258 { … … 1340 1266 1341 1267 1342 /**1343 * Gets the image relative address of a segment.1344 *1345 * This is a just a wrapper around RTDbgModSegmentByIndex.1346 *1347 * @returns The segment relative address.1348 * RTUINTPTR_MAX is returned if either the handle and segment index are1349 * invalid.1350 *1351 * @param hDbgMod The module handle.1352 * @param iSeg The segment index. No special segment indexes1353 * allowed (asserted).1354 */1355 1268 RTDECL(RTUINTPTR) RTDbgModSegmentRva(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg) 1356 1269 { … … 1362 1275 1363 1276 1364 /**1365 * Adds a line number to the module.1366 *1367 * @returns IPRT status code.1368 * @retval VERR_NOT_SUPPORTED if the module interpret doesn't support adding1369 * custom symbols. This is a common place occurrence.1370 * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.1371 * @retval VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE if the symbol name is too long or1372 * short.1373 * @retval VERR_DBG_INVALID_RVA if an image relative address is specified and1374 * it's not inside any of the segments defined by the module.1375 * @retval VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.1376 * @retval VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the1377 * end of the segment.1378 * @retval VERR_DBG_ADDRESS_WRAP if off+cb wraps around.1379 * @retval VERR_INVALID_PARAMETER if the symbol flags sets undefined bits.1380 *1381 * @param hDbgMod The module handle.1382 * @param pszSymbol The symbol name.1383 * @param iSeg The segment index.1384 * @param off The segment offset.1385 * @param cb The size of the symbol. Can be zero, although this1386 * may depend somewhat on the debug interpreter.1387 * @param fFlags Symbol flags. Reserved for the future, MBZ.1388 * @param piOrdinal Where to return the symbol ordinal on success. If1389 * the interpreter doesn't do ordinals, this will be set to1390 * UINT32_MAX. Optional.1391 */1392 1277 RTDECL(int) RTDbgModSymbolAdd(RTDBGMOD hDbgMod, const char *pszSymbol, RTDBGSEGIDX iSeg, RTUINTPTR off, 1393 1278 RTUINTPTR cb, uint32_t fFlags, uint32_t *piOrdinal) … … 1436 1321 1437 1322 1438 /**1439 * Gets the symbol count.1440 *1441 * This can be used together wtih RTDbgModSymbolByOrdinal or1442 * RTDbgModSymbolByOrdinalA to enumerate all the symbols.1443 *1444 * @returns The number of symbols in the module.1445 * UINT32_MAX is returned if the module handle is invalid or some other1446 * error occurs.1447 *1448 * @param hDbgMod The module handle.1449 */1450 1323 RTDECL(uint32_t) RTDbgModSymbolCount(RTDBGMOD hDbgMod) 1451 1324 { … … 1462 1335 1463 1336 1464 /**1465 * Queries symbol information by ordinal number.1466 *1467 * @returns IPRT status code.1468 * @retval VERR_SYMBOL_NOT_FOUND if there is no symbol at the given number.1469 * @retval VERR_DBG_NO_SYMBOLS if there aren't any symbols.1470 * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.1471 * @retval VERR_NOT_SUPPORTED if lookup by ordinal is not supported.1472 *1473 * @param hDbgMod The module handle.1474 * @param iOrdinal The symbol ordinal number. 0-based. The highest1475 * number is RTDbgModSymbolCount() - 1.1476 * @param pSymInfo Where to store the symbol information.1477 */1478 1337 RTDECL(int) RTDbgModSymbolByOrdinal(RTDBGMOD hDbgMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo) 1479 1338 { … … 1490 1349 1491 1350 1492 /**1493 * Queries symbol information by ordinal number.1494 *1495 * @returns IPRT status code.1496 * @retval VERR_DBG_NO_SYMBOLS if there aren't any symbols.1497 * @retval VERR_NOT_SUPPORTED if lookup by ordinal is not supported.1498 * @retval VERR_SYMBOL_NOT_FOUND if there is no symbol at the given number.1499 * @retval VERR_NO_MEMORY if RTDbgSymbolAlloc fails.1500 *1501 * @param hDbgMod The module handle.1502 * @param iOrdinal The symbol ordinal number. 0-based. The highest1503 * number is RTDbgModSymbolCount() - 1.1504 * @param ppSymInfo Where to store the pointer to the returned1505 * symbol information. Always set. Free with1506 * RTDbgSymbolFree.1507 */1508 1351 RTDECL(int) RTDbgModSymbolByOrdinalA(RTDBGMOD hDbgMod, uint32_t iOrdinal, PRTDBGSYMBOL *ppSymInfo) 1509 1352 { … … 1526 1369 1527 1370 1528 /**1529 * Queries symbol information by address.1530 *1531 * The returned symbol is what the debug info interpreter considers the symbol1532 * most applicable to the specified address. This usually means a symbol with an1533 * address equal or lower than the requested.1534 *1535 * @returns IPRT status code.1536 * @retval VERR_SYMBOL_NOT_FOUND if no suitable symbol was found.1537 * @retval VERR_DBG_NO_SYMBOLS if there aren't any symbols.1538 * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.1539 * @retval VERR_DBG_INVALID_RVA if an image relative address is specified and1540 * it's not inside any of the segments defined by the module.1541 * @retval VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.1542 * @retval VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the1543 * end of the segment.1544 * @retval VERR_INVALID_PARAMETER if incorrect flags.1545 *1546 * @param hDbgMod The module handle.1547 * @param iSeg The segment number.1548 * @param off The offset into the segment.1549 * @param fFlags Symbol search flags, see RTDBGSYMADDR_FLAGS_XXX.1550 * @param poffDisp Where to store the distance between the1551 * specified address and the returned symbol.1552 * Optional.1553 * @param pSymInfo Where to store the symbol information.1554 */1555 1371 RTDECL(int) RTDbgModSymbolByAddr(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags, 1556 1372 PRTINTPTR poffDisp, PRTDBGSYMBOL pSymInfo) … … 1591 1407 1592 1408 1593 /**1594 * Queries symbol information by address.1595 *1596 * The returned symbol is what the debug info interpreter considers the symbol1597 * most applicable to the specified address. This usually means a symbol with an1598 * address equal or lower than the requested.1599 *1600 * @returns IPRT status code.1601 * @retval VERR_SYMBOL_NOT_FOUND if no suitable symbol was found.1602 * @retval VERR_DBG_NO_SYMBOLS if there aren't any symbols.1603 * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.1604 * @retval VERR_DBG_INVALID_RVA if an image relative address is specified and1605 * it's not inside any of the segments defined by the module.1606 * @retval VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.1607 * @retval VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the1608 * end of the segment.1609 * @retval VERR_NO_MEMORY if RTDbgSymbolAlloc fails.1610 * @retval VERR_INVALID_PARAMETER if incorrect flags.1611 *1612 * @param hDbgMod The module handle.1613 * @param iSeg The segment index.1614 * @param off The offset into the segment.1615 * @param fFlags Symbol search flags, see RTDBGSYMADDR_FLAGS_XXX.1616 * @param poffDisp Where to store the distance between the1617 * specified address and the returned symbol. Optional.1618 * @param ppSymInfo Where to store the pointer to the returned1619 * symbol information. Always set. Free with1620 * RTDbgSymbolFree.1621 */1622 1409 RTDECL(int) RTDbgModSymbolByAddrA(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags, 1623 1410 PRTINTPTR poffDisp, PRTDBGSYMBOL *ppSymInfo) … … 1641 1428 1642 1429 1643 /**1644 * Queries symbol information by symbol name.1645 *1646 * @returns IPRT status code.1647 * @retval VERR_DBG_NO_SYMBOLS if there aren't any symbols.1648 * @retval VERR_SYMBOL_NOT_FOUND if no suitable symbol was found.1649 * @retval VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE if the symbol name is too long or1650 * short.1651 *1652 * @param hDbgMod The module handle.1653 * @param pszSymbol The symbol name.1654 * @param pSymInfo Where to store the symbol information.1655 */1656 1430 RTDECL(int) RTDbgModSymbolByName(RTDBGMOD hDbgMod, const char *pszSymbol, PRTDBGSYMBOL pSymInfo) 1657 1431 { … … 1679 1453 1680 1454 1681 /**1682 * Queries symbol information by symbol name.1683 *1684 * @returns IPRT status code.1685 * @retval VERR_DBG_NO_SYMBOLS if there aren't any symbols.1686 * @retval VERR_SYMBOL_NOT_FOUND if no suitable symbol was found.1687 * @retval VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE if the symbol name is too long or1688 * short.1689 * @retval VERR_NO_MEMORY if RTDbgSymbolAlloc fails.1690 *1691 * @param hDbgMod The module handle.1692 * @param pszSymbol The symbol name.1693 * @param ppSymInfo Where to store the pointer to the returned1694 * symbol information. Always set. Free with1695 * RTDbgSymbolFree.1696 */1697 1455 RTDECL(int) RTDbgModSymbolByNameA(RTDBGMOD hDbgMod, const char *pszSymbol, PRTDBGSYMBOL *ppSymInfo) 1698 1456 { … … 1715 1473 1716 1474 1717 /**1718 * Adds a line number to the module.1719 *1720 * @returns IPRT status code.1721 * @retval VERR_NOT_SUPPORTED if the module interpret doesn't support adding1722 * custom symbols. This should be consider a normal response.1723 * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.1724 * @retval VERR_DBG_FILE_NAME_OUT_OF_RANGE if the file name is too longer or1725 * empty.1726 * @retval VERR_DBG_INVALID_RVA if an image relative address is specified and1727 * it's not inside any of the segments defined by the module.1728 * @retval VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.1729 * @retval VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the1730 * end of the segment.1731 * @retval VERR_INVALID_PARAMETER if the line number flags sets undefined bits.1732 *1733 * @param hDbgMod The module handle.1734 * @param pszFile The file name.1735 * @param uLineNo The line number.1736 * @param iSeg The segment index.1737 * @param off The segment offset.1738 * @param piOrdinal Where to return the line number ordinal on1739 * success. If the interpreter doesn't do ordinals,1740 * this will be set to UINT32_MAX. Optional.1741 */1742 1475 RTDECL(int) RTDbgModLineAdd(RTDBGMOD hDbgMod, const char *pszFile, uint32_t uLineNo, 1743 1476 RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t *piOrdinal) … … 1784 1517 1785 1518 1786 /**1787 * Gets the line number count.1788 *1789 * This can be used together wtih RTDbgModLineByOrdinal or RTDbgModSymbolByLineA1790 * to enumerate all the line number information.1791 *1792 * @returns The number of line numbers in the module.1793 * UINT32_MAX is returned if the module handle is invalid or some other1794 * error occurs.1795 *1796 * @param hDbgMod The module handle.1797 */1798 1519 RTDECL(uint32_t) RTDbgModLineCount(RTDBGMOD hDbgMod) 1799 1520 { … … 1810 1531 1811 1532 1812 /**1813 * Queries line number information by ordinal number.1814 *1815 * This can be used to enumerate the line numbers for the module. Use1816 * RTDbgModLineCount() to figure the end of the ordinals.1817 *1818 * @returns IPRT status code.1819 * @retval VERR_DBG_NO_LINE_NUMBERS if there aren't any line numbers.1820 * @retval VERR_DBG_LINE_NOT_FOUND if there is no line number with that1821 * ordinal.1822 * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.1823 1824 * @param hDbgMod The module handle.1825 * @param iOrdinal The line number ordinal number.1826 * @param pLineInfo Where to store the information about the line1827 * number.1828 */1829 1533 RTDECL(int) RTDbgModLineByOrdinal(RTDBGMOD hDbgMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo) 1830 1534 { … … 1841 1545 1842 1546 1843 /**1844 * Queries line number information by ordinal number.1845 *1846 * This can be used to enumerate the line numbers for the module. Use1847 * RTDbgModLineCount() to figure the end of the ordinals.1848 *1849 * @returns IPRT status code.1850 * @retval VERR_DBG_NO_LINE_NUMBERS if there aren't any line numbers.1851 * @retval VERR_DBG_LINE_NOT_FOUND if there is no line number with that1852 * ordinal.1853 * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.1854 * @retval VERR_NO_MEMORY if RTDbgLineAlloc fails.1855 *1856 * @param hDbgMod The module handle.1857 * @param iOrdinal The line number ordinal number.1858 * @param ppLineInfo Where to store the pointer to the returned line1859 * number information. Always set. Free with1860 * RTDbgLineFree.1861 */1862 1547 RTDECL(int) RTDbgModLineByOrdinalA(RTDBGMOD hDbgMod, uint32_t iOrdinal, PRTDBGLINE *ppLineInfo) 1863 1548 { … … 1880 1565 1881 1566 1882 /**1883 * Queries line number information by address.1884 *1885 * The returned line number is what the debug info interpreter considers the1886 * one most applicable to the specified address. This usually means a line1887 * number with an address equal or lower than the requested.1888 *1889 * @returns IPRT status code.1890 * @retval VERR_DBG_NO_LINE_NUMBERS if there aren't any line numbers.1891 * @retval VERR_DBG_LINE_NOT_FOUND if no suitable line number was found.1892 * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.1893 * @retval VERR_DBG_INVALID_RVA if an image relative address is specified and1894 * it's not inside any of the segments defined by the module.1895 * @retval VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.1896 * @retval VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the1897 * end of the segment.1898 *1899 * @param hDbgMod The module handle.1900 * @param iSeg The segment number.1901 * @param off The offset into the segment.1902 * @param poffDisp Where to store the distance between the1903 * specified address and the returned symbol.1904 * Optional.1905 * @param pLineInfo Where to store the line number information.1906 */1907 1567 RTDECL(int) RTDbgModLineByAddr(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTINTPTR poffDisp, PRTDBGLINE pLineInfo) 1908 1568 { … … 1938 1598 1939 1599 1940 /**1941 * Queries line number information by address.1942 *1943 * The returned line number is what the debug info interpreter considers the1944 * one most applicable to the specified address. This usually means a line1945 * number with an address equal or lower than the requested.1946 *1947 * @returns IPRT status code.1948 * @retval VERR_DBG_NO_LINE_NUMBERS if there aren't any line numbers.1949 * @retval VERR_DBG_LINE_NOT_FOUND if no suitable line number was found.1950 * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.1951 * @retval VERR_DBG_INVALID_RVA if an image relative address is specified and1952 * it's not inside any of the segments defined by the module.1953 * @retval VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.1954 * @retval VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the1955 * end of the segment.1956 * @retval VERR_NO_MEMORY if RTDbgLineAlloc fails.1957 *1958 * @param hDbgMod The module handle.1959 * @param iSeg The segment number.1960 * @param off The offset into the segment.1961 * @param poffDisp Where to store the distance between the1962 * specified address and the returned symbol.1963 * Optional.1964 * @param ppLineInfo Where to store the pointer to the returned line1965 * number information. Always set. Free with1966 * RTDbgLineFree.1967 */1968 1600 RTDECL(int) RTDbgModLineByAddrA(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTINTPTR poffDisp, PRTDBGLINE *ppLineInfo) 1969 1601 { -
trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp
r46083 r46101 90 90 /** Size of the header (IMAGE_OPTIONAL_HEADER32::SizeOfHeaders). */ 91 91 uint32_t cbHeaders; 92 /** The image timestamp. */ 93 uint32_t uTimestamp; 92 94 /** The import data directory entry. */ 93 95 IMAGE_DATA_DIRECTORY ImportDir; … … 135 137 static void rtldrPEConvert32BitOptionalHeaderTo64Bit(PIMAGE_OPTIONAL_HEADER64 pOptHdr); 136 138 static void rtldrPEConvert32BitLoadConfigTo64Bit(PIMAGE_LOAD_CONFIG_DIRECTORY64 pLoadCfg); 137 static int rtldrPEApplyFixups(PRTLDRMODPE pModPe, const void *pvBitsR, void *pvBitsW, RTUINTPTR BaseAddress, RTUINTPTR OldBaseAddress); 139 static int rtldrPEApplyFixups(PRTLDRMODPE pModPe, const void *pvBitsR, void *pvBitsW, RTUINTPTR BaseAddress, RTUINTPTR OldBaseAddress); 140 141 142 143 /** 144 * Reads a section of a PE image given by RVA + size, using mapped bits if 145 * available or allocating heap memory and reading from the file. 146 * 147 * @returns IPRT status code. 148 * @param pThis Pointer to the PE loader module structure. 149 * @param pvBits Read only bits if available. NULL if not. 150 * @param uRva The RVA to read at. 151 * @param cbMem The number of bytes to read. 152 * @param ppvMem Where to return the memory on success (heap or 153 * inside pvBits). 154 */ 155 static int rtldrPEReadPartByRva(PRTLDRMODPE pThis, const void *pvBits, uint32_t uRva, uint32_t cbMem, void const **ppvMem) 156 { 157 *ppvMem = NULL; 158 if (!cbMem) 159 return VINF_SUCCESS; 160 161 /* 162 * Use bits if we've got some. 163 */ 164 if (pvBits) 165 { 166 *ppvMem = (uint8_t const *)pvBits + uRva; 167 return VINF_SUCCESS; 168 } 169 if (pThis->pvBits) 170 { 171 *ppvMem = (uint8_t const *)pThis->pvBits + uRva; 172 return VINF_SUCCESS; 173 } 174 175 /* 176 * Allocate a buffer and read the bits from the file (or whatever). 177 */ 178 if (!pThis->Core.pReader) 179 return VERR_ACCESS_DENIED; 180 181 uint8_t *pbMem = (uint8_t *)RTMemAllocZ(cbMem); 182 if (!pbMem) 183 return VERR_NO_MEMORY; 184 *ppvMem = pbMem; 185 186 /* Do the reading on a per section base. */ 187 RTFOFF const cbFile = pThis->Core.pReader->pfnSize(pThis->Core.pReader); 188 for (;;) 189 { 190 /* Translate the RVA into a file offset. */ 191 uint32_t offFile = uRva; 192 uint32_t cbToRead = cbMem; 193 uint32_t cbToAdv = cbMem; 194 195 if (uRva < pThis->paSections[0].VirtualAddress) 196 { 197 /* Special header section. */ 198 cbToRead = pThis->paSections[0].VirtualAddress - uRva; 199 if (cbToRead > cbMem) 200 cbToRead = cbMem; 201 cbToAdv = cbToRead; 202 203 /* The following capping is an approximation. */ 204 uint32_t offFirstRawData = RT_ALIGN(pThis->cbHeaders, _4K); 205 if ( pThis->paSections[0].PointerToRawData > 0 206 && pThis->paSections[0].SizeOfRawData > 0) 207 offFirstRawData = pThis->paSections[0].PointerToRawData; 208 if (offFile > offFirstRawData) 209 cbToRead = 0; 210 else if (offFile + cbToRead > offFirstRawData) 211 cbToRead = offFile + cbToRead - offFirstRawData; 212 } 213 else 214 { 215 /* Find the matching section and its mapping size. */ 216 uint32_t j = 0; 217 uint32_t cbMapping = 0; 218 while (j < pThis->cSections) 219 { 220 cbMapping = (j + 1 < pThis->cSections ? pThis->paSections[j + 1].VirtualAddress : pThis->cbImage) 221 - pThis->paSections[j].VirtualAddress; 222 if (uRva - pThis->paSections[j].VirtualAddress < cbMapping) 223 break; 224 j++; 225 } 226 if (j >= cbMapping) 227 break; /* This shouldn't happen, just return zeros if it does. */ 228 229 /* Adjust the sizes and calc the file offset. */ 230 if (cbToAdv > cbMapping) 231 cbToAdv = cbToRead = cbMapping; 232 if ( pThis->paSections[j].PointerToRawData > 0 233 && pThis->paSections[j].SizeOfRawData > 0) 234 { 235 offFile = uRva - pThis->paSections[j].VirtualAddress; 236 if (offFile + cbToRead > pThis->paSections[j].SizeOfRawData) 237 cbToRead = pThis->paSections[j].SizeOfRawData - offFile; 238 offFile += pThis->paSections[j].PointerToRawData; 239 } 240 else 241 { 242 offFile = -1; 243 cbToRead = 0; 244 } 245 } 246 247 /* Perform the read after adjusting a little (paranoia). */ 248 if (offFile > cbFile) 249 cbToRead = 0; 250 if (cbToRead) 251 { 252 if ((RTFOFF)offFile + cbToRead > cbFile) 253 cbToRead = cbFile - (RTFOFF)offFile; 254 int rc = pThis->Core.pReader->pfnRead(pThis->Core.pReader, pbMem, cbToRead, offFile); 255 if (RT_FAILURE(rc)) 256 { 257 RTMemFree((void *)*ppvMem); 258 *ppvMem = NULL; 259 return rc; 260 } 261 } 262 263 /* Advance */ 264 if (cbMem == cbToRead) 265 break; 266 cbMem -= cbToRead; 267 pbMem += cbToRead; 268 uRva += cbToRead; 269 } 270 271 return VINF_SUCCESS; 272 } 273 274 275 /** 276 * Reads a part of a PE file from the file and into a heap block. 277 * 278 * @returns IRPT status code. 279 * @param pThis Pointer to the PE loader module structure.. 280 * @param offFile The file offset. 281 * @param cbMem The number of bytes to read. 282 * @param ppvMem Where to return the heap block with the bytes on 283 * success. 284 */ 285 static int rtldrPEReadPartFromFile(PRTLDRMODPE pThis, uint32_t offFile, uint32_t cbMem, void const **ppvMem) 286 { 287 *ppvMem = NULL; 288 if (!cbMem) 289 return VINF_SUCCESS; 290 291 /* 292 * Allocate a buffer and read the bits from the file (or whatever). 293 */ 294 if (!pThis->Core.pReader) 295 return VERR_ACCESS_DENIED; 296 297 uint8_t *pbMem = (uint8_t *)RTMemAlloc(cbMem); 298 if (!pbMem) 299 return VERR_NO_MEMORY; 300 301 int rc = pThis->Core.pReader->pfnRead(pThis->Core.pReader, pbMem, cbMem, offFile); 302 if (RT_FAILURE(rc)) 303 { 304 RTMemFree((void *)*ppvMem); 305 return rc; 306 } 307 308 *ppvMem = pbMem; 309 return VINF_SUCCESS; 310 } 311 312 313 /** 314 * Reads a part of a PE image into memory one way or another. 315 * 316 * Either the RVA or the offFile must be valid. We'll prefer the RVA if 317 * possible. 318 * 319 * @returns IPRT status code. 320 * @param pThis Pointer to the PE loader module structure. 321 * @param pvBits Read only bits if available. NULL if not. 322 * @param uRva The RVA to read at. 323 * @param offFile The file offset. 324 * @param cbMem The number of bytes to read. 325 * @param ppvMem Where to return the memory on success (heap or 326 * inside pvBits). 327 */ 328 static int rtldrPEReadPart(PRTLDRMODPE pThis, const void *pvBits, RTFOFF offFile, RTLDRADDR uRva, 329 uint32_t cbMem, void const **ppvMem) 330 { 331 if (uRva == NIL_RTLDRADDR || uRva > pThis->cbImage) 332 { 333 if (offFile < 0) 334 return VERR_INVALID_PARAMETER; 335 return rtldrPEReadPartFromFile(pThis, offFile, cbMem, ppvMem); 336 } 337 return rtldrPEReadPartByRva(pThis, pvBits, uRva, cbMem, ppvMem); 338 } 339 340 341 /** 342 * Frees up memory returned by rtldrPEReadPart*. 343 * 344 * @param pThis Pointer to the PE loader module structure.. 345 * @param pvBits Read only bits if available. NULL if not.. 346 * @param pvMem The memory we were given by the reader method. 347 */ 348 static void rtldrPEFreePart(PRTLDRMODPE pThis, const void *pvBits, void const *pvMem) 349 { 350 if (!pvMem) 351 return; 352 353 if (pvBits && (uintptr_t)pvBits - (uintptr_t)pvMem < pThis->cbImage) 354 return; 355 if (pThis->pvBits && (uintptr_t)pThis->pvBits - (uintptr_t)pvMem < pThis->cbImage) 356 return; 357 358 RTMemFree((void *)pvMem); 359 } 138 360 139 361 … … 788 1010 789 1011 /* 790 * No bits supplied? Do we need to read the bits?1012 * Get the debug directory. 791 1013 */ 792 1014 if (!pvBits) 793 {794 if (!pModPe->pvBits)795 {796 rc = rtldrPEReadBits(pModPe);797 if (RT_FAILURE(rc))798 return rc;799 }800 1015 pvBits = pModPe->pvBits; 801 } 1016 1017 PCIMAGE_DEBUG_DIRECTORY paDbgDir; 1018 int rcRet = rtldrPEReadPartByRva(pModPe, pvBits, pModPe->DebugDir.VirtualAddress, pModPe->DebugDir.Size, 1019 (void const **)&paDbgDir); 1020 if (RT_FAILURE(rcRet)) 1021 return rcRet; 802 1022 803 1023 /* 804 1024 * Enumerate the debug directory. 805 1025 */ 806 PCIMAGE_DEBUG_DIRECTORY paDbgDir = PE_RVA2TYPE(pvBits, pModPe->DebugDir.VirtualAddress, PCIMAGE_DEBUG_DIRECTORY); 807 int rcRet = VINF_SUCCESS; 808 uint32_t const cEntries = pModPe->DebugDir.Size / sizeof(paDbgDir[0]); 1026 uint32_t const cEntries = pModPe->DebugDir.Size / sizeof(paDbgDir[0]); 809 1027 for (uint32_t i = 0; i < cEntries; i++) 810 1028 { … … 814 1032 continue; 815 1033 816 char szPath[RTPATH_MAX]; 817 RTLDRDBGINFO DbgInfo; 1034 void const *pvPart = NULL; 1035 char szPath[RTPATH_MAX]; 1036 RTLDRDBGINFO DbgInfo; 818 1037 RT_ZERO(DbgInfo.u); 819 1038 DbgInfo.iDbgInfo = i; … … 825 1044 DbgInfo.pszExtFile = NULL; 826 1045 1046 rc = VINF_SUCCESS; 827 1047 switch (paDbgDir[i].Type) 828 1048 { … … 834 1054 if ( paDbgDir[i].SizeOfData < sizeof(szPath) 835 1055 && paDbgDir[i].SizeOfData > 16 836 && DbgInfo.LinkAddress != NIL_RTLDRADDR) 1056 && ( DbgInfo.LinkAddress != NIL_RTLDRADDR 1057 || DbgInfo.offFile > 0) 1058 ) 837 1059 { 838 PCCVPDB20INFO pCv20 = PE_RVA2TYPE(pvBits, DbgInfo.LinkAddress, PCCVPDB20INFO); 839 if ( pCv20->u32Magic == CVPDB20INFO_MAGIC 840 && pCv20->offDbgInfo == 0 841 && paDbgDir[i].SizeOfData > RT_UOFFSETOF(CVPDB20INFO, szPdbFilename) ) 1060 rc = rtldrPEReadPart(pModPe, pvBits, DbgInfo.offFile, DbgInfo.LinkAddress, paDbgDir[i].SizeOfData, &pvPart); 1061 if (RT_SUCCESS(rc)) 842 1062 { 843 DbgInfo.enmType = RTLDRDBGINFOTYPE_CODEVIEW_PDB20; 844 DbgInfo.u.Pdb20.cbImage = pModPe->cbImage; 845 DbgInfo.u.Pdb20.uTimestamp = pCv20->uTimestamp; 846 DbgInfo.u.Pdb20.uAge = pCv20->uAge; 847 DbgInfo.pszExtFile = (const char *)&pCv20->szPdbFilename[0]; 1063 PCCVPDB20INFO pCv20 = (PCCVPDB20INFO)pvPart; 1064 if ( pCv20->u32Magic == CVPDB20INFO_MAGIC 1065 && pCv20->offDbgInfo == 0 1066 && paDbgDir[i].SizeOfData > RT_UOFFSETOF(CVPDB20INFO, szPdbFilename) ) 1067 { 1068 DbgInfo.enmType = RTLDRDBGINFOTYPE_CODEVIEW_PDB20; 1069 DbgInfo.u.Pdb20.cbImage = pModPe->cbImage; 1070 DbgInfo.u.Pdb20.uTimestamp = pCv20->uTimestamp; 1071 DbgInfo.u.Pdb20.uAge = pCv20->uAge; 1072 DbgInfo.pszExtFile = (const char *)&pCv20->szPdbFilename[0]; 1073 } 1074 else if ( pCv20->u32Magic == CVPDB70INFO_MAGIC 1075 && paDbgDir[i].SizeOfData > RT_UOFFSETOF(CVPDB70INFO, szPdbFilename) ) 1076 { 1077 PCCVPDB70INFO pCv70 = (PCCVPDB70INFO)pCv20; 1078 DbgInfo.enmType = RTLDRDBGINFOTYPE_CODEVIEW_PDB70; 1079 DbgInfo.u.Pdb70.cbImage = pModPe->cbImage; 1080 DbgInfo.u.Pdb70.Uuid = pCv70->PdbUuid; 1081 DbgInfo.u.Pdb70.uAge = pCv70->uAge; 1082 DbgInfo.pszExtFile = (const char *)&pCv70->szPdbFilename[0]; 1083 } 848 1084 } 849 else if ( pCv20->u32Magic == CVPDB70INFO_MAGIC 850 && paDbgDir[i].SizeOfData > RT_UOFFSETOF(CVPDB70INFO, szPdbFilename) ) 851 { 852 PCCVPDB70INFO pCv70 = (PCCVPDB70INFO)pCv20; 853 DbgInfo.enmType = RTLDRDBGINFOTYPE_CODEVIEW_PDB70; 854 DbgInfo.u.Pdb70.cbImage = pModPe->cbImage; 855 DbgInfo.u.Pdb70.Uuid = pCv70->PdbUuid; 856 DbgInfo.u.Pdb70.uAge = pCv70->uAge; 857 DbgInfo.pszExtFile = (const char *)&pCv70->szPdbFilename[0]; 858 } 1085 else 1086 rcRet = rc; 859 1087 } 860 1088 break; 861 1089 862 1090 case IMAGE_DEBUG_TYPE_MISC: 1091 DbgInfo.enmType = RTLDRDBGINFOTYPE_UNKNOWN; 863 1092 if ( paDbgDir[i].SizeOfData < sizeof(szPath) 864 && paDbgDir[i].SizeOfData > RT_UOFFSETOF(IMAGE_DEBUG_MISC, Data) 865 && DbgInfo.LinkAddress != NIL_RTLDRADDR) 1093 && paDbgDir[i].SizeOfData > RT_UOFFSETOF(IMAGE_DEBUG_MISC, Data)) 866 1094 { 867 PCIMAGE_DEBUG_MISC pMisc = PE_RVA2TYPE(pvBits, DbgInfo.LinkAddress, PCIMAGE_DEBUG_MISC); 868 if ( pMisc->DataType == IMAGE_DEBUG_MISC_EXENAME 869 && pMisc->Length == paDbgDir[i].SizeOfData) 1095 DbgInfo.enmType = RTLDRDBGINFOTYPE_CODEVIEW_DBG; 1096 DbgInfo.u.Dbg.cbImage = pModPe->cbImage; 1097 if (DbgInfo.LinkAddress != NIL_RTLDRADDR) 1098 DbgInfo.u.Dbg.uTimestamp = paDbgDir[i].TimeDateStamp; 1099 else 1100 DbgInfo.u.Dbg.uTimestamp = pModPe->uTimestamp; /* NT4 SP1 ntfs.sys hack. Generic? */ 1101 1102 rc = rtldrPEReadPart(pModPe, pvBits, DbgInfo.offFile, DbgInfo.LinkAddress, paDbgDir[i].SizeOfData, &pvPart); 1103 if (RT_SUCCESS(rc)) 870 1104 { 871 if (!pMisc->Unicode)872 DbgInfo.pszExtFile = (const char *)&pMisc->Data[0];873 else1105 PCIMAGE_DEBUG_MISC pMisc = (PCIMAGE_DEBUG_MISC)pvPart; 1106 if ( pMisc->DataType == IMAGE_DEBUG_MISC_EXENAME 1107 && pMisc->Length == paDbgDir[i].SizeOfData) 874 1108 { 875 char *pszPath = szPath; 876 rc = RTUtf16ToUtf8Ex((PCRTUTF16)&pMisc->Data[0], 877 (pMisc->Length - RT_OFFSETOF(IMAGE_DEBUG_MISC, Data)) / sizeof(RTUTF16), 878 &pszPath, sizeof(szPath), NULL); 879 if (RT_FAILURE(rc)) 1109 if (!pMisc->Unicode) 1110 DbgInfo.pszExtFile = (const char *)&pMisc->Data[0]; 1111 else 880 1112 { 881 rcRet = rc; 882 continue; 1113 char *pszPath = szPath; 1114 rc = RTUtf16ToUtf8Ex((PCRTUTF16)&pMisc->Data[0], 1115 (pMisc->Length - RT_OFFSETOF(IMAGE_DEBUG_MISC, Data)) / sizeof(RTUTF16), 1116 &pszPath, sizeof(szPath), NULL); 1117 if (RT_SUCCESS(rc)) 1118 DbgInfo.pszExtFile = szPath; 1119 else 1120 rcRet = rc; /* continue without a filename. */ 883 1121 } 884 DbgInfo.pszExtFile = szPath;885 1122 } 886 DbgInfo.enmType = RTLDRDBGINFOTYPE_CODEVIEW_DBG;887 DbgInfo.u.Dbg.cbImage = pModPe->cbImage;888 DbgInfo.u.Dbg.uTimestamp = paDbgDir[i].TimeDateStamp;889 1123 } 1124 else 1125 rcRet = rc; /* continue without a filename. */ 890 1126 } 891 1127 break; … … 910 1146 { 911 1147 rcRet = rc; 912 continue;1148 DbgInfo.pszExtFile = NULL; 913 1149 } 914 1150 } … … 917 1153 918 1154 rc = pfnCallback(pMod, &DbgInfo, pvUser); 1155 rtldrPEFreePart(pModPe, pvBits, pvPart); 919 1156 if (rc != VINF_SUCCESS) 920 return rc; 921 } 1157 { 1158 rcRet = rc; 1159 break; 1160 } 1161 } 1162 1163 rtldrPEFreePart(pModPe, pvBits, paDbgDir); 922 1164 return rcRet; 923 1165 } … … 1330 1572 * @param pFileHdr Pointer to the file header (valid). 1331 1573 * @param cbRawImage The raw image size. 1574 * @param fFlags Loader flags. 1332 1575 */ 1333 1576 static int rtldrPEValidateOptionalHeader(const IMAGE_OPTIONAL_HEADER64 *pOptHdr, const char *pszLogName, RTFOFF offNtHdrs, 1334 const IMAGE_FILE_HEADER *pFileHdr, RTFOFF cbRawImage )1577 const IMAGE_FILE_HEADER *pFileHdr, RTFOFF cbRawImage, uint32_t fFlags) 1335 1578 { 1336 1579 const uint16_t CorrectMagic = pFileHdr->SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32) … … 1487 1730 return VERR_BAD_EXE_FORMAT; 1488 1731 } 1489 if (pDir->Size > cb - pDir->VirtualAddress) 1732 if ( pDir->Size > cb - pDir->VirtualAddress 1733 && !(fFlags & RTLDR_O_FOR_DEBUG) /* NT4 SP1 ntfs.sys base relocs. */ ) 1490 1734 { 1491 1735 Log(("rtldrPEOpen: %s: dir no. %d Size=%#x is invalid (rva=%#x, limit=%#x)!!!\n", … … 1858 2102 if (FileHdr.SizeOfOptionalHeader != sizeof(OptHdr)) 1859 2103 rtldrPEConvert32BitOptionalHeaderTo64Bit(&OptHdr); 1860 rc = rtldrPEValidateOptionalHeader(&OptHdr, pszLogName, offNtHdrs, &FileHdr, pReader->pfnSize(pReader) );2104 rc = rtldrPEValidateOptionalHeader(&OptHdr, pszLogName, offNtHdrs, &FileHdr, pReader->pfnSize(pReader), fFlags); 1861 2105 if (RT_FAILURE(rc)) 1862 2106 return rc; … … 1901 2145 pModPe->cbImage = OptHdr.SizeOfImage; 1902 2146 pModPe->cbHeaders = OptHdr.SizeOfHeaders; 2147 pModPe->uTimestamp = FileHdr.TimeDateStamp; 1903 2148 pModPe->ImportDir = OptHdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; 1904 2149 pModPe->RelocDir = OptHdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; -
trunk/src/VBox/Runtime/common/string/strcache.cpp
r44529 r46101 167 167 168 168 169 RTDECL(const char *) RTStrCacheEnterLowerN(RTSTRCACHE hStrCache, const char *pchString, size_t cchString) 170 { 171 AssertPtr(pchString); 172 AssertReturn(cchString < _1G, NULL); 173 Assert(!RTStrEnd(pchString, cchString)); 174 175 char *pszRet = (char *)RTMemPoolDupEx((RTMEMPOOL)hStrCache, pchString, cchString, 1); 176 if (!pszRet) 177 RTStrToLower(pszRet); 178 return pszRet; 179 } 180 RT_EXPORT_SYMBOL(RTStrCacheEnterLowerN); 181 182 183 RTDECL(const char *) RTStrCacheEnterLower(RTSTRCACHE hStrCache, const char *psz) 184 { 185 return RTStrCacheEnterLowerN(hStrCache, psz, strlen(psz)); 186 } 187 RT_EXPORT_SYMBOL(RTStrCacheEnterLower); 188 189 169 190 RTDECL(uint32_t) RTStrCacheRetain(const char *psz) 170 191 { -
trunk/src/VBox/Runtime/generic/strcache-stubs-generic.cpp
r44529 r46101 78 78 79 79 80 RTDECL(const char *) RTStrCacheEnterLowerN(RTSTRCACHE hStrCache, const char *pchString, size_t cchString) 81 { 82 AssertPtr(pchString); 83 AssertReturn(cchString < _1G, NULL); 84 Assert(!RTStrEnd(pchString, cchString)); 85 86 char *pszRet = (char *)RTMemPoolDupEx((RTMEMPOOL)hStrCache, pchString, cchString, 1); 87 if (!pszRet) 88 RTStrToLower(pszRet); 89 return pszRet; 90 } 91 RT_EXPORT_SYMBOL(RTStrCacheEnterLowerN); 92 93 94 RTDECL(const char *) RTStrCacheEnterLower(RTSTRCACHE hStrCache, const char *psz) 95 { 96 return RTStrCacheEnterLowerN(hStrCache, psz, strlen(psz)); 97 } 98 RT_EXPORT_SYMBOL(RTStrCacheEnterLower); 99 100 80 101 RTDECL(uint32_t) RTStrCacheRetain(const char *psz) 81 102 { -
trunk/src/VBox/Runtime/include/internal/dbgmod.h
r46083 r46101 529 529 /** The module name (short). */ 530 530 char const *pszName; 531 /** The image file specified by the user. Can be NULL. */ 532 char const *pszImgFileSpecified; 531 533 /** The module filename. Can be NULL. */ 532 534 char const *pszImgFile; -
trunk/src/VBox/Runtime/include/internal/ldrPE.h
r46048 r46101 5 5 6 6 /* 7 * Copyright (C) 2006-201 0Oracle Corporation7 * Copyright (C) 2006-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 29 29 30 30 #include <iprt/types.h> 31 32 #pragma pack(4) 31 #include <iprt/assert.h> 32 33 #pragma pack(4) /** @todo Necessary? */ 33 34 34 35 … … 222 223 uint16_t Characteristics; 223 224 } IMAGE_FILE_HEADER; 225 AssertCompileSize(IMAGE_FILE_HEADER, 2+2+4+4+4+2+2); 224 226 typedef IMAGE_FILE_HEADER *PIMAGE_FILE_HEADER; 225 227 typedef IMAGE_FILE_HEADER const *PCIMAGE_FILE_HEADER; … … 315 317 IMAGE_OPTIONAL_HEADER32 OptionalHeader; 316 318 } IMAGE_NT_HEADERS32; 319 AssertCompileMemberOffset(IMAGE_NT_HEADERS32, FileHeader, 4); 320 AssertCompileMemberOffset(IMAGE_NT_HEADERS32, OptionalHeader, 24); 317 321 typedef IMAGE_NT_HEADERS32 *PIMAGE_NT_HEADERS32; 318 322 typedef IMAGE_NT_HEADERS32 const *PCIMAGE_NT_HEADERS32; … … 324 328 IMAGE_OPTIONAL_HEADER64 OptionalHeader; 325 329 } IMAGE_NT_HEADERS64; 330 AssertCompileMemberOffset(IMAGE_NT_HEADERS64, FileHeader, 4); 331 AssertCompileMemberOffset(IMAGE_NT_HEADERS64, OptionalHeader, 24); 326 332 typedef IMAGE_NT_HEADERS64 *PIMAGE_NT_HEADERS64; 327 333 typedef IMAGE_NT_HEADERS64 const *PCIMAGE_NT_HEADERS64;
Note:
See TracChangeset
for help on using the changeset viewer.