795
[darwin-xtools.git] / cctools / misc / inout.c
bloba1eb50eeec8bda04dff11249ee8ba547ef3ec046
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include "stuff/errors.h"
27 #include "stuff/breakout.h"
28 #include "stuff/rnd.h"
30 /* used by error routines as the name of the program */
31 char *progname = NULL;
33 static void usage(
34 void);
36 static void process(
37 struct arch *archs,
38 uint32_t narchs);
40 static void setup_object_symbolic_info(
41 struct object *object);
43 int
44 main(
45 int argc,
46 char **argv,
47 char **envp)
49 uint32_t i;
50 char *input, *output;
51 struct arch *archs;
52 uint32_t narchs;
54 progname = argv[0];
55 input = NULL;
56 output = NULL;
57 archs = NULL;
58 narchs = 0;
59 for(i = 1; i < argc; i++){
60 if(strcmp(argv[i], "-o") == 0){
61 if(i + 1 == argc){
62 error("missing argument(s) to: %s option", argv[i]);
63 usage();
65 if(output != NULL){
66 error("more than one: %s option specified", argv[i]);
67 usage();
69 output = argv[i+1];
70 i++;
72 else{
73 if(input != NULL){
74 error("more than one input file specified (%s and %s)",
75 argv[i], input);
76 usage();
78 input = argv[i];
81 if(input == NULL || output == NULL)
82 usage();
84 breakout(input, &archs, &narchs, FALSE);
85 if(errors)
86 exit(EXIT_FAILURE);
88 checkout(archs, narchs);
90 process(archs, narchs);
92 writeout(archs, narchs, output, 0777, TRUE, FALSE, FALSE, NULL);
94 if(errors)
95 return(EXIT_FAILURE);
96 else
97 return(EXIT_SUCCESS);
101 * usage() prints the current usage message and exits indicating failure.
103 static
104 void
105 usage(
106 void)
108 fprintf(stderr, "Usage: %s input -o output\n", progname);
109 exit(EXIT_FAILURE);
112 static
113 void
114 process(
115 struct arch *archs,
116 uint32_t narchs)
118 uint32_t i, j, offset, size;
119 struct object *object;
121 for(i = 0; i < narchs; i++){
122 if(archs[i].type == OFILE_ARCHIVE){
123 for(j = 0; j < archs[i].nmembers; j++){
124 if(archs[i].members[j].type == OFILE_Mach_O){
125 object = archs[i].members[j].object;
126 setup_object_symbolic_info(object);
130 * Reset the library offsets and size.
132 offset = 0;
133 for(j = 0; j < archs[i].nmembers; j++){
134 archs[i].members[j].offset = offset;
135 size = 0;
136 if(archs[i].members[j].member_long_name == TRUE){
137 size = rnd(archs[i].members[j].member_name_size,
138 sizeof(int32_t));
139 archs[i].toc_long_name = TRUE;
141 if(archs[i].members[j].object != NULL){
142 size += archs[i].members[j].object->object_size
143 - archs[i].members[j].object->input_sym_info_size
144 + archs[i].members[j].object->output_sym_info_size;
145 sprintf(archs[i].members[j].ar_hdr->ar_size, "%-*ld",
146 (int)sizeof(archs[i].members[j].ar_hdr->ar_size),
147 (long)(size));
149 * This has to be done by hand because sprintf puts a
150 * null at the end of the buffer.
152 memcpy(archs[i].members[j].ar_hdr->ar_fmag, ARFMAG,
153 (int)sizeof(archs[i].members[j].ar_hdr->ar_fmag));
155 else{
156 size += archs[i].members[j].unknown_size;
158 offset += sizeof(struct ar_hdr) + size;
160 archs[i].library_size = offset;
162 else if(archs[i].type == OFILE_Mach_O){
163 object = archs[i].object;
164 setup_object_symbolic_info(object);
169 static
170 void
171 setup_object_symbolic_info(
172 struct object *object)
174 uint32_t output_indirectsym_pad_diff;
176 if(object->st != NULL && object->st->nsyms != 0){
177 if(object->mh != NULL){
178 object->output_symbols = (struct nlist *)
179 (object->object_addr + object->st->symoff);
180 if(object->object_byte_sex != get_host_byte_sex())
181 swap_nlist(object->output_symbols,
182 object->st->nsyms,
183 get_host_byte_sex());
184 object->output_symbols64 = NULL;
186 else{
187 object->output_symbols64 = (struct nlist_64 *)
188 (object->object_addr + object->st->symoff);
189 if(object->object_byte_sex != get_host_byte_sex())
190 swap_nlist_64(object->output_symbols64,
191 object->st->nsyms,
192 get_host_byte_sex());
193 object->output_symbols = NULL;
195 object->output_nsymbols = object->st->nsyms;
196 object->output_strings =
197 object->object_addr + object->st->stroff;
198 object->output_strings_size = object->st->strsize;
199 if(object->mh != NULL){
200 object->input_sym_info_size =
201 object->st->nsyms * sizeof(struct nlist) +
202 object->st->strsize;
204 else{
205 object->input_sym_info_size =
206 object->st->nsyms * sizeof(struct nlist_64) +
207 object->st->strsize;
210 output_indirectsym_pad_diff = 0;
211 if(object->dyst != NULL){
212 object->output_ilocalsym = object->dyst->ilocalsym;
213 object->output_nlocalsym = object->dyst->nlocalsym;
214 object->output_iextdefsym = object->dyst->iextdefsym;
215 object->output_nextdefsym = object->dyst->nextdefsym;
216 object->output_iundefsym = object->dyst->iundefsym;
217 object->output_nundefsym = object->dyst->nundefsym;
218 object->output_indirect_symtab = (uint32_t *)
219 (object->object_addr + object->dyst->indirectsymoff);
220 object->output_loc_relocs = (struct relocation_info *)
221 (object->object_addr + object->dyst->locreloff);
222 if(object->split_info_cmd != NULL){
223 object->output_split_info_data =
224 (object->object_addr + object->split_info_cmd->dataoff);
225 object->output_split_info_data_size =
226 object->split_info_cmd->datasize;
228 if(object->func_starts_info_cmd != NULL){
229 object->output_func_start_info_data =
230 (object->object_addr + object->func_starts_info_cmd->dataoff);
231 object->output_func_start_info_data_size =
232 object->func_starts_info_cmd->datasize;
234 object->output_ext_relocs = (struct relocation_info *)
235 (object->object_addr + object->dyst->extreloff);
236 object->output_tocs =
237 (struct dylib_table_of_contents *)
238 (object->object_addr + object->dyst->tocoff);
239 object->output_ntoc = object->dyst->ntoc;
240 if(object->mh != NULL){
241 object->output_mods = (struct dylib_module *)
242 (object->object_addr + object->dyst->modtaboff);
243 object->output_mods64 = NULL;
245 else{
246 object->output_mods64 = (struct dylib_module_64 *)
247 (object->object_addr + object->dyst->modtaboff);
248 object->output_mods = NULL;
250 object->output_nmodtab = object->dyst->nmodtab;
251 object->output_refs = (struct dylib_reference *)
252 (object->object_addr + object->dyst->extrefsymoff);
253 object->output_nextrefsyms = object->dyst->nextrefsyms;
254 if(object->hints_cmd != NULL){
255 object->output_hints = (struct twolevel_hint *)
256 (object->object_addr +
257 object->hints_cmd->offset);
259 if(object->code_sig_cmd != NULL){
260 object->output_code_sig_data = object->object_addr +
261 object->code_sig_cmd->dataoff;
262 object->output_code_sig_data_size =
263 object->code_sig_cmd->datasize;
265 object->input_sym_info_size +=
266 object->dyst->nlocrel *
267 sizeof(struct relocation_info) +
268 object->dyst->nextrel *
269 sizeof(struct relocation_info) +
270 object->dyst->ntoc *
271 sizeof(struct dylib_table_of_contents)+
272 object->dyst->nextrefsyms *
273 sizeof(struct dylib_reference);
274 if(object->split_info_cmd != NULL)
275 object->input_sym_info_size += object->split_info_cmd->datasize;
276 if(object->func_starts_info_cmd != NULL)
277 object->input_sym_info_size +=
278 object->func_starts_info_cmd->datasize;
279 if(object->mh != NULL){
280 object->input_sym_info_size +=
281 object->dyst->nmodtab *
282 sizeof(struct dylib_module) +
283 object->dyst->nindirectsyms *
284 sizeof(uint32_t);
286 else{
287 object->input_sym_info_size +=
288 object->dyst->nmodtab *
289 sizeof(struct dylib_module_64)+
290 object->dyst->nindirectsyms *
291 sizeof(uint32_t) +
292 object->input_indirectsym_pad;
293 if(object->input_indirectsym_pad == 0 &&
294 (object->dyst->nindirectsyms % 2) != 0)
295 output_indirectsym_pad_diff = 4;
297 if(object->hints_cmd != NULL){
298 object->input_sym_info_size +=
299 object->hints_cmd->nhints *
300 sizeof(struct twolevel_hint);
302 if(object->code_sig_cmd != NULL){
303 object->input_sym_info_size = rnd(object->input_sym_info_size,
304 16);
305 object->input_sym_info_size += object->code_sig_cmd->datasize;
307 if(output_indirectsym_pad_diff != 0){
308 if(object->output_ntoc != 0)
309 object->dyst->tocoff += output_indirectsym_pad_diff;
310 if(object->output_nmodtab != 0)
311 object->dyst->modtaboff += output_indirectsym_pad_diff;
312 if(object->output_nextrefsyms != 0)
313 object->dyst->extrefsymoff += output_indirectsym_pad_diff;
314 if(object->output_strings_size != 0)
315 object->st->stroff += output_indirectsym_pad_diff;
316 object->seg_linkedit64->filesize += output_indirectsym_pad_diff;
317 if(object->seg_linkedit64->filesize >
318 object->seg_linkedit64->vmsize)
319 object->seg_linkedit64->vmsize +=
320 output_indirectsym_pad_diff;
323 object->output_sym_info_size =
324 object->input_sym_info_size + output_indirectsym_pad_diff;