darwin-xnu/bsd/kern/mach_fat.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
   3 *
   4 * @APPLE_LICENSE_HEADER_START@
   5 * 
   6 * The contents of this file constitute Original Code as defined in and
   7 * are subject to the Apple Public Source License Version 1.1 (the
   8 * "License").  You may not use this file except in compliance with the
   9 * License.  Please obtain a copy of the License at
  10 * http://www.apple.com/publicsource and read it before using this file.
  11 * 
  12 * This Original Code and all software distributed under the License are
  13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
  17 * License for the specific language governing rights and limitations
  18 * under the License.
  19 * 
  20 * @APPLE_LICENSE_HEADER_END@
  21 */
  22/* Copyright (c) 1991 NeXT Computer, Inc.  All rights reserved.
  23 *
  24 *      File:   kern/mach_fat.c
  25 *      Author: Peter King
  26 *
  27 *      Fat file support routines.
  28 *
  29 */
  30
  31#include <sys/param.h>
  32#include <sys/types.h>
  33#include <sys/uio.h>
  34#include <sys/vnode.h>
  35#include <vm/vm_kern.h>
  36#include <mach/kern_return.h>
  37#include <mach/vm_param.h>
  38#include <kern/cpu_number.h>
  39#include <mach-o/fat.h>
  40#include <kern/mach_loader.h>
  41#include <architecture/byte_order.h>
  42
  43/* XXX should be in common header */
  44extern int grade_binary(cpu_type_t exectype, cpu_subtype_t execsubtype);
  45
  46#define CPU_TYPE_NATIVE         (cpu_type())
  47#define CPU_TYPE_CLASSIC        CPU_TYPE_POWERPC
  48
  49/**********************************************************************
  50 * Routine:     fatfile_getarch2()
  51 *
  52 * Function:    Locate the architecture-dependant contents of a fat
  53 *              file that match this CPU.
  54 *
  55 * Args:        vp:             The vnode for the fat file.
  56 *              header:         A pointer to the fat file header.
  57 *              req_cpu_type:   The required cpu type.
  58 *              mask_bits:      Bits to mask from the sub-image type when
  59 *                              grading it vs. the req_cpu_type
  60 *              archret (out):  Pointer to fat_arch structure to hold
  61 *                              the results.
  62 *
  63 * Returns:     KERN_SUCCESS:   Valid architecture found.
  64 *              KERN_FAILURE:   No valid architecture found.
  65 **********************************************************************/
  66static load_return_t
  67fatfile_getarch2(
  68#if 0
  69        struct vnode    *vp,
  70#else
  71        __unused struct vnode   *vp,
  72#endif
  73        vm_offset_t     data_ptr,
  74        cpu_type_t      req_cpu_type,
  75        cpu_type_t      mask_bits,
  76        struct fat_arch *archret)
  77{
  78        /* vm_pager_t           pager; */
  79        vm_offset_t             addr;
  80        vm_size_t               size;
  81        load_return_t           lret;
  82        struct fat_arch         *arch;
  83        struct fat_arch         *best_arch;
  84        int                     grade;
  85        int                     best_grade;
  86        int                     nfat_arch;
  87        int                     end_of_archs;
  88        struct fat_header       *header;
  89#if 0
  90        off_t filesize;
  91#endif
  92
  93        /*
  94         *      Get the pager for the file.
  95         */
  96
  97        header = (struct fat_header *)data_ptr;
  98
  99        /*
 100         *      Map portion that must be accessible directly into
 101         *      kernel's map.
 102         */
 103        nfat_arch = NXSwapBigLongToHost(header->nfat_arch);
 104
 105        end_of_archs = sizeof(struct fat_header)
 106                + nfat_arch * sizeof(struct fat_arch);
 107#if 0
 108        filesize = ubc_getsize(vp);
 109        if (end_of_archs > (int)filesize) {
 110                return(LOAD_BADMACHO);
 111        }
 112#endif
 113
 114        /* This is beacuse we are reading only 512 bytes */
 115
 116        if (end_of_archs > 512)
 117                return(LOAD_BADMACHO);
 118        /*
 119         *      Round size of fat_arch structures up to page boundry.
 120         */
 121        size = round_page_32(end_of_archs);
 122        if (size == 0)
 123                return(LOAD_BADMACHO);
 124
 125        /*
 126         * Scan the fat_arch's looking for the best one.
 127         */
 128        addr = data_ptr;
 129        best_arch = NULL;
 130        best_grade = 0;
 131        arch = (struct fat_arch *) (addr + sizeof(struct fat_header));
 132        for (; nfat_arch-- > 0; arch++) {
 133
 134                /*
 135                 *      Check to see if right cpu type.
 136                 */
 137                if(((cpu_type_t)NXSwapBigIntToHost(arch->cputype) & ~mask_bits) != req_cpu_type)
 138                        continue;
 139
 140                /*
 141                 *      Get the grade of the cpu subtype.
 142                 */
 143                grade = grade_binary(
 144                            NXSwapBigIntToHost(arch->cputype),
 145                            NXSwapBigIntToHost(arch->cpusubtype));
 146
 147                /*
 148                 *      Remember it if it's the best we've seen.
 149                 */
 150                if (grade > best_grade) {
 151                        best_grade = grade;
 152                        best_arch = arch;
 153                }
 154        }
 155
 156        /*
 157         *      Return our results.
 158         */
 159        if (best_arch == NULL) {
 160                lret = LOAD_BADARCH;
 161        } else {
 162                archret->cputype        =
 163                            NXSwapBigIntToHost(best_arch->cputype);
 164                archret->cpusubtype     =
 165                            NXSwapBigIntToHost(best_arch->cpusubtype);
 166                archret->offset         =
 167                            NXSwapBigLongToHost(best_arch->offset);
 168                archret->size           =
 169                            NXSwapBigLongToHost(best_arch->size);
 170                archret->align          =
 171                            NXSwapBigLongToHost(best_arch->align);
 172
 173                lret = LOAD_SUCCESS;
 174        }
 175
 176        /*
 177         * Free the memory we allocated and return.
 178         */
 179        return(lret);
 180}
 181
 182extern char classichandler[];
 183
 184load_return_t
 185fatfile_getarch_affinity(
 186                struct vnode            *vp,
 187                vm_offset_t             data_ptr,
 188                struct fat_arch *archret,
 189                int                             affinity)
 190{
 191                load_return_t lret;
 192                int handler = (classichandler[0] != 0);
 193                cpu_type_t primary_type, fallback_type;
 194
 195                if (handler && affinity) {
 196                                primary_type = CPU_TYPE_CLASSIC;
 197                                fallback_type = CPU_TYPE_NATIVE;
 198                } else {
 199                                primary_type = CPU_TYPE_NATIVE;
 200                                fallback_type = CPU_TYPE_CLASSIC;
 201                }
 202                /*
 203                 * Ignore the architectural bits when determining if an image
 204                 * in a fat file should be skipped or graded.
 205                 */
 206                lret = fatfile_getarch2(vp, data_ptr, primary_type, CPU_ARCH_MASK, archret);
 207                if ((lret != 0) && handler) {
 208                        lret = fatfile_getarch2(vp, data_ptr, fallback_type,
 209                                                0, archret);
 210                }
 211                return lret;
 212}
 213
 214/**********************************************************************
 215 * Routine:     fatfile_getarch()
 216 *
 217 * Function:    Locate the architecture-dependant contents of a fat
 218 *              file that match this CPU.
 219 *
 220 * Args:        vp:             The vnode for the fat file.
 221 *              header:         A pointer to the fat file header.
 222 *              archret (out):  Pointer to fat_arch structure to hold
 223 *                              the results.
 224 *
 225 * Returns:     KERN_SUCCESS:   Valid architecture found.
 226 *              KERN_FAILURE:   No valid architecture found.
 227 **********************************************************************/
 228load_return_t
 229fatfile_getarch(
 230        struct vnode            *vp,
 231        vm_offset_t     data_ptr,
 232        struct fat_arch         *archret)
 233{
 234        return fatfile_getarch2(vp, data_ptr, CPU_TYPE_NATIVE, 0, archret);
 235}
 236
 237/**********************************************************************
 238 * Routine:     fatfile_getarch_with_bits()
 239 *
 240 * Function:    Locate the architecture-dependant contents of a fat
 241 *              file that match this CPU.
 242 *
 243 * Args:        vp:             The vnode for the fat file.
 244 *              archbits:       Architecture specific feature bits
 245 *              header:         A pointer to the fat file header.
 246 *              archret (out):  Pointer to fat_arch structure to hold
 247 *                              the results.
 248 *
 249 * Returns:     KERN_SUCCESS:   Valid architecture found.
 250 *              KERN_FAILURE:   No valid architecture found.
 251 **********************************************************************/
 252load_return_t
 253fatfile_getarch_with_bits(
 254        struct vnode            *vp,
 255        integer_t               archbits,
 256        vm_offset_t     data_ptr,
 257        struct fat_arch         *archret)
 258{
 259        return fatfile_getarch2(vp, data_ptr, archbits | CPU_TYPE_NATIVE, 0, archret);
 260}
 261
 262
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.