- Timestamp:
- Oct 10, 2020 11:20:58 AM (4 years ago)
- Location:
- trunk/src/VBox/HostDrivers/Support
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp
r86304 r86512 1813 1813 ("SUP_IOCTL_LDR_LOAD: offPrevEnd %#lx cbImageBits %#lx\n", (long)i, (long)offPrevEnd, (long)pReq->u.In.cbImageBits)); 1814 1814 } 1815 REQ_CHECK_EXPR_FMT(!(pReq->u.In.fFlags & ~SUPLDRLOAD_F_VALID_MASK), 1816 ("SUP_IOCTL_LDR_LOAD: fFlags=%#x\n", (unsigned)pReq->u.In.fFlags)); 1815 1817 1816 1818 /* execute */ … … 5134 5136 pImage->cUsage = 1; 5135 5137 pImage->pDevExt = pDevExt; 5138 pImage->pImageImport = NULL; 5136 5139 pImage->uMagic = SUPDRVLDRIMAGE_MAGIC; 5137 5140 memcpy(pImage->szName, pReq->u.In.szName, cchName + 1); … … 5295 5298 PSUPDRVLDRUSAGE pUsage; 5296 5299 PSUPDRVLDRIMAGE pImage; 5300 PSUPDRVLDRIMAGE pImageImport; 5297 5301 int rc; 5298 5302 SUPDRV_CHECK_SMAP_SETUP(); … … 5342 5346 supdrvLdrUnlock(pDevExt); 5343 5347 return supdrvLdrLoadError(VERR_PERMISSION_DENIED, pReq, "Loader is locked down"); 5348 } 5349 5350 /* 5351 * If the new image is a dependant of VMMR0.r0, resolve it via the 5352 * caller's usage list and make sure it's in ready state. 5353 */ 5354 pImageImport = NULL; 5355 if (pReq->u.In.fFlags & SUPLDRLOAD_F_DEP_VMMR0) 5356 { 5357 PSUPDRVLDRUSAGE pUsageDependency = pSession->pLdrUsage; 5358 while (pUsageDependency && pUsageDependency->pImage->pvImage != pDevExt->pvVMMR0) 5359 pUsageDependency = pUsageDependency->pNext; 5360 if (!pUsageDependency || !pDevExt->pvVMMR0) 5361 { 5362 supdrvLdrUnlock(pDevExt); 5363 return supdrvLdrLoadError(VERR_MODULE_NOT_FOUND, pReq, "VMMR0.r0 not loaded by session"); 5364 } 5365 pImageImport = pUsageDependency->pImage; 5366 if (pImageImport->uState != SUP_IOCTL_LDR_LOAD) 5367 { 5368 supdrvLdrUnlock(pDevExt); 5369 return supdrvLdrLoadError(VERR_MODULE_NOT_FOUND, pReq, "VMMR0.r0 is not ready (state %#x)", pImageImport->uState); 5370 } 5344 5371 } 5345 5372 … … 5520 5547 if (RT_SUCCESS(rc)) 5521 5548 { 5549 /* Increase the usage counter of any import image. */ 5550 if (pImageImport) 5551 { 5552 pImageImport->cUsage++; 5553 pImage->pImageImport = pImageImport; 5554 } 5555 5556 /* Done! */ 5522 5557 SUPR0Printf("vboxdrv: %RKv %s\n", pImage->pvImage, pImage->szName); 5523 5558 pReq->u.Out.uErrorMagic = 0; … … 5592 5627 rc = VINF_SUCCESS; 5593 5628 pImage = pUsage->pImage; 5629 Log(("SUP_IOCTL_LDR_FREE: pImage=%p %s cUsage=%d r3=%d r0=%u\n", 5630 pImage, pImage->szName, pImage->cUsage, pUsage->cRing3Usage, pUsage->cRing0Usage)); 5594 5631 if (pImage->cUsage <= 1 || pUsage->cRing3Usage + pUsage->cRing0Usage <= 1) 5595 5632 { … … 5991 6028 static void supdrvLdrFree(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage) 5992 6029 { 5993 PSUPDRVLDRIMAGE pImagePrev; 5994 LogFlow(("supdrvLdrFree: pImage=%p\n", pImage)); 5995 5996 /* 5997 * Warn if we're releasing images while the image loader interface is 5998 * locked down -- we won't be able to reload them! 5999 */ 6000 if (pDevExt->fLdrLockedDown) 6001 Log(("supdrvLdrFree: Warning: unloading '%s' image, while loader interface is locked down!\n", pImage->szName)); 6002 6003 /* find it - arg. should've used doubly linked list. */ 6004 Assert(pDevExt->pLdrImages); 6005 pImagePrev = NULL; 6006 if (pDevExt->pLdrImages != pImage) 6007 { 6008 pImagePrev = pDevExt->pLdrImages; 6009 while (pImagePrev->pNext != pImage) 6010 pImagePrev = pImagePrev->pNext; 6011 Assert(pImagePrev->pNext == pImage); 6012 } 6013 6014 /* unlink */ 6015 if (pImagePrev) 6016 pImagePrev->pNext = pImage->pNext; 6017 else 6018 pDevExt->pLdrImages = pImage->pNext; 6019 6020 /* check if this is VMMR0.r0 unset its entry point pointers. */ 6021 if (pDevExt->pvVMMR0 == pImage->pvImage) 6022 supdrvLdrUnsetVMMR0EPs(pDevExt); 6023 6024 /* check for objects with destructors in this image. (Shouldn't happen.) */ 6025 if (pDevExt->pObjs) 6026 { 6027 unsigned cObjs = 0; 6028 PSUPDRVOBJ pObj; 6029 RTSpinlockAcquire(pDevExt->Spinlock); 6030 for (pObj = pDevExt->pObjs; pObj; pObj = pObj->pNext) 6031 if (RT_UNLIKELY((uintptr_t)pObj->pfnDestructor - (uintptr_t)pImage->pvImage < pImage->cbImageBits)) 6032 { 6033 pObj->pfnDestructor = NULL; 6034 cObjs++; 6035 } 6036 RTSpinlockRelease(pDevExt->Spinlock); 6037 if (cObjs) 6038 OSDBGPRINT(("supdrvLdrFree: Image '%s' has %d dangling objects!\n", pImage->szName, cObjs)); 6039 } 6040 6041 /* call termination function if fully loaded. */ 6042 if ( pImage->pfnModuleTerm 6043 && pImage->uState == SUP_IOCTL_LDR_LOAD) 6044 { 6045 LogFlow(("supdrvIOCtl_LdrLoad: calling pfnModuleTerm=%p\n", pImage->pfnModuleTerm)); 6046 pDevExt->hLdrTermThread = RTThreadNativeSelf(); 6047 pImage->pfnModuleTerm(pImage); 6048 pDevExt->hLdrTermThread = NIL_RTNATIVETHREAD; 6049 } 6050 6051 /* Inform the tracing component. */ 6052 supdrvTracerModuleUnloading(pDevExt, pImage); 6053 6054 /* Do native unload if appropriate, then inform the native code about the 6055 unloading (mainly for non-native loading case). */ 6056 if (pImage->fNative) 6057 supdrvOSLdrUnload(pDevExt, pImage); 6058 supdrvOSLdrNotifyUnloaded(pDevExt, pImage); 6059 6060 /* free the image */ 6061 pImage->uMagic = SUPDRVLDRIMAGE_MAGIC_DEAD; 6062 pImage->cUsage = 0; 6063 pImage->pDevExt = NULL; 6064 pImage->pNext = NULL; 6065 pImage->uState = SUP_IOCTL_LDR_FREE; 6030 unsigned cLoops; 6031 for (cLoops = 0; ; cLoops++) 6032 { 6033 PSUPDRVLDRIMAGE pImagePrev; 6034 PSUPDRVLDRIMAGE pImageImport; 6035 LogFlow(("supdrvLdrFree: pImage=%p %s [loop %u]\n", pImage, pImage->szName, cLoops)); 6036 AssertBreak(cLoops < 2); 6037 6038 /* 6039 * Warn if we're releasing images while the image loader interface is 6040 * locked down -- we won't be able to reload them! 6041 */ 6042 if (pDevExt->fLdrLockedDown) 6043 Log(("supdrvLdrFree: Warning: unloading '%s' image, while loader interface is locked down!\n", pImage->szName)); 6044 6045 /* find it - arg. should've used doubly linked list. */ 6046 Assert(pDevExt->pLdrImages); 6047 pImagePrev = NULL; 6048 if (pDevExt->pLdrImages != pImage) 6049 { 6050 pImagePrev = pDevExt->pLdrImages; 6051 while (pImagePrev->pNext != pImage) 6052 pImagePrev = pImagePrev->pNext; 6053 Assert(pImagePrev->pNext == pImage); 6054 } 6055 6056 /* unlink */ 6057 if (pImagePrev) 6058 pImagePrev->pNext = pImage->pNext; 6059 else 6060 pDevExt->pLdrImages = pImage->pNext; 6061 6062 /* check if this is VMMR0.r0 unset its entry point pointers. */ 6063 if (pDevExt->pvVMMR0 == pImage->pvImage) 6064 supdrvLdrUnsetVMMR0EPs(pDevExt); 6065 6066 /* check for objects with destructors in this image. (Shouldn't happen.) */ 6067 if (pDevExt->pObjs) 6068 { 6069 unsigned cObjs = 0; 6070 PSUPDRVOBJ pObj; 6071 RTSpinlockAcquire(pDevExt->Spinlock); 6072 for (pObj = pDevExt->pObjs; pObj; pObj = pObj->pNext) 6073 if (RT_UNLIKELY((uintptr_t)pObj->pfnDestructor - (uintptr_t)pImage->pvImage < pImage->cbImageBits)) 6074 { 6075 pObj->pfnDestructor = NULL; 6076 cObjs++; 6077 } 6078 RTSpinlockRelease(pDevExt->Spinlock); 6079 if (cObjs) 6080 OSDBGPRINT(("supdrvLdrFree: Image '%s' has %d dangling objects!\n", pImage->szName, cObjs)); 6081 } 6082 6083 /* call termination function if fully loaded. */ 6084 if ( pImage->pfnModuleTerm 6085 && pImage->uState == SUP_IOCTL_LDR_LOAD) 6086 { 6087 LogFlow(("supdrvIOCtl_LdrLoad: calling pfnModuleTerm=%p\n", pImage->pfnModuleTerm)); 6088 pDevExt->hLdrTermThread = RTThreadNativeSelf(); 6089 pImage->pfnModuleTerm(pImage); 6090 pDevExt->hLdrTermThread = NIL_RTNATIVETHREAD; 6091 } 6092 6093 /* Inform the tracing component. */ 6094 supdrvTracerModuleUnloading(pDevExt, pImage); 6095 6096 /* Do native unload if appropriate, then inform the native code about the 6097 unloading (mainly for non-native loading case). */ 6098 if (pImage->fNative) 6099 supdrvOSLdrUnload(pDevExt, pImage); 6100 supdrvOSLdrNotifyUnloaded(pDevExt, pImage); 6101 6102 /* free the image */ 6103 pImage->uMagic = SUPDRVLDRIMAGE_MAGIC_DEAD; 6104 pImage->cUsage = 0; 6105 pImage->pDevExt = NULL; 6106 pImage->pNext = NULL; 6107 pImage->uState = SUP_IOCTL_LDR_FREE; 6066 6108 #ifdef SUPDRV_USE_MEMOBJ_FOR_LDR_IMAGE 6067 RTR0MemObjFree(pImage->hMemObjImage, true /*fMappings*/);6068 pImage->hMemObjImage = NIL_RTR0MEMOBJ;6109 RTR0MemObjFree(pImage->hMemObjImage, true /*fMappings*/); 6110 pImage->hMemObjImage = NIL_RTR0MEMOBJ; 6069 6111 #else 6070 RTMemExecFree(pImage->pvImageAlloc, pImage->cbImageBits + 31);6071 pImage->pvImageAlloc = NULL;6112 RTMemExecFree(pImage->pvImageAlloc, pImage->cbImageBits + 31); 6113 pImage->pvImageAlloc = NULL; 6072 6114 #endif 6073 pImage->pvImage = NULL; 6074 RTMemFree(pImage->pachStrTab); 6075 pImage->pachStrTab = NULL; 6076 RTMemFree(pImage->paSymbols); 6077 pImage->paSymbols = NULL; 6078 RTMemFree(pImage->paSegments); 6079 pImage->paSegments = NULL; 6080 RTMemFree(pImage); 6115 pImage->pvImage = NULL; 6116 RTMemFree(pImage->pachStrTab); 6117 pImage->pachStrTab = NULL; 6118 RTMemFree(pImage->paSymbols); 6119 pImage->paSymbols = NULL; 6120 RTMemFree(pImage->paSegments); 6121 pImage->paSegments = NULL; 6122 6123 pImageImport = pImage->pImageImport; 6124 pImage->pImageImport = NULL; 6125 6126 RTMemFree(pImage); 6127 6128 /* 6129 * Deal with any import image. 6130 */ 6131 if (!pImageImport) 6132 break; 6133 if (pImageImport->cUsage > 1) 6134 { 6135 pImageImport->cUsage--; 6136 break; 6137 } 6138 pImage = pImageImport; 6139 } 6081 6140 } 6082 6141 -
trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h
r85590 r86512 222 222 * @todo Pending work on next major version change: 223 223 * - Nothing. 224 * @note 0x002f0000 is used by 6.0. The next version number must be 0x00300000. 225 */ 226 #define SUPDRV_IOC_VERSION 0x002e0000 224 */ 225 #define SUPDRV_IOC_VERSION 0x00300000 227 226 228 227 /** SUP_IOCTL_COOKIE. */ … … 482 481 /** Size of image data in achImage. */ 483 482 uint32_t cbImageWithEverything; 483 /** Flags (SUPLDRLOAD_F_XXX). */ 484 uint32_t fFlags; 484 485 /** The image data. */ 485 486 uint8_t abImage[1]; … … 499 500 * @remarks The value is choosen to be an unlikely init and term address. */ 500 501 #define SUPLDRLOAD_ERROR_MAGIC UINT64_C(0xabcdefef0feddcb9) 502 /** The module depends on VMMR0. */ 503 #define SUPLDRLOAD_F_DEP_VMMR0 RT_BIT_32(0) 504 /** Valid flag mask. */ 505 #define SUPLDRLOAD_F_VALID_MASK UINT32_C(0x00000001) 501 506 /** @} */ 502 507 -
trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
r85766 r86512 373 373 /** Pointer to the device extension. */ 374 374 struct SUPDRVDEVEXT *pDevExt; 375 /** Image (VMMR0.r0) containing functions/data that this one uses. */ 376 struct SUPDRVLDRIMAGE *pImageImport; 375 377 #ifdef RT_OS_WINDOWS 376 378 /** The section object for the loaded image (fNative=true). */ … … 558 560 * This takes care of its own locking in an IRQ safe manner. */ 559 561 RTHANDLETABLE hHandleTable; 560 /** Load usage records . (protected by SUPDRVDEVEXT::mtxLdr) */562 /** Load usage records (LIFO!). (protected by SUPDRVDEVEXT::mtxLdr) */ 561 563 PSUPDRVLDRUSAGE volatile pLdrUsage; 562 564 -
trunk/src/VBox/HostDrivers/Support/SUPLibLdr.cpp
r85555 r86512 125 125 const char *pszModule; 126 126 PRTERRINFO pErrInfo; 127 uint32_t fLoadReq; /**< SUPLDRLOAD_F_XXX */ 127 128 } SUPLDRRESIMPARGS, *PSUPLDRRESIMPARGS; 128 129 … … 187 188 * Check the VMMR0.r0 module if loaded. 188 189 */ 189 /** @todo call the SUPR3LoadModule caller.... */190 /** @todo proper reference counting and such. */191 190 if (g_pvVMMR0 != NIL_RTR0PTR) 192 191 { … … 195 194 { 196 195 *pValue = (uintptr_t)pvValue; 196 pArgs->fLoadReq |= SUPLDRLOAD_F_DEP_VMMR0; 197 197 return VINF_SUCCESS; 198 198 } … … 519 519 * Get the image bits. 520 520 */ 521 SUPLDRRESIMPARGS Args = { pszModule, pErrInfo };521 SUPLDRRESIMPARGS Args = { pszModule, pErrInfo, 0 }; 522 522 int rc = RTLdrGetBits(hLdrMod, &pLoadReq->u.In.abImage[0], uImageBase, supLoadModuleResolveImport, &Args); 523 523 if (RT_FAILURE(rc)) … … 659 659 pLoadReq->u.In.cbImageWithEverything = cbImageWithEverything; 660 660 pLoadReq->u.In.pvImageBase = uImageBase; 661 pLoadReq->u.In.fFlags = Args.fLoadReq; 661 662 if (!g_uSupFakeMode) 662 663 {
Note:
See TracChangeset
for help on using the changeset viewer.