2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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@
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
;
40 static void setup_object_symbolic_info(
41 struct object
*object
);
59 for(i
= 1; i
< argc
; i
++){
60 if(strcmp(argv
[i
], "-o") == 0){
62 error("missing argument(s) to: %s option", argv
[i
]);
66 error("more than one: %s option specified", argv
[i
]);
74 error("more than one input file specified (%s and %s)",
81 if(input
== NULL
|| output
== NULL
)
84 breakout(input
, &archs
, &narchs
, FALSE
);
88 checkout(archs
, narchs
);
90 process(archs
, narchs
);
92 writeout(archs
, narchs
, output
, 0777, TRUE
, FALSE
, FALSE
, NULL
);
101 * usage() prints the current usage message and exits indicating failure.
108 fprintf(stderr
, "Usage: %s input -o output\n", progname
);
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.
133 for(j
= 0; j
< archs
[i
].nmembers
; j
++){
134 archs
[i
].members
[j
].offset
= offset
;
136 if(archs
[i
].members
[j
].member_long_name
== TRUE
){
137 size
= rnd(archs
[i
].members
[j
].member_name_size
,
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
),
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
));
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
);
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
,
183 get_host_byte_sex());
184 object
->output_symbols64
= NULL
;
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
,
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
) +
205 object
->input_sym_info_size
=
206 object
->st
->nsyms
* sizeof(struct nlist_64
) +
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
;
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
) +
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
*
287 object
->input_sym_info_size
+=
288 object
->dyst
->nmodtab
*
289 sizeof(struct dylib_module_64
)+
290 object
->dyst
->nindirectsyms
*
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
,
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
;