]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/mach_fat.c
xnu-792.21.3.tar.gz
[apple/xnu.git] / bsd / kern / mach_fat.c
index eca9d60e25315270f9dd251c171434c8b2888039..a9418aa8f981bf6e8b63351c6bf0e2a341deea57 100644 (file)
@@ -1,16 +1,19 @@
 /*
  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ * 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
  * 
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
@@ -20,7 +23,7 @@
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /* Copyright (c) 1991 NeXT Computer, Inc.  All rights reserved.
  *
 #include <kern/mach_loader.h>
 #include <architecture/byte_order.h>
 
+/* XXX should be in common header */
+extern int grade_binary(cpu_type_t exectype, cpu_subtype_t execsubtype);
+
+#define CPU_TYPE_NATIVE                (cpu_type())
+#define CPU_TYPE_CLASSIC       CPU_TYPE_POWERPC
 
 /**********************************************************************
- * Routine:    fatfile_getarch()
+ * Routine:    fatfile_getarch2()
  *
  * Function:   Locate the architecture-dependant contents of a fat
  *             file that match this CPU.
  *
  * Args:       vp:             The vnode for the fat file.
  *             header:         A pointer to the fat file header.
+ *             req_cpu_type:   The required cpu type.
+ *             mask_bits:      Bits to mask from the sub-image type when
+ *                             grading it vs. the req_cpu_type
  *             archret (out):  Pointer to fat_arch structure to hold
  *                             the results.
  *
  * Returns:    KERN_SUCCESS:   Valid architecture found.
  *             KERN_FAILURE:   No valid architecture found.
  **********************************************************************/
-load_return_t
-fatfile_getarch(
-       struct vnode            *vp,
-       vm_offset_t     data_ptr,
-       struct fat_arch         *archret)
+static load_return_t
+fatfile_getarch2(
+#if 0
+       struct vnode    *vp,
+#else
+       __unused struct vnode   *vp,
+#endif
+       vm_offset_t     data_ptr,
+       cpu_type_t      req_cpu_type,
+       cpu_type_t      mask_bits,
+       struct fat_arch *archret)
 {
        /* vm_pager_t           pager; */
        vm_offset_t             addr;
        vm_size_t               size;
-       kern_return_t           kret;
        load_return_t           lret;
-       struct machine_slot     *ms;
        struct fat_arch         *arch;
        struct fat_arch         *best_arch;
        int                     grade;
        int                     best_grade;
        int                     nfat_arch;
-       int                     end_of_archs;
+       off_t           end_of_archs;
        struct fat_header       *header;
+#if 0
        off_t filesize;
+#endif
 
        /*
         *      Get the pager for the file.
@@ -91,8 +108,8 @@ fatfile_getarch(
         */
        nfat_arch = NXSwapBigLongToHost(header->nfat_arch);
 
-       end_of_archs = sizeof(struct fat_header)
-               + nfat_arch * sizeof(struct fat_arch);
+       end_of_archs = (off_t)nfat_arch * sizeof(struct fat_arch) + 
+               sizeof(struct fat_header);
 #if 0
        filesize = ubc_getsize(vp);
        if (end_of_archs > (int)filesize) {
@@ -100,22 +117,24 @@ fatfile_getarch(
        }
 #endif
 
-       /* This is beacuse we are reading only 512 bytes */
-
-       if (end_of_archs > 512)
+       /*
+        * This check is limited on the top end because we are reading
+        * only PAGE_SIZE bytes
+        */
+       if (end_of_archs > PAGE_SIZE ||
+               end_of_archs < (sizeof(struct fat_header)+sizeof(struct fat_arch)))
                return(LOAD_BADMACHO);
        /*
         *      Round size of fat_arch structures up to page boundry.
         */
-       size = round_page(end_of_archs);
-       if (size <= 0)
+       size = round_page_32(end_of_archs);
+       if (size == 0)
                return(LOAD_BADMACHO);
 
        /*
         * Scan the fat_arch's looking for the best one.
         */
        addr = data_ptr;
-       ms = &machine_slot[cpu_number()];
        best_arch = NULL;
        best_grade = 0;
        arch = (struct fat_arch *) (addr + sizeof(struct fat_header));
@@ -124,13 +143,14 @@ fatfile_getarch(
                /*
                 *      Check to see if right cpu type.
                 */
-               if(NXSwapBigIntToHost(arch->cputype) != ms->cpu_type)
+               if(((cpu_type_t)NXSwapBigIntToHost(arch->cputype) & ~mask_bits) != req_cpu_type)
                        continue;
 
                /*
                 *      Get the grade of the cpu subtype.
                 */
-               grade = grade_cpu_subtype(
+               grade = grade_binary(
+                           NXSwapBigIntToHost(arch->cputype),
                            NXSwapBigIntToHost(arch->cpusubtype));
 
                /*
@@ -168,4 +188,83 @@ fatfile_getarch(
        return(lret);
 }
 
+extern char classichandler[];
+
+load_return_t
+fatfile_getarch_affinity(
+               struct vnode            *vp,
+               vm_offset_t             data_ptr,
+               struct fat_arch *archret,
+               int                             affinity)
+{
+               load_return_t lret;
+               int handler = (classichandler[0] != 0);
+               cpu_type_t primary_type, fallback_type;
+
+               if (handler && affinity) {
+                               primary_type = CPU_TYPE_CLASSIC;
+                               fallback_type = CPU_TYPE_NATIVE;
+               } else {
+                               primary_type = CPU_TYPE_NATIVE;
+                               fallback_type = CPU_TYPE_CLASSIC;
+               }
+               /*
+                * Ignore the architectural bits when determining if an image
+                * in a fat file should be skipped or graded.
+                */
+               lret = fatfile_getarch2(vp, data_ptr, primary_type, CPU_ARCH_MASK, archret);
+               if ((lret != 0) && handler) {
+                       lret = fatfile_getarch2(vp, data_ptr, fallback_type,
+                                               0, archret);
+               }
+               return lret;
+}
+
+/**********************************************************************
+ * Routine:    fatfile_getarch()
+ *
+ * Function:   Locate the architecture-dependant contents of a fat
+ *             file that match this CPU.
+ *
+ * Args:       vp:             The vnode for the fat file.
+ *             header:         A pointer to the fat file header.
+ *             archret (out):  Pointer to fat_arch structure to hold
+ *                             the results.
+ *
+ * Returns:    KERN_SUCCESS:   Valid architecture found.
+ *             KERN_FAILURE:   No valid architecture found.
+ **********************************************************************/
+load_return_t
+fatfile_getarch(
+       struct vnode            *vp,
+       vm_offset_t     data_ptr,
+       struct fat_arch         *archret)
+{
+       return fatfile_getarch2(vp, data_ptr, CPU_TYPE_NATIVE, 0, archret);
+}
+
+/**********************************************************************
+ * Routine:    fatfile_getarch_with_bits()
+ *
+ * Function:   Locate the architecture-dependant contents of a fat
+ *             file that match this CPU.
+ *
+ * Args:       vp:             The vnode for the fat file.
+ *             archbits:       Architecture specific feature bits
+ *             header:         A pointer to the fat file header.
+ *             archret (out):  Pointer to fat_arch structure to hold
+ *                             the results.
+ *
+ * Returns:    KERN_SUCCESS:   Valid architecture found.
+ *             KERN_FAILURE:   No valid architecture found.
+ **********************************************************************/
+load_return_t
+fatfile_getarch_with_bits(
+       struct vnode            *vp,
+       integer_t               archbits,
+       vm_offset_t     data_ptr,
+       struct fat_arch         *archret)
+{
+       return fatfile_getarch2(vp, data_ptr, archbits | CPU_TYPE_NATIVE, 0, archret);
+}