VirtualBox

Ignore:
Timestamp:
May 26, 2011 7:25:54 PM (14 years ago)
Author:
vboxsync
Message:

SUPDrv,VMM,VBoxDD*: Implemented native loading of the angnostic modules on solaris (disabled by default).

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/Makefile.kmk

    r36062 r37228  
    446446 vboxdrv_DEFS        += VBOX_WITH_NETFLT
    447447endif
     448ifdef VBOX_WITH_NATIVE_SOLARIS_LOADING
     449 vboxdrv_DEFS        += VBOX_WITH_NATIVE_SOLARIS_LOADING
     450endif
    448451vboxdrv_DEPS         += $(VBOX_SVN_REV_KMK)
    449452vboxdrv_INCS         := $(PATH_SUB_CURRENT)
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.c

    r37211 r37228  
    42774277    /*
    42784278     * Search the symbol strings.
     4279     *
     4280     * Note! The int32_t is for native loading on solaris where the data
     4281     *       and text segments are in very different places.
    42794282     */
    42804283    pchStrings = pImage->pachStrTab;
     
    42824285    for (i = 0; i < pImage->cSymbols; i++)
    42834286    {
    4284         if (    paSyms[i].offSymbol < pImage->cbImageBits /* paranoia */
    4285             &&  paSyms[i].offName + cbSymbol <= pImage->cbStrTab
     4287        if (    paSyms[i].offName + cbSymbol <= pImage->cbStrTab
    42864288            &&  !memcmp(pchStrings + paSyms[i].offName, pReq->u.In.szSymbol, cbSymbol))
    42874289        {
    4288             pvSymbol = (uint8_t *)pImage->pvImage + paSyms[i].offSymbol;
     4290            pvSymbol = (uint8_t *)pImage->pvImage + (int32_t)paSyms[i].offSymbol;
    42894291            rc = VINF_SUCCESS;
    42904292            break;
     
    43664368            for (i = 0; i < pImage->cSymbols; i++)
    43674369            {
    4368                 if (    paSyms[i].offSymbol < pImage->cbImageBits /* paranoia */
    4369                     &&  paSyms[i].offName + cbSymbol <= pImage->cbStrTab
     4370                if (    paSyms[i].offName + cbSymbol <= pImage->cbStrTab
    43704371                    &&  !memcmp(pchStrings + paSyms[i].offName, pszSymbol, cbSymbol))
    43714372                {
     
    43734374                     * Found it! Calc the symbol address and add a reference to the module.
    43744375                     */
    4375                     pReq->u.Out.pfnSymbol = (PFNRT)((uint8_t *)pImage->pvImage + paSyms[i].offSymbol);
     4376                    pReq->u.Out.pfnSymbol = (PFNRT)((uint8_t *)pImage->pvImage + (int32_t)paSyms[i].offSymbol);
    43764377                    rc = supdrvLdrAddUsage(pSession, pImage);
    43774378                    break;
  • trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h

    r36191 r37228  
    299299    RTR0MEMOBJ                      hMemLock;
    300300#endif
     301#if defined(RT_OS_SOLARIS) && defined(VBOX_WITH_NATIVE_SOLARIS_LOADING)
     302    /** The Solaris module ID. */
     303    int                             idSolMod;
     304    /** Pointer to the module control structure. */
     305    struct modctl                  *pSolModCtl;
     306#endif
    301307    /** Whether it's loaded by the native loader or not. */
    302308    bool                            fNative;
  • trunk/src/VBox/HostDrivers/Support/SUPLib.cpp

    r36262 r37228  
    16891689
    16901690    /*
     1691     * Symbols that are undefined by convention.
     1692     */
     1693#ifdef RT_OS_SOLARIS
     1694    static const char * const s_apszConvSyms[] =
     1695    {
     1696        "", "mod_getctl",
     1697        "", "mod_install",
     1698        "", "mod_remove",
     1699        "", "mod_info",
     1700        "", "mod_miscops",
     1701    };
     1702    for (unsigned i = 0; i < RT_ELEMENTS(s_apszConvSyms); i += 2)
     1703    {
     1704        if (   !RTStrCmp(s_apszConvSyms[i],     pszModule)
     1705            && !RTStrCmp(s_apszConvSyms[i + 1], pszSymbol))
     1706        {
     1707            *pValue = ~(uintptr_t)0;
     1708            return VINF_SUCCESS;
     1709        }
     1710    }
     1711#endif
     1712
     1713    /*
    16911714     * Despair.
    16921715     */
  • trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c

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