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; }
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); }
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; }