X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/43866e378188c25dd1e2208016ab3cbeb086ae6c..21362eb3e66fd2c787aee132bce100a44d71a99c:/bsd/kern/mach_fat.c diff --git a/bsd/kern/mach_fat.c b/bsd/kern/mach_fat.c index eca9d60e2..a9418aa8f 100644 --- a/bsd/kern/mach_fat.c +++ b/bsd/kern/mach_fat.c @@ -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. * @@ -43,41 +46,55 @@ #include #include +/* 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); +}