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).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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