VirtualBox

Ignore:
Timestamp:
Jul 29, 2020 10:10:49 AM (5 years ago)
Author:
vboxsync
Message:

SUP,*: Some changes to the SUP_IOCTL_LDR_OPEN and SUP_IOCTL_LDR_LOAD interfaces adding memory protection regions for better WX compliance. Preps for linux 5.8 where we'll be using RTR0MemObjAllocPage rather than RTMemExecAlloc for images, switch from relocatable ELF files to shared objects. bugref:9801

Location:
trunk/src/VBox/HostDrivers/Support
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp

    r85450 r85507  
    17331733            PSUPLDROPEN pReq = (PSUPLDROPEN)pReqHdr;
    17341734            REQ_CHECK_SIZES(SUP_IOCTL_LDR_OPEN);
    1735             REQ_CHECK_EXPR(SUP_IOCTL_LDR_OPEN, pReq->u.In.cbImageWithTabs > 0);
    1736             REQ_CHECK_EXPR(SUP_IOCTL_LDR_OPEN, pReq->u.In.cbImageWithTabs < 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);
    17371737            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);
    17401739            REQ_CHECK_EXPR(SUP_IOCTL_LDR_OPEN, pReq->u.In.szName[0]);
    17411740            REQ_CHECK_EXPR(SUP_IOCTL_LDR_OPEN, RTStrEnd(pReq->u.In.szName, sizeof(pReq->u.In.szName)));
     
    17531752            PSUPLDRLOAD pReq = (PSUPLDRLOAD)pReqHdr;
    17541753            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);
    17571755            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));
    17621762            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));
    17681777
    17691778            if (pReq->u.In.cSymbols)
     
    17731782                for (i = 0; i < pReq->u.In.cSymbols; i++)
    17741783                {
    1775                     REQ_CHECK_EXPR_FMT(paSyms[i].offSymbol < pReq->u.In.cbImageWithTabs,
    1776                                        ("SUP_IOCTL_LDR_LOAD: sym #%ld: symb off %#lx (max=%#lx)\n", (long)i, (long)paSyms[i].offSymbol, (long)pReq->u.In.cbImageWithTabs));
     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));
    17771786                    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.cbImageWithTabs));
     1787                                       ("SUP_IOCTL_LDR_LOAD: sym #%ld: name off %#lx (max=%#lx)\n", (long)i, (long)paSyms[i].offName, (long)pReq->u.In.cbImageWithEverything));
    17791788                    REQ_CHECK_EXPR_FMT(RTStrEnd((char const *)&pReq->u.In.abImage[pReq->u.In.offStrTab + paSyms[i].offName],
    17801789                                                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.cbImageWithTabs));
     1790                                       ("SUP_IOCTL_LDR_LOAD: sym #%ld: unterminated name! (%#lx / %#lx)\n", (long)i, (long)paSyms[i].offName, (long)pReq->u.In.cbImageWithEverything));
    17821791                }
     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));
    17831814            }
    17841815
     
    50245055    SUPDRV_CHECK_SMAP_SETUP();
    50255056    SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    5026     LogFlow(("supdrvIOCtl_LdrOpen: szName=%s cbImageWithTabs=%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));
    50275058
    50285059    /*
     
    50385069            if (RT_LIKELY(pImage->cUsage < UINT32_MAX / 2U))
    50395070            {
    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. */
    50415073                pImage->cUsage++;
    50425074                pReq->u.Out.pvImageBase   = pImage->pvImage;
     
    50815113    pImage = (PSUPDRVLDRIMAGE)pv;
    50825114    pImage->pvImage         = NULL;
     5115#ifdef SUPDRV_USE_MEMOBJ_FOR_LDR_IMAGE
     5116    pImage->hMemObjImage    = NIL_RTR0MEMOBJ;
     5117#else
    50835118    pImage->pvImageAlloc    = NULL;
    5084     pImage->cbImageWithTabs = pReq->u.In.cbImageWithTabs;
     5119#endif
     5120    pImage->cbImageWithEverything = pReq->u.In.cbImageWithEverything;
    50855121    pImage->cbImageBits     = pReq->u.In.cbImageBits;
    50865122    pImage->cSymbols        = 0;
     
    50885124    pImage->pachStrTab      = NULL;
    50895125    pImage->cbStrTab        = 0;
     5126    pImage->cSegments       = 0;
     5127    pImage->paSegments      = NULL;
    50905128    pImage->pfnModuleInit   = NULL;
    50915129    pImage->pfnModuleTerm   = NULL;
     
    51055143    if (rc == VERR_NOT_SUPPORTED)
    51065144    {
     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
    51075153        pImage->pvImageAlloc = RTMemExecAlloc(pImage->cbImageBits + 31);
    51085154        pImage->pvImage     = RT_ALIGN_P(pImage->pvImageAlloc, 32);
    51095155        pImage->fNative     = false;
    51105156        rc = pImage->pvImageAlloc ? VINF_SUCCESS : VERR_NO_EXEC_MEMORY;
     5157#endif
    51115158        SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    51125159    }
     
    51365183    supdrvLdrUnlock(pDevExt);
    51375184    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 symbol
    5152  *                          capitalized it signifies a specific symbol, otherwise it
    5153  *                          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     }
    51815185    return VINF_SUCCESS;
    51825186}
     
    52055209
    52065210/**
     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 */
     5228static 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/**
    52075275 * Loads the image bits.
    52085276 *
     
    52205288    int             rc;
    52215289    SUPDRV_CHECK_SMAP_SETUP();
    5222     LogFlow(("supdrvIOCtl_LdrLoad: pvImageBase=%p cbImageWithBits=%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));
    52235291    SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    52245292
     
    52425310     * Validate input.
    52435311     */
    5244     if (   pImage->cbImageWithTabs != pReq->u.In.cbImageWithTabs
    5245         || pImage->cbImageBits     != pReq->u.In.cbImageBits)
     5312    if (   pImage->cbImageWithEverything != pReq->u.In.cbImageWithEverything
     5313        || pImage->cbImageBits           != pReq->u.In.cbImageBits)
    52465314    {
    52475315        supdrvLdrUnlock(pDevExt);
    5248         return supdrvLdrLoadError(VERR_INVALID_HANDLE, pReq, "Image size mismatch found: %d(prep) != %d(load) or %d != %d",
    5249                                   pImage->cbImageWithTabs, 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);
    52505318    }
    52515319
     
    52735341
    52745342        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);
    52805349            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;
    52825354            break;
    52835355
    52845356        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);
    52865358            if (RT_FAILURE(rc))
    5287                 return supdrvLdrLoadError(rc, pReq, "Invalid pfnServiceReq pointer: %p", pReq->u.In.EP.Service.pfnServiceReq);
     5359                return rc;
    52885360            if (    pReq->u.In.EP.Service.apvReserved[0] != NIL_RTR0PTR
    52895361                ||  pReq->u.In.EP.Service.apvReserved[1] != NIL_RTR0PTR
     
    52915363            {
    52925364                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],
    52985367                                          pReq->u.In.EP.Service.apvReserved[2]);
    52995368            }
     
    53055374    }
    53065375
    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);
    53085377    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);
    53115380    if (RT_FAILURE(rc))
    5312         return supdrvLdrLoadError(rc, pReq, "Invalid pfnModuleTerm pointer: %p", pReq->u.In.pfnModuleTerm);
     5381        return rc;
    53135382    SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    53145383
     
    53225391        if (pImage->cbStrTab)
    53235392        {
    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)
    53285395                rc = supdrvLdrLoadError(VERR_NO_MEMORY, pReq, "Out of memory for string table: %#x", pImage->cbStrTab);
    53295396            SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
     
    53345401        {
    53355402            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)
    53405405                rc = supdrvLdrLoadError(VERR_NO_MEMORY, pReq, "Out of memory for symbol table: %#x", cbSymbols);
    53415406            SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    53425407        }
    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.
    53475424     */
    53485425    if (RT_SUCCESS(rc))
     
    53565433        else
    53575434        {
     5435#ifdef SUPDRV_USE_MEMOBJ_FOR_LDR_IMAGE
     5436            uint32_t i;
    53585437            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
    53595455            Log(("vboxdrv: Loaded '%s' at %p\n", pImage->szName, pImage->pvImage));
    53605456        }
     
    59516047    pImage->pNext   = NULL;
    59526048    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
    59536053    RTMemExecFree(pImage->pvImageAlloc, pImage->cbImageBits + 31);
    59546054    pImage->pvImageAlloc = NULL;
     6055#endif
     6056    pImage->pvImage = NULL;
    59556057    RTMemFree(pImage->pachStrTab);
    59566058    pImage->pachStrTab = NULL;
    59576059    RTMemFree(pImage->paSymbols);
    59586060    pImage->paSymbols = NULL;
     6061    RTMemFree(pImage->paSegments);
     6062    pImage->paSegments = NULL;
    59596063    RTMemFree(pImage);
    59606064}
  • trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h

    r85450 r85507  
    221221 *
    222222 * @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                              0x002d0002
     223 *          - Nothing.
     224 */
     225#define SUPDRV_IOC_VERSION                              0x002e0000
    226226
    227227/** SUP_IOCTL_COOKIE. */
     
    315315        struct
    316316        {
    317             /** Size of the image we'll be loading (including tables). */
    318             uint32_t        cbImageWithTabs;
     317            /** Size of the image we'll be loading (including all tables). */
     318            uint32_t        cbImageWithEverything;
    319319            /** The size of the image bits. (Less or equal to cbImageWithTabs.) */
    320320            uint32_t        cbImageBits;
     
    390390/** Pointer to a const symbol table entry. */
    391391typedef 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 */
     400typedef 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. */
     412typedef SUPLDRSEG *PSUPLDRSEG;
     413/** Pointer to a const segment table entry. */
     414typedef SUPLDRSEG const *PCSUPLDRSEG;
    392415
    393416/**
     
    444467             * approaching offSymbols). */
    445468            uint32_t        cbImageBits;
    446             /** The offset of the symbol table. */
     469            /** The offset of the symbol table (SUPLDRSYM array). */
    447470            uint32_t        offSymbols;
    448471            /** The number of entries in the symbol table. */
     
    452475            /** Size of the string table. */
    453476            uint32_t        cbStrTab;
     477            /** Offset to the segment table (SUPLDRSEG array). */
     478            uint32_t        offSegments;
     479            /** Number of segments. */
     480            uint32_t        cSegments;
    454481            /** Size of image data in achImage. */
    455             uint32_t        cbImageWithTabs;
     482            uint32_t        cbImageWithEverything;
    456483            /** The image data. */
    457484            uint8_t         abImage[1];
  • trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h

    r85174 r85507  
    144144 * @todo fix the mutex implementation on linux and make this the default. */
    145145# 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
    146153#endif
    147154
     
    327334    /** Pointer to the image. */
    328335    void                           *pvImage;
     336#ifdef SUPDRV_USE_MEMOBJ_FOR_LDR_IMAGE
     337    /** The memory object for the module allocation. */
     338    RTR0MEMOBJ                      hMemObjImage;
     339#else
    329340    /** Pointer to the allocated image buffer.
    330341     * pvImage is 32-byte aligned or it may governed by the native loader (this
    331342     * member is NULL then). */
    332343    void                           *pvImageAlloc;
     344#endif
    333345    /** Magic value (SUPDRVLDRIMAGE_MAGIC). */
    334346    uint32_t                        uMagic;
    335347    /** Size of the image including the tables. This is mainly for verification
    336348     * of the load request. */
    337     uint32_t                        cbImageWithTabs;
     349    uint32_t                        cbImageWithEverything;
    338350    /** Size of the image. */
    339351    uint32_t                        cbImageBits;
     
    346358    /** Size of the string table. */
    347359    uint32_t                        cbStrTab;
     360    /** Number of segments. */
     361    uint32_t                        cSegments;
     362    /** Segments (for memory protection). */
     363    PSUPLDRSEG                      paSegments;
    348364    /** Pointer to the optional module initialization callback. */
    349365    PFNR0MODULEINIT                 pfnModuleInit;
  • trunk/src/VBox/HostDrivers/Support/SUPLib.cpp

    r85450 r85507  
    276276        strcpy(CookieReq.u.In.szMagic, SUPCOOKIE_MAGIC);
    277277        CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION;
    278         const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x002d0000
     278        const uint32_t uMinVersion = /*(SUPDRV_IOC_VERSION & 0xffff0000) == 0x002d0000
    279279                                   ? 0x002d0002
    280                                    : SUPDRV_IOC_VERSION & 0xffff0000;
     280                                   :*/ SUPDRV_IOC_VERSION & 0xffff0000;
    281281        CookieReq.u.In.u32MinVersion = uMinVersion;
    282282        rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_COOKIE, &CookieReq, SUP_IOCTL_COOKIE_SIZE);
  • trunk/src/VBox/HostDrivers/Support/SUPLibLdr.cpp

    r85506 r85507  
    335335
    336336
     337/** Argument package for supLoadModuleCompileSegmentsCB. */
     338typedef 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 */
     353static 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 */
     503static 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
    337694/**
    338695 * Worker for SUPR3LoadModule().
     
    357714    AssertPtrReturn(pszModule, VERR_INVALID_PARAMETER);
    358715    AssertPtrReturn(ppvImageBase, VERR_INVALID_PARAMETER);
     716    /** @todo abspath it right into SUPLDROPEN */
    359717    AssertReturn(strlen(pszModule) < RT_SIZEOFMEMB(SUPLDROPEN, u.In.szName), VERR_FILENAME_TOO_LONG);
    360718    char szAbsFilename[RT_SIZEOFMEMB(SUPLDROPEN, u.In.szFilename)];
     
    372730     */
    373731    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))
    376734    {
    377735        LogRel(("SUP: RTLdrOpen failed for %s (%s) %Rrc\n", pszModule, pszFilename, rc));
     
    386744    if (RT_SUCCESS(rc))
    387745    {
    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 
    392746        /*
    393          * Open the R0 image.
     747         * Figure out the number of segments needed first.
    394748         */
    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))
    407759        {
    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
    421770            /*
    422              * We need to load it.
    423              * Allocate memory for the image bits.
     771             * Open the R0 image.
    424772             */
    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)
    427798            {
    428799                /*
    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.
    430804                 */
    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)
    437808                {
    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);
    578816                }
    579817                else
    580818                {
    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));
    584822                }
    585                 RTMemTmpFree(pLoadReq);
    586823            }
     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             */
    587840            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");
    593842        }
    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");
    612845    }
    613846    else
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette