Root/
Source at commit 1321 created 12 years 9 months ago. By meklort, Add __extendsfdf2 from LLVM | |
---|---|
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 |