877.5
[darwin-xtools/darwin-xtools-svp.git] / cctools / libstuff / checkout.c
blob676ceec9d86d6c9467573804c8f44f9204b843c4
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 #ifndef RLD
24 #include <stdio.h>
25 #include <string.h>
26 #include <xar/xar.h>
27 #include "stuff/ofile.h"
28 #include "stuff/breakout.h"
29 #include "stuff/rnd.h"
31 static void check_object(
32 struct arch *arch,
33 struct member *member,
34 struct object *object);
36 static void symbol_string_at_end(
37 struct arch *arch,
38 struct member *member,
39 struct object *object);
41 static void dyld_order(
42 struct arch *arch,
43 struct member *member,
44 struct object *object);
46 static void order_error(
47 struct arch *arch,
48 struct member *member,
49 char *reason);
51 __private_extern__
52 void
53 checkout(
54 struct arch *archs,
55 uint32_t narchs)
57 uint32_t i, j;
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);
74 static
75 void
76 check_object(
77 struct arch *arch,
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.
91 object->st = NULL;
92 object->dyst = NULL;
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;
99 dl_id = NULL;
100 lc = object->load_commands;
101 if(object->mh != NULL){
102 ncmds = object->mh->ncmds;
103 flags = object->mh->flags;
105 else{
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){
205 if(dl_id != NULL)
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 "
212 "command): ", i);
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)) &&
218 dl_id == NULL)
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
236 * just before it.
238 if(object->dyst == NULL){
239 symbol_string_at_end(arch, member, object);
241 else{
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
254 * symbol table
255 * local symbols
256 * defined external symbols
257 * undefined symbols
258 * two-level namespace hints
259 * external relocation entries
260 * indirect symbol table
261 * table of contents
262 * module table
263 * reference table
264 * string 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
276 * the sections.
277 * The order of the symbolic info is:
278 * local relocation entries
279 * symbol table
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
285 * string table
286 * strings for external symbols
287 * strings for local symbols
288 * code signature data (16 byte aligned)
290 dyld_order(arch, member, object);
292 else{
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
296 * the assembler:
297 * The order of the symbolic info is:
298 * relocation entries (by section)
299 * indirect symbol table
300 * symbol table
301 * local symbols (in order as appeared in stabs)
302 * defined external symbols (sorted by name)
303 * undefined symbols (sorted by name)
304 * string table
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)
313 * symbol table
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
318 * string table
319 * strings for external symbols
320 * strings for local symbols
321 * code signature
323 symbol_string_at_end(arch, member, object);
328 static
329 void
330 dyld_order(
331 struct arch *arch,
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
340 " segment): ");
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: ");
360 else{
361 if(object->seg_linkedit64 == NULL)
362 fatal_arch(arch, member, "malformed file (no " SEG_LINKEDIT
363 " segment): ");
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 "
388 "out of place");
390 else if (object->dyld_info->bind_off != 0){
391 if (object->dyld_info->bind_off != offset)
392 order_error(arch, member, "dyld_info "
393 "out of place");
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 "
400 "out of place");
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 "
422 "out of place");
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 "
454 "of place");
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);
462 else
463 offset += object->st->nsyms * sizeof(struct nlist_64);
465 isym = 0;
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 "
474 "place");
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"
490 " out of place");
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 "
497 "out of place");
498 offset += object->dyst->nindirectsyms *
499 sizeof(uint32_t);
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);
513 else{
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;
542 else{
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");
599 static
600 void
601 order_error(
602 struct arch *arch,
603 struct member *member,
604 char *reason)
606 fatal_arch(arch, member, "file not in an order that can be processed "
607 "(%s): ", reason);
610 static
611 void
612 symbol_string_at_end(
613 struct arch *arch,
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;
625 if(sigend != end)
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)
639 end = 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
678 * Mac OS X 10.4.
680 if(object->mh64 != NULL &&
681 (object->dyst->nindirectsyms % 2) != 0){
682 rounded_indirectend = rnd(indirectend, 8);
684 else{
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: ");
702 else{
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: ");
710 else{
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: ");
718 else{
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) */