Changeset 85507 in vbox for trunk/src/VBox/HostDrivers/Support
- Timestamp:
- Jul 29, 2020 10:10:49 AM (5 years ago)
- Location:
- trunk/src/VBox/HostDrivers/Support
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp
r85450 r85507 1733 1733 PSUPLDROPEN pReq = (PSUPLDROPEN)pReqHdr; 1734 1734 REQ_CHECK_SIZES(SUP_IOCTL_LDR_OPEN); 1735 REQ_CHECK_EXPR(SUP_IOCTL_LDR_OPEN, pReq->u.In.cbImageWith Tabs> 0);1736 REQ_CHECK_EXPR(SUP_IOCTL_LDR_OPEN, pReq->u.In.cbImageWith Tabs< 16*_1M);1735 REQ_CHECK_EXPR(SUP_IOCTL_LDR_OPEN, pReq->u.In.cbImageWithEverything > 0); 1736 REQ_CHECK_EXPR(SUP_IOCTL_LDR_OPEN, pReq->u.In.cbImageWithEverything < 16*_1M); 1737 1737 REQ_CHECK_EXPR(SUP_IOCTL_LDR_OPEN, pReq->u.In.cbImageBits > 0); 1738 REQ_CHECK_EXPR(SUP_IOCTL_LDR_OPEN, pReq->u.In.cbImageBits > 0); 1739 REQ_CHECK_EXPR(SUP_IOCTL_LDR_OPEN, pReq->u.In.cbImageBits < pReq->u.In.cbImageWithTabs); 1738 REQ_CHECK_EXPR(SUP_IOCTL_LDR_OPEN, pReq->u.In.cbImageBits < pReq->u.In.cbImageWithEverything); 1740 1739 REQ_CHECK_EXPR(SUP_IOCTL_LDR_OPEN, pReq->u.In.szName[0]); 1741 1740 REQ_CHECK_EXPR(SUP_IOCTL_LDR_OPEN, RTStrEnd(pReq->u.In.szName, sizeof(pReq->u.In.szName))); … … 1753 1752 PSUPLDRLOAD pReq = (PSUPLDRLOAD)pReqHdr; 1754 1753 REQ_CHECK_EXPR(Name, pReq->Hdr.cbIn >= SUP_IOCTL_LDR_LOAD_SIZE_IN(32)); 1755 REQ_CHECK_SIZES_EX(SUP_IOCTL_LDR_LOAD, SUP_IOCTL_LDR_LOAD_SIZE_IN(pReq->u.In.cbImageWithTabs), SUP_IOCTL_LDR_LOAD_SIZE_OUT); 1756 REQ_CHECK_EXPR(SUP_IOCTL_LDR_LOAD, pReq->u.In.cSymbols <= 16384); 1754 REQ_CHECK_SIZES_EX(SUP_IOCTL_LDR_LOAD, SUP_IOCTL_LDR_LOAD_SIZE_IN(pReq->u.In.cbImageWithEverything), SUP_IOCTL_LDR_LOAD_SIZE_OUT); 1757 1755 REQ_CHECK_EXPR_FMT( !pReq->u.In.cSymbols 1758 || ( pReq->u.In.offSymbols < pReq->u.In.cbImageWithTabs 1759 && pReq->u.In.offSymbols + pReq->u.In.cSymbols * sizeof(SUPLDRSYM) <= pReq->u.In.cbImageWithTabs), 1760 ("SUP_IOCTL_LDR_LOAD: offSymbols=%#lx cSymbols=%#lx cbImageWithTabs=%#lx\n", (long)pReq->u.In.offSymbols, 1761 (long)pReq->u.In.cSymbols, (long)pReq->u.In.cbImageWithTabs)); 1756 || ( pReq->u.In.cSymbols <= 16384 1757 && pReq->u.In.offSymbols >= pReq->u.In.cbImageBits 1758 && pReq->u.In.offSymbols < pReq->u.In.cbImageWithEverything 1759 && pReq->u.In.offSymbols + pReq->u.In.cSymbols * sizeof(SUPLDRSYM) <= pReq->u.In.cbImageWithEverything), 1760 ("SUP_IOCTL_LDR_LOAD: offSymbols=%#lx cSymbols=%#lx cbImageWithEverything=%#lx\n", (long)pReq->u.In.offSymbols, 1761 (long)pReq->u.In.cSymbols, (long)pReq->u.In.cbImageWithEverything)); 1762 1762 REQ_CHECK_EXPR_FMT( !pReq->u.In.cbStrTab 1763 || ( pReq->u.In.offStrTab < pReq->u.In.cbImageWithTabs 1764 && pReq->u.In.offStrTab + pReq->u.In.cbStrTab <= pReq->u.In.cbImageWithTabs 1765 && pReq->u.In.cbStrTab <= pReq->u.In.cbImageWithTabs), 1766 ("SUP_IOCTL_LDR_LOAD: offStrTab=%#lx cbStrTab=%#lx cbImageWithTabs=%#lx\n", (long)pReq->u.In.offStrTab, 1767 (long)pReq->u.In.cbStrTab, (long)pReq->u.In.cbImageWithTabs)); 1763 || ( pReq->u.In.offStrTab < pReq->u.In.cbImageWithEverything 1764 && pReq->u.In.offStrTab >= pReq->u.In.cbImageBits 1765 && pReq->u.In.offStrTab + pReq->u.In.cbStrTab <= pReq->u.In.cbImageWithEverything 1766 && pReq->u.In.cbStrTab <= pReq->u.In.cbImageWithEverything), 1767 ("SUP_IOCTL_LDR_LOAD: offStrTab=%#lx cbStrTab=%#lx cbImageWithEverything=%#lx\n", (long)pReq->u.In.offStrTab, 1768 (long)pReq->u.In.cbStrTab, (long)pReq->u.In.cbImageWithEverything)); 1769 REQ_CHECK_EXPR_FMT( pReq->u.In.cSegments >= 1 1770 && pReq->u.In.cSegments <= 128 1771 && pReq->u.In.cSegments <= pReq->u.In.cbImageBits / PAGE_SIZE 1772 && pReq->u.In.offSegments >= pReq->u.In.cbImageBits 1773 && pReq->u.In.offSegments < pReq->u.In.cbImageWithEverything 1774 && pReq->u.In.offSegments + pReq->u.In.cSegments * sizeof(SUPLDRSEG) <= pReq->u.In.cbImageWithEverything, 1775 ("SUP_IOCTL_LDR_LOAD: offSegments=%#lx cSegments=%#lx cbImageWithEverything=%#lx\n", (long)pReq->u.In.offSegments, 1776 (long)pReq->u.In.cSegments, (long)pReq->u.In.cbImageWithEverything)); 1768 1777 1769 1778 if (pReq->u.In.cSymbols) … … 1773 1782 for (i = 0; i < pReq->u.In.cSymbols; i++) 1774 1783 { 1775 REQ_CHECK_EXPR_FMT(paSyms[i].offSymbol < pReq->u.In.cbImageWith Tabs,1776 ("SUP_IOCTL_LDR_LOAD: sym #%ld: symb off %#lx (max=%#lx)\n", (long)i, (long)paSyms[i].offSymbol, (long)pReq->u.In.cbImageWith Tabs));1784 REQ_CHECK_EXPR_FMT(paSyms[i].offSymbol < pReq->u.In.cbImageWithEverything, 1785 ("SUP_IOCTL_LDR_LOAD: sym #%ld: symb off %#lx (max=%#lx)\n", (long)i, (long)paSyms[i].offSymbol, (long)pReq->u.In.cbImageWithEverything)); 1777 1786 REQ_CHECK_EXPR_FMT(paSyms[i].offName < pReq->u.In.cbStrTab, 1778 ("SUP_IOCTL_LDR_LOAD: sym #%ld: name off %#lx (max=%#lx)\n", (long)i, (long)paSyms[i].offName, (long)pReq->u.In.cbImageWith Tabs));1787 ("SUP_IOCTL_LDR_LOAD: sym #%ld: name off %#lx (max=%#lx)\n", (long)i, (long)paSyms[i].offName, (long)pReq->u.In.cbImageWithEverything)); 1779 1788 REQ_CHECK_EXPR_FMT(RTStrEnd((char const *)&pReq->u.In.abImage[pReq->u.In.offStrTab + paSyms[i].offName], 1780 1789 pReq->u.In.cbStrTab - paSyms[i].offName), 1781 ("SUP_IOCTL_LDR_LOAD: sym #%ld: unterminated name! (%#lx / %#lx)\n", (long)i, (long)paSyms[i].offName, (long)pReq->u.In.cbImageWith Tabs));1790 ("SUP_IOCTL_LDR_LOAD: sym #%ld: unterminated name! (%#lx / %#lx)\n", (long)i, (long)paSyms[i].offName, (long)pReq->u.In.cbImageWithEverything)); 1782 1791 } 1792 } 1793 { 1794 uint32_t i; 1795 uint32_t offPrevEnd = 0; 1796 PSUPLDRSEG paSegs = (PSUPLDRSEG)&pReq->u.In.abImage[pReq->u.In.offSegments]; 1797 for (i = 0; i < pReq->u.In.cSegments; i++) 1798 { 1799 REQ_CHECK_EXPR_FMT(paSegs[i].off < pReq->u.In.cbImageBits && !(paSegs[i].off & PAGE_OFFSET_MASK), 1800 ("SUP_IOCTL_LDR_LOAD: seg #%ld: off %#lx (max=%#lx)\n", (long)i, (long)paSegs[i].off, (long)pReq->u.In.cbImageBits)); 1801 REQ_CHECK_EXPR_FMT(paSegs[i].cb <= pReq->u.In.cbImageBits, 1802 ("SUP_IOCTL_LDR_LOAD: seg #%ld: cb %#lx (max=%#lx)\n", (long)i, (long)paSegs[i].cb, (long)pReq->u.In.cbImageBits)); 1803 REQ_CHECK_EXPR_FMT(paSegs[i].off + paSegs[i].cb <= pReq->u.In.cbImageBits, 1804 ("SUP_IOCTL_LDR_LOAD: seg #%ld: off %#lx + cb %#lx = %#lx (max=%#lx)\n", (long)i, (long)paSegs[i].off, (long)paSegs[i].cb, (long)(paSegs[i].off + paSegs[i].cb), (long)pReq->u.In.cbImageBits)); 1805 REQ_CHECK_EXPR_FMT(paSegs[i].fProt != 0, 1806 ("SUP_IOCTL_LDR_LOAD: seg #%ld: off %#lx + cb %#lx\n", (long)i, (long)paSegs[i].off, (long)paSegs[i].cb)); 1807 REQ_CHECK_EXPR_FMT(paSegs[i].fUnused == 0, ("SUP_IOCTL_LDR_LOAD: seg #%ld: off %#lx\n", (long)i, (long)paSegs[i].off)); 1808 REQ_CHECK_EXPR_FMT(offPrevEnd == paSegs[i].off, 1809 ("SUP_IOCTL_LDR_LOAD: seg #%ld: off %#lx offPrevEnd %#lx\n", (long)i, (long)paSegs[i].off, (long)offPrevEnd)); 1810 offPrevEnd = paSegs[i].off + paSegs[i].cb; 1811 } 1812 REQ_CHECK_EXPR_FMT(offPrevEnd == pReq->u.In.cbImageBits, 1813 ("SUP_IOCTL_LDR_LOAD: offPrevEnd %#lx cbImageBits %#lx\n", (long)i, (long)offPrevEnd, (long)pReq->u.In.cbImageBits)); 1783 1814 } 1784 1815 … … 5024 5055 SUPDRV_CHECK_SMAP_SETUP(); 5025 5056 SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING); 5026 LogFlow(("supdrvIOCtl_LdrOpen: szName=%s cbImageWith Tabs=%d\n", pReq->u.In.szName, pReq->u.In.cbImageWithTabs));5057 LogFlow(("supdrvIOCtl_LdrOpen: szName=%s cbImageWithEverything=%d\n", pReq->u.In.szName, pReq->u.In.cbImageWithEverything)); 5027 5058 5028 5059 /* … … 5038 5069 if (RT_LIKELY(pImage->cUsage < UINT32_MAX / 2U)) 5039 5070 { 5040 /** @todo check cbImageBits and cbImageWithTabs here, if they differs that indicates that the images are different. */ 5071 /** @todo check cbImageBits and cbImageWithEverything here, if they differs 5072 * that indicates that the images are different. */ 5041 5073 pImage->cUsage++; 5042 5074 pReq->u.Out.pvImageBase = pImage->pvImage; … … 5081 5113 pImage = (PSUPDRVLDRIMAGE)pv; 5082 5114 pImage->pvImage = NULL; 5115 #ifdef SUPDRV_USE_MEMOBJ_FOR_LDR_IMAGE 5116 pImage->hMemObjImage = NIL_RTR0MEMOBJ; 5117 #else 5083 5118 pImage->pvImageAlloc = NULL; 5084 pImage->cbImageWithTabs = pReq->u.In.cbImageWithTabs; 5119 #endif 5120 pImage->cbImageWithEverything = pReq->u.In.cbImageWithEverything; 5085 5121 pImage->cbImageBits = pReq->u.In.cbImageBits; 5086 5122 pImage->cSymbols = 0; … … 5088 5124 pImage->pachStrTab = NULL; 5089 5125 pImage->cbStrTab = 0; 5126 pImage->cSegments = 0; 5127 pImage->paSegments = NULL; 5090 5128 pImage->pfnModuleInit = NULL; 5091 5129 pImage->pfnModuleTerm = NULL; … … 5105 5143 if (rc == VERR_NOT_SUPPORTED) 5106 5144 { 5145 #ifdef SUPDRV_USE_MEMOBJ_FOR_LDR_IMAGE 5146 rc = RTR0MemObjAllocPage(&pImage->hMemObjImage, pImage->cbImageBits, true /*fExecutable*/); 5147 if (RT_SUCCESS(rc)) 5148 { 5149 pImage->pvImage = RTR0MemObjAddress(pImage->hMemObjImage); 5150 pImage->fNative = false; 5151 } 5152 #else 5107 5153 pImage->pvImageAlloc = RTMemExecAlloc(pImage->cbImageBits + 31); 5108 5154 pImage->pvImage = RT_ALIGN_P(pImage->pvImageAlloc, 32); 5109 5155 pImage->fNative = false; 5110 5156 rc = pImage->pvImageAlloc ? VINF_SUCCESS : VERR_NO_EXEC_MEMORY; 5157 #endif 5111 5158 SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING); 5112 5159 } … … 5136 5183 supdrvLdrUnlock(pDevExt); 5137 5184 SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING); 5138 return VINF_SUCCESS;5139 }5140 5141 5142 /**5143 * Worker that validates a pointer to an image entrypoint.5144 *5145 * @returns IPRT status code.5146 * @param pDevExt The device globals.5147 * @param pImage The loader image.5148 * @param pv The pointer into the image.5149 * @param fMayBeNull Whether it may be NULL.5150 * @param fCheckNative Whether to check with the native loaders.5151 * @param pszSymbol The entrypoint name or log name. If the symbol5152 * capitalized it signifies a specific symbol, otherwise it5153 * for logging.5154 * @param pbImageBits The image bits prepared by ring-3.5155 *5156 * @remarks Will leave the lock on failure.5157 */5158 static int supdrvLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, bool fMayBeNull,5159 bool fCheckNative, const uint8_t *pbImageBits, const char *pszSymbol)5160 {5161 if (!fMayBeNull || pv)5162 {5163 if ((uintptr_t)pv - (uintptr_t)pImage->pvImage >= pImage->cbImageBits)5164 {5165 supdrvLdrUnlock(pDevExt);5166 Log(("Out of range (%p LB %#x): %s=%p\n", pImage->pvImage, pImage->cbImageBits, pszSymbol, pv));5167 return VERR_INVALID_PARAMETER;5168 }5169 5170 if (pImage->fNative && fCheckNative)5171 {5172 int rc = supdrvOSLdrValidatePointer(pDevExt, pImage, pv, pbImageBits, pszSymbol);5173 if (RT_FAILURE(rc))5174 {5175 supdrvLdrUnlock(pDevExt);5176 Log(("Bad entry point address: %s=%p (rc=%Rrc)\n", pszSymbol, pv, rc));5177 return rc;5178 }5179 }5180 }5181 5185 return VINF_SUCCESS; 5182 5186 } … … 5205 5209 5206 5210 /** 5211 * Worker that validates a pointer to an image entrypoint. 5212 * 5213 * Calls supdrvLdrLoadError on error. 5214 * 5215 * @returns IPRT status code. 5216 * @param pDevExt The device globals. 5217 * @param pImage The loader image. 5218 * @param pv The pointer into the image. 5219 * @param fMayBeNull Whether it may be NULL. 5220 * @param pszSymbol The entrypoint name or log name. If the symbol is 5221 * capitalized it signifies a specific symbol, otherwise it 5222 * for logging. 5223 * @param pbImageBits The image bits prepared by ring-3. 5224 * @param pReq The request for passing to supdrvLdrLoadError. 5225 * 5226 * @note Will leave the loader lock on failure! 5227 */ 5228 static int supdrvLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, bool fMayBeNull, 5229 const uint8_t *pbImageBits, const char *pszSymbol, PSUPLDRLOAD pReq) 5230 { 5231 if (!fMayBeNull || pv) 5232 { 5233 uint32_t iSeg; 5234 5235 /* Must be within the image bits: */ 5236 uintptr_t const uRva = (uintptr_t)pv - (uintptr_t)pImage->pvImage; 5237 if (uRva >= pImage->cbImageBits) 5238 { 5239 supdrvLdrUnlock(pDevExt); 5240 return supdrvLdrLoadError(VERR_INVALID_PARAMETER, pReq, 5241 "Invalid entry point address %p given for %s: RVA %#zx, image size %#zx", 5242 pv, pszSymbol, uRva, pImage->cbImageBits); 5243 } 5244 5245 /* Must be in an executable segment: */ 5246 for (iSeg = 0; iSeg < pImage->cSegments; iSeg++) 5247 if (uRva - pImage->paSegments[iSeg].off < (uintptr_t)pImage->paSegments[iSeg].cb) 5248 { 5249 if (pImage->paSegments[iSeg].fProt & SUPLDR_PROT_EXEC) 5250 break; 5251 supdrvLdrUnlock(pDevExt); 5252 return supdrvLdrLoadError(VERR_INVALID_PARAMETER, pReq, 5253 "Bad entry point %p given for %s: not executable (seg #%u: %#RX32 LB %#RX32 prot %#x)", 5254 pv, pszSymbol, iSeg, pImage->paSegments[iSeg].off, pImage->paSegments[iSeg].cb, 5255 pImage->paSegments[iSeg].fProt); 5256 } 5257 5258 if (pImage->fNative) 5259 { 5260 /** @todo pass pReq along to the native code. */ 5261 int rc = supdrvOSLdrValidatePointer(pDevExt, pImage, pv, pbImageBits, pszSymbol); 5262 if (RT_FAILURE(rc)) 5263 { 5264 supdrvLdrUnlock(pDevExt); 5265 return supdrvLdrLoadError(VERR_INVALID_PARAMETER, pReq, 5266 "Bad entry point address %p for %s: rc=%Rrc\n", pv, pszSymbol, rc); 5267 } 5268 } 5269 } 5270 return VINF_SUCCESS; 5271 } 5272 5273 5274 /** 5207 5275 * Loads the image bits. 5208 5276 * … … 5220 5288 int rc; 5221 5289 SUPDRV_CHECK_SMAP_SETUP(); 5222 LogFlow(("supdrvIOCtl_LdrLoad: pvImageBase=%p cbImageWith Bits=%d\n", pReq->u.In.pvImageBase, pReq->u.In.cbImageWithTabs));5290 LogFlow(("supdrvIOCtl_LdrLoad: pvImageBase=%p cbImageWithEverything=%d\n", pReq->u.In.pvImageBase, pReq->u.In.cbImageWithEverything)); 5223 5291 SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING); 5224 5292 … … 5242 5310 * Validate input. 5243 5311 */ 5244 if ( pImage->cbImageWith Tabs != pReq->u.In.cbImageWithTabs5245 || pImage->cbImageBits != pReq->u.In.cbImageBits)5312 if ( pImage->cbImageWithEverything != pReq->u.In.cbImageWithEverything 5313 || pImage->cbImageBits != pReq->u.In.cbImageBits) 5246 5314 { 5247 5315 supdrvLdrUnlock(pDevExt); 5248 return supdrvLdrLoadError(VERR_INVALID_HANDLE, pReq, "Image size mismatch found: % d(prep) != %d(load) or %d != %d",5249 pImage->cbImageWith Tabs, pReq->u.In.cbImageWithTabs, pImage->cbImageBits, pReq->u.In.cbImageBits);5316 return supdrvLdrLoadError(VERR_INVALID_HANDLE, pReq, "Image size mismatch found: %u(prep) != %u(load) or %u != %u", 5317 pImage->cbImageWithEverything, pReq->u.In.cbImageWithEverything, pImage->cbImageBits, pReq->u.In.cbImageBits); 5250 5318 } 5251 5319 … … 5273 5341 5274 5342 case SUPLDRLOADEP_VMMR0: 5275 rc = supdrvLdrValidatePointer( pDevExt, pImage, pReq->u.In.EP.VMMR0.pvVMMR0, false, false, pReq->u.In.abImage, "pvVMMR0"); 5276 if (RT_SUCCESS(rc)) 5277 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.EP.VMMR0.pvVMMR0EntryFast, false, true, pReq->u.In.abImage, "VMMR0EntryFast"); 5278 if (RT_SUCCESS(rc)) 5279 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.EP.VMMR0.pvVMMR0EntryEx, false, true, pReq->u.In.abImage, "VMMR0EntryEx"); 5343 if (pReq->u.In.EP.VMMR0.pvVMMR0 != pImage->pvImage) 5344 { 5345 supdrvLdrUnlock(pDevExt); 5346 return supdrvLdrLoadError(rc, pReq, "Invalid pvVMMR0 pointer: %p, expected %p", pReq->u.In.EP.VMMR0.pvVMMR0, pImage->pvImage); 5347 } 5348 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.EP.VMMR0.pvVMMR0EntryFast, false, pReq->u.In.abImage, "VMMR0EntryFast", pReq); 5280 5349 if (RT_FAILURE(rc)) 5281 return supdrvLdrLoadError(rc, pReq, "Invalid VMMR0 pointer"); 5350 return rc; 5351 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.EP.VMMR0.pvVMMR0EntryEx, false, pReq->u.In.abImage, "VMMR0EntryEx", pReq); 5352 if (RT_FAILURE(rc)) 5353 return rc; 5282 5354 break; 5283 5355 5284 5356 case SUPLDRLOADEP_SERVICE: 5285 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.EP.Service.pfnServiceReq, false, true, pReq->u.In.abImage, "pfnServiceReq");5357 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.EP.Service.pfnServiceReq, false, pReq->u.In.abImage, "pfnServiceReq", pReq); 5286 5358 if (RT_FAILURE(rc)) 5287 return supdrvLdrLoadError(rc, pReq, "Invalid pfnServiceReq pointer: %p", pReq->u.In.EP.Service.pfnServiceReq);5359 return rc; 5288 5360 if ( pReq->u.In.EP.Service.apvReserved[0] != NIL_RTR0PTR 5289 5361 || pReq->u.In.EP.Service.apvReserved[1] != NIL_RTR0PTR … … 5291 5363 { 5292 5364 supdrvLdrUnlock(pDevExt); 5293 return supdrvLdrLoadError(VERR_INVALID_PARAMETER, pReq, 5294 "Out of range (%p LB %#x): apvReserved={%p,%p,%p} MBZ!", 5295 pImage->pvImage, pReq->u.In.cbImageWithTabs, 5296 pReq->u.In.EP.Service.apvReserved[0], 5297 pReq->u.In.EP.Service.apvReserved[1], 5365 return supdrvLdrLoadError(VERR_INVALID_PARAMETER, pReq, "apvReserved={%p,%p,%p} MBZ!", 5366 pReq->u.In.EP.Service.apvReserved[0], pReq->u.In.EP.Service.apvReserved[1], 5298 5367 pReq->u.In.EP.Service.apvReserved[2]); 5299 5368 } … … 5305 5374 } 5306 5375 5307 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.pfnModuleInit, true, true, pReq->u.In.abImage, "ModuleInit");5376 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.pfnModuleInit, true, pReq->u.In.abImage, "ModuleInit", pReq); 5308 5377 if (RT_FAILURE(rc)) 5309 return supdrvLdrLoadError(rc, pReq, "Invalid pfnModuleInit pointer: %p", pReq->u.In.pfnModuleInit);5310 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.pfnModuleTerm, true, true, pReq->u.In.abImage, "ModuleTerm");5378 return rc; 5379 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.pfnModuleTerm, true, pReq->u.In.abImage, "ModuleTerm", pReq); 5311 5380 if (RT_FAILURE(rc)) 5312 return supdrvLdrLoadError(rc, pReq, "Invalid pfnModuleTerm pointer: %p", pReq->u.In.pfnModuleTerm);5381 return rc; 5313 5382 SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING); 5314 5383 … … 5322 5391 if (pImage->cbStrTab) 5323 5392 { 5324 pImage->pachStrTab = (char *)RTMemAlloc(pImage->cbStrTab); 5325 if (pImage->pachStrTab) 5326 memcpy(pImage->pachStrTab, &pReq->u.In.abImage[pReq->u.In.offStrTab], pImage->cbStrTab); 5327 else 5393 pImage->pachStrTab = (char *)RTMemDup(&pReq->u.In.abImage[pReq->u.In.offStrTab], pImage->cbStrTab); 5394 if (!pImage->pachStrTab) 5328 5395 rc = supdrvLdrLoadError(VERR_NO_MEMORY, pReq, "Out of memory for string table: %#x", pImage->cbStrTab); 5329 5396 SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING); … … 5334 5401 { 5335 5402 size_t cbSymbols = pImage->cSymbols * sizeof(SUPLDRSYM); 5336 pImage->paSymbols = (PSUPLDRSYM)RTMemAlloc(cbSymbols); 5337 if (pImage->paSymbols) 5338 memcpy(pImage->paSymbols, &pReq->u.In.abImage[pReq->u.In.offSymbols], cbSymbols); 5339 else 5403 pImage->paSymbols = (PSUPLDRSYM)RTMemDup(&pReq->u.In.abImage[pReq->u.In.offSymbols], cbSymbols); 5404 if (!pImage->paSymbols) 5340 5405 rc = supdrvLdrLoadError(VERR_NO_MEMORY, pReq, "Out of memory for symbol table: %#x", cbSymbols); 5341 5406 SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING); 5342 5407 } 5343 } 5344 5345 /* 5346 * Copy the bits / complete native loading. 5408 5409 pImage->cSegments = pReq->u.In.cSegments; 5410 if (RT_SUCCESS(rc)) 5411 { 5412 size_t cbSegments = pImage->cSegments * sizeof(SUPLDRSEG); 5413 pImage->paSegments = (PSUPLDRSEG)RTMemDup(&pReq->u.In.abImage[pReq->u.In.offSegments], cbSegments); 5414 if (pImage->paSegments) /* Align the last segment size to avoid upsetting RTR0MemObjProtect. */ /** @todo relax RTR0MemObjProtect */ 5415 pImage->paSegments[pImage->cSegments - 1].cb = RT_ALIGN_32(pImage->paSegments[pImage->cSegments - 1].cb, PAGE_SIZE); 5416 else 5417 rc = supdrvLdrLoadError(VERR_NO_MEMORY, pReq, "Out of memory for segment table: %#x", cbSegments); 5418 SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING); 5419 } 5420 } 5421 5422 /* 5423 * Copy the bits and apply permissions / complete native loading. 5347 5424 */ 5348 5425 if (RT_SUCCESS(rc)) … … 5356 5433 else 5357 5434 { 5435 #ifdef SUPDRV_USE_MEMOBJ_FOR_LDR_IMAGE 5436 uint32_t i; 5358 5437 memcpy(pImage->pvImage, &pReq->u.In.abImage[0], pImage->cbImageBits); 5438 5439 for (i = 0; i < pImage->cSegments; i++) 5440 { 5441 rc = RTR0MemObjProtect(pImage->hMemObjImage, pImage->paSegments[i].off, pImage->paSegments[i].cb, 5442 pImage->paSegments[i].fProt); 5443 if (RT_SUCCESS(rc)) 5444 continue; 5445 if (rc == VERR_NOT_SUPPORTED) 5446 rc = VINF_SUCCESS; 5447 else 5448 rc = supdrvLdrLoadError(rc, pReq, "RTR0MemObjProtect failed on seg#%u %#RX32 LB %#RX32 fProt=%#x", 5449 i, pImage->paSegments[i].off, pImage->paSegments[i].cb, pImage->paSegments[i].fProt); 5450 break; 5451 } 5452 #else 5453 memcpy(pImage->pvImage, &pReq->u.In.abImage[0], pImage->cbImageBits); 5454 #endif 5359 5455 Log(("vboxdrv: Loaded '%s' at %p\n", pImage->szName, pImage->pvImage)); 5360 5456 } … … 5951 6047 pImage->pNext = NULL; 5952 6048 pImage->uState = SUP_IOCTL_LDR_FREE; 6049 #ifdef SUPDRV_USE_MEMOBJ_FOR_LDR_IMAGE 6050 RTR0MemObjFree(pImage->hMemObjImage, true /*fMappings*/); 6051 pImage->hMemObjImage = NIL_RTR0MEMOBJ; 6052 #else 5953 6053 RTMemExecFree(pImage->pvImageAlloc, pImage->cbImageBits + 31); 5954 6054 pImage->pvImageAlloc = NULL; 6055 #endif 6056 pImage->pvImage = NULL; 5955 6057 RTMemFree(pImage->pachStrTab); 5956 6058 pImage->pachStrTab = NULL; 5957 6059 RTMemFree(pImage->paSymbols); 5958 6060 pImage->paSymbols = NULL; 6061 RTMemFree(pImage->paSegments); 6062 pImage->paSegments = NULL; 5959 6063 RTMemFree(pImage); 5960 6064 } -
trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h
r85450 r85507 221 221 * 222 222 * @todo Pending work on next major version change: 223 * - Move SUP_IOCTL_FAST_DO_NOP and SUP_VMMR0_DO_NEM_RUN after NEM.224 */ 225 #define SUPDRV_IOC_VERSION 0x002 d0002223 * - Nothing. 224 */ 225 #define SUPDRV_IOC_VERSION 0x002e0000 226 226 227 227 /** SUP_IOCTL_COOKIE. */ … … 315 315 struct 316 316 { 317 /** Size of the image we'll be loading (including tables). */318 uint32_t cbImageWith Tabs;317 /** Size of the image we'll be loading (including all tables). */ 318 uint32_t cbImageWithEverything; 319 319 /** The size of the image bits. (Less or equal to cbImageWithTabs.) */ 320 320 uint32_t cbImageBits; … … 390 390 /** Pointer to a const symbol table entry. */ 391 391 typedef SUPLDRSYM const *PCSUPLDRSYM; 392 393 #define SUPLDR_PROT_READ 1 /**< Grant read access (RTMEM_PROT_READ). */ 394 #define SUPLDR_PROT_WRITE 2 /**< Grant write access (RTMEM_PROT_WRITE). */ 395 #define SUPLDR_PROT_EXEC 4 /**< Grant execute access (RTMEM_PROT_EXEC). */ 396 397 /** 398 * A segment table entry - chiefly for conveying memory protection. 399 */ 400 typedef struct SUPLDRSEG 401 { 402 /** The RVA of the segment. */ 403 uint32_t off; 404 /** The size of the segment. */ 405 uint32_t cb : 28; 406 /** The segment protection (SUPLDR_PROT_XXX). */ 407 uint32_t fProt : 3; 408 /** MBZ. */ 409 uint32_t fUnused; 410 } SUPLDRSEG; 411 /** Pointer to a segment table entry. */ 412 typedef SUPLDRSEG *PSUPLDRSEG; 413 /** Pointer to a const segment table entry. */ 414 typedef SUPLDRSEG const *PCSUPLDRSEG; 392 415 393 416 /** … … 444 467 * approaching offSymbols). */ 445 468 uint32_t cbImageBits; 446 /** The offset of the symbol table . */469 /** The offset of the symbol table (SUPLDRSYM array). */ 447 470 uint32_t offSymbols; 448 471 /** The number of entries in the symbol table. */ … … 452 475 /** Size of the string table. */ 453 476 uint32_t cbStrTab; 477 /** Offset to the segment table (SUPLDRSEG array). */ 478 uint32_t offSegments; 479 /** Number of segments. */ 480 uint32_t cSegments; 454 481 /** Size of image data in achImage. */ 455 uint32_t cbImageWith Tabs;482 uint32_t cbImageWithEverything; 456 483 /** The image data. */ 457 484 uint8_t abImage[1]; -
trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
r85174 r85507 144 144 * @todo fix the mutex implementation on linux and make this the default. */ 145 145 # define SUPDRV_USE_MUTEX_FOR_GIP 146 #endif 147 148 149 #if 0 /*def RT_OS_LINUX*/ 150 /** Use the RTR0MemObj API rather than the RTMemExecAlloc for the images. 151 * This is a good idea in general, but a necessity for @bugref{9801}. */ 152 # define SUPDRV_USE_MEMOBJ_FOR_LDR_IMAGE 146 153 #endif 147 154 … … 327 334 /** Pointer to the image. */ 328 335 void *pvImage; 336 #ifdef SUPDRV_USE_MEMOBJ_FOR_LDR_IMAGE 337 /** The memory object for the module allocation. */ 338 RTR0MEMOBJ hMemObjImage; 339 #else 329 340 /** Pointer to the allocated image buffer. 330 341 * pvImage is 32-byte aligned or it may governed by the native loader (this 331 342 * member is NULL then). */ 332 343 void *pvImageAlloc; 344 #endif 333 345 /** Magic value (SUPDRVLDRIMAGE_MAGIC). */ 334 346 uint32_t uMagic; 335 347 /** Size of the image including the tables. This is mainly for verification 336 348 * of the load request. */ 337 uint32_t cbImageWith Tabs;349 uint32_t cbImageWithEverything; 338 350 /** Size of the image. */ 339 351 uint32_t cbImageBits; … … 346 358 /** Size of the string table. */ 347 359 uint32_t cbStrTab; 360 /** Number of segments. */ 361 uint32_t cSegments; 362 /** Segments (for memory protection). */ 363 PSUPLDRSEG paSegments; 348 364 /** Pointer to the optional module initialization callback. */ 349 365 PFNR0MODULEINIT pfnModuleInit; -
trunk/src/VBox/HostDrivers/Support/SUPLib.cpp
r85450 r85507 276 276 strcpy(CookieReq.u.In.szMagic, SUPCOOKIE_MAGIC); 277 277 CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION; 278 const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x002d0000278 const uint32_t uMinVersion = /*(SUPDRV_IOC_VERSION & 0xffff0000) == 0x002d0000 279 279 ? 0x002d0002 280 : SUPDRV_IOC_VERSION & 0xffff0000;280 :*/ SUPDRV_IOC_VERSION & 0xffff0000; 281 281 CookieReq.u.In.u32MinVersion = uMinVersion; 282 282 rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_COOKIE, &CookieReq, SUP_IOCTL_COOKIE_SIZE); -
trunk/src/VBox/HostDrivers/Support/SUPLibLdr.cpp
r85506 r85507 335 335 336 336 337 /** Argument package for supLoadModuleCompileSegmentsCB. */ 338 typedef struct SUPLDRCOMPSEGTABARGS 339 { 340 uint32_t uStartRva; 341 uint32_t uEndRva; 342 uint32_t fProt; 343 uint32_t iSegs; 344 uint32_t cSegsAlloc; 345 PSUPLDRSEG paSegs; 346 PRTERRINFO pErrInfo; 347 } SUPLDRCOMPSEGTABARGS, *PSUPLDRCOMPSEGTABARGS; 348 349 /** 350 * @callback_method_impl{FNRTLDRENUMSEGS, 351 * Compile list of segments with the same memory protection.} 352 */ 353 static DECLCALLBACK(int) supLoadModuleCompileSegmentsCB(RTLDRMOD hLdrMod, PCRTLDRSEG pSeg, void *pvUser) 354 { 355 PSUPLDRCOMPSEGTABARGS pArgs = (PSUPLDRCOMPSEGTABARGS)pvUser; 356 AssertCompile(RTMEM_PROT_READ == SUPLDR_PROT_READ); 357 AssertCompile(RTMEM_PROT_WRITE == SUPLDR_PROT_WRITE); 358 AssertCompile(RTMEM_PROT_EXEC == SUPLDR_PROT_EXEC); 359 RT_NOREF(hLdrMod); 360 361 /* Ignore segments not part of the loaded image. */ 362 if (pSeg->RVA == NIL_RTLDRADDR || pSeg->cbMapped == 0) 363 return VINF_SUCCESS; 364 365 /* We currently ASSUME that all relevant segments are in ascending RVA order. */ 366 AssertReturn(pSeg->RVA >= pArgs->uEndRva, 367 RTERRINFO_LOG_REL_SET_F(pArgs->pErrInfo, VERR_BAD_EXE_FORMAT, "Out of order segment: %p LB %#zx #%.*s", 368 pSeg->RVA, pSeg->cb, pSeg->cchName, pSeg->pszName)); 369 370 /* We ASSUME the cbMapped field is implemented. */ 371 AssertReturn(pSeg->cbMapped != NIL_RTLDRADDR, VERR_INTERNAL_ERROR_2); 372 AssertReturn(pSeg->cbMapped < _1G, VERR_INTERNAL_ERROR_4); 373 uint32_t cbMapped = (uint32_t)pSeg->cbMapped; 374 AssertReturn(pSeg->RVA < _1G, VERR_INTERNAL_ERROR_3); 375 uint32_t uRvaSeg = (uint32_t)pSeg->RVA; 376 Log2(("supLoadModuleCompileSegmentsCB: %RTptr/%RTptr LB %RTptr prot %#x %s\n", 377 pSeg->LinkAddress, pSeg->RVA, pSeg->cbMapped, pSeg->fProt, pSeg->pszName)); 378 379 /* 380 * If the protection is the same as the previous segment, 381 * just update uEndRva and continue. 382 */ 383 uint32_t fProt = pSeg->fProt; 384 #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) 385 if (fProt & RTMEM_PROT_EXEC) 386 fProt |= fProt & RTMEM_PROT_READ; 387 #endif 388 if (pSeg->fProt == pArgs->fProt) 389 { 390 pArgs->uEndRva = uRvaSeg + cbMapped; 391 Log2(("supLoadModuleCompileSegmentsCB: -> merged\n")); 392 return VINF_SUCCESS; 393 } 394 395 /* 396 * The protection differs, so commit current segment and start a new one. 397 * However, if the new segment and old segment share a page, this becomes 398 * a little more complicated... 399 */ 400 if (pArgs->uStartRva < pArgs->uEndRva) 401 { 402 if (((pArgs->uEndRva - 1) >> PAGE_SHIFT) != (uRvaSeg >> PAGE_SHIFT)) 403 { 404 /* No common page, so make the new segment start on a page boundrary. */ 405 cbMapped += uRvaSeg & PAGE_OFFSET_MASK; 406 uRvaSeg &= ~(uint32_t)PAGE_OFFSET_MASK; 407 Assert(pArgs->uEndRva <= uRvaSeg); 408 Log2(("supLoadModuleCompileSegmentsCB: -> new, no common\n")); 409 } 410 else if ((fProt & pArgs->fProt) == fProt) 411 { 412 /* The current segment includes the memory protections of the 413 previous, so include the common page in it: */ 414 uint32_t const cbCommon = PAGE_SIZE - (uRvaSeg & PAGE_OFFSET_MASK); 415 if (cbCommon >= cbMapped) 416 { 417 pArgs->uEndRva = uRvaSeg + cbMapped; 418 Log2(("supLoadModuleCompileSegmentsCB: -> merge, %#x common, upgrading prot to %#x\n", cbCommon, pArgs->fProt)); 419 return VINF_SUCCESS; /* New segment was smaller than a page. */ 420 } 421 cbMapped -= cbCommon; 422 uRvaSeg += cbCommon; 423 Assert(pArgs->uEndRva <= uRvaSeg); 424 Log2(("supLoadModuleCompileSegmentsCB: -> new, %#x common into previous\n", cbCommon)); 425 } 426 else if ((fProt & pArgs->fProt) == pArgs->fProt) 427 { 428 /* The new segment includes the memory protections of the 429 previous, so include the common page in it: */ 430 cbMapped += uRvaSeg & PAGE_OFFSET_MASK; 431 uRvaSeg &= ~(uint32_t)PAGE_OFFSET_MASK; 432 if (uRvaSeg == pArgs->uStartRva) 433 { 434 pArgs->fProt = fProt; 435 pArgs->uEndRva = uRvaSeg + cbMapped; 436 Log2(("supLoadModuleCompileSegmentsCB: -> upgrade current protection\n")); 437 return VINF_SUCCESS; /* Current segment was smaller than a page. */ 438 } 439 Log2(("supLoadModuleCompileSegmentsCB: -> new, %#x common into new\n", (uint32_t)(pSeg->RVA & PAGE_OFFSET_MASK))); 440 } 441 else 442 { 443 /* Create a new segment for the common page with the combined protection. */ 444 Log2(("supLoadModuleCompileSegmentsCB: -> its complicated...\n")); 445 pArgs->uEndRva &= ~(uint32_t)PAGE_OFFSET_MASK; 446 if (pArgs->uEndRva > pArgs->uStartRva) 447 { 448 Log2(("supLoadModuleCompileSegmentsCB: SUP Seg #%u: %#x LB %#x prot %#x\n", 449 pArgs->iSegs, pArgs->uStartRva, pArgs->uEndRva - pArgs->uStartRva, pArgs->fProt)); 450 if (pArgs->paSegs) 451 { 452 AssertReturn(pArgs->iSegs < pArgs->cSegsAlloc, VERR_INTERNAL_ERROR_5); 453 pArgs->paSegs[pArgs->iSegs].off = pArgs->uStartRva; 454 pArgs->paSegs[pArgs->iSegs].cb = pArgs->uEndRva - pArgs->uStartRva; 455 pArgs->paSegs[pArgs->iSegs].fProt = pArgs->fProt; 456 } 457 pArgs->iSegs++; 458 pArgs->uStartRva = pArgs->uEndRva; 459 } 460 pArgs->fProt |= fProt; 461 462 uint32_t const cbCommon = PAGE_SIZE - (uRvaSeg & PAGE_OFFSET_MASK); 463 if (cbCommon <= cbMapped) 464 { 465 fProt |= pArgs->fProt; 466 pArgs->uEndRva = uRvaSeg + cbMapped; 467 return VINF_SUCCESS; /* New segment was smaller than a page. */ 468 } 469 cbMapped -= cbCommon; 470 uRvaSeg += cbCommon; 471 Assert(uRvaSeg - pArgs->uStartRva == PAGE_SIZE); 472 } 473 474 /* The current segment should end where the new one starts, no gaps. */ 475 pArgs->uEndRva = uRvaSeg; 476 477 /* Emit the current segment */ 478 Log2(("supLoadModuleCompileSegmentsCB: SUP Seg #%u: %#x LB %#x prot %#x\n", 479 pArgs->iSegs, pArgs->uStartRva, pArgs->uEndRva - pArgs->uStartRva, pArgs->fProt)); 480 if (pArgs->paSegs) 481 { 482 AssertReturn(pArgs->iSegs < pArgs->cSegsAlloc, VERR_INTERNAL_ERROR_5); 483 pArgs->paSegs[pArgs->iSegs].off = pArgs->uStartRva; 484 pArgs->paSegs[pArgs->iSegs].cb = pArgs->uEndRva - pArgs->uStartRva; 485 pArgs->paSegs[pArgs->iSegs].fProt = pArgs->fProt; 486 } 487 pArgs->iSegs++; 488 } 489 /* else: current segment is empty */ 490 491 /* Start the new segment. */ 492 Assert(!(uRvaSeg & PAGE_OFFSET_MASK)); 493 pArgs->fProt = fProt; 494 pArgs->uStartRva = uRvaSeg; 495 pArgs->uEndRva = uRvaSeg + cbMapped; 496 return VINF_SUCCESS; 497 } 498 499 500 /** 501 * Worker for supLoadModule(). 502 */ 503 static int supLoadModuleInner(RTLDRMOD hLdrMod, PSUPLDRLOAD pLoadReq, uint32_t cbImageWithEverything, 504 RTR0PTR uImageBase, size_t cbImage, const char *pszModule, const char *pszFilename, 505 bool fNativeLoader, bool fIsVMMR0, const char *pszSrvReqHandler, 506 uint32_t offSymTab, uint32_t cSymbols, 507 uint32_t offStrTab, size_t cbStrTab, 508 uint32_t offSegTab, uint32_t cSegments, 509 PRTERRINFO pErrInfo) 510 { 511 /* 512 * Get the image bits. 513 */ 514 SUPLDRRESIMPARGS Args = { pszModule, pErrInfo }; 515 int rc = RTLdrGetBits(hLdrMod, &pLoadReq->u.In.abImage[0], uImageBase, supLoadModuleResolveImport, &Args); 516 if (RT_FAILURE(rc)) 517 { 518 LogRel(("SUP: RTLdrGetBits failed for %s (%s). rc=%Rrc\n", pszModule, pszFilename, rc)); 519 if (!RTErrInfoIsSet(pErrInfo)) 520 RTErrInfoSetF(pErrInfo, rc, "RTLdrGetBits failed"); 521 return rc; 522 } 523 524 /* 525 * Get the entry points. 526 */ 527 RTUINTPTR VMMR0EntryFast = 0; 528 RTUINTPTR VMMR0EntryEx = 0; 529 RTUINTPTR SrvReqHandler = 0; 530 RTUINTPTR ModuleInit = 0; 531 RTUINTPTR ModuleTerm = 0; 532 const char *pszEp = NULL; 533 if (fIsVMMR0) 534 { 535 rc = RTLdrGetSymbolEx(hLdrMod, &pLoadReq->u.In.abImage[0], uImageBase, 536 UINT32_MAX, pszEp = "VMMR0EntryFast", &VMMR0EntryFast); 537 if (RT_SUCCESS(rc)) 538 rc = RTLdrGetSymbolEx(hLdrMod, &pLoadReq->u.In.abImage[0], uImageBase, 539 UINT32_MAX, pszEp = "VMMR0EntryEx", &VMMR0EntryEx); 540 } 541 else if (pszSrvReqHandler) 542 rc = RTLdrGetSymbolEx(hLdrMod, &pLoadReq->u.In.abImage[0], uImageBase, 543 UINT32_MAX, pszEp = pszSrvReqHandler, &SrvReqHandler); 544 if (RT_SUCCESS(rc)) 545 { 546 int rc2 = RTLdrGetSymbolEx(hLdrMod, &pLoadReq->u.In.abImage[0], uImageBase, 547 UINT32_MAX, pszEp = "ModuleInit", &ModuleInit); 548 if (RT_FAILURE(rc2)) 549 ModuleInit = 0; 550 551 rc2 = RTLdrGetSymbolEx(hLdrMod, &pLoadReq->u.In.abImage[0], uImageBase, 552 UINT32_MAX, pszEp = "ModuleTerm", &ModuleTerm); 553 if (RT_FAILURE(rc2)) 554 ModuleTerm = 0; 555 } 556 if (RT_FAILURE(rc)) 557 { 558 LogRel(("SUP: Failed to get entry point '%s' for %s (%s) rc=%Rrc\n", pszEp, pszModule, pszFilename, rc)); 559 return RTErrInfoSetF(pErrInfo, rc, "Failed to resolve entry point '%s'", pszEp); 560 } 561 562 /* 563 * Create the symbol and string tables. 564 */ 565 SUPLDRCREATETABSARGS CreateArgs; 566 CreateArgs.cbImage = cbImage; 567 CreateArgs.pSym = (PSUPLDRSYM)&pLoadReq->u.In.abImage[offSymTab]; 568 CreateArgs.pszBase = (char *)&pLoadReq->u.In.abImage[offStrTab]; 569 CreateArgs.psz = CreateArgs.pszBase; 570 rc = RTLdrEnumSymbols(hLdrMod, 0, NULL, 0, supLoadModuleCreateTabsCB, &CreateArgs); 571 if (RT_FAILURE(rc)) 572 { 573 LogRel(("SUP: RTLdrEnumSymbols failed for %s (%s) rc=%Rrc\n", pszModule, pszFilename, rc)); 574 return RTErrInfoSetF(pErrInfo, rc, "RTLdrEnumSymbols #2 failed"); 575 } 576 AssertRelease((size_t)(CreateArgs.psz - CreateArgs.pszBase) <= cbStrTab); 577 AssertRelease((size_t)(CreateArgs.pSym - (PSUPLDRSYM)&pLoadReq->u.In.abImage[offSymTab]) <= cSymbols); 578 579 /* 580 * Create the segment table. 581 */ 582 SUPLDRCOMPSEGTABARGS SegArgs; 583 SegArgs.uStartRva = 0; 584 SegArgs.uEndRva = 0; 585 SegArgs.fProt = RTMEM_PROT_READ; 586 SegArgs.iSegs = 0; 587 SegArgs.cSegsAlloc = cSegments; 588 SegArgs.paSegs = (PSUPLDRSEG)&pLoadReq->u.In.abImage[offSegTab]; 589 SegArgs.pErrInfo = pErrInfo; 590 rc = RTLdrEnumSegments(hLdrMod, supLoadModuleCompileSegmentsCB, &SegArgs); 591 if (RT_FAILURE(rc)) 592 { 593 LogRel(("SUP: RTLdrEnumSegments failed for %s (%s) rc=%Rrc\n", pszModule, pszFilename, rc)); 594 return RTErrInfoSetF(pErrInfo, rc, "RTLdrEnumSegments #2 failed"); 595 } 596 SegArgs.uEndRva = cbImage; 597 if (SegArgs.uEndRva > SegArgs.uStartRva) 598 { 599 SegArgs.paSegs[SegArgs.iSegs].off = SegArgs.uStartRva; 600 SegArgs.paSegs[SegArgs.iSegs].cb = SegArgs.uEndRva - SegArgs.uStartRva; 601 SegArgs.paSegs[SegArgs.iSegs].fProt = SegArgs.fProt; 602 SegArgs.iSegs++; 603 } 604 for (uint32_t i = 0; i < SegArgs.iSegs; i++) 605 LogRel(("SUP: seg #%u: %c%c%c %#010RX32 LB %#010RX32\n", i, /** @todo LogRel2 */ 606 SegArgs.paSegs[i].fProt & SUPLDR_PROT_READ ? 'R' : ' ', 607 SegArgs.paSegs[i].fProt & SUPLDR_PROT_WRITE ? 'W' : ' ', 608 SegArgs.paSegs[i].fProt & SUPLDR_PROT_EXEC ? 'X' : ' ', 609 SegArgs.paSegs[i].off, SegArgs.paSegs[i].cb)); 610 AssertRelease(SegArgs.iSegs == cSegments); 611 AssertRelease(SegArgs.cSegsAlloc == cSegments); 612 613 /* 614 * Upload the image. 615 */ 616 pLoadReq->Hdr.u32Cookie = g_u32Cookie; 617 pLoadReq->Hdr.u32SessionCookie = g_u32SessionCookie; 618 pLoadReq->Hdr.cbIn = SUP_IOCTL_LDR_LOAD_SIZE_IN(cbImageWithEverything); 619 pLoadReq->Hdr.cbOut = SUP_IOCTL_LDR_LOAD_SIZE_OUT; 620 pLoadReq->Hdr.fFlags = SUPREQHDR_FLAGS_MAGIC | SUPREQHDR_FLAGS_EXTRA_IN; 621 pLoadReq->Hdr.rc = VERR_INTERNAL_ERROR; 622 623 pLoadReq->u.In.pfnModuleInit = (RTR0PTR)ModuleInit; 624 pLoadReq->u.In.pfnModuleTerm = (RTR0PTR)ModuleTerm; 625 if (fIsVMMR0) 626 { 627 pLoadReq->u.In.eEPType = SUPLDRLOADEP_VMMR0; 628 pLoadReq->u.In.EP.VMMR0.pvVMMR0 = uImageBase; 629 pLoadReq->u.In.EP.VMMR0.pvVMMR0EntryFast= (RTR0PTR)VMMR0EntryFast; 630 pLoadReq->u.In.EP.VMMR0.pvVMMR0EntryEx = (RTR0PTR)VMMR0EntryEx; 631 } 632 else if (pszSrvReqHandler) 633 { 634 pLoadReq->u.In.eEPType = SUPLDRLOADEP_SERVICE; 635 pLoadReq->u.In.EP.Service.pfnServiceReq = (RTR0PTR)SrvReqHandler; 636 pLoadReq->u.In.EP.Service.apvReserved[0] = NIL_RTR0PTR; 637 pLoadReq->u.In.EP.Service.apvReserved[1] = NIL_RTR0PTR; 638 pLoadReq->u.In.EP.Service.apvReserved[2] = NIL_RTR0PTR; 639 } 640 else 641 pLoadReq->u.In.eEPType = SUPLDRLOADEP_NOTHING; 642 pLoadReq->u.In.offStrTab = offStrTab; 643 pLoadReq->u.In.cbStrTab = (uint32_t)cbStrTab; 644 AssertRelease(pLoadReq->u.In.cbStrTab == cbStrTab); 645 pLoadReq->u.In.cbImageBits = (uint32_t)cbImage; 646 pLoadReq->u.In.offSymbols = offSymTab; 647 pLoadReq->u.In.cSymbols = cSymbols; 648 pLoadReq->u.In.offSegments = offSegTab; 649 pLoadReq->u.In.cSegments = cSegments; 650 pLoadReq->u.In.cbImageWithEverything = cbImageWithEverything; 651 pLoadReq->u.In.pvImageBase = uImageBase; 652 if (!g_uSupFakeMode) 653 { 654 rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_LDR_LOAD, pLoadReq, SUP_IOCTL_LDR_LOAD_SIZE(cbImageWithEverything)); 655 if (RT_SUCCESS(rc)) 656 rc = pLoadReq->Hdr.rc; 657 else 658 LogRel(("SUP: SUP_IOCTL_LDR_LOAD ioctl for %s (%s) failed rc=%Rrc\n", pszModule, pszFilename, rc)); 659 } 660 else 661 rc = VINF_SUCCESS; 662 if ( RT_SUCCESS(rc) 663 || rc == VERR_ALREADY_LOADED /* A competing process. */ 664 ) 665 { 666 LogRel(("SUP: Loaded %s (%s) at %#RKv - ModuleInit at %RKv and ModuleTerm at %RKv%s\n", 667 pszModule, pszFilename, uImageBase, (RTR0PTR)ModuleInit, (RTR0PTR)ModuleTerm, 668 fNativeLoader ? " using the native ring-0 loader" : "")); 669 if (fIsVMMR0) 670 { 671 g_pvVMMR0 = uImageBase; 672 LogRel(("SUP: VMMR0EntryEx located at %RKv and VMMR0EntryFast at %RKv\n", (RTR0PTR)VMMR0EntryEx, (RTR0PTR)VMMR0EntryFast)); 673 } 674 #ifdef RT_OS_WINDOWS 675 LogRel(("SUP: windbg> .reload /f %s=%#RKv\n", pszFilename, uImageBase)); 676 #endif 677 return VINF_SUCCESS; 678 } 679 680 /* 681 * Failed, bail out. 682 */ 683 LogRel(("SUP: Loading failed for %s (%s) rc=%Rrc\n", pszModule, pszFilename, rc)); 684 if ( pLoadReq->u.Out.uErrorMagic == SUPLDRLOAD_ERROR_MAGIC 685 && pLoadReq->u.Out.szError[0] != '\0') 686 { 687 LogRel(("SUP: %s\n", pLoadReq->u.Out.szError)); 688 return RTErrInfoSet(pErrInfo, rc, pLoadReq->u.Out.szError); 689 } 690 return RTErrInfoSet(pErrInfo, rc, "SUP_IOCTL_LDR_LOAD failed"); 691 } 692 693 337 694 /** 338 695 * Worker for SUPR3LoadModule(). … … 357 714 AssertPtrReturn(pszModule, VERR_INVALID_PARAMETER); 358 715 AssertPtrReturn(ppvImageBase, VERR_INVALID_PARAMETER); 716 /** @todo abspath it right into SUPLDROPEN */ 359 717 AssertReturn(strlen(pszModule) < RT_SIZEOFMEMB(SUPLDROPEN, u.In.szName), VERR_FILENAME_TOO_LONG); 360 718 char szAbsFilename[RT_SIZEOFMEMB(SUPLDROPEN, u.In.szFilename)]; … … 372 730 */ 373 731 RTLDRMOD hLdrMod; 374 rc = RTLdrOpen (pszFilename, 0, RTLDRARCH_HOST, &hLdrMod);375 if ( !RT_SUCCESS(rc))732 rc = RTLdrOpenEx(pszFilename, 0 /*fFlags*/, RTLDRARCH_HOST, &hLdrMod, pErrInfo); 733 if (RT_FAILURE(rc)) 376 734 { 377 735 LogRel(("SUP: RTLdrOpen failed for %s (%s) %Rrc\n", pszModule, pszFilename, rc)); … … 386 744 if (RT_SUCCESS(rc)) 387 745 { 388 const uint32_t offSymTab = RT_ALIGN_32(CalcArgs.cbImage, 8);389 const uint32_t offStrTab = offSymTab + CalcArgs.cSymbols * sizeof(SUPLDRSYM);390 const uint32_t cbImageWithTabs = RT_ALIGN_32(offStrTab + CalcArgs.cbStrings, 8);391 392 746 /* 393 * Open the R0 image.747 * Figure out the number of segments needed first. 394 748 */ 395 SUPLDROPEN OpenReq; 396 OpenReq.Hdr.u32Cookie = g_u32Cookie; 397 OpenReq.Hdr.u32SessionCookie = g_u32SessionCookie; 398 OpenReq.Hdr.cbIn = SUP_IOCTL_LDR_OPEN_SIZE_IN; 399 OpenReq.Hdr.cbOut = SUP_IOCTL_LDR_OPEN_SIZE_OUT; 400 OpenReq.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT; 401 OpenReq.Hdr.rc = VERR_INTERNAL_ERROR; 402 OpenReq.u.In.cbImageWithTabs = cbImageWithTabs; 403 OpenReq.u.In.cbImageBits = (uint32_t)CalcArgs.cbImage; 404 strcpy(OpenReq.u.In.szName, pszModule); 405 strcpy(OpenReq.u.In.szFilename, pszFilename); 406 if (!g_uSupFakeMode) 749 SUPLDRCOMPSEGTABARGS SegArgs; 750 SegArgs.uStartRva = 0; 751 SegArgs.uEndRva = 0; 752 SegArgs.fProt = RTMEM_PROT_READ; 753 SegArgs.iSegs = 0; 754 SegArgs.cSegsAlloc = 0; 755 SegArgs.paSegs = NULL; 756 SegArgs.pErrInfo = pErrInfo; 757 rc = RTLdrEnumSegments(hLdrMod, supLoadModuleCompileSegmentsCB, &SegArgs); 758 if (RT_SUCCESS(rc)) 407 759 { 408 rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_LDR_OPEN, &OpenReq, SUP_IOCTL_LDR_OPEN_SIZE); 409 if (RT_SUCCESS(rc)) 410 rc = OpenReq.Hdr.rc; 411 } 412 else 413 { 414 OpenReq.u.Out.fNeedsLoading = true; 415 OpenReq.u.Out.pvImageBase = 0xef423420; 416 } 417 *ppvImageBase = (void *)OpenReq.u.Out.pvImageBase; 418 if ( RT_SUCCESS(rc) 419 && OpenReq.u.Out.fNeedsLoading) 420 { 760 Assert(SegArgs.uEndRva <= RTLdrSize(hLdrMod)); 761 SegArgs.uEndRva = RTLdrSize(hLdrMod); 762 if (SegArgs.uEndRva > SegArgs.uStartRva) 763 SegArgs.iSegs++; 764 765 const uint32_t offSymTab = RT_ALIGN_32(CalcArgs.cbImage, 8); 766 const uint32_t offStrTab = offSymTab + CalcArgs.cSymbols * sizeof(SUPLDRSYM); 767 const uint32_t offSegTab = RT_ALIGN_32(offStrTab + CalcArgs.cbStrings, 8); 768 const uint32_t cbImageWithEverything = RT_ALIGN_32(offSegTab + sizeof(SUPLDRSEG) * SegArgs.iSegs, 8); 769 421 770 /* 422 * We need to load it. 423 * Allocate memory for the image bits. 771 * Open the R0 image. 424 772 */ 425 PSUPLDRLOAD pLoadReq = (PSUPLDRLOAD)RTMemTmpAlloc(SUP_IOCTL_LDR_LOAD_SIZE(cbImageWithTabs)); 426 if (pLoadReq) 773 SUPLDROPEN OpenReq; 774 OpenReq.Hdr.u32Cookie = g_u32Cookie; 775 OpenReq.Hdr.u32SessionCookie = g_u32SessionCookie; 776 OpenReq.Hdr.cbIn = SUP_IOCTL_LDR_OPEN_SIZE_IN; 777 OpenReq.Hdr.cbOut = SUP_IOCTL_LDR_OPEN_SIZE_OUT; 778 OpenReq.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT; 779 OpenReq.Hdr.rc = VERR_INTERNAL_ERROR; 780 OpenReq.u.In.cbImageWithEverything = cbImageWithEverything; 781 OpenReq.u.In.cbImageBits = (uint32_t)CalcArgs.cbImage; 782 strcpy(OpenReq.u.In.szName, pszModule); 783 strcpy(OpenReq.u.In.szFilename, pszFilename); 784 if (!g_uSupFakeMode) 785 { 786 rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_LDR_OPEN, &OpenReq, SUP_IOCTL_LDR_OPEN_SIZE); 787 if (RT_SUCCESS(rc)) 788 rc = OpenReq.Hdr.rc; 789 } 790 else 791 { 792 OpenReq.u.Out.fNeedsLoading = true; 793 OpenReq.u.Out.pvImageBase = 0xef423420; 794 } 795 *ppvImageBase = (void *)OpenReq.u.Out.pvImageBase; 796 if ( RT_SUCCESS(rc) 797 && OpenReq.u.Out.fNeedsLoading) 427 798 { 428 799 /* 429 * Get the image bits. 800 * We need to load it. 801 * 802 * Allocate the request and pass it to an inner work function 803 * that populates it and sends it off to the driver. 430 804 */ 431 432 SUPLDRRESIMPARGS Args = { pszModule, pErrInfo }; 433 rc = RTLdrGetBits(hLdrMod, &pLoadReq->u.In.abImage[0], (uintptr_t)OpenReq.u.Out.pvImageBase, 434 supLoadModuleResolveImport, &Args); 435 436 if (RT_SUCCESS(rc)) 805 const uint32_t cbLoadReq = SUP_IOCTL_LDR_LOAD_SIZE(cbImageWithEverything); 806 PSUPLDRLOAD pLoadReq = (PSUPLDRLOAD)RTMemTmpAlloc(cbLoadReq); 807 if (pLoadReq) 437 808 { 438 /* 439 * Get the entry points. 440 */ 441 RTUINTPTR VMMR0EntryFast = 0; 442 RTUINTPTR VMMR0EntryEx = 0; 443 RTUINTPTR SrvReqHandler = 0; 444 RTUINTPTR ModuleInit = 0; 445 RTUINTPTR ModuleTerm = 0; 446 const char *pszEp = NULL; 447 if (fIsVMMR0) 448 { 449 rc = RTLdrGetSymbolEx(hLdrMod, &pLoadReq->u.In.abImage[0], (uintptr_t)OpenReq.u.Out.pvImageBase, 450 UINT32_MAX, pszEp = "VMMR0EntryFast", &VMMR0EntryFast); 451 if (RT_SUCCESS(rc)) 452 rc = RTLdrGetSymbolEx(hLdrMod, &pLoadReq->u.In.abImage[0], (uintptr_t)OpenReq.u.Out.pvImageBase, 453 UINT32_MAX, pszEp = "VMMR0EntryEx", &VMMR0EntryEx); 454 } 455 else if (pszSrvReqHandler) 456 rc = RTLdrGetSymbolEx(hLdrMod, &pLoadReq->u.In.abImage[0], (uintptr_t)OpenReq.u.Out.pvImageBase, 457 UINT32_MAX, pszEp = pszSrvReqHandler, &SrvReqHandler); 458 if (RT_SUCCESS(rc)) 459 { 460 int rc2 = RTLdrGetSymbolEx(hLdrMod, &pLoadReq->u.In.abImage[0], (uintptr_t)OpenReq.u.Out.pvImageBase, 461 UINT32_MAX, pszEp = "ModuleInit", &ModuleInit); 462 if (RT_FAILURE(rc2)) 463 ModuleInit = 0; 464 465 rc2 = RTLdrGetSymbolEx(hLdrMod, &pLoadReq->u.In.abImage[0], (uintptr_t)OpenReq.u.Out.pvImageBase, 466 UINT32_MAX, pszEp = "ModuleTerm", &ModuleTerm); 467 if (RT_FAILURE(rc2)) 468 ModuleTerm = 0; 469 } 470 if (RT_SUCCESS(rc)) 471 { 472 /* 473 * Create the symbol and string tables. 474 */ 475 SUPLDRCREATETABSARGS CreateArgs; 476 CreateArgs.cbImage = CalcArgs.cbImage; 477 CreateArgs.pSym = (PSUPLDRSYM)&pLoadReq->u.In.abImage[offSymTab]; 478 CreateArgs.pszBase = (char *)&pLoadReq->u.In.abImage[offStrTab]; 479 CreateArgs.psz = CreateArgs.pszBase; 480 rc = RTLdrEnumSymbols(hLdrMod, 0, NULL, 0, supLoadModuleCreateTabsCB, &CreateArgs); 481 if (RT_SUCCESS(rc)) 482 { 483 AssertRelease((size_t)(CreateArgs.psz - CreateArgs.pszBase) <= CalcArgs.cbStrings); 484 AssertRelease((size_t)(CreateArgs.pSym - (PSUPLDRSYM)&pLoadReq->u.In.abImage[offSymTab]) <= CalcArgs.cSymbols); 485 486 /* 487 * Upload the image. 488 */ 489 pLoadReq->Hdr.u32Cookie = g_u32Cookie; 490 pLoadReq->Hdr.u32SessionCookie = g_u32SessionCookie; 491 pLoadReq->Hdr.cbIn = SUP_IOCTL_LDR_LOAD_SIZE_IN(cbImageWithTabs); 492 pLoadReq->Hdr.cbOut = SUP_IOCTL_LDR_LOAD_SIZE_OUT; 493 pLoadReq->Hdr.fFlags = SUPREQHDR_FLAGS_MAGIC | SUPREQHDR_FLAGS_EXTRA_IN; 494 pLoadReq->Hdr.rc = VERR_INTERNAL_ERROR; 495 496 pLoadReq->u.In.pfnModuleInit = (RTR0PTR)ModuleInit; 497 pLoadReq->u.In.pfnModuleTerm = (RTR0PTR)ModuleTerm; 498 if (fIsVMMR0) 499 { 500 pLoadReq->u.In.eEPType = SUPLDRLOADEP_VMMR0; 501 pLoadReq->u.In.EP.VMMR0.pvVMMR0 = OpenReq.u.Out.pvImageBase; 502 pLoadReq->u.In.EP.VMMR0.pvVMMR0EntryFast= (RTR0PTR)VMMR0EntryFast; 503 pLoadReq->u.In.EP.VMMR0.pvVMMR0EntryEx = (RTR0PTR)VMMR0EntryEx; 504 } 505 else if (pszSrvReqHandler) 506 { 507 pLoadReq->u.In.eEPType = SUPLDRLOADEP_SERVICE; 508 pLoadReq->u.In.EP.Service.pfnServiceReq = (RTR0PTR)SrvReqHandler; 509 pLoadReq->u.In.EP.Service.apvReserved[0] = NIL_RTR0PTR; 510 pLoadReq->u.In.EP.Service.apvReserved[1] = NIL_RTR0PTR; 511 pLoadReq->u.In.EP.Service.apvReserved[2] = NIL_RTR0PTR; 512 } 513 else 514 pLoadReq->u.In.eEPType = SUPLDRLOADEP_NOTHING; 515 pLoadReq->u.In.offStrTab = offStrTab; 516 pLoadReq->u.In.cbStrTab = (uint32_t)CalcArgs.cbStrings; 517 AssertRelease(pLoadReq->u.In.cbStrTab == CalcArgs.cbStrings); 518 pLoadReq->u.In.cbImageBits = (uint32_t)CalcArgs.cbImage; 519 pLoadReq->u.In.offSymbols = offSymTab; 520 pLoadReq->u.In.cSymbols = CalcArgs.cSymbols; 521 pLoadReq->u.In.cbImageWithTabs = cbImageWithTabs; 522 pLoadReq->u.In.pvImageBase = OpenReq.u.Out.pvImageBase; 523 if (!g_uSupFakeMode) 524 { 525 rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_LDR_LOAD, pLoadReq, SUP_IOCTL_LDR_LOAD_SIZE(cbImageWithTabs)); 526 if (RT_SUCCESS(rc)) 527 rc = pLoadReq->Hdr.rc; 528 else 529 LogRel(("SUP: SUP_IOCTL_LDR_LOAD ioctl for %s (%s) failed rc=%Rrc\n", pszModule, pszFilename, rc)); 530 } 531 else 532 rc = VINF_SUCCESS; 533 if ( RT_SUCCESS(rc) 534 || rc == VERR_ALREADY_LOADED /* A competing process. */ 535 ) 536 { 537 LogRel(("SUP: Loaded %s (%s) at %#RKv - ModuleInit at %RKv and ModuleTerm at %RKv%s\n", 538 pszModule, pszFilename, OpenReq.u.Out.pvImageBase, (RTR0PTR)ModuleInit, (RTR0PTR)ModuleTerm, 539 OpenReq.u.Out.fNativeLoader ? " using the native ring-0 loader" : "")); 540 if (fIsVMMR0) 541 { 542 g_pvVMMR0 = OpenReq.u.Out.pvImageBase; 543 LogRel(("SUP: VMMR0EntryEx located at %RKv and VMMR0EntryFast at %RKv\n", (RTR0PTR)VMMR0EntryEx, (RTR0PTR)VMMR0EntryFast)); 544 } 545 #ifdef RT_OS_WINDOWS 546 LogRel(("SUP: windbg> .reload /f %s=%#RKv\n", pszFilename, OpenReq.u.Out.pvImageBase)); 547 #endif 548 549 RTMemTmpFree(pLoadReq); 550 RTLdrClose(hLdrMod); 551 return VINF_SUCCESS; 552 } 553 554 /* 555 * Failed, bail out. 556 */ 557 LogRel(("SUP: Loading failed for %s (%s) rc=%Rrc\n", pszModule, pszFilename, rc)); 558 if ( pLoadReq->u.Out.uErrorMagic == SUPLDRLOAD_ERROR_MAGIC 559 && pLoadReq->u.Out.szError[0] != '\0') 560 { 561 LogRel(("SUP: %s\n", pLoadReq->u.Out.szError)); 562 RTErrInfoSet(pErrInfo, rc, pLoadReq->u.Out.szError); 563 } 564 else 565 RTErrInfoSet(pErrInfo, rc, "SUP_IOCTL_LDR_LOAD failed"); 566 } 567 else 568 { 569 LogRel(("SUP: RTLdrEnumSymbols failed for %s (%s) rc=%Rrc\n", pszModule, pszFilename, rc)); 570 RTErrInfoSetF(pErrInfo, rc, "RTLdrEnumSymbols #2 failed"); 571 } 572 } 573 else 574 { 575 LogRel(("SUP: Failed to get entry point '%s' for %s (%s) rc=%Rrc\n", pszEp, pszModule, pszFilename, rc)); 576 RTErrInfoSetF(pErrInfo, rc, "Failed to resolve entry point '%s'", pszEp); 577 } 809 rc = supLoadModuleInner(hLdrMod, pLoadReq, cbImageWithEverything, OpenReq.u.Out.pvImageBase, CalcArgs.cbImage, 810 pszModule, pszFilename, OpenReq.u.Out.fNativeLoader, fIsVMMR0, pszSrvReqHandler, 811 offSymTab, CalcArgs.cSymbols, 812 offStrTab, CalcArgs.cbStrings, 813 offSegTab, SegArgs.iSegs, 814 pErrInfo); 815 RTMemTmpFree(pLoadReq); 578 816 } 579 817 else 580 818 { 581 LogRel(("SUP: RTLdrGetBits failed for %s (%s). rc=%Rrc\n", pszModule, pszFilename, rc));582 if (!RTErrInfoIsSet(pErrInfo))583 RTErrInfoSetF(pErrInfo, rc, "RTLdrGetBits failed");819 AssertMsgFailed(("failed to allocated %u bytes for SUPLDRLOAD_IN structure!\n", SUP_IOCTL_LDR_LOAD_SIZE(cbImageWithEverything))); 820 rc = RTErrInfoSetF(pErrInfo, VERR_NO_TMP_MEMORY, "Failed to allocate %u bytes for the load request", 821 SUP_IOCTL_LDR_LOAD_SIZE(cbImageWithEverything)); 584 822 } 585 RTMemTmpFree(pLoadReq);586 823 } 824 /* 825 * Already loaded? 826 */ 827 else if (RT_SUCCESS(rc)) 828 { 829 if (fIsVMMR0) 830 g_pvVMMR0 = OpenReq.u.Out.pvImageBase; 831 LogRel(("SUP: Opened %s (%s) at %#RKv%s.\n", pszModule, pszFilename, OpenReq.u.Out.pvImageBase, 832 OpenReq.u.Out.fNativeLoader ? " loaded by the native ring-0 loader" : "")); 833 #ifdef RT_OS_WINDOWS 834 LogRel(("SUP: windbg> .reload /f %s=%#RKv\n", pszFilename, OpenReq.u.Out.pvImageBase)); 835 #endif 836 } 837 /* 838 * No, failed. 839 */ 587 840 else 588 { 589 AssertMsgFailed(("failed to allocated %u bytes for SUPLDRLOAD_IN structure!\n", SUP_IOCTL_LDR_LOAD_SIZE(cbImageWithTabs))); 590 rc = VERR_NO_TMP_MEMORY; 591 RTErrInfoSetF(pErrInfo, rc, "Failed to allocate %u bytes for the load request", SUP_IOCTL_LDR_LOAD_SIZE(cbImageWithTabs)); 592 } 841 RTErrInfoSet(pErrInfo, rc, "SUP_IOCTL_LDR_OPEN failed"); 593 842 } 594 /* 595 * Already loaded? 596 */ 597 else if (RT_SUCCESS(rc)) 598 { 599 if (fIsVMMR0) 600 g_pvVMMR0 = OpenReq.u.Out.pvImageBase; 601 LogRel(("SUP: Opened %s (%s) at %#RKv%s.\n", pszModule, pszFilename, OpenReq.u.Out.pvImageBase, 602 OpenReq.u.Out.fNativeLoader ? " loaded by the native ring-0 loader" : "")); 603 #ifdef RT_OS_WINDOWS 604 LogRel(("SUP: windbg> .reload /f %s=%#RKv\n", pszFilename, OpenReq.u.Out.pvImageBase)); 605 #endif 606 } 607 /* 608 * No, failed. 609 */ 610 else 611 RTErrInfoSet(pErrInfo, rc, "SUP_IOCTL_LDR_OPEN failed"); 843 else if (!RTErrInfoIsSet(pErrInfo) && pErrInfo) 844 RTErrInfoSetF(pErrInfo, rc, "RTLdrEnumSegments #1 failed"); 612 845 } 613 846 else
Note:
See TracChangeset
for help on using the changeset viewer.