Root/
Source at commit 1406 created 12 years 10 months ago. By meklort, Revert drivers.c so that kexts are only loaded when OSBundleRequired is set and that value is not safe mode. Added some comments about it too. | |
---|---|
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 | /*␊ |
23 | * macho-to-xcoff.c - Converts a Mach-O file an XCOFF.␊ |
24 | *␊ |
25 | * Copyright (c) 1998-2002 Apple Computer, Inc.␊ |
26 | *␊ |
27 | * DRI: Josh de Cesare␊ |
28 | */␊ |
29 | ␊ |
30 | #define __srr0 srr0␉␉␉␉␉// works with or without conformance␊ |
31 | #include <stdio.h>␊ |
32 | #include <stdlib.h>␊ |
33 | #include <strings.h>␊ |
34 | #include <mach-o/loader.h>␊ |
35 | #include <mach/thread_status.h>␊ |
36 | #include <mach/ppc/thread_status.h>␊ |
37 | ␊ |
38 | ␊ |
39 | char *progname;␊ |
40 | static FILE *machoF;␊ |
41 | static FILE *xcoffF;␊ |
42 | ␊ |
43 | static struct mach_header mhead;␊ |
44 | ␊ |
45 | typedef unsigned char UInt8;␊ |
46 | typedef unsigned short UInt16;␊ |
47 | typedef unsigned long UInt32;␊ |
48 | ␊ |
49 | #if defined(__i386__) || defined(__x86_64__)␊ |
50 | #define SWAPL(value) ( (((value) >> 24) & 0xff) | \␊ |
51 | ␉␉␉ (((value) >> 8) & 0xff00) | \␊ |
52 | ␉␉␉ (((value) << 8) & 0xff0000) | \␊ |
53 | ␉␉␉ (((value) << 24) & 0xff000000) )␊ |
54 | ␊ |
55 | #define SWAPS(value) ( (((value) >> 8) & 0xff) | \␊ |
56 | ␉␉␉ (((value) << 8) & 0xff00) )␊ |
57 | #else␊ |
58 | #define SWAPS(W)␉(W)␊ |
59 | #define SWAPL(L)␉(L)␊ |
60 | #endif␊ |
61 | ␊ |
62 | typedef struct {␊ |
63 | /* File header */␊ |
64 | UInt16 magic;␊ |
65 | #define kFileMagic␉␉␉0x1DF␊ |
66 | UInt16 nSections;␊ |
67 | UInt32 timeAndDate;␊ |
68 | UInt32 symPtr;␊ |
69 | UInt32 nSyms;␊ |
70 | UInt16 optHeaderSize;␊ |
71 | UInt16 flags;␊ |
72 | } XFileHeader;␊ |
73 | ␊ |
74 | typedef struct {␊ |
75 | /* Optional header */␊ |
76 | UInt16 magic;␊ |
77 | #define kOptHeaderMagic␉␉0x10B␊ |
78 | UInt16 version;␊ |
79 | UInt32 textSize;␊ |
80 | UInt32 dataSize;␊ |
81 | UInt32 BSSSize;␊ |
82 | UInt32 entryPoint;␊ |
83 | UInt32 textStart;␊ |
84 | UInt32 dataStart;␊ |
85 | UInt32 toc;␊ |
86 | UInt16 snEntry;␊ |
87 | UInt16 snText;␊ |
88 | UInt16 snData;␊ |
89 | UInt16 snTOC;␊ |
90 | UInt16 snLoader;␊ |
91 | UInt16 snBSS;␊ |
92 | UInt8 filler[28];␊ |
93 | } XOptHeader;␊ |
94 | ␊ |
95 | typedef struct {␊ |
96 | char name[8];␊ |
97 | UInt32 pAddr;␊ |
98 | UInt32 vAddr;␊ |
99 | UInt32 size;␊ |
100 | UInt32 sectionFileOffset;␊ |
101 | UInt32 relocationsFileOffset;␊ |
102 | UInt32 lineNumbersFileOffset;␊ |
103 | UInt16 nRelocations;␊ |
104 | UInt16 nLineNumbers;␊ |
105 | UInt32 flags;␊ |
106 | } XSection;␊ |
107 | ␊ |
108 | enum SectionNumbers {␊ |
109 | kTextSN = 1,␊ |
110 | kDataSN,␊ |
111 | kBSSSN␊ |
112 | };␊ |
113 | ␊ |
114 | #define kTextName␉".text"␊ |
115 | #define kDataName␉".data"␊ |
116 | #define kBSSName␉".bss"␊ |
117 | ␊ |
118 | static struct {␊ |
119 | XFileHeader file;␊ |
120 | XOptHeader opt;␊ |
121 | XSection text;␊ |
122 | XSection data;␊ |
123 | XSection BSS;␊ |
124 | } xHead = {␊ |
125 | {␉/* file */␊ |
126 | SWAPS(kFileMagic),␉␉␉/* magic */␊ |
127 | SWAPS(3),␉␉␉␉␉/* nSections */␊ |
128 | 0,␉␉␉␉␉␉␉/* timeAndDate */␊ |
129 | 0,␉␉␉␉␉␉␉/* symPtr */␊ |
130 | 0,␉␉␉␉␉␉␉/* nSyms */␊ |
131 | SWAPS(sizeof (XOptHeader)),␉/* optHeaderSize */␊ |
132 | 0␊ |
133 | },␊ |
134 | {␉/* opt */␊ |
135 | SWAPS(kOptHeaderMagic),␉␉/* magic */␊ |
136 | 0,␉␉␉␉␉␉␉/* version */␊ |
137 | 0,␉␉␉␉␉␉␉/* textSize */␊ |
138 | 0,␉␉␉␉␉␉␉/* dataSize */␊ |
139 | 0,␉␉␉␉␉␉␉/* BSSSize */␊ |
140 | 0,␉␉␉␉␉␉␉/* entryPoint */␊ |
141 | 0,␉␉␉␉␉␉␉/* textStart */␊ |
142 | 0,␉␉␉␉␉␉␉/* dataStart */␊ |
143 | 0,␉␉␉␉␉␉␉/* toc */␊ |
144 | SWAPS(kTextSN),␉␉␉␉/* snEntry */␊ |
145 | SWAPS(kTextSN),␉␉␉␉/* snText */␊ |
146 | SWAPS(kDataSN),␉␉␉␉/* snData */␊ |
147 | SWAPS(0),␉␉␉␉␉/* snTOC */␊ |
148 | SWAPS(0),␉␉␉␉␉/* snLoader */␊ |
149 | SWAPS(kBSSSN),␉␉␉␉/* snBSS */␊ |
150 | },␊ |
151 | {␉/* text section */␊ |
152 | kTextName␊ |
153 | },␊ |
154 | {␉/* data section */␊ |
155 | kDataName␊ |
156 | },␊ |
157 | {␉/* BSS section */␊ |
158 | kBSSName␊ |
159 | }␊ |
160 | };␊ |
161 | ␊ |
162 | ␊ |
163 | static UInt32 textFileOffset;␊ |
164 | static UInt32 textSize;␊ |
165 | static UInt32 dataFileOffset;␊ |
166 | static UInt32 dataSize;␊ |
167 | static UInt32 bssSize;␊ |
168 | ␊ |
169 | ␊ |
170 | static void usage (char *msg)␊ |
171 | {␊ |
172 | printf ("Usage: %s mach-o-file-name xcoff-file-name\n\n%s\n",␊ |
173 | ␉ progname, msg);␊ |
174 | exit (1);␊ |
175 | }␊ |
176 | ␊ |
177 | ␊ |
178 | static void copyMachOSectionToXCOFF (UInt32 machoOffset, UInt32 sectionSize)␊ |
179 | {␊ |
180 | static char buf[65536];␊ |
181 | ␊ |
182 | fseek (machoF, machoOffset, SEEK_SET);␊ |
183 | ␊ |
184 | while (sectionSize) {␊ |
185 | long readSize = sectionSize > sizeof (buf) ? sizeof (buf) : sectionSize;␊ |
186 | long writeSize;␊ |
187 | long actualSize;␊ |
188 | ␊ |
189 | actualSize = fread (buf, 1, readSize, machoF);␊ |
190 | if (actualSize < 0) perror ("read error for section");␊ |
191 | ␊ |
192 | writeSize = actualSize;␊ |
193 | actualSize = fwrite (buf, 1, writeSize, xcoffF);␊ |
194 | if (actualSize < 0) perror ("write error for section");␊ |
195 | ␊ |
196 | sectionSize -= actualSize;␊ |
197 | }␊ |
198 | }␊ |
199 | ␊ |
200 | ␊ |
201 | int main (int argc, char **argv)␊ |
202 | {␊ |
203 | int n;␊ |
204 | char *cmdsP, *cp;␊ |
205 | ␊ |
206 | #define LCP␉␉((struct load_command *) cp)␊ |
207 | #define SCP␉␉((struct segment_command *) cp)␊ |
208 | ␊ |
209 | progname = argv[0];␊ |
210 | ␊ |
211 | if (argc < 3) usage ("wrong number of parameters");␊ |
212 | ␊ |
213 | machoF = fopen (argv[1], "rb");␊ |
214 | if (machoF == 0) perror ("Can't open mach-o file");␊ |
215 | xcoffF = fopen (argv[2], "wb");␊ |
216 | if (xcoffF == 0) perror ("Can't create and/or open XCOFF file");␊ |
217 | ␊ |
218 | n = fread (&mhead, sizeof (mhead), 1, machoF);␊ |
219 | if (n != 1) perror ("error reading mach-o file header");␊ |
220 | ␊ |
221 | if (SWAPL(mhead.magic) != MH_MAGIC␊ |
222 | || SWAPL(mhead.filetype) != MH_EXECUTE)␊ |
223 | usage ("bad mach-o file header");␊ |
224 | ␊ |
225 | cmdsP = malloc (SWAPL(mhead.sizeofcmds));␊ |
226 | if (cmdsP == 0) usage ("cmdsP allocation failed");␊ |
227 | ␊ |
228 | n = fread (cmdsP, SWAPL(mhead.sizeofcmds), 1, machoF);␊ |
229 | if (n != 1) perror ("error reading mach-o commands");␊ |
230 | ␊ |
231 | printf("Mach-o file has magic=0x%08lX, %ld commands\n", (long unsigned int)SWAPL(mhead.magic), (long int)SWAPL(mhead.ncmds));␊ |
232 | ␊ |
233 | for (n = 0, cp = cmdsP; n < SWAPL(mhead.ncmds); ++n, cp += SWAPL(LCP->cmdsize)) {␊ |
234 | ␊ |
235 | switch (SWAPL(LCP->cmd)) {␊ |
236 | case LC_SEGMENT:␊ |
237 | printf ("segment: %s: 0x%08lX of 0x%08lX bytes\n",␊ |
238 | ␉ SCP->segname, (long unsigned int)SWAPL(SCP->vmaddr), (long unsigned int)SWAPL(SCP->vmsize));␊ |
239 | ␊ |
240 | if (strncmp (SCP->segname, SEG_TEXT, sizeof (SCP->segname)) == 0) {␊ |
241 | ␉textFileOffset = SWAPL(SCP->fileoff);␊ |
242 | ␉textSize = SWAPL(SCP->filesize);␊ |
243 | ␉printf ("__TEXT size = 0x%08lX\n", textSize);␊ |
244 | ␉xHead.text.pAddr = xHead.text.vAddr = SCP->vmaddr;␊ |
245 | ␉xHead.text.size = SCP->vmsize;␊ |
246 | } else␊ |
247 | ␉if (strncmp (SCP->segname, SEG_DATA, sizeof (SCP->segname)) == 0) {␊ |
248 | ␉ dataFileOffset = SWAPL(SCP->fileoff);␊ |
249 | ␉ dataSize = SWAPL(SCP->filesize);␊ |
250 | ␉ printf ("__DATA size = 0x%08lX\n", dataSize);␊ |
251 | ␉ bssSize = SWAPL(SCP->vmsize) - SWAPL(SCP->filesize);␊ |
252 | ␉ printf ("__BSS size = 0x%08lX\n", bssSize);␊ |
253 | ␉ xHead.data.pAddr = xHead.data.vAddr = SCP->vmaddr;␊ |
254 | ␉ ␊ |
255 | ␉ /* Use just FILE part -- rest is BSS */␊ |
256 | ␉ xHead.data.size = SCP->filesize;␊ |
257 | ␉} else {␊ |
258 | ␉ printf ("ignoring mach-o section \"%s\"\n", SCP->segname);␊ |
259 | ␉}␊ |
260 | break;␊ |
261 | ␊ |
262 | case LC_THREAD:␊ |
263 | case LC_UNIXTHREAD:␊ |
264 | xHead.opt.entryPoint = ((ppc_thread_state_t *) ␊ |
265 | ␉␉␉ (cp + sizeof(struct thread_command)␊ |
266 | ␉␉␉ + 2 * sizeof(unsigned long)) )->srr0;␊ |
267 | printf("Entry point %lx\n\n", SWAPL(xHead.opt.entryPoint));␊ |
268 | break;␊ |
269 | }␊ |
270 | }␊ |
271 | ␊ |
272 | /* Construct BSS out of thin air: the part of the data section␊ |
273 | that is NOT file mapped */␊ |
274 | xHead.BSS.pAddr = xHead.BSS.vAddr = SWAPL(SWAPL(xHead.data.pAddr) + SWAPL(xHead.data.size));␊ |
275 | xHead.BSS.size = SWAPL(bssSize);␊ |
276 | ␊ |
277 | /* Calculate the section file offsets in the resulting XCOFF file */␊ |
278 | xHead.text.sectionFileOffset = SWAPL(sizeof (xHead.file) + sizeof (xHead.opt)␊ |
279 | ␉␉␉␉ + sizeof (xHead.text) + sizeof (xHead.data) + sizeof (xHead.BSS));␊ |
280 | xHead.data.sectionFileOffset = SWAPL(SWAPL(xHead.text.sectionFileOffset) + SWAPL(xHead.text.size));␊ |
281 | ␊ |
282 | /* MT - write opt header */␊ |
283 | xHead.opt.textSize = xHead.text.size;␊ |
284 | xHead.opt.dataSize = xHead.data.size;␊ |
285 | xHead.opt.BSSSize = xHead.BSS.size;␊ |
286 | if (argc == 4) sscanf(argv[3],"%lx",&xHead.opt.entryPoint);␊ |
287 | ␊ |
288 | /* Write out the XCOFF file, copying the relevant mach-o file sections */␊ |
289 | fwrite (&xHead, sizeof (xHead), 1, xcoffF);␊ |
290 | ␊ |
291 | copyMachOSectionToXCOFF (textFileOffset, textSize);␊ |
292 | copyMachOSectionToXCOFF (dataFileOffset, dataSize);␊ |
293 | ␊ |
294 | fclose (machoF);␊ |
295 | fclose (xcoffF);␊ |
296 | ␊ |
297 | return 0;␊ |
298 | }␊ |
299 |