Beispiel #1
0
static cmi_t *
cmi_load_modctl(modctl_t *modp)
{
	cmi_ops_t *ops;
	uintptr_t ver;
	cmi_t *cmi;
	cmi_api_ver_t apiver;

	ASSERT(MUTEX_HELD(&cmi_load_lock));

	for (cmi = cmi_list; cmi != NULL; cmi = cmi->cmi_next) {
		if (cmi->cmi_modp == modp)
			return (cmi);
	}

	if ((ver = modlookup_by_modctl(modp, "_cmi_api_version")) == NULL) {
		/*
		 * Apparently a cpu module before versioning was introduced -
		 * we call this version 0.
		 */
		apiver = CMI_API_VERSION_0;
	} else {
		apiver = *((cmi_api_ver_t *)ver);
		if (!CMI_API_VERSION_CHKMAGIC(apiver)) {
			cmn_err(CE_WARN, "cpu module '%s' is invalid: "
			    "_cmi_api_version 0x%x has bad magic",
			    modp->mod_modname, apiver);
			return (NULL);
		}
	}

	if (apiver != CMI_API_VERSION) {
		cmn_err(CE_WARN, "cpu module '%s' has API version %d, "
		    "kernel requires API version %d", modp->mod_modname,
		    CMI_API_VERSION_TOPRINT(apiver),
		    CMI_API_VERSION_TOPRINT(CMI_API_VERSION));
		return (NULL);
	}

	if ((ops = cmi_getops(modp)) == NULL)
		return (NULL);

	cmi = kmem_zalloc(sizeof (*cmi), KM_SLEEP);
	cmi->cmi_ops = ops;
	cmi->cmi_modp = modp;

	cmi_link(cmi);

	return (cmi);
}
/**
 * Resolves a module entry point address.
 *
 * @returns VBox status code.
 * @param   pImage              The image.
 * @param   pszSymbol           The symbol name.
 * @param   ppvValue            Where to store the value.  On input this holds
 *                              the symbol value SUPLib calculated.
 */
static int supdrvSolLdrResolvEp(PSUPDRVLDRIMAGE pImage, const char *pszSymbol, void **ppvValue)
{
    /* Don't try resolve symbols which, according to SUPLib, aren't there. */
    if (!*ppvValue)
        return VINF_SUCCESS;

    uintptr_t uValue = modlookup_by_modctl(pImage->pSolModCtl, pszSymbol);
    if (!uValue)
    {
        LogRel(("supdrvOSLdrLoad on %s failed to resolve %s\n", pImage->szName, pszSymbol));
        return VERR_SYMBOL_NOT_FOUND;
    }
    *ppvValue = (void *)uValue;
    return VINF_SUCCESS;
}
Beispiel #3
0
static cms_t *
cms_load_modctl(modctl_t *modp)
{
	cms_ops_t *ops;
	uintptr_t ver;
	cms_t *cms;
	cms_api_ver_t apiver;

	ASSERT(MUTEX_HELD(&cms_load_lock));

	for (cms = cms_list; cms != NULL; cms = cms->cms_next) {
		if (cms->cms_modp == modp)
			return (cms);
	}

	if ((ver = modlookup_by_modctl(modp, "_cms_api_version")) == NULL) {
		cmn_err(CE_WARN, "cpu model-specific module '%s' is invalid:  "
		    "no _cms_api_version", modp->mod_modname);
		return (NULL);
	} else {
		apiver = *((cms_api_ver_t *)ver);
		if (!CMS_API_VERSION_CHKMAGIC(apiver)) {
			cmn_err(CE_WARN, "cpu model-specific module '%s' is "
			    "invalid: _cms_api_version 0x%x has bad magic",
			    modp->mod_modname, apiver);
			return (NULL);
		}
	}

	if (apiver != CMS_API_VERSION) {
		cmn_err(CE_WARN, "cpu model-specific module '%s' has API "
		    "version %d, kernel requires API version %d",
		    modp->mod_modname, CMS_API_VERSION_TOPRINT(apiver),
		    CMS_API_VERSION_TOPRINT(CMS_API_VERSION));
	return (NULL);
	}

	if ((ops = cms_getops(modp)) == NULL)
		return (NULL);

	cms = kmem_zalloc(sizeof (cms_t), KM_SLEEP);
	cms->cms_ops = ops;
	cms->cms_modp = modp;

	cms_link(cms);

	return (cms);
}
Beispiel #4
0
static cms_ops_t *
cms_getops(modctl_t *modp)
{
	cms_ops_t *ops;

	if ((ops = (cms_ops_t *)modlookup_by_modctl(modp, "_cms_ops")) ==
	    NULL) {
		cmn_err(CE_WARN, "cpu_ms module '%s' is invalid: no _cms_ops "
		    "found", modp->mod_modname);
		return (NULL);
	}

	if (ops->cms_init == NULL) {
		cmn_err(CE_WARN, "cpu_ms module '%s' is invalid: no cms_init "
		    "entry point", modp->mod_modname);
		return (NULL);
	}

	return (ops);
}
int  VBOXCALL   supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
{
#if 0 /* This doesn't work because of text alignment. */
    /*
     * Comparing is very very difficult since text and data may be allocated
     * separately.
     */
    size_t cbCompare = RT_MIN(pImage->cbImageBits, 64);
    if (memcmp(pImage->pvImage, pbImageBits, cbCompare))
    {
        LogRel(("Image mismatch: %s (%p)\n", pImage->szName, pImage->pvImage));
        LogRel(("Native: %.*Rhxs\n", cbCompare, pImage->pvImage));
        LogRel(("SUPLib: %.*Rhxs\n", cbCompare, pbImageBits));
        return VERR_LDR_MISMATCH_NATIVE;
    }
#endif

    /*
     * Get the exported symbol addresses.
     */
    int rc;
    modctl_t *pModCtl = mod_hold_by_id(pImage->idSolMod);
    if (pModCtl && pModCtl == pImage->pSolModCtl)
    {
        uint32_t iSym = pImage->cSymbols;
        while (iSym-- > 0)
        {
            const char *pszSymbol = &pImage->pachStrTab[pImage->paSymbols[iSym].offName];
            uintptr_t uValue = modlookup_by_modctl(pImage->pSolModCtl, pszSymbol);
            if (!uValue)
            {
                LogRel(("supdrvOSLdrLoad on %s failed to resolve the exported symbol: '%s'\n", pImage->szName, pszSymbol));
                break;
            }
            uintptr_t offSymbol = uValue - (uintptr_t)pImage->pvImage;
            pImage->paSymbols[iSym].offSymbol = offSymbol;
            if (pImage->paSymbols[iSym].offSymbol != (int32_t)offSymbol)
            {
                LogRel(("supdrvOSLdrLoad on %s symbol out of range: %p (%s) \n", pImage->szName, offSymbol, pszSymbol));
                break;
            }
        }

        rc = iSym == UINT32_MAX ? VINF_SUCCESS : VERR_LDR_GENERAL_FAILURE;

        /*
         * Get the standard module entry points.
         */
        if (RT_SUCCESS(rc))
        {
            rc = supdrvSolLdrResolvEp(pImage, "ModuleInit", (void **)&pImage->pfnModuleInit);
            if (RT_SUCCESS(rc))
                rc = supdrvSolLdrResolvEp(pImage, "ModuleTerm", (void **)&pImage->pfnModuleTerm);

            switch (pReq->u.In.eEPType)
            {
                case SUPLDRLOADEP_VMMR0:
                {
                    if (RT_SUCCESS(rc))
                        rc = supdrvSolLdrResolvEp(pImage, "VMMR0EntryInt",  (void **)&pReq->u.In.EP.VMMR0.pvVMMR0EntryInt);
                    if (RT_SUCCESS(rc))
                        rc = supdrvSolLdrResolvEp(pImage, "VMMR0EntryFast", (void **)&pReq->u.In.EP.VMMR0.pvVMMR0EntryFast);
                    if (RT_SUCCESS(rc))
                        rc = supdrvSolLdrResolvEp(pImage, "VMMR0EntryEx",   (void **)&pReq->u.In.EP.VMMR0.pvVMMR0EntryEx);
                    break;
                }

                case SUPLDRLOADEP_SERVICE:
                {
                    /** @todo we need the name of the entry point. */
                    return VERR_NOT_SUPPORTED;
                }
            }
        }

        mod_release_mod(pImage->pSolModCtl);
    }
    else
    {
        LogRel(("mod_hold_by_id failed in supdrvOSLdrLoad on %s: %p\n", pImage->szName, pModCtl));
        rc = VERR_LDR_MISMATCH_NATIVE;
    }
    return rc;
}