Chameleon Applications

Chameleon Applications Svn Source Tree

Root/branches/iFabio/i386/libsaio/load.c

Source at commit 214 created 13 years 5 months ago.
By ifabio, update to chameleon trunk 630, and now the pakage folder is the same as blackosx branch, also add Icon "building" into buildpkg script, and add mint theme info into the English localizable.strings.
1/*
2 * Copyright (c) 2003 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 2.0 (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/*
23 * load.c - Functions for decoding a Mach-o Kernel.
24 *
25 * Copyright (c) 1998-2003 Apple Computer, Inc.
26 *
27 */
28
29#include <mach-o/fat.h>
30#include <mach-o/loader.h>
31#include <mach/machine/thread_status.h>
32
33#include <sl.h>
34
35static long DecodeSegment(long cmdBase, unsigned int*load_addr, unsigned int *load_size);
36static long DecodeUnixThread(long cmdBase, unsigned int *entry);
37static long DecodeSymbolTable(long cmdBase);
38
39
40static unsigned long gBinaryAddress;
41bool gHaveKernelCache;/* XXX aserebln: uninitialized? and only set to true, never to false */
42cpu_type_t archCpuType=CPU_TYPE_I386;
43
44// Public Functions
45
46long ThinFatFile(void **binary, unsigned long *length)
47{
48 unsigned long nfat, swapped, size = 0;
49 struct fat_header *fhp = (struct fat_header *)*binary;
50 struct fat_arch *fap =
51 (struct fat_arch *)((unsigned long)*binary + sizeof(struct fat_header));
52 cpu_type_t fapcputype;
53 uint32_t fapoffset;
54 uint32_t fapsize;
55
56 if (fhp->magic == FAT_MAGIC) {
57 nfat = fhp->nfat_arch;
58 swapped = 0;
59 } else if (fhp->magic == FAT_CIGAM) {
60 nfat = OSSwapInt32(fhp->nfat_arch);
61 swapped = 1;
62 } else {
63 return -1;
64 }
65
66 for (; nfat > 0; nfat--, fap++) {
67 if (swapped) {
68 fapcputype = OSSwapInt32(fap->cputype);
69 fapoffset = OSSwapInt32(fap->offset);
70 fapsize = OSSwapInt32(fap->size);
71 }
72else
73{
74fapcputype = fap->cputype;
75fapoffset = fap->offset;
76fapsize = fap->size;
77}
78
79 if (fapcputype == archCpuType) {
80 *binary = (void *) ((unsigned long)*binary + fapoffset);
81 size = fapsize;
82 break;
83 }
84 }
85
86 if (length != 0) *length = size;
87
88 return 0;
89}
90
91long DecodeMachO(void *binary, entry_t *rentry, char **raddr, int *rsize)
92{
93 struct mach_header *mH;
94 unsigned long ncmds, cmdBase, cmd, cmdsize, cmdstart;
95 // long headerBase, headerAddr, headerSize;
96 unsigned int vmaddr = ~0;
97 unsigned int vmend = 0;
98 unsigned long cnt;
99 long ret = -1;
100 unsigned int entry = 0;
101
102 gBinaryAddress = (unsigned long)binary;
103
104 mH = (struct mach_header *)(gBinaryAddress);
105 switch (archCpuType)
106{
107case CPU_TYPE_I386:
108if (mH->magic != MH_MAGIC) {
109error("Mach-O file has bad magic number\n");
110return -1;
111}
112cmdstart = (unsigned long)gBinaryAddress + sizeof(struct mach_header);
113break;
114case CPU_TYPE_X86_64:
115if (mH->magic != MH_MAGIC_64 && mH->magic == MH_MAGIC)
116return -1;
117if (mH->magic != MH_MAGIC_64) {
118error("Mach-O file has bad magic number\n");
119return -1;
120}
121cmdstart = (unsigned long)gBinaryAddress + sizeof(struct mach_header_64);
122break;
123default:
124error("Unknown CPU type\n");
125return -1;
126}
127
128 cmdBase = cmdstart;
129
130#if DEBUG
131 printf("magic: %x\n", (unsigned)mH->magic);
132 printf("cputype: %x\n", (unsigned)mH->cputype);
133 printf("cpusubtype: %x\n", (unsigned)mH->cpusubtype);
134 printf("filetype: %x\n", (unsigned)mH->filetype);
135 printf("ncmds: %x\n", (unsigned)mH->ncmds);
136 printf("sizeofcmds: %x\n", (unsigned)mH->sizeofcmds);
137 printf("flags: %x\n", (unsigned)mH->flags);
138 getc();
139#endif
140
141 ncmds = mH->ncmds;
142
143 for (cnt = 0; cnt < ncmds; cnt++) {
144 cmd = ((long *)cmdBase)[0];
145 cmdsize = ((long *)cmdBase)[1];
146 unsigned int load_addr;
147 unsigned int load_size;
148
149 switch (cmd) {
150case LC_SEGMENT_64:
151 case LC_SEGMENT:
152 ret = DecodeSegment(cmdBase, &load_addr, &load_size);
153 if (ret == 0 && load_size != 0 && load_addr >= KERNEL_ADDR) {
154 vmaddr = min(vmaddr, load_addr);
155 vmend = max(vmend, load_addr + load_size);
156 }
157 break;
158
159 case LC_UNIXTHREAD:
160 ret = DecodeUnixThread(cmdBase, &entry);
161 break;
162
163 case LC_SYMTAB:
164 break;
165
166 default:
167#if NOTDEF
168 printf("Ignoring cmd type %d.\n", (unsigned)cmd);
169#endif
170 break;
171 }
172
173 if (ret != 0) return -1;
174
175 cmdBase += cmdsize;
176 }
177
178 *rentry = (entry_t)( (unsigned long) entry & 0x3fffffff );
179 *rsize = vmend - vmaddr;
180 *raddr = (char *)vmaddr;
181
182 cmdBase = cmdstart;
183 for (cnt = 0; cnt < ncmds; cnt++) {
184cmd = ((long *)cmdBase)[0];
185cmdsize = ((long *)cmdBase)[1];
186
187if(cmd==LC_SYMTAB)
188 if (DecodeSymbolTable(cmdBase)!=0)
189return -1;
190
191cmdBase += cmdsize;
192 }
193
194 return ret;
195}
196
197// Private Functions
198
199static long DecodeSegment(long cmdBase, unsigned int *load_addr, unsigned int *load_size)
200{
201 unsigned long vmaddr, fileaddr;
202 long vmsize, filesize;
203 char *segname;
204
205 if (((long *)cmdBase)[0]==LC_SEGMENT_64)
206 {
207 struct segment_command_64 *segCmd;
208
209 segCmd = (struct segment_command_64 *)cmdBase;
210
211 vmaddr = (segCmd->vmaddr & 0x3fffffff);
212 vmsize = segCmd->vmsize;
213 fileaddr = (gBinaryAddress + segCmd->fileoff);
214 filesize = segCmd->filesize;
215
216 segname=segCmd->segname;
217 }
218 else
219 {
220 struct segment_command *segCmd;
221
222 segCmd = (struct segment_command *)cmdBase;
223
224 vmaddr = (segCmd->vmaddr & 0x3fffffff);
225 vmsize = segCmd->vmsize;
226 fileaddr = (gBinaryAddress + segCmd->fileoff);
227 filesize = segCmd->filesize;
228
229 segname=segCmd->segname;
230 }
231
232 if (vmsize == 0 || filesize == 0) {
233 *load_addr = ~0;
234 *load_size = 0;
235 return 0;
236 }
237
238#if DEBUG
239 printf("segname: %s, vmaddr: %x, vmsize: %x, fileoff: %x, filesize: %x, nsects: %d, flags: %x.\n",
240 segCmd->segname, (unsigned)vmaddr, (unsigned)vmsize, (unsigned)fileaddr, (unsigned)filesize,
241 (unsigned) segCmd->nsects, (unsigned)segCmd->flags);
242 getc();
243#endif
244
245 if (! ((vmaddr >= KERNEL_ADDR &&
246 (vmaddr + vmsize) <= (KERNEL_ADDR + KERNEL_LEN)) ||
247 (vmaddr >= HIB_ADDR &&
248 (vmaddr + vmsize) <= (HIB_ADDR + HIB_LEN)))) {
249 stop("Kernel overflows available space");
250 }
251
252 if (vmsize && (strcmp(segname, "__PRELINK") == 0))
253 gHaveKernelCache = true;
254
255 // Copy from file load area.
256 if (vmsize>0 && filesize>0)
257 bcopy((char *)fileaddr, (char *)vmaddr, vmsize>filesize?filesize:vmsize);
258
259 // Zero space at the end of the segment.
260 if (vmsize > filesize)
261 bzero((char *)(vmaddr + filesize), vmsize - filesize);
262
263 *load_addr = vmaddr;
264 *load_size = vmsize;
265
266 return 0;
267}
268
269static long DecodeUnixThread(long cmdBase, unsigned int *entry)
270{
271switch (archCpuType)
272{
273case CPU_TYPE_I386:
274{
275i386_thread_state_t *i386ThreadState;
276
277i386ThreadState = (i386_thread_state_t *)
278(cmdBase + sizeof(struct thread_command) + 8);
279
280#if defined(__DARWIN_UNIX03) && __DARWIN_UNIX03
281*entry = i386ThreadState->__eip;
282#else
283*entry = i386ThreadState->eip;
284#endif
285return 0;
286}
287
288case CPU_TYPE_X86_64:
289{
290x86_thread_state64_t *x86_64ThreadState;
291
292x86_64ThreadState = (x86_thread_state64_t *)
293(cmdBase + sizeof(struct thread_command) + 8);
294
295#if defined(__DARWIN_UNIX03) && __DARWIN_UNIX03
296*entry = x86_64ThreadState->__rip;
297#else
298*entry = x86_64ThreadState->rip;
299#endif
300return 0;
301}
302
303default:
304error("Unknown CPU type\n");
305return -1;
306}
307}
308
309static long DecodeSymbolTable(long cmdBase)
310{
311 struct symtab_command *symTab, *symTableSave;
312 long tmpAddr, symsSize, totalSize;
313 long gSymbolTableAddr;
314 long gSymbolTableSize;
315
316 symTab = (struct symtab_command *)cmdBase;
317
318#if DEBUG
319 printf("symoff: %x, nsyms: %x, stroff: %x, strsize: %x\n",
320 symTab->symoff, symTab->nsyms, symTab->stroff, symTab->strsize);
321getc ();
322#endif
323
324 symsSize = symTab->stroff - symTab->symoff;
325 totalSize = symsSize + symTab->strsize;
326
327 gSymbolTableSize = totalSize + sizeof(struct symtab_command);
328 gSymbolTableAddr = AllocateKernelMemory(gSymbolTableSize);
329 // Add the SymTab to the memory-map.
330 AllocateMemoryRange("Kernel-__SYMTAB", gSymbolTableAddr, gSymbolTableSize, -1);
331
332 symTableSave = (struct symtab_command *)gSymbolTableAddr;
333 tmpAddr = gSymbolTableAddr + sizeof(struct symtab_command);
334
335 symTableSave->symoff = tmpAddr;
336 symTableSave->nsyms = symTab->nsyms;
337 symTableSave->stroff = tmpAddr + symsSize;
338 symTableSave->strsize = symTab->strsize;
339
340 bcopy((char *)(gBinaryAddress + symTab->symoff),
341(char *)tmpAddr, totalSize);
342 return 0;
343}
344

Archive Download this file

Revision: 214