VirtualBox

Ignore:
Timestamp:
Dec 4, 2008 7:31:22 PM (16 years ago)
Author:
vboxsync
Message:

SUPDrv: Another failed attempt at resolving host_vmxon/off.

File:
1 edited

Legend:

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

    r14914 r15003  
    660660}
    661661
     662#if 0 /* doesn't work. */
    662663
    663664/*
     
    665666 * host_vmxon & host_vmxoff in Tiger.
    666667 */
    667 #if 0
    668668__BEGIN_DECLS
    669669#if 1
     
    677677#endif
    678678__END_DECLS
     679PFNRT g_pfn = (PFNRT)&host_vmxon;
    679680
    680681static int g_fWeakHostVmxOnOff = false;
     
    693694    g_fWeakHostVmxOnOff = true;
    694695}
    695 #endif
    696696#endif
    697697
     
    741741#endif
    742742}
     743
     744
     745#else /* more non-working code: */
     746
     747#include <mach-o/loader.h>
     748#include </usr/include/mach-o/nlist.h> /* ugly! but it's missing from the Kernel.framework */
     749
     750__BEGIN_DECLS
     751extern struct mach_header  _mh_execute_header;
     752//extern kmod_info_t        *kmod;
     753typedef struct pmap *pmap_t;
     754extern pmap_t kernel_pmap;
     755extern ppnum_t pmap_find_phys(pmap_t, addr64_t);
     756__END_DECLS
     757
     758RTDECL(int) RTLdrGetKernelSymbol(const char *pszSymbol, void **ppvValue)
     759{
     760    struct mach_header const           *pMHdr = &_mh_execute_header;
     761
     762    /*
     763     * Validate basic restrictions.
     764     */
     765    AssertPtrReturn(pMHdr, VERR_INVALID_POINTER);
     766    AssertMsgReturn(pMHdr->magic    == MH_MAGIC,   ("%#x\n", pMHdr->magic),    VERR_INVALID_EXE_SIGNATURE);
     767    AssertMsgReturn(pMHdr->filetype == MH_EXECUTE, ("%#x\n", pMHdr->filetype), VERR_BAD_EXE_FORMAT);
     768
     769    /*
     770     * Search for the __LINKEDIT segment and LC_SYMTAB.
     771     */
     772    struct symtab_command const        *pSymTabCmd = NULL;
     773    struct segment_command const       *pLinkEditSeg = NULL;
     774    union
     775    {
     776        void const                     *pv;
     777        uint8_t const                  *pb;
     778        struct load_command const      *pGen;
     779        struct segment_command const   *pSeg;
     780        struct symtab_command const    *pSymTab;
     781    } Cmd;
     782
     783    Cmd.pv = pMHdr + 1;
     784    uint32_t iCmd = pMHdr->ncmds;
     785    uint32_t cbCmdLeft = pMHdr->sizeofcmds;
     786    while (iCmd-- > 0)
     787    {
     788        AssertReturn(Cmd.pGen->cmdsize <= cbCmdLeft, VERR_BAD_EXE_FORMAT);
     789
     790        if (    Cmd.pGen->cmd == LC_SEGMENT
     791            &&  !strcmp(Cmd.pSeg->segname, "__LINKEDIT")
     792            &&  !pLinkEditSeg)
     793            pLinkEditSeg = Cmd.pSeg;
     794        else if (   Cmd.pGen->cmd == LC_SYMTAB
     795                 && Cmd.pGen->cmdsize == sizeof(struct symtab_command)
     796                 && !pSymTabCmd)
     797            pSymTabCmd = Cmd.pSymTab;
     798
     799        /* advance */
     800        cbCmdLeft -= Cmd.pGen->cmdsize;
     801        Cmd.pb += Cmd.pGen->cmdsize;
     802    }
     803
     804    /*
     805     * Check that the link edit segment and symbol table was found
     806     * and that the former contains the latter. Then calculate the
     807     * addresses of the symbol and string tables.
     808     */
     809    AssertReturn(pLinkEditSeg, VERR_BAD_EXE_FORMAT);
     810    AssertReturn(pSymTabCmd, VERR_BAD_EXE_FORMAT);
     811    AssertReturn(pSymTabCmd->symoff - pLinkEditSeg->fileoff < pLinkEditSeg->filesize, VERR_BAD_EXE_FORMAT);
     812    AssertReturn(pSymTabCmd->symoff + pSymTabCmd->nsyms * sizeof(struct nlist) - pLinkEditSeg->fileoff <= pLinkEditSeg->filesize, VERR_BAD_EXE_FORMAT);
     813    AssertReturn(pSymTabCmd->stroff - pLinkEditSeg->fileoff < pLinkEditSeg->filesize, VERR_BAD_EXE_FORMAT);
     814    AssertReturn(pSymTabCmd->stroff + pSymTabCmd->strsize - pLinkEditSeg->fileoff <= pLinkEditSeg->filesize, VERR_BAD_EXE_FORMAT);
     815    AssertReturn(pLinkEditSeg->filesize <= pLinkEditSeg->vmsize, VERR_BAD_EXE_FORMAT);
     816    const struct nlist *paSyms    = (const struct nlist *)(pLinkEditSeg->vmaddr + pSymTabCmd->symoff - pLinkEditSeg->fileoff);
     817    const char         *pchStrTab = (const char         *)(pLinkEditSeg->vmaddr + pSymTabCmd->stroff - pLinkEditSeg->fileoff);
     818
     819    /*
     820     * Check that the link edit segment wasn't freed yet.
     821     */
     822    ppnum_t PgNo = pmap_find_phys(kernel_pmap, pLinkEditSeg->vmaddr);
     823    if (!PgNo)
     824        return VERR_MODULE_NOT_FOUND;
     825
     826    /*
     827     * Search the symbol table for the desired symbol.
     828     */
     829    uint32_t const cbStrTab = pSymTabCmd->strsize;
     830    uint32_t const cSyms    = pSymTabCmd->nsyms;
     831    for (uint32_t iSym = 0; iSym < cSyms; iSym++)
     832    {
     833        unsigned int uSymType = paSyms[iSym].n_type & N_TYPE;
     834        if (    (uSymType == N_SECT || uSymType == N_ABS)
     835            &&  paSyms[iSym].n_un.n_strx > 0
     836            &&  (unsigned long)paSyms[iSym].n_un.n_strx < cbStrTab)
     837        {
     838            const char *pszName = pchStrTab + paSyms[iSym].n_un.n_strx;
     839#ifdef RT_ARCH_X86
     840            if (    pszName[0] == '_'  /* cdecl symbols are prefixed */
     841                &&  !strcmp(pszName + 1, pszSymbol))
     842#else
     843            if (!strcmp(pszName, pszSymbol))
     844#endif
     845            {
     846                *ppvValue = (uint8_t *)paSyms[iSym].n_value;
     847                return VINF_SUCCESS;
     848            }
     849        }
     850    }
     851    return VERR_SYMBOL_NOT_FOUND;
     852}
     853
     854static bool volatile g_fHostVmxResolved = false;
     855static int (*g_pfnHostVmxOn)(boolean_t exclusive) = NULL;
     856static void (*g_pfnHostVmxOff)(void) = NULL;
     857
     858
     859/**
     860 * Enables or disables VT-x using kernel functions.
     861 *
     862 * @returns VBox status code. VERR_NOT_SUPPORTED has a special meaning.
     863 * @param   fEnable     Whether to enable or disable.
     864 */
     865int VBOXCALL supdrvOSEnableVTx(bool fEnable)
     866{
     867    /*
     868     * Lazy initialization.
     869     */
     870    if (!g_fHostVmxResolved)
     871    {
     872        void *pvOn;
     873        int rc = RTLdrGetKernelSymbol("host_vmxon", &pvOn);
     874        if (RT_SUCCESS(rc))
     875        {
     876            void *pvOff;
     877            rc = RTLdrGetKernelSymbol("host_vmxoff", &pvOff);
     878            if (RT_SUCCESS(rc))
     879            {
     880                ASMAtomicUoWritePtr((void * volatile *)&g_pfnHostVmxOff, pvOff);
     881                ASMAtomicUoWritePtr((void * volatile *)&g_pfnHostVmxOn, pvOn);
     882            }
     883        }
     884        ASMAtomicWriteBool(&g_fHostVmxResolved, true);
     885    }
     886
     887    /*
     888     * Available?
     889     */
     890    if (!g_pfnHostVmxOn || !g_pfnHostVmxOff)
     891        return VERR_NOT_SUPPORTED;
     892
     893    /*
     894     * Do the job.
     895     */
     896    int rc;
     897    if (fEnable)
     898    {
     899        rc = g_pfnHostVmxOn(false /* exclusive */);
     900        if (rc == 0 /* all ok */)
     901            rc = VINF_SUCCESS;
     902        else if (rc == 1 /* unsupported */)
     903            rc = VERR_VMX_NO_VMX;
     904        else if (rc == 2 /* exclusive user */)
     905            rc = VERR_VMX_IN_VMX_ROOT_MODE;
     906        else
     907            rc = VERR_UNRESOLVED_ERROR;
     908    }
     909    else
     910    {
     911        g_pfnHostVmxOff();
     912        rc = VINF_SUCCESS;
     913    }
     914    return rc;
     915}
     916
     917#endif /* doesn't work*/
    743918
    744919
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