]>
git.saurik.com Git - apple/xnu.git/blob - bsd/kern/mach_fat.c
   2  * Copyright (c) 1991-2005 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. The rights granted to you under the License 
  10  * may not be used to create, or enable the creation or redistribution of, 
  11  * unlawful or unlicensed copies of an Apple operating system, or to 
  12  * circumvent, violate, or enable the circumvention or violation of, any 
  13  * terms of an Apple operating system software license agreement. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  18  * The Original Code and all software distributed under the License are 
  19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  23  * Please see the License for the specific language governing rights and 
  24  * limitations under the License. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  28 #include <sys/param.h> 
  29 #include <sys/types.h> 
  31 #include <sys/vnode.h> 
  32 #include <vm/vm_kern.h> 
  33 #include <mach/kern_return.h> 
  34 #include <mach/vm_param.h> 
  35 #include <kern/cpu_number.h> 
  36 #include <mach-o/fat.h> 
  37 #include <kern/mach_loader.h> 
  38 #include <libkern/OSByteOrder.h> 
  39 #include <machine/exec.h> 
  41 /********************************************************************** 
  42  * Routine:     fatfile_getarch2() 
  44  * Function:    Locate the architecture-dependant contents of a fat 
  45  *              file that match this CPU. 
  47  * Args:        vp:             The vnode for the fat file. 
  48  *              header:         A pointer to the fat file header. 
  49  *              req_cpu_type:   The required cpu type. 
  50  *              mask_bits:      Bits to mask from the sub-image type when 
  51  *                              grading it vs. the req_cpu_type 
  52  *              archret (out):  Pointer to fat_arch structure to hold 
  55  * Returns:     KERN_SUCCESS:   Valid architecture found. 
  56  *              KERN_FAILURE:   No valid architecture found. 
  57  **********************************************************************/ 
  63         __unused 
struct vnode   
*vp
, 
  66         cpu_type_t      req_cpu_type
, 
  68         struct fat_arch 
*archret
) 
  70         /* vm_pager_t           pager; */ 
  74         struct fat_arch         
*arch
; 
  75         struct fat_arch         
*best_arch
; 
  81         cpu_type_t              testsubtype
; 
  82         struct fat_header       
*header
; 
  88          *      Get the pager for the file. 
  91         header 
= (struct fat_header 
*)data_ptr
; 
  94          *      Map portion that must be accessible directly into 
  97         nfat_arch 
= OSSwapBigToHostInt32(header
->nfat_arch
); 
  99         end_of_archs 
= (off_t
)nfat_arch 
* sizeof(struct fat_arch
) + 
 100                         sizeof(struct fat_header
); 
 102         filesize 
= ubc_getsize(vp
); 
 103         if (end_of_archs 
> (int)filesize
) { 
 104                 return(LOAD_BADMACHO
); 
 109          * This check is limited on the top end because we are reading 
 110          * only PAGE_SIZE bytes 
 112         if (end_of_archs 
> PAGE_SIZE 
|| 
 113             end_of_archs 
< (sizeof(struct fat_header
)+sizeof(struct fat_arch
))) 
 114                 return(LOAD_BADMACHO
); 
 117          *      Round size of fat_arch structures up to page boundry. 
 119         size 
= round_page_32(end_of_archs
); 
 121                 return(LOAD_BADMACHO
); 
 124          * Ignore LIB64 flag so that binary slices with the flag set 
 125          * don't choke in grade_binary. 
 127         mask_bits 
|= CPU_SUBTYPE_LIB64
; 
 130          * Scan the fat_arch's looking for the best one.  */ 
 134         arch 
= (struct fat_arch 
*) (addr 
+ sizeof(struct fat_header
)); 
 135         for (; nfat_arch
-- > 0; arch
++) { 
 138                  *      Collect flags from both cputype and cpusubtype  
 140                 testtype 
= OSSwapBigToHostInt32(arch
->cputype
) | 
 141                                 (OSSwapBigToHostInt32(arch
->cpusubtype
) &  
 143                 testsubtype 
= OSSwapBigToHostInt32(arch
->cpusubtype
)  
 147                  *      Check to see if right cpu type. 
 149                 if((testtype 
& ~mask_bits
) != req_cpu_type
) { 
 154                  *      Get the grade of the cpu subtype (without feature flags) 
 156                 grade 
= grade_binary( 
 157                                 (testtype 
& ~CPU_SUBTYPE_LIB64
),  
 161                  *      Remember it if it's the best we've seen. 
 163                 if (grade 
> best_grade
) { 
 170          *      Return our results. 
 172         if (best_arch 
== NULL
) { 
 176                             OSSwapBigToHostInt32(best_arch
->cputype
); 
 177                 archret
->cpusubtype     
= 
 178                             OSSwapBigToHostInt32(best_arch
->cpusubtype
); 
 180                             OSSwapBigToHostInt32(best_arch
->offset
); 
 182                             OSSwapBigToHostInt32(best_arch
->size
); 
 184                             OSSwapBigToHostInt32(best_arch
->align
); 
 190          * Free the memory we allocated and return. 
 196 fatfile_getarch_affinity( 
 198                 vm_offset_t             data_ptr
, 
 199                 struct fat_arch 
*archret
, 
 203                 int handler 
= (exec_archhandler_ppc
.path
[0] != 0); 
 204                 cpu_type_t primary_type
, fallback_type
; 
 206                 if (handler 
&& affinity
) { 
 207                                 primary_type 
= CPU_TYPE_POWERPC
; 
 208                                 fallback_type 
= cpu_type(); 
 210                                 primary_type 
= cpu_type(); 
 211                                 fallback_type 
= CPU_TYPE_POWERPC
; 
 214                  * Ignore all architectural bits when determining if an image 
 215                  * in a fat file should be skipped or graded. 
 217                 lret 
= fatfile_getarch2(vp
, data_ptr
, primary_type
,  
 218                                 CPU_ARCH_MASK
, archret
); 
 219                 if ((lret 
!= 0) && handler
) { 
 220                         lret 
= fatfile_getarch2(vp
, data_ptr
, fallback_type
, 
 221                                                 CPU_SUBTYPE_LIB64
, archret
); 
 226 /********************************************************************** 
 227  * Routine:     fatfile_getarch() 
 229  * Function:    Locate the architecture-dependant contents of a fat 
 230  *              file that match this CPU. 
 232  * Args:        vp:             The vnode for the fat file. 
 233  *              header:         A pointer to the fat file header. 
 234  *              archret (out):  Pointer to fat_arch structure to hold 
 237  * Returns:     KERN_SUCCESS:   Valid architecture found. 
 238  *              KERN_FAILURE:   No valid architecture found. 
 239  **********************************************************************/ 
 243         vm_offset_t     data_ptr
, 
 244         struct fat_arch         
*archret
) 
 246         return fatfile_getarch2(vp
, data_ptr
, cpu_type(),  
 247                         CPU_SUBTYPE_LIB64
, archret
); 
 250 /********************************************************************** 
 251  * Routine:     fatfile_getarch_with_bits() 
 253  * Function:    Locate the architecture-dependant contents of a fat 
 254  *              file that match this CPU. 
 256  * Args:        vp:             The vnode for the fat file. 
 257  *              archbits:       Architecture specific feature bits 
 258  *              header:         A pointer to the fat file header. 
 259  *              archret (out):  Pointer to fat_arch structure to hold 
 262  * Returns:     KERN_SUCCESS:   Valid architecture found. 
 263  *              KERN_FAILURE:   No valid architecture found. 
 264  **********************************************************************/ 
 266 fatfile_getarch_with_bits( 
 269         vm_offset_t     data_ptr
, 
 270         struct fat_arch         
*archret
) 
 272         return fatfile_getarch2(vp
, data_ptr
, archbits 
| cpu_type(),  
 273                         CPU_SUBTYPE_LIB64
, archret
);