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@
27 #include "stuff/ofile.h"
28 #include "stuff/breakout.h"
29 #include "stuff/rnd.h"
31 static void check_object(
33 struct member
*member
,
34 struct object
*object
);
36 static void symbol_string_at_end(
38 struct member
*member
,
39 struct object
*object
);
41 static void dyld_order(
43 struct member
*member
,
44 struct object
*object
);
46 static void order_error(
48 struct member
*member
,
59 for(i
= 0; i
< narchs
; i
++){
60 if(archs
[i
].type
== OFILE_ARCHIVE
){
61 for(j
= 0; j
< archs
[i
].nmembers
; j
++){
62 if(archs
[i
].members
[j
].type
== OFILE_Mach_O
){
63 check_object(archs
+ i
, archs
[i
].members
+ j
,
64 archs
[i
].members
[j
].object
);
68 else if(archs
[i
].type
== OFILE_Mach_O
){
69 check_object(archs
+ i
, NULL
, archs
[i
].object
);
78 struct member
*member
,
79 struct object
*object
)
81 uint32_t i
, ncmds
, flags
;
82 struct load_command
*lc
;
83 struct segment_command
*sg
;
84 struct segment_command_64
*sg64
;
85 struct dylib_command
*dl_id
;
88 * Set up the symtab load command field and link edit segment feilds in
89 * the object structure.
93 object
->hints_cmd
= NULL
;
94 object
->seg_bitcode
= NULL
;
95 object
->seg_bitcode64
= NULL
;
96 object
->seg_linkedit
= NULL
;
97 object
->seg_linkedit64
= NULL
;
98 object
->code_sig_cmd
= NULL
;
100 lc
= object
->load_commands
;
101 if(object
->mh
!= NULL
){
102 ncmds
= object
->mh
->ncmds
;
103 flags
= object
->mh
->flags
;
106 ncmds
= object
->mh64
->ncmds
;
107 flags
= object
->mh64
->flags
;
109 for(i
= 0; i
< ncmds
; i
++){
110 if(lc
->cmd
== LC_SYMTAB
){
111 if(object
->st
!= NULL
)
112 fatal_arch(arch
, member
, "malformed file (more than one "
113 "LC_SYMTAB load command): ");
114 object
->st
= (struct symtab_command
*)lc
;
116 else if(lc
->cmd
== LC_DYSYMTAB
){
117 if(object
->dyst
!= NULL
)
118 fatal_arch(arch
, member
, "malformed file (more than one "
119 "LC_DYSYMTAB load command): ");
120 object
->dyst
= (struct dysymtab_command
*)lc
;
122 else if(lc
->cmd
== LC_TWOLEVEL_HINTS
){
123 if(object
->hints_cmd
!= NULL
)
124 fatal_arch(arch
, member
, "malformed file (more than one "
125 "LC_TWOLEVEL_HINTS load command): ");
126 object
->hints_cmd
= (struct twolevel_hints_command
*)lc
;
128 else if(lc
->cmd
== LC_CODE_SIGNATURE
){
129 if(object
->code_sig_cmd
!= NULL
)
130 fatal_arch(arch
, member
, "malformed file (more than one "
131 "LC_CODE_SIGNATURE load command): ");
132 object
->code_sig_cmd
= (struct linkedit_data_command
*)lc
;
134 else if(lc
->cmd
== LC_SEGMENT_SPLIT_INFO
){
135 if(object
->split_info_cmd
!= NULL
)
136 fatal_arch(arch
, member
, "malformed file (more than one "
137 "LC_SEGMENT_SPLIT_INFO load command): ");
138 object
->split_info_cmd
= (struct linkedit_data_command
*)lc
;
140 else if(lc
->cmd
== LC_FUNCTION_STARTS
){
141 if(object
->func_starts_info_cmd
!= NULL
)
142 fatal_arch(arch
, member
, "malformed file (more than one "
143 "LC_FUNCTION_STARTS load command): ");
144 object
->func_starts_info_cmd
=
145 (struct linkedit_data_command
*)lc
;
147 else if(lc
->cmd
== LC_DATA_IN_CODE
){
148 if(object
->data_in_code_cmd
!= NULL
)
149 fatal_arch(arch
, member
, "malformed file (more than one "
150 "LC_DATA_IN_CODE load command): ");
151 object
->data_in_code_cmd
=
152 (struct linkedit_data_command
*)lc
;
154 else if(lc
->cmd
== LC_DYLIB_CODE_SIGN_DRS
){
155 if(object
->code_sign_drs_cmd
!= NULL
)
156 fatal_arch(arch
, member
, "malformed file (more than one "
157 "LC_DYLIB_CODE_SIGN_DRS load command): ");
158 object
->code_sign_drs_cmd
=
159 (struct linkedit_data_command
*)lc
;
161 else if(lc
->cmd
== LC_LINKER_OPTIMIZATION_HINT
){
162 if(object
->link_opt_hint_cmd
!= NULL
)
163 fatal_arch(arch
, member
, "malformed file (more than one "
164 "LC_LINKER_OPTIMIZATION_HINT load command): ");
165 object
->link_opt_hint_cmd
=
166 (struct linkedit_data_command
*)lc
;
168 else if((lc
->cmd
== LC_DYLD_INFO
) ||(lc
->cmd
== LC_DYLD_INFO_ONLY
)){
169 if(object
->dyld_info
!= NULL
)
170 fatal_arch(arch
, member
, "malformed file (more than one "
171 "LC_DYLD_INFO load command): ");
172 object
->dyld_info
= (struct dyld_info_command
*)lc
;
174 else if(lc
->cmd
== LC_SEGMENT
){
175 sg
= (struct segment_command
*)lc
;
176 if(strcmp(sg
->segname
, SEG_LINKEDIT
) == 0){
177 if(object
->seg_linkedit
!= NULL
)
178 fatal_arch(arch
, member
, "malformed file (more than "
179 "one " SEG_LINKEDIT
"segment): ");
180 object
->seg_linkedit
= sg
;
182 else if(strcmp(sg
->segname
, "__LLVM") == 0){
183 if(object
->seg_bitcode
!= NULL
)
184 fatal_arch(arch
, member
, "malformed file (more than "
185 "one __LLVM segment): ");
186 object
->seg_bitcode
= sg
;
189 else if(lc
->cmd
== LC_SEGMENT_64
){
190 sg64
= (struct segment_command_64
*)lc
;
191 if(strcmp(sg64
->segname
, SEG_LINKEDIT
) == 0){
192 if(object
->seg_linkedit64
!= NULL
)
193 fatal_arch(arch
, member
, "malformed file (more than "
194 "one " SEG_LINKEDIT
"segment): ");
195 object
->seg_linkedit64
= sg64
;
197 else if(strcmp(sg64
->segname
, "__LLVM") == 0){
198 if(object
->seg_bitcode64
!= NULL
)
199 fatal_arch(arch
, member
, "malformed file (more than "
200 "one __LLVM segment): ");
201 object
->seg_bitcode64
= sg64
;
204 else if(lc
->cmd
== LC_ID_DYLIB
){
206 fatal_arch(arch
, member
, "malformed file (more than one "
207 "LC_ID_DYLIB load command): ");
208 dl_id
= (struct dylib_command
*)lc
;
209 if(dl_id
->dylib
.name
.offset
>= dl_id
->cmdsize
)
210 fatal_arch(arch
, member
, "malformed file (name.offset of "
211 "load command %u extends past the end of the load "
214 lc
= (struct load_command
*)((char *)lc
+ lc
->cmdsize
);
216 if((object
->mh_filetype
== MH_DYLIB
||
217 (object
->mh_filetype
== MH_DYLIB_STUB
&& ncmds
> 0)) &&
219 fatal_arch(arch
, member
, "malformed file (no LC_ID_DYLIB load "
220 "command in %s file): ", object
->mh_filetype
== MH_DYLIB
?
221 "MH_DYLIB" : "MH_DYLIB_STUB");
222 if(object
->hints_cmd
!= NULL
){
223 if(object
->dyst
== NULL
&& object
->hints_cmd
->nhints
!= 0)
224 fatal_arch(arch
, member
, "malformed file (LC_TWOLEVEL_HINTS "
225 "load command present without an LC_DYSYMTAB load command):");
226 if(object
->hints_cmd
->nhints
!= 0 &&
227 object
->hints_cmd
->nhints
!= object
->dyst
->nundefsym
)
228 fatal_arch(arch
, member
, "malformed file (LC_TWOLEVEL_HINTS "
229 "load command's nhints does not match LC_DYSYMTAB load "
230 "command's nundefsym):");
234 * For objects without a dynamic symbol table check to see that the
235 * string table is at the end of the file and that the symbol table is
238 if(object
->dyst
== NULL
){
239 symbol_string_at_end(arch
, member
, object
);
243 * This file has a dynamic symbol table command. We handle three
244 * cases, a dynamic shared library, a file for the dynamic linker,
245 * and a relocatable object file. Since it has a dynamic symbol
246 * table command it could have an indirect symbol table.
248 if(object
->mh_filetype
== MH_DYLIB
/* ||
249 object->mh_filetype == MH_DYLIB_STUB */ ){
251 * This is a dynamic shared library.
252 * The order of the symbolic info is:
253 * local relocation entries
256 * defined external symbols
258 * two-level namespace hints
259 * external relocation entries
260 * indirect symbol table
265 * strings for external symbols
266 * strings for local symbols
267 * code signature data (16 byte aligned)
269 dyld_order(arch
, member
, object
);
271 else if(flags
& MH_DYLDLINK
){
273 * This is a file for the dynamic linker (output of ld(1) with
274 * -output_for_dyld . That is the relocation entries are split
275 * into local and external and hanging off the dysymtab not off
277 * The order of the symbolic info is:
278 * local relocation entries
280 * local symbols (in order as appeared in stabs)
281 * defined external symbols (sorted by name)
282 * undefined symbols (sorted by name)
283 * external relocation entries
284 * indirect symbol table
286 * strings for external symbols
287 * strings for local symbols
288 * code signature data (16 byte aligned)
290 dyld_order(arch
, member
, object
);
294 * This is a relocatable object file either the output of the
295 * assembler or output of ld(1) with -r. For the output of
297 * The order of the symbolic info is:
298 * relocation entries (by section)
299 * indirect symbol table
301 * local symbols (in order as appeared in stabs)
302 * defined external symbols (sorted by name)
303 * undefined symbols (sorted by name)
305 * strings for external symbols
306 * strings for local symbols
307 * With this order the symbol table can be replaced and the
308 * relocation entries and the indirect symbol table entries
309 * can be updated in the file and not moved.
310 * For the output of ld -r:
311 * The order of the symbolic info is:
312 * relocation entries (by section)
314 * local symbols (in order as appeared in stabs)
315 * defined external symbols (sorted by name)
316 * undefined symbols (sorted by name)
317 * indirect symbol table
319 * strings for external symbols
320 * strings for local symbols
323 symbol_string_at_end(arch
, member
, object
);
332 struct member
*member
,
333 struct object
*object
)
335 uint32_t offset
, rounded_offset
, isym
;
337 if(object
->mh
!= NULL
){
338 if(object
->seg_linkedit
== NULL
)
339 fatal_arch(arch
, member
, "malformed file (no " SEG_LINKEDIT
341 if(object
->seg_linkedit
->filesize
!= 0 &&
342 object
->seg_linkedit
->fileoff
+
343 object
->seg_linkedit
->filesize
!= object
->object_size
)
344 fatal_arch(arch
, member
, "the " SEG_LINKEDIT
" segment "
345 "does not cover the end of the file (can't "
346 "be processed) in: ");
348 offset
= object
->seg_linkedit
->fileoff
;
350 if(object
->seg_bitcode
!= NULL
){
351 if(object
->seg_bitcode
->filesize
< sizeof(struct xar_header
))
352 fatal_arch(arch
, member
, "the __LLVM segment too small "
353 "(less than sizeof(struct xar_header)) in: ");
354 if(object
->seg_bitcode
->fileoff
+
355 object
->seg_bitcode
->filesize
!= offset
)
356 fatal_arch(arch
, member
, "the __LLVM segment not directly "
357 "before the " SEG_LINKEDIT
" segment in: ");
361 if(object
->seg_linkedit64
== NULL
)
362 fatal_arch(arch
, member
, "malformed file (no " SEG_LINKEDIT
364 if(object
->seg_linkedit64
->filesize
!= 0 &&
365 object
->seg_linkedit64
->fileoff
+
366 object
->seg_linkedit64
->filesize
!= object
->object_size
)
367 fatal_arch(arch
, member
, "the " SEG_LINKEDIT
" segment "
368 "does not cover the end of the file (can't "
369 "be processed) in: ");
371 offset
= object
->seg_linkedit64
->fileoff
;
373 if(object
->seg_bitcode64
!= NULL
){
374 if(object
->seg_bitcode64
->filesize
< sizeof(struct xar_header
))
375 fatal_arch(arch
, member
, "the __LLVM segment too small "
376 "(less than sizeof(struct xar_header)) in: ");
377 if(object
->seg_bitcode64
->fileoff
+
378 object
->seg_bitcode64
->filesize
!= offset
)
379 fatal_arch(arch
, member
, "the __LLVM segment not directly "
380 "before the " SEG_LINKEDIT
" segment in: ");
383 if(object
->dyld_info
!= NULL
){
384 /* dyld_info starts at beginning of __LINKEDIT */
385 if (object
->dyld_info
->rebase_off
!= 0){
386 if (object
->dyld_info
->rebase_off
!= offset
)
387 order_error(arch
, member
, "dyld_info "
390 else if (object
->dyld_info
->bind_off
!= 0){
391 if (object
->dyld_info
->bind_off
!= offset
)
392 order_error(arch
, member
, "dyld_info "
395 else if(object
->dyld_info
->export_off
!= 0){
396 if(object
->dyld_info
->export_off
!= offset
&&
397 object
->dyld_info
->weak_bind_size
!= 0 &&
398 object
->dyld_info
->lazy_bind_size
!= 0)
399 order_error(arch
, member
, "dyld_info "
402 /* update offset to end of dyld_info contents */
403 if (object
->dyld_info
->export_size
!= 0)
404 offset
= object
->dyld_info
->export_off
+
405 object
->dyld_info
->export_size
;
406 else if (object
->dyld_info
->lazy_bind_size
!= 0)
407 offset
= object
->dyld_info
->lazy_bind_off
+
408 object
->dyld_info
->lazy_bind_size
;
409 else if (object
->dyld_info
->weak_bind_size
!= 0)
410 offset
= object
->dyld_info
->weak_bind_off
+
411 object
->dyld_info
->weak_bind_size
;
412 else if (object
->dyld_info
->bind_size
!= 0)
413 offset
= object
->dyld_info
->bind_off
+
414 object
->dyld_info
->bind_size
;
415 else if (object
->dyld_info
->rebase_size
!= 0)
416 offset
= object
->dyld_info
->rebase_off
+
417 object
->dyld_info
->rebase_size
;
419 if(object
->dyst
->nlocrel
!= 0){
420 if(object
->dyst
->locreloff
!= offset
)
421 order_error(arch
, member
, "local relocation entries "
423 offset
+= object
->dyst
->nlocrel
*
424 sizeof(struct relocation_info
);
426 if(object
->split_info_cmd
!= NULL
){
427 if(object
->split_info_cmd
->dataoff
!= 0 &&
428 object
->split_info_cmd
->dataoff
!= offset
)
429 order_error(arch
, member
, "split info data out of place");
430 offset
+= object
->split_info_cmd
->datasize
;
432 if(object
->func_starts_info_cmd
!= NULL
){
433 if(object
->func_starts_info_cmd
->dataoff
!= 0 &&
434 object
->func_starts_info_cmd
->dataoff
!= offset
)
435 order_error(arch
, member
, "function starts data out of place");
436 offset
+= object
->func_starts_info_cmd
->datasize
;
438 if(object
->data_in_code_cmd
!= NULL
){
439 if(object
->data_in_code_cmd
->dataoff
!= 0 &&
440 object
->data_in_code_cmd
->dataoff
!= offset
)
441 order_error(arch
, member
, "data in code info out of place");
442 offset
+= object
->data_in_code_cmd
->datasize
;
444 if(object
->code_sign_drs_cmd
!= NULL
){
445 if(object
->code_sign_drs_cmd
->dataoff
!= 0 &&
446 object
->code_sign_drs_cmd
->dataoff
!= offset
)
447 order_error(arch
, member
, "code signing DRs info out of place");
448 offset
+= object
->code_sign_drs_cmd
->datasize
;
450 if(object
->link_opt_hint_cmd
!= NULL
){
451 if(object
->link_opt_hint_cmd
->dataoff
!= 0 &&
452 object
->link_opt_hint_cmd
->dataoff
!= offset
)
453 order_error(arch
, member
, "linker optimization hint info out "
455 offset
+= object
->link_opt_hint_cmd
->datasize
;
457 if(object
->st
->nsyms
!= 0){
458 if(object
->st
->symoff
!= offset
)
459 order_error(arch
, member
, "symbol table out of place");
460 if(object
->mh
!= NULL
)
461 offset
+= object
->st
->nsyms
* sizeof(struct nlist
);
463 offset
+= object
->st
->nsyms
* sizeof(struct nlist_64
);
466 if(object
->dyst
->nlocalsym
!= 0){
467 if(object
->dyst
->ilocalsym
!= isym
)
468 order_error(arch
, member
, "local symbols out of place");
469 isym
+= object
->dyst
->nlocalsym
;
471 if(object
->dyst
->nextdefsym
!= 0){
472 if(object
->dyst
->iextdefsym
!= isym
)
473 order_error(arch
, member
, "externally defined symbols out of "
475 isym
+= object
->dyst
->nextdefsym
;
477 if(object
->dyst
->nundefsym
!= 0){
478 if(object
->dyst
->iundefsym
!= isym
)
479 order_error(arch
, member
, "undefined symbols out of place");
480 isym
+= object
->dyst
->nundefsym
;
482 if(object
->hints_cmd
!= NULL
&& object
->hints_cmd
->nhints
!= 0){
483 if(object
->hints_cmd
->offset
!= offset
)
484 order_error(arch
, member
, "hints table out of place");
485 offset
+= object
->hints_cmd
->nhints
* sizeof(struct twolevel_hint
);
487 if(object
->dyst
->nextrel
!= 0){
488 if(object
->dyst
->extreloff
!= offset
)
489 order_error(arch
, member
, "external relocation entries"
491 offset
+= object
->dyst
->nextrel
*
492 sizeof(struct relocation_info
);
494 if(object
->dyst
->nindirectsyms
!= 0){
495 if(object
->dyst
->indirectsymoff
!= offset
)
496 order_error(arch
, member
, "indirect symbol table "
498 offset
+= object
->dyst
->nindirectsyms
*
503 * If this is a 64-bit Mach-O file and has an odd number of indirect
504 * symbol table entries the next offset MAYBE rounded to a multiple of
505 * 8 or MAY NOT BE. This should done to keep all the tables aligned but
506 * was not done for 64-bit Mach-O in Mac OS X 10.4.
508 object
->input_indirectsym_pad
= 0;
509 if(object
->mh64
!= NULL
&&
510 (object
->dyst
->nindirectsyms
% 2) != 0){
511 rounded_offset
= rnd(offset
, 8);
514 rounded_offset
= offset
;
517 if(object
->dyst
->ntoc
!= 0){
518 if(object
->dyst
->tocoff
!= offset
&&
519 object
->dyst
->tocoff
!= rounded_offset
)
520 order_error(arch
, member
, "table of contents out of place");
521 if(object
->dyst
->tocoff
== offset
){
522 offset
+= object
->dyst
->ntoc
*
523 sizeof(struct dylib_table_of_contents
);
524 rounded_offset
= offset
;
526 else if(object
->dyst
->tocoff
== rounded_offset
){
527 object
->input_indirectsym_pad
= rounded_offset
- offset
;
528 rounded_offset
+= object
->dyst
->ntoc
*
529 sizeof(struct dylib_table_of_contents
);
530 offset
= rounded_offset
;
533 if(object
->dyst
->nmodtab
!= 0){
534 if(object
->dyst
->modtaboff
!= offset
&&
535 object
->dyst
->modtaboff
!= rounded_offset
)
536 order_error(arch
, member
, "module table out of place");
537 if(object
->mh
!= NULL
){
538 offset
+= object
->dyst
->nmodtab
*
539 sizeof(struct dylib_module
);
540 rounded_offset
= offset
;
543 if(object
->dyst
->modtaboff
== offset
){
544 offset
+= object
->dyst
->nmodtab
*
545 sizeof(struct dylib_module_64
);
546 rounded_offset
= offset
;
548 else if(object
->dyst
->modtaboff
== rounded_offset
){
549 object
->input_indirectsym_pad
= rounded_offset
- offset
;
550 rounded_offset
+= object
->dyst
->nmodtab
*
551 sizeof(struct dylib_module_64
);
552 offset
= rounded_offset
;
556 if(object
->dyst
->nextrefsyms
!= 0){
557 if(object
->dyst
->extrefsymoff
!= offset
&&
558 object
->dyst
->extrefsymoff
!= rounded_offset
)
559 order_error(arch
, member
, "reference table out of place");
560 if(object
->dyst
->extrefsymoff
== offset
){
561 offset
+= object
->dyst
->nextrefsyms
*
562 sizeof(struct dylib_reference
);
563 rounded_offset
= offset
;
565 else if(object
->dyst
->extrefsymoff
== rounded_offset
){
566 object
->input_indirectsym_pad
= rounded_offset
- offset
;
567 rounded_offset
+= object
->dyst
->nextrefsyms
*
568 sizeof(struct dylib_reference
);
569 offset
= rounded_offset
;
572 if(object
->st
->strsize
!= 0){
573 if(object
->st
->stroff
!= offset
&&
574 object
->st
->stroff
!= rounded_offset
)
575 order_error(arch
, member
, "string table out of place");
576 if(object
->st
->stroff
== offset
){
577 offset
+= object
->st
->strsize
;
578 rounded_offset
= offset
;
580 else if(object
->st
->stroff
== rounded_offset
){
581 object
->input_indirectsym_pad
= rounded_offset
- offset
;
582 rounded_offset
+= object
->st
->strsize
;
583 offset
= rounded_offset
;
586 if(object
->code_sig_cmd
!= NULL
){
587 rounded_offset
= rnd(rounded_offset
, 16);
588 if(object
->code_sig_cmd
->dataoff
!= rounded_offset
)
589 order_error(arch
, member
, "code signature data out of place");
590 rounded_offset
+= object
->code_sig_cmd
->datasize
;
591 offset
= rounded_offset
;
593 if(offset
!= object
->object_size
&&
594 rounded_offset
!= object
->object_size
)
595 order_error(arch
, member
, "link edit information does not fill the "
596 SEG_LINKEDIT
" segment");
603 struct member
*member
,
606 fatal_arch(arch
, member
, "file not in an order that can be processed "
612 symbol_string_at_end(
614 struct member
*member
,
615 struct object
*object
)
617 uint32_t end
, sigend
, strend
, rounded_strend
;
618 uint32_t indirectend
, rounded_indirectend
;
620 if(object
->st
!= NULL
&& object
->st
->nsyms
!= 0){
621 end
= object
->object_size
;
622 if(object
->code_sig_cmd
!= NULL
){
623 sigend
= object
->code_sig_cmd
->dataoff
+
624 object
->code_sig_cmd
->datasize
;
626 fatal_arch(arch
, member
, "code signature not at the end "
627 "of the file (can't be processed) in file: ");
629 * The code signature starts at a 16 byte offset. So if the
630 * string table end rouned to 16 bytes is the offset where the
631 * code signature starts then just back up the current "end" to
632 * the end of the string table.
634 end
= object
->code_sig_cmd
->dataoff
;
635 if(object
->st
->strsize
!= 0){
636 strend
= object
->st
->stroff
+ object
->st
->strsize
;
637 rounded_strend
= rnd(strend
, 16);
638 if(object
->code_sig_cmd
->dataoff
== rounded_strend
)
642 if(object
->st
->strsize
!= 0){
643 strend
= object
->st
->stroff
+ object
->st
->strsize
;
645 * Since archive member sizes are now rounded to 8 bytes the
646 * string table may not be exactly at the end of the
647 * object_size due to rounding.
649 rounded_strend
= rnd(strend
, 8);
650 if(strend
!= end
&& rounded_strend
!= end
)
651 fatal_arch(arch
, member
, "string table not at the end "
652 "of the file (can't be processed) in file: ");
654 * To make the code work that assumes the end of string table is
655 * at the end of the object file change the object_size to be
656 * the end of the string table here. This could be done at the
657 * end of this routine but since all the later checks are fatal
658 * we'll just do this here. If there is a code signature after
659 * string table don't do this.
661 if(rounded_strend
!= strend
&& object
->code_sig_cmd
== NULL
)
662 object
->object_size
= strend
;
663 end
= object
->st
->stroff
;
665 if(object
->dyst
!= NULL
&&
666 object
->dyst
->nindirectsyms
!= 0 &&
667 object
->st
->nsyms
!= 0 &&
668 object
->dyst
->indirectsymoff
> object
->st
->symoff
){
670 indirectend
= object
->dyst
->indirectsymoff
+
671 object
->dyst
->nindirectsyms
* sizeof(uint32_t);
674 * If this is a 64-bit Mach-O file and has an odd number of
675 * indirect symbol table entries the next offset MAYBE rounded
676 * to a multiple of 8 or MAY NOT BE. This should done to keep
677 * all the tables aligned but was not done for 64-bit Mach-O in
680 if(object
->mh64
!= NULL
&&
681 (object
->dyst
->nindirectsyms
% 2) != 0){
682 rounded_indirectend
= rnd(indirectend
, 8);
685 rounded_indirectend
= indirectend
;
688 if(indirectend
!= end
&& rounded_indirectend
!= end
){
689 fatal_arch(arch
, member
, "indirect symbol table does not "
690 "directly preceed the string table (can't be "
691 "processed) in file: ");
693 object
->input_indirectsym_pad
= end
- indirectend
;
694 end
= object
->dyst
->indirectsymoff
;
695 if(object
->mh
!= NULL
){
696 if(object
->st
->symoff
+
697 object
->st
->nsyms
* sizeof(struct nlist
) != end
)
698 fatal_arch(arch
, member
, "symbol table does not "
699 "directly preceed the indirect symbol table (can't "
700 "be processed) in file: ");
703 if(object
->st
->symoff
+
704 object
->st
->nsyms
* sizeof(struct nlist_64
) != end
)
705 fatal_arch(arch
, member
, "symbol table does not "
706 "directly preceed the indirect symbol table (can't "
707 "be processed) in file: ");
711 if(object
->mh
!= NULL
){
712 if(object
->st
->symoff
+
713 object
->st
->nsyms
* sizeof(struct nlist
) != end
)
714 fatal_arch(arch
, member
, "symbol table and string "
715 "table not at the end of the file (can't be "
716 "processed) in file: ");
719 if(object
->st
->symoff
+
720 object
->st
->nsyms
* sizeof(struct nlist_64
) != end
)
721 fatal_arch(arch
, member
, "symbol table and string "
722 "table not at the end of the file (can't be "
723 "processed) in file: ");
726 if(object
->seg_linkedit
!= NULL
&&
727 (object
->seg_linkedit
->flags
& SG_FVMLIB
) != SG_FVMLIB
&&
728 object
->seg_linkedit
->filesize
!= 0){
729 if(object
->seg_linkedit
->fileoff
+
730 object
->seg_linkedit
->filesize
!= object
->object_size
)
731 fatal_arch(arch
, member
, "the " SEG_LINKEDIT
" segment "
732 "does not cover the symbol and string table (can't "
733 "be processed) in file: ");
737 #endif /* !defined(RLD) */