Changeset 45994 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- May 12, 2013 7:16:16 PM (12 years ago)
- Location:
- trunk/src/VBox/Runtime/common
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/dbg/dbgcfg.cpp
r45988 r45994 124 124 125 125 126 126 127 /******************************************************************************* 127 128 * Defined Constants And Macros * … … 158 159 159 160 161 RTDECL(int) RTDbgCfgOpenPeImage(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t cbImage, uint32_t uTimestamp, 162 PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 163 { 164 int rc = pfnCallback(hDbgCfg, pszFilename, pvUser1, pvUser2); 165 if (rc == VINF_CALLBACK_RETURN || rc == VERR_CALLBACK_RETURN) 166 return rc; 167 168 return rc; 169 } 170 171 RTDECL(int) RTDbgCfgOpenPdb70(RTDBGCFG hDbgCfg, const char *pszFilename, PCRTUUID pUuid, uint32_t uAge, 172 PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 173 { 174 int rc = pfnCallback(hDbgCfg, pszFilename, pvUser1, pvUser2); 175 if (rc == VINF_CALLBACK_RETURN || rc == VERR_CALLBACK_RETURN) 176 return rc; 177 178 return rc; 179 } 180 181 RTDECL(int) RTDbgCfgOpenPdb20(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t cbImage, uint32_t uTimestamp, uint32_t uAge, 182 PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 183 { 184 return VERR_NOT_IMPLEMENTED; 185 } 186 187 188 RTDECL(int) RTDbgCfgOpenDbg(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t cbImage, uint32_t uTimestamp, 189 PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 190 { 191 return VERR_NOT_IMPLEMENTED; 192 } 193 194 195 RTDECL(int) RTDbgCfgOpenDwo(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t uCrc32, 196 PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2) 197 { 198 return VERR_NOT_IMPLEMENTED; 199 } 160 200 161 201 … … 695 735 } 696 736 else if (rc != VERR_ENV_VAR_NOT_FOUND) 697 break; 737 break; 738 else 739 rc = VINF_SUCCESS; 698 740 } 699 741 RTMemTmpFree(pszEnvVar); -
trunk/src/VBox/Runtime/common/dbg/dbgmod.cpp
r45984 r45994 29 29 * Header Files * 30 30 *******************************************************************************/ 31 #define LOG_GROUP RTLOGGROUP_DBG 31 32 #include <iprt/dbg.h> 32 33 #include "internal/iprt.h" … … 37 38 #include <iprt/err.h> 38 39 #include <iprt/initterm.h> 40 #include <iprt/log.h> 39 41 #include <iprt/mem.h> 40 42 #include <iprt/once.h> … … 484 486 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName); 485 487 } 488 else 489 rc = VERR_NO_STR_MEMORY; 486 490 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile); 487 491 } 492 else 493 rc = VERR_NO_STR_MEMORY; 488 494 RTCritSectDelete(&pDbgMod->CritSect); 489 495 } … … 563 569 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName); 564 570 } 571 else 572 rc = VERR_NO_STR_MEMORY; 565 573 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszDbgFile); 566 574 } 575 else 576 rc = VERR_NO_STR_MEMORY; 567 577 RTCritSectDelete(&pDbgMod->CritSect); 568 578 } … … 572 582 } 573 583 RT_EXPORT_SYMBOL(RTDbgModCreateFromMap); 584 585 586 587 588 /* 589 * 590 * P E I M A G E 591 * P E I M A G E 592 * P E I M A G E 593 * 594 */ 595 596 597 /** 598 * Opens debug information for an image. 599 * 600 * @returns IPRT status code 601 * @param pDbgMod The debug module structure. 602 * 603 * @note This will generally not look for debug info stored in external 604 * files. rtDbgModFromPeImageExtDbgInfoCallback can help with that. 605 */ 606 static int rtDbgModOpenDebugInfoInsideImage(PRTDBGMODINT pDbgMod) 607 { 608 AssertReturn(!pDbgMod->pDbgVt, VERR_DBG_MOD_IPE); 609 AssertReturn(pDbgMod->pImgVt, VERR_DBG_MOD_IPE); 610 611 int rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT); 612 if (RT_SUCCESS(rc)) 613 { 614 for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext) 615 { 616 pDbgMod->pDbgVt = pDbg->pVt; 617 pDbgMod->pvDbgPriv = NULL; 618 rc = pDbg->pVt->pfnTryOpen(pDbgMod); 619 if (RT_SUCCESS(rc)) 620 { 621 /* 622 * That's it! 623 */ 624 ASMAtomicIncU32(&pDbg->cUsers); 625 RTSemRWReleaseRead(g_hDbgModRWSem); 626 return VINF_SUCCESS; 627 } 628 pDbgMod->pDbgVt = NULL; 629 Assert(pDbgMod->pvDbgPriv == NULL); 630 } 631 RTSemRWReleaseRead(g_hDbgModRWSem); 632 } 633 634 return VERR_DBG_NO_MATCHING_INTERPRETER; 635 } 636 637 638 /** @callback_method_impl{FNRTDBGCFGOPEN} */ 639 static DECLCALLBACK(int) rtDbgModExtDbgInfoOpenCallback(RTDBGCFG hDbgCfg, const char *pszFilename, void *pvUser1, void *pvUser2) 640 { 641 PRTDBGMODINT pDbgMod = (PRTDBGMODINT)pvUser1; 642 PCRTLDRDBGINFO pDbgInfo = (PCRTLDRDBGINFO)pvUser2; 643 NOREF(pDbgInfo); /** @todo consider a more direct search for a interpreter. */ 644 645 Assert(!pDbgMod->pDbgVt); 646 Assert(!pDbgMod->pvDbgPriv); 647 Assert(!pDbgMod->pszDbgFile); 648 649 /* 650 * Set the debug file name and try possible interpreters. 651 */ 652 pDbgMod->pszDbgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename); 653 654 int rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT); 655 if (RT_SUCCESS(rc)) 656 { 657 for (PRTDBGMODREGDBG pDbg = g_pDbgHead; pDbg; pDbg = pDbg->pNext) 658 { 659 pDbgMod->pDbgVt = pDbg->pVt; 660 pDbgMod->pvDbgPriv = NULL; 661 rc = pDbg->pVt->pfnTryOpen(pDbgMod); 662 if (RT_SUCCESS(rc)) 663 { 664 /* 665 * Got it! 666 */ 667 ASMAtomicIncU32(&pDbg->cUsers); 668 RTSemRWReleaseRead(g_hDbgModRWSem); 669 return VINF_CALLBACK_RETURN; 670 } 671 pDbgMod->pDbgVt = NULL; 672 Assert(pDbgMod->pvDbgPriv == NULL); 673 } 674 } 675 676 /* No joy. */ 677 RTSemRWReleaseRead(g_hDbgModRWSem); 678 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszDbgFile); 679 pDbgMod->pszDbgFile = NULL; 680 return rc; 681 } 682 683 684 /** 685 * Argument package used by rtDbgModOpenDebugInfoExternalToImage. 686 */ 687 typedef struct RTDBGMODOPENDIETI 688 { 689 PRTDBGMODINT pDbgMod; 690 RTDBGCFG hDbgCfg; 691 } RTDBGMODOPENDIETI; 692 693 694 /** @callback_method_impl{FNRTLDRENUMDBG} */ 695 static DECLCALLBACK(int) 696 rtDbgModOpenDebugInfoExternalToImageCallback(RTLDRMOD hLdrMod, PCRTLDRDBGINFO pDbgInfo, void *pvUser) 697 { 698 if (!pDbgInfo->pszExtFile) 699 return VINF_SUCCESS; 700 701 int rc; 702 RTDBGMODOPENDIETI *pArgs = (RTDBGMODOPENDIETI *)pvUser; 703 switch (pDbgInfo->enmType) 704 { 705 case RTLDRDBGINFOTYPE_CODEVIEW_PDB70: 706 rc = RTDbgCfgOpenPdb70(pArgs->hDbgCfg, pDbgInfo->pszExtFile, 707 &pDbgInfo->u.Pdb70.Uuid, 708 pDbgInfo->u.Pdb70.uAge, 709 rtDbgModExtDbgInfoOpenCallback, pArgs->pDbgMod, (void *)pDbgInfo); 710 break; 711 712 case RTLDRDBGINFOTYPE_CODEVIEW_PDB20: 713 rc = RTDbgCfgOpenPdb20(pArgs->hDbgCfg, pDbgInfo->pszExtFile, 714 pDbgInfo->u.Pdb20.cbImage, 715 pDbgInfo->u.Pdb20.uTimestamp, 716 pDbgInfo->u.Pdb20.uAge, 717 rtDbgModExtDbgInfoOpenCallback, pArgs->pDbgMod, (void *)pDbgInfo); 718 break; 719 720 case RTLDRDBGINFOTYPE_CODEVIEW_DBG: 721 rc = RTDbgCfgOpenDbg(pArgs->hDbgCfg, pDbgInfo->pszExtFile, 722 pDbgInfo->u.Dbg.cbImage, 723 pDbgInfo->u.Dbg.uTimestamp, 724 rtDbgModExtDbgInfoOpenCallback, pArgs->pDbgMod, (void *)pDbgInfo); 725 break; 726 727 case RTLDRDBGINFOTYPE_DWARF_DWO: 728 rc = RTDbgCfgOpenDwo(pArgs->hDbgCfg, pDbgInfo->pszExtFile, 729 pDbgInfo->u.Dwo.uCrc32, 730 rtDbgModExtDbgInfoOpenCallback, pArgs->pDbgMod, (void *)pDbgInfo); 731 break; 732 733 default: 734 Log(("rtDbgModOpenDebugInfoExternalToImageCallback: Don't know how to handle enmType=%d and pszFileExt=%s\n", 735 pDbgInfo->enmType, pDbgInfo->pszExtFile)); 736 return VERR_DBG_TODO; 737 } 738 if (RT_SUCCESS(rc)) 739 { 740 LogFlow(("RTDbgMod: Successfully opened external debug info '%s' for '%s'\n", 741 pArgs->pDbgMod->pszDbgFile, pArgs->pDbgMod->pszImgFile)); 742 return VINF_CALLBACK_RETURN; 743 } 744 Log(("rtDbgModOpenDebugInfoExternalToImageCallback: '%s' (enmType=%d) for '%s' -> %Rrc\n", 745 pDbgInfo->pszExtFile, pDbgInfo->enmType, pArgs->pDbgMod->pszImgFile, rc)); 746 return rc; 747 } 748 749 750 /** 751 * Opens debug info listed in the image that is stored in a separate file. 752 * 753 * @returns IPRT status code 754 * @param pDbgMod The debug module. 755 * @param hDbgCfg The debug config. Can be NIL. 756 */ 757 static int rtDbgModOpenDebugInfoExternalToImage(PRTDBGMODINT pDbgMod, RTDBGCFG hDbgCfg) 758 { 759 RTDBGMODOPENDIETI Args; 760 Args.pDbgMod = pDbgMod; 761 Args.hDbgCfg = hDbgCfg; 762 int rc = pDbgMod->pImgVt->pfnEnumDbgInfo(pDbgMod, rtDbgModOpenDebugInfoExternalToImageCallback, &Args); 763 if (RT_SUCCESS(rc) && pDbgMod->pDbgVt) 764 return VINF_SUCCESS; 765 return VERR_NOT_FOUND; 766 } 767 768 769 770 /** @callback_method_impl{FNRTDBGCFGOPEN} */ 771 static DECLCALLBACK(int) rtDbgModFromPeImageOpenCallback(RTDBGCFG hDbgCfg, const char *pszFilename, void *pvUser1, void *pvUser2) 772 { 773 PRTDBGMODINT pDbgMod = (PRTDBGMODINT)pvUser1; 774 PRTDBGMODDEFERRED pDeferred = (PRTDBGMODDEFERRED)pvUser2; 775 LogFlow(("rtDbgModFromPeImageOpenCallback: %s\n", pszFilename)); 776 777 Assert(pDbgMod->pImgVt == NULL); 778 Assert(pDbgMod->pvImgPriv == NULL); 779 Assert(pDbgMod->pDbgVt == NULL); 780 Assert(pDbgMod->pvDbgPriv == NULL); 781 782 /* 783 * Find an image reader which groks the file. 784 */ 785 int rc = RTSemRWRequestRead(g_hDbgModRWSem, RT_INDEFINITE_WAIT); 786 if (RT_SUCCESS(rc)) 787 { 788 rc = VERR_DBG_NO_MATCHING_INTERPRETER; 789 PRTDBGMODREGIMG pImg; 790 for (pImg = g_pImgHead; pImg; pImg = pImg->pNext) 791 { 792 pDbgMod->pImgVt = pImg->pVt; 793 pDbgMod->pvImgPriv = NULL; 794 rc = pImg->pVt->pfnTryOpen(pDbgMod); 795 if (RT_SUCCESS(rc)) 796 break; 797 pDbgMod->pImgVt = NULL; 798 Assert(pDbgMod->pvImgPriv == NULL); 799 } 800 } 801 RTSemRWReleaseRead(g_hDbgModRWSem); 802 if (RT_FAILURE(rc)) 803 { 804 LogFlow(("rtDbgModFromPeImageOpenCallback: Failed %Rrc - %s\n", rc, pszFilename)); 805 return rc; 806 } 807 808 /* 809 * Check the deferred info. 810 */ 811 RTUINTPTR cbImage = pDbgMod->pImgVt->pfnImageSize(pDbgMod); 812 if ( pDeferred->cbImage == 0 813 || pDeferred->cbImage == cbImage) 814 { 815 uint32_t uTimestamp = pDeferred->u.PeImage.uTimestamp; /** @todo add method for getting the timestamp. */ 816 if ( pDeferred->u.PeImage.uTimestamp == 0 817 || pDeferred->u.PeImage.uTimestamp == uTimestamp) 818 { 819 Log(("RTDbgMod: Found matching PE image '%s'\n", pszFilename)); 820 821 /* 822 * We found the executable image we need, now go find any debug 823 * info associated with it. For PE images, this is generally 824 * found in an external file, so we do a sweep for that first. 825 */ 826 rc = rtDbgModOpenDebugInfoExternalToImage(pDbgMod, pDeferred->hDbgCfg); 827 if (RT_SUCCESS(rc)) 828 return VINF_CALLBACK_RETURN; 829 830 /* 831 * Try open debug info inside the module, falling back on exports. 832 */ 833 rc = rtDbgModOpenDebugInfoInsideImage(pDbgMod); 834 if (RT_SUCCESS(rc)) 835 return VINF_CALLBACK_RETURN; 836 /** @todo search for external files that could contain more useful info, like 837 * .map files?? No? */ 838 rc = rtDbgModCreateForExports(pDbgMod); 839 if (RT_SUCCESS(rc)) 840 return VINF_CALLBACK_RETURN; 841 842 /* Something bad happened, just give up. */ 843 Log(("rtDbgModFromPeImageOpenCallback: rtDbgModCreateForExports failed: %Rrc\n", rc)); 844 } 845 else 846 { 847 LogFlow(("rtDbgModFromPeImageOpenCallback: uTimestamp mismatch (found %#x, expected %#x) - %s\n", 848 uTimestamp, pDeferred->u.PeImage.uTimestamp, pszFilename)); 849 rc = VERR_DBG_FILE_MISMATCH; 850 } 851 } 852 else 853 { 854 LogFlow(("rtDbgModFromPeImageOpenCallback: cbImage mismatch (found %#x, expected %#x) - %s\n", 855 cbImage, pDeferred->cbImage, pszFilename)); 856 rc = VERR_DBG_FILE_MISMATCH; 857 } 858 859 pDbgMod->pImgVt->pfnClose(pDbgMod); 860 pDbgMod->pImgVt = NULL; 861 pDbgMod->pvImgPriv = NULL; 862 863 return rc; 864 } 865 866 867 /** @callback_method_impl{FNRTDBGMODDEFERRED} */ 868 static DECLCALLBACK(int) rtDbgModFromPeImageDeferredCallback(PRTDBGMODINT pDbgMod, PRTDBGMODDEFERRED pDeferred) 869 { 870 int rc; 871 872 Assert(pDbgMod->pszImgFile); 873 if (pDeferred->hDbgCfg != NIL_RTDBGCFG) 874 rc = RTDbgCfgOpenPeImage(pDeferred->hDbgCfg, pDbgMod->pszImgFile, 875 pDeferred->cbImage, pDeferred->u.PeImage.uTimestamp, 876 rtDbgModFromPeImageOpenCallback, pDbgMod, pDeferred); 877 else 878 rc = rtDbgModFromPeImageOpenCallback(NIL_RTDBGCFG, pDbgMod->pszImgFile, pDbgMod, pDeferred); 879 880 return rc; 881 } 882 883 884 RTDECL(int) RTDbgModCreateFromPeImage(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, uint32_t cbImage, 885 uint32_t uTimestamp, RTDBGCFG hDbgCfg) 886 { 887 /* 888 * Input validation and lazy initialization. 889 */ 890 AssertPtrReturn(phDbgMod, VERR_INVALID_POINTER); 891 *phDbgMod = NIL_RTDBGMOD; 892 AssertPtrReturn(pszFilename, VERR_INVALID_POINTER); 893 AssertReturn(*pszFilename, VERR_INVALID_PARAMETER); 894 if (!pszName) 895 pszName = RTPathFilename(pszFilename); 896 AssertPtrReturn(pszName, VERR_INVALID_POINTER); 897 898 int rc = rtDbgModLazyInit(); 899 if (RT_FAILURE(rc)) 900 return rc; 901 902 uint64_t fDbgCfg = 0; 903 if (hDbgCfg) 904 { 905 rc = RTDbgCfgQueryUInt(hDbgCfg, RTDBGCFGPROP_FLAGS, &fDbgCfg); 906 AssertRCReturn(rc, rc); 907 } 908 909 /* 910 * Allocate a new module instance. 911 */ 912 PRTDBGMODINT pDbgMod = (PRTDBGMODINT)RTMemAllocZ(sizeof(*pDbgMod)); 913 if (!pDbgMod) 914 return VERR_NO_MEMORY; 915 pDbgMod->u32Magic = RTDBGMOD_MAGIC; 916 pDbgMod->cRefs = 1; 917 rc = RTCritSectInit(&pDbgMod->CritSect); 918 if (RT_SUCCESS(rc)) 919 { 920 pDbgMod->pszName = RTStrCacheEnter(g_hDbgModStrCache, pszName); 921 if (pDbgMod->pszName) 922 { 923 pDbgMod->pszImgFile = RTStrCacheEnter(g_hDbgModStrCache, pszFilename); 924 if (pDbgMod->pszImgFile) 925 { 926 /* 927 * Do it now or procrastinate? 928 */ 929 if (!(fDbgCfg & RTDBGCFG_FLAGS_DEFERRED) || !cbImage) 930 { 931 RTDBGMODDEFERRED Deferred; 932 Deferred.cbImage = cbImage; 933 Deferred.hDbgCfg = hDbgCfg; 934 Deferred.u.PeImage.uTimestamp = uTimestamp; 935 rc = rtDbgModFromPeImageDeferredCallback(pDbgMod, &Deferred); 936 } 937 else 938 { 939 PRTDBGMODDEFERRED pDeferred; 940 rc = rtDbgModDeferredCreate(pDbgMod, rtDbgModFromPeImageDeferredCallback, cbImage, hDbgCfg, &pDeferred); 941 if (RT_SUCCESS(rc)) 942 pDeferred->u.PeImage.uTimestamp = uTimestamp; 943 } 944 if (RT_SUCCESS(rc)) 945 { 946 *phDbgMod = pDbgMod; 947 return VINF_SUCCESS; 948 } 949 950 /* bail out */ 951 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszName); 952 } 953 else 954 rc = VERR_NO_STR_MEMORY; 955 RTStrCacheRelease(g_hDbgModStrCache, pDbgMod->pszImgFile); 956 } 957 else 958 rc = VERR_NO_STR_MEMORY; 959 RTCritSectDelete(&pDbgMod->CritSect); 960 } 961 962 RTMemFree(pDbgMod); 963 return rc; 964 } 965 RT_EXPORT_SYMBOL(RTDbgModCreateFromImage); 574 966 575 967 -
trunk/src/VBox/Runtime/common/dbg/dbgmoddwarf.cpp
r45975 r45994 4308 4308 4309 4309 /** @callback_method_impl{FNRTLDRENUMDBG} */ 4310 static DECLCALLBACK(int) rtDbgModDwarfEnumCallback(RTLDRMOD hLdrMod, uint32_t iDbgInfo, RTLDRDBGINFOTYPE enmType, 4311 uint16_t iMajorVer, uint16_t iMinorVer, const char *pszPartNm, 4312 RTFOFF offFile, RTLDRADDR LinkAddress, RTLDRADDR cb, 4313 const char *pszExtFile, void *pvUser) 4314 { 4315 NOREF(hLdrMod); NOREF(iDbgInfo); NOREF(iMajorVer); NOREF(iMinorVer); NOREF(LinkAddress); 4316 4310 static DECLCALLBACK(int) rtDbgModDwarfEnumCallback(RTLDRMOD hLdrMod, PCRTLDRDBGINFO pDbgInfo, void *pvUser) 4311 { 4317 4312 /* 4318 4313 * Skip stuff we can't handle. 4319 4314 */ 4320 if ( enmType != RTLDRDBGINFOTYPE_DWARF 4321 || !pszPartNm 4322 || pszExtFile) 4315 if (pDbgInfo->enmType != RTLDRDBGINFOTYPE_DWARF) 4323 4316 return VINF_SUCCESS; 4317 const char *pszSection = pDbgInfo->u.Dwarf.pszSection; 4318 if (!pszSection || !*pszSection) 4319 return VINF_SUCCESS; 4320 Assert(!pDbgInfo->pszExtFile); 4324 4321 4325 4322 /* … … 4327 4324 * or underscores. 4328 4325 */ 4329 if (!strncmp(psz PartNm, RT_STR_TUPLE(".debug_"))) /* ELF */4330 psz PartNm+= sizeof(".debug_") - 1;4331 else if (!strncmp(psz PartNm, RT_STR_TUPLE("__debug_"))) /* Mach-O */4332 psz PartNm+= sizeof("__debug_") - 1;4333 else if (!strcmp(psz PartNm, ".WATCOM_references"))4326 if (!strncmp(pszSection, RT_STR_TUPLE(".debug_"))) /* ELF */ 4327 pszSection += sizeof(".debug_") - 1; 4328 else if (!strncmp(pszSection, RT_STR_TUPLE("__debug_"))) /* Mach-O */ 4329 pszSection += sizeof("__debug_") - 1; 4330 else if (!strcmp(pszSection, ".WATCOM_references")) 4334 4331 return VINF_SUCCESS; /* Ignore special watcom section for now.*/ 4335 4332 else 4336 AssertMsgFailedReturn(("%s\n", psz PartNm), VINF_SUCCESS /*ignore*/);4333 AssertMsgFailedReturn(("%s\n", pszSection), VINF_SUCCESS /*ignore*/); 4337 4334 4338 4335 /* … … 4341 4338 krtDbgModDwarfSect enmSect; 4342 4339 if (0) { /* dummy */ } 4343 #define ELSE_IF_STRCMP_SET(a_Name) else if (!strcmp(psz PartNm, #a_Name)) enmSect = krtDbgModDwarfSect_ ## a_Name4340 #define ELSE_IF_STRCMP_SET(a_Name) else if (!strcmp(pszSection, #a_Name)) enmSect = krtDbgModDwarfSect_ ## a_Name 4344 4341 ELSE_IF_STRCMP_SET(abbrev); 4345 4342 ELSE_IF_STRCMP_SET(aranges); … … 4358 4355 else 4359 4356 { 4360 AssertMsgFailed(("%s\n", psz PartNm));4357 AssertMsgFailed(("%s\n", pszSection)); 4361 4358 return VINF_SUCCESS; 4362 4359 } … … 4366 4363 */ 4367 4364 PRTDBGMODDWARF pThis = (PRTDBGMODDWARF)pvUser; 4368 AssertMsgReturn(!pThis->aSections[enmSect].fPresent, ("duplicate %s\n", psz PartNm), VINF_SUCCESS /*ignore*/);4365 AssertMsgReturn(!pThis->aSections[enmSect].fPresent, ("duplicate %s\n", pszSection), VINF_SUCCESS /*ignore*/); 4369 4366 4370 4367 pThis->aSections[enmSect].fPresent = true; 4371 pThis->aSections[enmSect].offFile = offFile;4368 pThis->aSections[enmSect].offFile = pDbgInfo->offFile; 4372 4369 pThis->aSections[enmSect].pv = NULL; 4373 pThis->aSections[enmSect].cb = (size_t) cb;4374 if (pThis->aSections[enmSect].cb != cb)4370 pThis->aSections[enmSect].cb = (size_t)pDbgInfo->cb; 4371 if (pThis->aSections[enmSect].cb != pDbgInfo->cb) 4375 4372 pThis->aSections[enmSect].cb = ~(size_t)0; 4376 4373 -
trunk/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h
r45982 r45994 760 760 continue; 761 761 762 RTLDRDBGINFO DbgInfo; 762 763 const char *pszSectName = ELF_SH_STR(pModElf, paShdrs[iShdr].sh_name); 763 764 if ( !strncmp(pszSectName, RT_STR_TUPLE(".debug_")) 764 765 || !strcmp(pszSectName, ".WATCOM_references") ) 765 766 { 766 rc = pfnCallback(pMod, iShdr - 1, RTLDRDBGINFOTYPE_DWARF, 0, 0, pszSectName, 767 paShdrs[iShdr].sh_offset, 768 paShdrs[iShdr].sh_addr, 769 paShdrs[iShdr].sh_size, 770 NULL, pvUser); 771 if (rc != VINF_SUCCESS) 772 return rc; 767 RT_ZERO(DbgInfo.u); 768 DbgInfo.enmType = RTLDRDBGINFOTYPE_DWARF; 769 DbgInfo.offFile = paShdrs[iShdr].sh_offset; 770 DbgInfo.cb = paShdrs[iShdr].sh_size; 771 DbgInfo.u.Dwarf.pszSection = pszSectName; 773 772 } 774 773 else if (!strcmp(pszSectName, ".gnu_debuglink")) … … 776 775 if ((paShdrs[iShdr].sh_size & 3) || paShdrs[iShdr].sh_size < 8) 777 776 return VERR_BAD_EXE_FORMAT; 778 const char *pszExtFile = (const char *)((uintptr_t)pModElf->pvBits + paShdrs[iShdr].sh_offset); 779 if (!RTStrEnd(pszExtFile, paShdrs[iShdr].sh_size)) 777 778 RT_ZERO(DbgInfo.u); 779 DbgInfo.enmType = RTLDRDBGINFOTYPE_DWARF_DWO; 780 DbgInfo.pszExtFile = (const char *)((uintptr_t)pModElf->pvBits + paShdrs[iShdr].sh_offset); 781 if (!RTStrEnd(DbgInfo.pszExtFile, paShdrs[iShdr].sh_size)) 780 782 return VERR_BAD_EXE_FORMAT; 781 782 uint32_t uCrc32 = *(uint32_t *)((uintptr_t)pszExtFile + paShdrs[iShdr].sh_size - sizeof(uint32_t)); 783 char szCrc32[16]; 784 RTStrPrintf(szCrc32, sizeof(szCrc32), "%#010x", uCrc32); 785 786 rc = pfnCallback(pMod, iShdr - 1, RTLDRDBGINFOTYPE_DWARF, 0, 0, szCrc32, 787 paShdrs[iShdr].sh_offset, 788 paShdrs[iShdr].sh_addr, 789 paShdrs[iShdr].sh_size, 790 pszExtFile, pvUser); 791 if (rc != VINF_SUCCESS) 792 return rc; 793 } 783 DbgInfo.u.Dwo.uCrc32 = *(uint32_t *)((uintptr_t)DbgInfo.pszExtFile + paShdrs[iShdr].sh_size - sizeof(uint32_t)); 784 DbgInfo.offFile = -1; 785 DbgInfo.cb = 0; 786 } 787 else 788 continue; 789 790 DbgInfo.LinkAddress = NIL_RTLDRADDR; 791 DbgInfo.iDbgInfo = iShdr - 1; 792 793 rc = pfnCallback(pMod, &DbgInfo, pvUser); 794 if (rc != VINF_SUCCESS) 795 return rc; 796 794 797 } 795 798 -
trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp
r44528 r45994 36 36 #include <iprt/assert.h> 37 37 #include <iprt/log.h> 38 #include <iprt/path.h> 38 39 #include <iprt/string.h> 39 40 #include <iprt/err.h> 41 #include <iprt/formats/codeview.h> 40 42 #include "internal/ldrPE.h" 41 43 #include "internal/ldr.h" … … 70 72 /** The offset of the NT headers. */ 71 73 RTFOFF offNtHdrs; 74 /** The offset of the first byte after the section table. */ 75 RTFOFF offEndOfHdrs; 72 76 73 77 /** The machine type (IMAGE_FILE_HEADER::Machine). */ … … 94 98 /** The export data directory entry. */ 95 99 IMAGE_DATA_DIRECTORY ExportDir; 100 /** The debug directory entry. */ 101 IMAGE_DATA_DIRECTORY DebugDir; 96 102 } RTLDRMODPE, *PRTLDRMODPE; 97 103 … … 752 758 continue; 753 759 } 754 else 755 756 760 761 /* Get plain export address */ 762 Value = PE_RVA2TYPE(BaseAddress, uRVAExport, RTUINTPTR); 757 763 758 764 /* … … 773 779 PFNRTLDRENUMDBG pfnCallback, void *pvUser) 774 780 { 775 NOREF(pMod); NOREF(pvBits); NOREF(pfnCallback); NOREF(pvUser); 776 return VINF_NOT_SUPPORTED; 781 PRTLDRMODPE pModPe = (PRTLDRMODPE)pMod; 782 int rc; 783 784 /* 785 * Debug info directory empty? 786 */ 787 if ( !pModPe->DebugDir.VirtualAddress 788 || !pModPe->DebugDir.Size) 789 return VINF_SUCCESS; 790 791 /* 792 * No bits supplied? Do we need to read the bits? 793 */ 794 if (!pvBits) 795 { 796 if (!pModPe->pvBits) 797 { 798 rc = rtldrPEReadBits(pModPe); 799 if (RT_FAILURE(rc)) 800 return rc; 801 } 802 pvBits = pModPe->pvBits; 803 } 804 805 /* 806 * Enumerate the debug directory. 807 */ 808 PCIMAGE_DEBUG_DIRECTORY paDbgDir = PE_RVA2TYPE(pvBits, pModPe->DebugDir.VirtualAddress, PCIMAGE_DEBUG_DIRECTORY); 809 int rcRet = VINF_SUCCESS; 810 uint32_t const cEntries = pModPe->DebugDir.Size / sizeof(paDbgDir[0]); 811 for (uint32_t i = 0; i < cEntries; i++) 812 { 813 if (paDbgDir[i].PointerToRawData < pModPe->offEndOfHdrs) 814 continue; 815 if (paDbgDir[i].SizeOfData < 4) 816 continue; 817 818 char szPath[RTPATH_MAX]; 819 RTLDRDBGINFO DbgInfo; 820 RT_ZERO(DbgInfo.u); 821 DbgInfo.iDbgInfo = i; 822 DbgInfo.offFile = paDbgDir[i].PointerToRawData; 823 DbgInfo.LinkAddress = paDbgDir[i].AddressOfRawData < pModPe->cbImage 824 && paDbgDir[i].AddressOfRawData >= pModPe->offEndOfHdrs 825 ? paDbgDir[i].AddressOfRawData : NIL_RTLDRADDR; 826 DbgInfo.cb = paDbgDir[i].SizeOfData; 827 DbgInfo.pszExtFile = NULL; 828 829 switch (paDbgDir[i].Type) 830 { 831 case IMAGE_DEBUG_TYPE_CODEVIEW: 832 DbgInfo.enmType = RTLDRDBGINFOTYPE_CODEVIEW; 833 DbgInfo.u.Cv.uMajorVer = paDbgDir[i].MajorVersion; 834 DbgInfo.u.Cv.uMinorVer = paDbgDir[i].MinorVersion; 835 DbgInfo.u.Cv.uTimestamp = paDbgDir[i].TimeDateStamp; 836 if ( paDbgDir[i].SizeOfData < sizeof(szPath) 837 && paDbgDir[i].SizeOfData > 16 838 && DbgInfo.LinkAddress != NIL_RTLDRADDR) 839 { 840 PCCVPDB20INFO pCv20 = PE_RVA2TYPE(pvBits, DbgInfo.LinkAddress, PCCVPDB20INFO); 841 if ( pCv20->u32Magic == CVPDB20INFO_MAGIC 842 && pCv20->offDbgInfo == 0 843 && paDbgDir[i].SizeOfData > RT_OFFSETOF(CVPDB20INFO, szPdbFilename) ) 844 { 845 DbgInfo.enmType = RTLDRDBGINFOTYPE_CODEVIEW_PDB20; 846 DbgInfo.u.Pdb20.cbImage = pModPe->cbImage; 847 DbgInfo.u.Pdb20.uTimestamp = pCv20->uTimestamp; 848 DbgInfo.u.Pdb20.uAge = pCv20->uAge; 849 DbgInfo.pszExtFile = (const char *)&pCv20->szPdbFilename[0]; 850 } 851 else if ( pCv20->u32Magic == CVPDB70INFO_MAGIC 852 && paDbgDir[i].SizeOfData > RT_OFFSETOF(CVPDB70INFO, szPdbFilename) ) 853 { 854 PCCVPDB70INFO pCv70 = (PCCVPDB70INFO)pCv20; 855 DbgInfo.enmType = RTLDRDBGINFOTYPE_CODEVIEW_PDB70; 856 DbgInfo.u.Pdb70.cbImage = pModPe->cbImage; 857 DbgInfo.u.Pdb70.Uuid = pCv70->PdbUuid; 858 DbgInfo.u.Pdb70.uAge = pCv70->uAge; 859 DbgInfo.pszExtFile = (const char *)&pCv70->szPdbFilename[0]; 860 } 861 } 862 break; 863 864 case IMAGE_DEBUG_TYPE_MISC: 865 if ( paDbgDir[i].SizeOfData < sizeof(szPath) 866 && paDbgDir[i].SizeOfData > RT_OFFSETOF(IMAGE_DEBUG_MISC, Data) 867 && DbgInfo.LinkAddress != NIL_RTLDRADDR) 868 { 869 PCIMAGE_DEBUG_MISC pMisc = PE_RVA2TYPE(pvBits, DbgInfo.LinkAddress, PCIMAGE_DEBUG_MISC); 870 if ( pMisc->DataType == IMAGE_DEBUG_MISC_EXENAME 871 && pMisc->Length == paDbgDir[i].SizeOfData) 872 { 873 if (!pMisc->Unicode) 874 DbgInfo.pszExtFile = (const char *)&pMisc->Data[0]; 875 else 876 { 877 char *pszPath = szPath; 878 rc = RTUtf16ToUtf8Ex((PCRTUTF16)&pMisc->Data[0], 879 (pMisc->Length - RT_OFFSETOF(IMAGE_DEBUG_MISC, Data)) / sizeof(RTUTF16), 880 &pszPath, sizeof(szPath), NULL); 881 if (RT_FAILURE(rc)) 882 { 883 rcRet = rc; 884 continue; 885 } 886 DbgInfo.pszExtFile = szPath; 887 } 888 DbgInfo.enmType = RTLDRDBGINFOTYPE_CODEVIEW_DBG; 889 DbgInfo.u.Dbg.cbImage = pModPe->cbImage; 890 DbgInfo.u.Dbg.uTimestamp = paDbgDir[i].TimeDateStamp; 891 } 892 } 893 break; 894 895 default: 896 DbgInfo.enmType = RTLDRDBGINFOTYPE_UNKNOWN; 897 break; 898 } 899 900 /* Fix (hack) the file name encoding. We don't have Windows-1252 handy, 901 so we'll be using Latin-1 as a reasonable approximation. 902 (I don't think we know exactly which encoding this is anyway, as 903 it's probably the current ANSI/Windows code page for the process 904 generating the image anyways.) */ 905 if (DbgInfo.pszExtFile && DbgInfo.pszExtFile != szPath) 906 { 907 char *pszPath = szPath; 908 rc = RTLatin1ToUtf8Ex(DbgInfo.pszExtFile, 909 paDbgDir[i].SizeOfData - ((uintptr_t)DbgInfo.pszExtFile - (uintptr_t)pvBits), 910 &pszPath, sizeof(szPath), NULL); 911 if (RT_FAILURE(rc)) 912 { 913 rcRet = rc; 914 continue; 915 } 916 } 917 if (DbgInfo.pszExtFile) 918 RTPathChangeToUnixSlashes(szPath, true /*fForce*/); 919 920 rc = pfnCallback(pMod, &DbgInfo, pvUser); 921 if (rc != VINF_SUCCESS) 922 return rc; 923 } 924 return rcRet; 777 925 } 778 926 … … 1606 1754 if (!paSections) 1607 1755 return VERR_NO_MEMORY; 1608 rc = pReader->pfnRead(pReader, paSections, cbSections, offNtHdrs + 4 + sizeof(IMAGE_FILE_HEADER) + FileHdr.SizeOfOptionalHeader); 1756 rc = pReader->pfnRead(pReader, paSections, cbSections, 1757 offNtHdrs + 4 + sizeof(IMAGE_FILE_HEADER) + FileHdr.SizeOfOptionalHeader); 1609 1758 if (RT_SUCCESS(rc)) 1610 1759 { … … 1628 1777 pModPe->pvBits = NULL; 1629 1778 pModPe->offNtHdrs = offNtHdrs; 1779 pModPe->offEndOfHdrs = offNtHdrs + 4 + sizeof(IMAGE_FILE_HEADER) + FileHdr.SizeOfOptionalHeader + cbSections; 1630 1780 pModPe->u16Machine = FileHdr.Machine; 1631 1781 pModPe->fFile = FileHdr.Characteristics; … … 1639 1789 pModPe->RelocDir = OptHdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; 1640 1790 pModPe->ExportDir = OptHdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; 1791 pModPe->DebugDir = OptHdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]; 1641 1792 1642 1793 /* -
trunk/src/VBox/Runtime/common/ldr/ldrkStuff.cpp
r44528 r45994 599 599 NOREF(pMod); 600 600 601 RTLDRDBGINFOTYPE enmMyType; 601 RTLDRDBGINFO DbgInfo; 602 RT_ZERO(DbgInfo.u); 603 DbgInfo.iDbgInfo = iDbgInfo; 604 DbgInfo.offFile = offFile; 605 DbgInfo.LinkAddress = LinkAddress; 606 DbgInfo.cb = cb; 607 DbgInfo.pszExtFile = pszExtFile; 608 602 609 switch (enmType) 603 610 { 604 case KLDRDBGINFOTYPE_UNKNOWN: enmMyType = RTLDRDBGINFOTYPE_UNKNOWN; break; 605 case KLDRDBGINFOTYPE_STABS: enmMyType = RTLDRDBGINFOTYPE_STABS; break; 606 case KLDRDBGINFOTYPE_DWARF: enmMyType = RTLDRDBGINFOTYPE_DWARF; break; 607 case KLDRDBGINFOTYPE_CODEVIEW: enmMyType = RTLDRDBGINFOTYPE_CODEVIEW; break; 608 case KLDRDBGINFOTYPE_WATCOM: enmMyType = RTLDRDBGINFOTYPE_WATCOM; break; 609 case KLDRDBGINFOTYPE_HLL: enmMyType = RTLDRDBGINFOTYPE_HLL; break; 611 case KLDRDBGINFOTYPE_UNKNOWN: 612 DbgInfo.enmType = RTLDRDBGINFOTYPE_UNKNOWN; 613 break; 614 case KLDRDBGINFOTYPE_STABS: 615 DbgInfo.enmType = RTLDRDBGINFOTYPE_STABS; 616 break; 617 case KLDRDBGINFOTYPE_DWARF: 618 DbgInfo.enmType = RTLDRDBGINFOTYPE_DWARF; 619 if (pszExtFile) 620 DbgInfo.enmType = RTLDRDBGINFOTYPE_DWARF_DWO; 621 break; 622 case KLDRDBGINFOTYPE_CODEVIEW: 623 DbgInfo.enmType = RTLDRDBGINFOTYPE_CODEVIEW; 624 /* Should make some more effort here... Assume the IPRT loader will kick in before we get here! */ 625 break; 626 case KLDRDBGINFOTYPE_WATCOM: 627 DbgInfo.enmType = RTLDRDBGINFOTYPE_WATCOM; 628 break; 629 case KLDRDBGINFOTYPE_HLL: 630 DbgInfo.enmType = RTLDRDBGINFOTYPE_HLL; 631 break; 610 632 default: 611 633 AssertFailed(); 612 enmMyType = RTLDRDBGINFOTYPE_UNKNOWN;634 DbgInfo.enmType = RTLDRDBGINFOTYPE_UNKNOWN; 613 635 break; 614 636 } 615 637 616 int rc = pArgs->u.pfnEnumDbgInfo(&pArgs->pMod->Core, iDbgInfo, enmMyType, iMajorVer, iMinorVer, pszPartNm, 617 offFile, LinkAddress, cb, pszExtFile, pArgs->pvUser); 638 int rc = pArgs->u.pfnEnumDbgInfo(&pArgs->pMod->Core, &DbgInfo, pArgs->pvUser); 618 639 if (RT_FAILURE(rc)) 619 640 return rc; /* don't bother converting. */
Note:
See TracChangeset
for help on using the changeset viewer.