]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/mach_fat.c
6ccadf16e2c8667d959c66dae111239a74082370
[apple/xnu.git] / bsd / kern / mach_fat.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /* Copyright (c) 1991 NeXT Computer, Inc. All rights reserved.
26 *
27 * File: kern/mach_fat.c
28 * Author: Peter King
29 *
30 * Fat file support routines.
31 *
32 */
33
34 #include <sys/param.h>
35 #include <sys/types.h>
36 #include <sys/uio.h>
37 #include <sys/vnode.h>
38 #include <vm/vm_kern.h>
39 #include <mach/kern_return.h>
40 #include <mach/vm_param.h>
41 #include <kern/cpu_number.h>
42 #include <mach-o/fat.h>
43 #include <kern/mach_loader.h>
44 #include <architecture/byte_order.h>
45
46
47 /**********************************************************************
48 * Routine: fatfile_getarch()
49 *
50 * Function: Locate the architecture-dependant contents of a fat
51 * file that match this CPU.
52 *
53 * Args: vp: The vnode for the fat file.
54 * header: A pointer to the fat file header.
55 * archret (out): Pointer to fat_arch structure to hold
56 * the results.
57 *
58 * Returns: KERN_SUCCESS: Valid architecture found.
59 * KERN_FAILURE: No valid architecture found.
60 **********************************************************************/
61 load_return_t
62 fatfile_getarch(
63 struct vnode *vp,
64 vm_offset_t data_ptr,
65 struct fat_arch *archret)
66 {
67 /* vm_pager_t pager; */
68 vm_offset_t addr;
69 vm_size_t size;
70 kern_return_t kret;
71 load_return_t lret;
72 struct machine_slot *ms;
73 struct fat_arch *arch;
74 struct fat_arch *best_arch;
75 int grade;
76 int best_grade;
77 int nfat_arch;
78 int end_of_archs;
79 struct fat_header *header;
80 off_t filesize;
81
82 /*
83 * Get the pager for the file.
84 */
85
86 header = (struct fat_header *)data_ptr;
87
88 /*
89 * Map portion that must be accessible directly into
90 * kernel's map.
91 */
92 nfat_arch = NXSwapBigLongToHost(header->nfat_arch);
93
94 end_of_archs = sizeof(struct fat_header)
95 + nfat_arch * sizeof(struct fat_arch);
96 #if 0
97 filesize = ubc_getsize(vp);
98 if (end_of_archs > (int)filesize) {
99 return(LOAD_BADMACHO);
100 }
101 #endif
102
103 /* This is beacuse we are reading only 512 bytes */
104
105 if (end_of_archs > 512)
106 return(LOAD_BADMACHO);
107 /*
108 * Round size of fat_arch structures up to page boundry.
109 */
110 size = round_page_32(end_of_archs);
111 if (size <= 0)
112 return(LOAD_BADMACHO);
113
114 /*
115 * Scan the fat_arch's looking for the best one.
116 */
117 addr = data_ptr;
118 ms = &machine_slot[cpu_number()];
119 best_arch = NULL;
120 best_grade = 0;
121 arch = (struct fat_arch *) (addr + sizeof(struct fat_header));
122 for (; nfat_arch-- > 0; arch++) {
123
124 /*
125 * Check to see if right cpu type.
126 */
127 if(NXSwapBigIntToHost(arch->cputype) != ms->cpu_type)
128 continue;
129
130 /*
131 * Get the grade of the cpu subtype.
132 */
133 grade = grade_cpu_subtype(
134 NXSwapBigIntToHost(arch->cpusubtype));
135
136 /*
137 * Remember it if it's the best we've seen.
138 */
139 if (grade > best_grade) {
140 best_grade = grade;
141 best_arch = arch;
142 }
143 }
144
145 /*
146 * Return our results.
147 */
148 if (best_arch == NULL) {
149 lret = LOAD_BADARCH;
150 } else {
151 archret->cputype =
152 NXSwapBigIntToHost(best_arch->cputype);
153 archret->cpusubtype =
154 NXSwapBigIntToHost(best_arch->cpusubtype);
155 archret->offset =
156 NXSwapBigLongToHost(best_arch->offset);
157 archret->size =
158 NXSwapBigLongToHost(best_arch->size);
159 archret->align =
160 NXSwapBigLongToHost(best_arch->align);
161
162 lret = LOAD_SUCCESS;
163 }
164
165 /*
166 * Free the memory we allocated and return.
167 */
168 return(lret);
169 }
170
171