Chameleon

Chameleon Svn Source Tree

Root/trunk/i386/util/machOconv.c

1/*
2 * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 2.0 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24#include <stdio.h>
25#include <stdlib.h>
26#include <mach/mach.h>
27#include <mach/mach_error.h>
28#include <sys/file.h>
29#include <mach-o/loader.h>
30#include <libkern/OSByteOrder.h>
31#include <unistd.h>
32
33intinfile, outfile;
34
35struct mach_headermh;
36void *cmds;
37
38boolean_tswap_ends;
39
40static unsigned long swap(
41 unsigned long x
42)
43{
44 if (swap_ends)
45return OSSwapInt32(x);
46 else
47return x;
48}
49
50int
51main(int argc, char *argv[])
52{
53 kern_return_tresult;
54 vm_address_tdata;
55 intnc, ncmds;
56 char *cp;
57
58 if (argc == 2) {
59infile = open(argv[1], O_RDONLY);
60if (infile < 0)
61 goto usage;
62outfile = fileno(stdout);
63 }
64 else if (argc == 3) {
65 infile = open(argv[1], O_RDONLY);
66if (infile < 0)
67 goto usage;
68outfile = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0644);
69if (outfile < 0)
70 goto usage;
71 }
72 else {
73usage:
74 fprintf(stderr, "usage: machOconv inputfile [outputfile]\n");
75exit(1);
76 }
77
78 nc = read(infile, &mh, sizeof (mh));
79 if (nc < 0) {
80perror("read mach header");
81exit(1);
82 }
83 if (nc < (int)sizeof (mh)) {
84fprintf(stderr, "read mach header: premature EOF %d\n", nc);
85exit(1);
86 }
87 if (mh.magic == MH_MAGIC)
88swap_ends = FALSE;
89 else if (mh.magic == MH_CIGAM)
90swap_ends = TRUE;
91 else {
92 fprintf(stderr, "bad magic number %lx\n", (unsigned long)mh.magic);
93exit(1);
94 }
95
96 cmds = calloc(swap(mh.sizeofcmds), sizeof (char));
97 if (cmds == 0) {
98fprintf(stderr, "alloc load commands: no memory\n");
99exit(1);
100 }
101 nc = read(infile, cmds, swap(mh.sizeofcmds));
102 if (nc < 0) {
103perror("read load commands");
104exit(1);
105 }
106 if (nc < (int)swap(mh.sizeofcmds)) {
107fprintf(stderr, "read load commands: premature EOF %d\n", nc);
108exit(1);
109 }
110
111 for (ncmds = swap(mh.ncmds), cp = cmds;
112ncmds > 0; ncmds--) {
113 boolean_tisDATA;
114 unsignedvmsize;
115
116#define lcp((struct load_command *)cp)
117switch(swap(lcp->cmd)) {
118
119case LC_SEGMENT:
120#define scp((struct segment_command *)cp)
121 isDATA = (strcmp(scp->segname, "__DATA") == 0);
122 if (isDATA)
123 vmsize = swap(scp->filesize);
124 else
125 vmsize = swap(scp->vmsize);
126 result = vm_allocate(mach_task_self(), &data, vmsize, TRUE);
127 if (result != KERN_SUCCESS) {
128mach_error("vm_allocate segment data", result);
129exit(1);
130 }
131
132 lseek(infile, swap(scp->fileoff), L_SET);
133 nc = read(infile, (void *)data, swap(scp->filesize));
134 if (nc < 0) {
135perror("read segment data");
136exit(1);
137 }
138 if (nc < (int)swap(scp->filesize)) {
139fprintf(stderr, "read segment data: premature EOF %d\n", nc);
140exit(1);
141 }
142
143 nc = write(outfile, (void *)data, vmsize);
144 if (nc < (int)vmsize) {
145perror("write segment data");
146exit(1);
147 }
148
149 vm_deallocate(mach_task_self(), data, vmsize);
150 break;
151}
152
153cp += swap(lcp->cmdsize);
154 }
155
156 exit(0);
157}
158

Archive Download this file

Revision: 1