Changeset 15003 in vbox for trunk/src/VBox/HostDrivers/Support
- Timestamp:
- Dec 4, 2008 7:31:22 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
r14914 r15003 660 660 } 661 661 662 #if 0 /* doesn't work. */ 662 663 663 664 /* … … 665 666 * host_vmxon & host_vmxoff in Tiger. 666 667 */ 667 #if 0668 668 __BEGIN_DECLS 669 669 #if 1 … … 677 677 #endif 678 678 __END_DECLS 679 PFNRT g_pfn = (PFNRT)&host_vmxon; 679 680 680 681 static int g_fWeakHostVmxOnOff = false; … … 693 694 g_fWeakHostVmxOnOff = true; 694 695 } 695 #endif696 696 #endif 697 697 … … 741 741 #endif 742 742 } 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 751 extern struct mach_header _mh_execute_header; 752 //extern kmod_info_t *kmod; 753 typedef struct pmap *pmap_t; 754 extern pmap_t kernel_pmap; 755 extern ppnum_t pmap_find_phys(pmap_t, addr64_t); 756 __END_DECLS 757 758 RTDECL(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 854 static bool volatile g_fHostVmxResolved = false; 855 static int (*g_pfnHostVmxOn)(boolean_t exclusive) = NULL; 856 static 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 */ 865 int 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*/ 743 918 744 919
Note:
See TracChangeset
for help on using the changeset viewer.