1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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
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
95
96
97 header = (struct fat_header *)data_ptr;
98
99
100
101
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
115
116 if (end_of_archs > 512)
117 return(LOAD_BADMACHO);
118
119
120
121 size = round_page_32(end_of_archs);
122 if (size == 0)
123 return(LOAD_BADMACHO);
124
125
126
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
136
137 if(((cpu_type_t)NXSwapBigIntToHost(arch->cputype) & ~mask_bits) != req_cpu_type)
138 continue;
139
140
141
142
143 grade = grade_binary(
144 NXSwapBigIntToHost(arch->cputype),
145 NXSwapBigIntToHost(arch->cpusubtype));
146
147
148
149
150 if (grade > best_grade) {
151 best_grade = grade;
152 best_arch = arch;
153 }
154 }
155
156
157
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
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
204
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
216
217
218
219
220
221
222
223
224
225
226
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
239
240
241
242
243
244
245
246
247
248
249
250
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