]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/mach_fat.c
xnu-792.6.22.tar.gz
[apple/xnu.git] / bsd / kern / mach_fat.c
index 6c25ae9d446ceca4bd1854aff8e772a75bc1c937..408d2ecb21df92f7276a2027056a715c69a092bb 100644 (file)
 #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;
@@ -74,7 +86,9 @@ fatfile_getarch(
        int                     nfat_arch;
        int                     end_of_archs;
        struct fat_header       *header;
+#if 0
        off_t filesize;
+#endif
 
        /*
         *      Get the pager for the file.
@@ -104,15 +118,14 @@ fatfile_getarch(
        /*
         *      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));
@@ -121,13 +134,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));
 
                /*
@@ -165,4 +179,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);
+}