Changeset 37228 in vbox for trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c
- Timestamp:
- May 26, 2011 7:25:54 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c
r37219 r37228 35 35 #include <sys/buf.h> 36 36 #include <sys/modctl.h> 37 #include <sys/kobj.h> 37 38 #include <sys/open.h> 38 39 #include <sys/conf.h> … … 51 52 #include <iprt/spinlock.h> 52 53 #include <iprt/mp.h> 54 #include <iprt/path.h> 53 55 #include <iprt/power.h> 54 56 #include <iprt/process.h> … … 893 895 } 894 896 897 #if defined(VBOX_WITH_NATIVE_SOLARIS_LOADING) \ 898 && !defined(VBOX_WITHOUT_NATIVE_R0_LOADER) 895 899 896 900 int VBOXCALL supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename) 897 901 { 898 /** @todo This is something that shouldn't be impossible to implement 899 * here and would make a few people happy. */ 902 pImage->idSolMod = -1; 903 pImage->pSolModCtl = NULL; 904 905 # if 1 /* This approach requires _init/_fini/_info stubs. */ 906 /* 907 * Construct a filename that escapes the module search path and let us 908 * specify a root path. 909 */ 910 const char *pszName = RTPathFilename(pszFilename); 911 AssertReturn(pszName, VERR_INVALID_PARAMETER); 912 char *pszSubDir = RTStrAPrintf2("../../../../../../../../../../../%.*s", pszName - pszFilename, pszFilename); 913 if (!pszSubDir) 914 return VERR_NO_STR_MEMORY; 915 916 int idMod = modload(pszSubDir, pszName); 917 RTStrFree(pszSubDir); 918 if (idMod == -1) 919 { 920 LogRel(("modload(,%s): failed, could be anything...\n", pszFilename)); 921 return VERR_LDR_GENERAL_FAILURE; 922 } 923 924 modctl_t *pModCtl = mod_hold_by_id(idMod); 925 if (!pModCtl) 926 { 927 LogRel(("mod_hold_by_id(,%s): failed, weird.\n", pszFilename)); 928 /* No point in calling modunload. */ 929 return VERR_LDR_GENERAL_FAILURE; 930 } 931 pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD | MOD_NOUNLOAD; /* paranoia */ 932 933 # else 934 935 const int idMod = -1; 936 modctl_t *pModCtl = mod_hold_by_name(pszFilename); 937 if (!pModCtl) 938 { 939 LogRel(("mod_hold_by_name failed for '%s'\n", pszFilename)); 940 return VERR_LDR_GENERAL_FAILURE; 941 } 942 943 int rc = kobj_load_module(pModCtl, 0 /*use_path*/); 944 if (rc != 0) 945 { 946 LogRel(("kobj_load_module failed with rc=%d for '%s'\n", rc, pszFilename)); 947 mod_release_mod(pModCtl); 948 return RTErrConvertFromErrno(rc); 949 } 950 # endif 951 952 /* 953 * Get the module info. 954 */ 955 struct modinfo ModInfo; 956 kobj_getmodinfo(pModCtl->mod_mp, &ModInfo); 957 pImage->pvImage = ModInfo.mi_base; 958 pImage->idSolMod = idMod; 959 pImage->pSolModCtl = pModCtl; 960 961 mod_release_mod(pImage->pSolModCtl); 962 LogRel(("supdrvOSLdrOpen: succeeded for '%s' (mi_base=%p mi_base=%#x), id=%d ctl=%p\n", 963 pszFilename, ModInfo.mi_base, ModInfo.mi_size, idMod, pModCtl)); 964 return VINF_SUCCESS; 965 } 966 967 968 int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits) 969 { 970 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); 971 if (kobj_addrcheck(pImage->pSolModCtl->mod_mp, pv)) 972 return VERR_INVALID_PARAMETER; 973 return VINF_SUCCESS; 974 } 975 976 977 int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits) 978 { 979 /* 980 * Comparing is very very difficult since text and data may be allocated 981 * separately. 982 */ 983 size_t cbCompare = RT_MIN(pImage->cbImageBits, 64); 984 if (memcmp(pImage->pvImage, pbImageBits, cbCompare)) 985 { 986 LogRel(("Image mismatch: %s\n", pImage->szName)); 987 LogRel(("Native: %.*Rhxs\n", cbCompare, pImage->pvImage)); 988 LogRel(("SUPLib: %.*Rhxs\n", cbCompare, pbImageBits)); 989 return VERR_LDR_MISMATCH_NATIVE; 990 } 991 992 993 /* 994 * Get the symbol addresses. 995 */ 996 int rc; 997 modctl_t *pModCtl = mod_hold_by_id(pImage->idSolMod); 998 if (pModCtl && pModCtl == pImage->pSolModCtl) 999 { 1000 uint32_t iSym = pImage->cSymbols; 1001 while (iSym-- > 0) 1002 { 1003 const char *pszSymbol = &pImage->pachStrTab[pImage->paSymbols[iSym].offName]; 1004 uintptr_t uValue = modlookup_by_modctl(pImage->pSolModCtl, pszSymbol); 1005 if (!uValue) 1006 { 1007 LogRel(("supdrvOSLdrLoad on %s failed to resolve the exported symbol: '%s'\n", pImage->szName, pszSymbol)); 1008 break; 1009 } 1010 uintptr_t offSymbol = uValue - (uintptr_t)pImage->pvImage; 1011 pImage->paSymbols[iSym].offSymbol = offSymbol; 1012 if (pImage->paSymbols[iSym].offSymbol != (int32_t)offSymbol) 1013 { 1014 LogRel(("supdrvOSLdrLoad on %s symbol out of range: %p (%s) \n", pImage->szName, offSymbol, pszSymbol)); 1015 break; 1016 } 1017 } 1018 1019 rc = iSym == UINT32_MAX ? VINF_SUCCESS : VERR_LDR_GENERAL_FAILURE; 1020 mod_release_mod(pImage->pSolModCtl); 1021 } 1022 else 1023 { 1024 LogRel(("mod_hold_by_id failed in supdrvOSLdrLoad on %s: %p\n", pImage->szName, pModCtl)); 1025 rc = VERR_LDR_MISMATCH_NATIVE; 1026 } 1027 return rc; 1028 } 1029 1030 1031 void VBOXCALL supdrvOSLdrUnload(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage) 1032 { 1033 # if 1 1034 pImage->pSolModCtl->mod_loadflags &= ~MOD_NOUNLOAD; 1035 int rc = modunload(pImage->idSolMod); 1036 if (rc) 1037 LogRel(("modunload(%u (%s)) failed: %d\n", pImage->idSolMod, pImage->szName, rc)); 1038 # else 1039 kobj_unload_module(pImage->pSolModCtl); 1040 # endif 1041 pImage->pSolModCtl = NULL; 1042 pImage->idSolMod = NULL; 1043 } 1044 1045 #else /* !VBOX_WITH_NATIVE_SOLARIS_LOADING */ 1046 1047 int VBOXCALL supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename) 1048 { 900 1049 NOREF(pDevExt); NOREF(pImage); NOREF(pszFilename); 901 1050 return VERR_NOT_SUPPORTED; … … 921 1070 NOREF(pDevExt); NOREF(pImage); 922 1071 } 1072 1073 #endif /* !VBOX_WITH_NATIVE_SOLARIS_LOADING */ 923 1074 924 1075
Note:
See TracChangeset
for help on using the changeset viewer.