Changeset 46131 in vbox for trunk/src/VBox/Runtime/common/ldr
- Timestamp:
- May 16, 2013 5:07:57 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp
r46118 r46131 893 893 894 894 895 /** 896 * Slow version of rtldrPEEnumSymbols that'll work without all of the image 897 * being accessible. 898 * 899 * This is mainly for use in debuggers and similar. 900 */ 901 static int rtldrPEEnumSymbolsSlow(PRTLDRMODPE pThis, unsigned fFlags, RTUINTPTR BaseAddress, 902 PFNRTLDRENUMSYMS pfnCallback, void *pvUser) 903 { 904 /* 905 * We enumerates by ordinal, which means using a slow linear search for 906 * getting any name 907 */ 908 PCIMAGE_EXPORT_DIRECTORY pExpDir = NULL; 909 int rc = rtldrPEReadPartByRva(pThis, NULL, pThis->ExportDir.VirtualAddress, pThis->ExportDir.Size, 910 (void const **)&pExpDir); 911 if (RT_FAILURE(rc)) 912 return rc; 913 uint32_t const cOrdinals = RT_MAX(pExpDir->NumberOfNames, pExpDir->NumberOfFunctions); 914 915 uint32_t const *paAddress = NULL; 916 rc = rtldrPEReadPartByRva(pThis, NULL, pExpDir->AddressOfFunctions, cOrdinals * sizeof(uint32_t), 917 (void const **)&paAddress); 918 uint32_t const *paRVANames = NULL; 919 if (RT_SUCCESS(rc) && pExpDir->NumberOfNames) 920 rc = rtldrPEReadPartByRva(pThis, NULL, pExpDir->AddressOfNames, pExpDir->NumberOfNames * sizeof(uint32_t), 921 (void const **)&paRVANames); 922 uint16_t const *paOrdinals = NULL; 923 if (RT_SUCCESS(rc) && pExpDir->NumberOfNames) 924 rc = rtldrPEReadPartByRva(pThis, NULL, pExpDir->AddressOfNameOrdinals, pExpDir->NumberOfNames * sizeof(uint16_t), 925 (void const **)&paOrdinals); 926 if (RT_SUCCESS(rc)) 927 { 928 uintptr_t uNamePrev = 0; 929 for (uint32_t uOrdinal = 0; uOrdinal < cOrdinals; uOrdinal++) 930 { 931 if (paAddress[uOrdinal] /* needed? */) 932 { 933 /* 934 * Look for name. 935 */ 936 uint32_t uRvaName = UINT32_MAX; 937 /* Search from previous + 1 to the end. */ 938 unsigned uName = uNamePrev + 1; 939 while (uName < pExpDir->NumberOfNames) 940 { 941 if (paOrdinals[uName] == uOrdinal) 942 { 943 uRvaName = paRVANames[uName]; 944 uNamePrev = uName; 945 break; 946 } 947 uName++; 948 } 949 if (uRvaName == UINT32_MAX) 950 { 951 /* Search from start to the previous. */ 952 uName = 0; 953 for (uName = 0 ; uName <= uNamePrev; uName++) 954 { 955 if (paOrdinals[uName] == uOrdinal) 956 { 957 uRvaName = paRVANames[uName]; 958 uNamePrev = uName; 959 break; 960 } 961 } 962 } 963 964 /* 965 * Get address. 966 */ 967 uintptr_t uRVAExport = paAddress[uOrdinal]; 968 RTUINTPTR Value; 969 if ( uRVAExport - (uintptr_t)pThis->ExportDir.VirtualAddress 970 < pThis->ExportDir.Size) 971 { 972 if (!(fFlags & RTLDR_ENUM_SYMBOL_FLAGS_NO_FWD)) 973 { 974 /* Resolve forwarder. */ 975 AssertMsgFailed(("Forwarders are not supported!\n")); 976 } 977 continue; 978 } 979 980 /* Get plain export address */ 981 Value = PE_RVA2TYPE(BaseAddress, uRVAExport, RTUINTPTR); 982 983 /* Read in the name if found one. */ 984 char szAltName[32]; 985 const char *pszName = NULL; 986 if (uRvaName != UINT32_MAX) 987 { 988 size_t cbName = 0x1000 - (uRvaName & 0xfff); 989 if (cbName < 10 || cbName > 512) 990 cbName = 128; 991 rc = rtldrPEReadPartByRva(pThis, NULL, uRvaName, cbName, (void const **)&pszName); 992 while (RT_SUCCESS(rc) && RTStrNLen(pszName, cbName) == cbName) 993 { 994 rtldrPEFreePart(pThis, NULL, pszName); 995 pszName = NULL; 996 if (cbName >= _4K) 997 break; 998 cbName += 128; 999 rc = rtldrPEReadPartByRva(pThis, NULL, uRvaName, cbName, (void const **)&pszName); 1000 } 1001 } 1002 if (!pszName) 1003 { 1004 RTStrPrintf(szAltName, sizeof(szAltName), "Ordinal%#x", uOrdinal); 1005 pszName = szAltName; 1006 } 1007 1008 /* 1009 * Call back. 1010 */ 1011 rc = pfnCallback(&pThis->Core, pszName, uOrdinal + pExpDir->Base, Value, pvUser); 1012 if (pszName != szAltName && pszName) 1013 rtldrPEFreePart(pThis, NULL, pszName); 1014 if (rc) 1015 break; 1016 } 1017 } 1018 } 1019 1020 rtldrPEFreePart(pThis, NULL, paOrdinals); 1021 rtldrPEFreePart(pThis, NULL, paRVANames); 1022 rtldrPEFreePart(pThis, NULL, paAddress); 1023 rtldrPEFreePart(pThis, NULL, pExpDir); 1024 return rc; 1025 1026 } 1027 1028 895 1029 /** @copydoc RTLDROPS::pfnEnumSymbols */ 896 1030 static DECLCALLBACK(int) rtldrPEEnumSymbols(PRTLDRMODINTERNAL pMod, unsigned fFlags, const void *pvBits, RTUINTPTR BaseAddress, … … 916 1050 int rc = rtldrPEReadBits(pModPe); 917 1051 if (RT_FAILURE(rc)) 918 return r c;1052 return rtldrPEEnumSymbolsSlow(pModPe, fFlags, BaseAddress, pfnCallback, pvUser); 919 1053 } 920 1054 pvBits = pModPe->pvBits;
Note:
See TracChangeset
for help on using the changeset viewer.