782
[darwin-xtools.git] / cctools / ld / ld.c
blobeae01600ac2aff33db48081d1e558bb9db39d393
1 /*
2 * Copyright (c) 1999-2003 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
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 #ifdef SHLIB
24 #include "shlib.h"
25 #endif /* SHLIB */
27 * The Apple, Inc. Mach-O (Mach object file format) link-editor. This file
28 * contains the main() routine and the global error handling routines and other
29 * miscellaneous small global routines. It also defines the global varaibles
30 * that are set or changed by command line arguments.
32 #include <stdlib.h>
33 #include <string.h>
34 #include <stdarg.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <mach-o/loader.h>
38 #include <mach-o/nlist.h>
39 #include "stuff/arch.h"
40 #include "stuff/version_number.h"
41 #include "stuff/guess_short_name.h"
42 #include "stuff/macosx_deployment_target.h"
43 #include "stuff/execute.h"
44 #if !(defined(KLD))
45 #include <stdio.h>
46 #endif
47 #if !(defined(KLD) && defined(__STATIC__))
48 #include <signal.h>
49 #include <errno.h>
50 #include <libc.h>
51 #include <ar.h>
52 #include <mach/mach.h>
53 #include <mach/mach_error.h>
54 #include "stuff/seg_addr_table.h"
55 #ifndef RLD
56 #include "stuff/symbol_list.h"
57 #endif
58 #include <mach/mach_init.h>
59 #if defined(__OPENSTEP__) || defined(__GONZO_BUNSEN_BEAKER__)
60 #include <servers/netname.h>
61 #else
62 #include <servers/bootstrap.h>
63 #endif
64 #else /* defined(KLD) && defined(__STATIC__) */
65 #include <mach/mach.h>
66 #include <mach/kern_return.h>
67 #endif /* !(defined(KLD) && defined(__STATIC__)) */
69 #include "ld.h"
70 #ifndef RLD
71 static char *mkstr(
72 const char *args,
73 ...);
74 #endif /* !defined(RLD) */
75 #include "specs.h"
76 #include "pass1.h"
77 #include "live_refs.h"
78 #include "objects.h"
79 #include "sections.h"
80 #include "fvmlibs.h"
81 #include "symbols.h"
82 #include "layout.h"
83 #include "pass2.h"
85 /* name of this program as executed (argv[0]) */
86 __private_extern__ char *progname = NULL;
87 /* indication of an error set in error(), for processing a number of errors
88 and then exiting */
89 __private_extern__ unsigned long errors = 0;
90 /* the pagesize of the machine this program is running on, getpagesize() value*/
91 __private_extern__ unsigned long host_pagesize = 0;
92 /* the byte sex of the machine this program is running on */
93 __private_extern__ enum byte_sex host_byte_sex = UNKNOWN_BYTE_SEX;
95 /* name of output file */
96 __private_extern__ char *outputfile = NULL;
97 /* type of output file */
98 __private_extern__ unsigned long filetype = MH_EXECUTE;
99 /* multi or single module dylib output */
100 __private_extern__ enum bool multi_module_dylib = TRUE;
101 #ifndef RLD
102 static enum bool filetype_specified = FALSE;
103 static enum bool moduletype_specified = FALSE;
104 /* if the -A flag is specified use to set the object file type */
105 static enum bool Aflag_specified = FALSE;
106 #endif /* !defined(RLD) */
108 * The architecture of the output file as specified by -arch and the cputype
109 * and cpusubtype of the object files being loaded which will be the output
110 * cputype and cpusubtype. specific_arch_flag is true if an -arch flag is
111 * specified and the flag for a specific implementation of an architecture.
113 __private_extern__ struct arch_flag arch_flag =
114 #if defined(KLD) && defined(__STATIC__)
116 #ifdef __ppc__
117 { "ppc", CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL };
118 #elif __i386__
119 { "i386", CPU_TYPE_I386, CPU_SUBTYPE_I386_ALL };
120 #elif __arm__
121 { "arm", CPU_TYPE_ARM, CPU_SUBTYPE_ARM_ALL };
122 #else
123 #error "unsupported architecture for static KLD"
124 #endif
126 #else /* !(defined(KLD) && defined(__STATIC__)) */
127 { 0 };
128 #endif /* defined(KLD) && defined(__STATIC__) */
129 __private_extern__ enum bool specific_arch_flag = FALSE;
132 * The -force_cpusubtype_ALL flag.
134 __private_extern__ enum bool force_cpusubtype_ALL = FALSE;
136 /* the byte sex of the output file */
137 __private_extern__ enum byte_sex target_byte_sex = UNKNOWN_BYTE_SEX;
138 static enum bool arch_multiple = FALSE; /* print one arch message before error*/
140 __private_extern__
141 enum bool trace = FALSE; /* print stages of link-editing */
142 __private_extern__
143 enum bool save_reloc = FALSE; /* save relocation information */
144 __private_extern__
145 enum bool output_for_dyld = FALSE; /* produce output for use with dyld */
146 __private_extern__
147 enum bool bind_at_load = FALSE; /* mark the output for dyld to be bound
148 when loaded */
149 __private_extern__
150 enum bool no_fix_prebinding = FALSE; /* mark the output for dyld to never
151 run fix_prebinding */
152 __private_extern__
153 enum bool load_map = FALSE; /* print a load map */
154 __private_extern__
155 enum bool define_comldsyms = TRUE; /* define common and link-editor defined
156 symbol reguardless of file type */
157 #ifndef RLD
158 static enum bool
159 dflag_specified = FALSE; /* the -d flag has been specified */
160 #endif /* !defined(RLD) */
161 __private_extern__
162 enum bool seglinkedit = FALSE; /* create the link edit segment */
163 #ifndef RLD
164 static enum bool
165 seglinkedit_specified = FALSE; /* if either -seglinkedit or */
166 /* -noseglinkedit was specified */
167 #endif /* !defined(RLD) */
168 __private_extern__
169 enum bool whyload = FALSE; /* print why archive members are
170 loaded */
171 #ifndef RLD
172 static enum bool whatsloaded = FALSE; /* print which object files are loaded*/
173 #endif /* !defined(RLD) */
174 __private_extern__
175 enum bool flush = TRUE; /* Use the output_flush routine to flush
176 output file by pages */
177 __private_extern__
178 enum bool sectorder_detail = FALSE; /* print sectorder warnings in detail */
179 __private_extern__
180 enum bool nowarnings = FALSE; /* suppress warnings */
181 __private_extern__
182 enum bool no_arch_warnings = FALSE; /* suppress wrong arch warnings */
183 __private_extern__
184 enum bool arch_errors_fatal = FALSE; /* cause wrong arch errors to be fatal*/
185 __private_extern__
186 enum bool archive_ObjC = FALSE; /* objective-C archive semantics */
187 __private_extern__
188 enum bool archive_all = FALSE; /* always load everything in archives */
189 __private_extern__
190 enum bool keep_private_externs = FALSE; /* don't turn private externs into
191 non-external symbols */
192 /* TRUE if -dynamic is specified, FALSE if -static is specified */
193 __private_extern__
194 enum bool dynamic = TRUE;
195 #ifndef RLD
196 static enum bool dynamic_specified = FALSE;
197 static enum bool static_specified = FALSE;
198 #endif
200 /* The level of symbol table stripping */
201 __private_extern__ enum strip_levels strip_level = STRIP_DUP_INCLS;
202 /* Strip the base file symbols (the -A argument's symbols) */
203 __private_extern__ enum bool strip_base_symbols = FALSE;
205 /* strip dead blocks */
206 __private_extern__ enum bool dead_strip = FALSE;
207 /* don't strip module init and term sections */
208 __private_extern__ enum bool no_dead_strip_inits_and_terms = FALSE;
209 /* print timings for dead striping code */
210 __private_extern__ enum bool dead_strip_times = FALSE;
212 #ifndef RLD
214 * Data structures to perform selective exporting of global symbols.
215 * save_symbols is the names of the symbols from -exported_symbols_list
216 * remove_symbols is the names of the symbols from -unexported_symbols_list
218 __private_extern__ struct symbol_list *save_symbols = NULL;
219 __private_extern__ uint32_t nsave_symbols = 0;
220 __private_extern__ struct symbol_list *remove_symbols = NULL;
221 __private_extern__ uint32_t nremove_symbols = 0;
224 * -executable_path option's argument, executable_path is used to replace
225 * @executable_path for dependent libraries.
227 __private_extern__ char *executable_path = NULL;
228 #endif /* RLD */
231 /* The list of symbols to be traced */
232 __private_extern__ char **trace_syms = NULL;
233 __private_extern__ unsigned long ntrace_syms = 0;
235 /* The number of references of undefined symbols to print */
236 __private_extern__ unsigned long Yflag = 0;
238 /* The list of allowed undefined symbols */
239 __private_extern__ char **undef_syms = NULL;
240 __private_extern__ unsigned long nundef_syms = 0;
242 /* The list of -dylib_file arguments */
243 __private_extern__ char **dylib_files = NULL;
244 __private_extern__ unsigned long ndylib_files = 0;
246 /* The checking for undefined symbols */
247 __private_extern__ enum undefined_check_level undefined_flag = UNDEFINED_ERROR;
248 #ifndef RLD
249 static enum bool undefined_flag_specified = FALSE;
250 #endif
252 /* The checking for (twolevel namespace) multiply defined symbols */
253 __private_extern__ enum multiply_defined_check_level
254 multiply_defined_flag = MULTIPLY_DEFINED_WARNING;
255 __private_extern__ enum multiply_defined_check_level
256 multiply_defined_unused_flag = MULTIPLY_DEFINED_SUPPRESS;
257 /* the -nomultidefs option */
258 __private_extern__ enum bool nomultidefs = FALSE;
259 #ifndef RLD
260 static enum bool multiply_defined_flag_specified = FALSE;
261 static enum bool multiply_defined_unused_flag_specified = FALSE;
262 #endif
264 /* The checking for read only relocs */
265 __private_extern__ enum read_only_reloc_check_level
266 read_only_reloc_flag = READ_ONLY_RELOC_ERROR;
268 /* The checking for section difference relocs */
269 __private_extern__ enum sect_diff_reloc_check_level
270 sect_diff_reloc_flag = SECT_DIFF_RELOC_SUPPRESS;
272 /* The handling for weak reference mismatches */
273 __private_extern__ enum weak_reference_mismatches_handling
274 weak_reference_mismatches = WEAK_REFS_MISMATCH_ERROR;
276 /* The Mac OS X deployment target */
277 __private_extern__ struct macosx_deployment_target
278 macosx_deployment_target = { 0 };
280 /* The prebinding optimization */
281 #ifndef RLD
282 static enum bool prebinding_flag_specified = FALSE;
283 #endif
284 __private_extern__ enum bool prebinding = FALSE;
285 __private_extern__ enum bool prebind_allow_overlap = FALSE;
286 __private_extern__ enum bool prebind_all_twolevel_modules = FALSE;
287 #ifndef RLD
288 static enum bool read_only_reloc_flag_specified = FALSE;
289 static enum bool sect_diff_reloc_flag_specified = FALSE;
290 static enum bool weak_reference_mismatches_specified = FALSE;
291 static enum bool prebind_all_twolevel_modules_specified = FALSE;
292 static enum bool unprebound_library(
293 char *dylib_install_name,
294 char *seg_addr_table_filename);
295 #endif
297 /* True if -m is specified to allow multiply symbols, as a warning */
298 __private_extern__ enum bool allow_multiply_defined_symbols = FALSE;
300 /* The segment alignment and pagezero_size, note the segalign is reset in
301 * layout() by get_segalign_from_flag() based on the target architecture.
303 __private_extern__ unsigned long segalign = 0x2000;
304 #ifndef RLD
305 __private_extern__ enum bool segalign_specified = FALSE;
306 #endif /* !defined(RLD) */
307 __private_extern__ unsigned long pagezero_size = 0;
309 /* The default section alignment */
310 __private_extern__ unsigned long defaultsectalign = DEFAULTSECTALIGN;
312 /* The first segment address */
313 __private_extern__ unsigned long seg1addr = 0;
314 __private_extern__ enum bool seg1addr_specified = FALSE;
316 /* read-only and read-write segment addresses */
317 __private_extern__ unsigned long segs_read_only_addr = 0;
318 __private_extern__ enum bool segs_read_only_addr_specified = FALSE;
319 __private_extern__ unsigned long segs_read_write_addr = 0;
320 __private_extern__ enum bool segs_read_write_addr_specified = FALSE;
322 #ifndef RLD
323 /* file name of the segment address table */
324 static char *seg_addr_table_name = NULL;
325 /* the file system path name to use instead of the install name */
326 static char *seg_addr_table_filename = NULL;
327 #endif /* !defined(RLD) */
329 /* The stack address and size */
330 __private_extern__ unsigned long stack_addr = 0;
331 __private_extern__ enum bool stack_addr_specified = FALSE;
332 __private_extern__ unsigned long stack_size = 0;
333 __private_extern__ enum bool stack_size_specified = FALSE;
335 /* TRUE if -allow_stack_execute is specified */
336 __private_extern__ enum bool allow_stack_execute = FALSE;
338 #ifndef RLD
339 /* A -segaddr option was specified */
340 static enum bool segaddr_specified = FALSE;
341 #endif /* !defined(RLD) */
344 * The header pad, the default is set to the size of a section strcuture so
345 * that if /bin/objcunique is run on the result and up to two sections can be
346 * added.
348 __private_extern__ unsigned long headerpad = sizeof(struct section) * 2;
349 #ifndef RLD
350 static enum bool headerpad_specified = FALSE;
351 #endif /* !defined(RLD) */
353 * If specified makes sure the header pad is big enough to change all the
354 * install name of the dylibs in the output to MAXPATHLEN.
356 __private_extern__ enum bool headerpad_max_install_names = FALSE;
358 /* The name of the specified entry point */
359 __private_extern__ char *entry_point_name = NULL;
361 /* The name of the specified library initialization routine */
362 __private_extern__ char *init_name = NULL;
364 /* The dylib information */
365 __private_extern__ char *dylib_install_name = NULL;
366 __private_extern__ uint32_t dylib_current_version = 0;
367 __private_extern__ uint32_t dylib_compatibility_version = 0;
369 /* the umbrella/sub/client framework information */
370 __private_extern__ enum bool sub_framework = FALSE;
371 __private_extern__ enum bool umbrella_framework = FALSE;
372 __private_extern__ char *sub_framework_name = NULL;
373 __private_extern__ char *umbrella_framework_name = NULL;
374 __private_extern__ char *client_name = NULL;
375 __private_extern__ char **allowable_clients = NULL;
376 __private_extern__ unsigned long nallowable_clients = 0;
378 /* The list of sub_umbrella frameworks */
379 __private_extern__ char **sub_umbrellas = NULL;
380 __private_extern__ unsigned long nsub_umbrellas = 0;
382 /* The list of sub_library dynamic libraries */
383 __private_extern__ char **sub_librarys = NULL;
384 __private_extern__ unsigned long nsub_librarys = 0;
386 /* The dylinker information */
387 __private_extern__ char *dylinker_install_name = NULL;
389 #ifndef RLD
390 /* set to the -bundle_loader argument if specified */
391 static char *bundle_loader = NULL;
392 #endif
394 /* set to TRUE if -private_bundle is specified */
395 __private_extern__ enum bool private_bundle = FALSE;
397 /* The value of the environment variable NEXT_ROOT or the -syslibroot argument*/
398 __private_extern__ char *next_root = NULL;
399 #ifndef RLD
400 static enum bool syslibroot_specified = FALSE;
401 #endif
403 /* TRUE if the environment variable LD_TRACE_ARCHIVES
404 (or temporarily RC_TRACE_ARCHIVES) is set */
405 __private_extern__ enum bool ld_trace_archives = FALSE;
407 /* TRUE if the environment variable LD_TRACE_DYLIBS
408 (or temporarily RC_TRACE_DYLIBS) is set */
409 __private_extern__ enum bool ld_trace_dylibs = FALSE;
411 /* TRUE if the environment variable LD_TRACE_PREBINDING_DISABLED
412 (or temporarily LD_TRACE_PREBINDING_DISABLED) is set */
413 __private_extern__ enum bool ld_trace_prebinding_disabled = FALSE;
415 #ifndef KLD
416 /* The file LD_TRACE_FILE references, or NULL if none is set */
417 static const char *trace_file_path = NULL;
418 #endif
420 /* the argument to -final_output if any */
421 __private_extern__ char *final_output = NULL;
423 /* The variables to support namespace options */
424 __private_extern__ enum bool namespace_specified = FALSE;
425 __private_extern__ enum bool twolevel_namespace = TRUE;
426 __private_extern__ enum bool force_flat_namespace = FALSE;
428 #ifndef RLD
429 /* Variable to support options logging. */
430 static enum bool ld_print_options = FALSE;
431 #endif
434 * Because the MacOS X 10.0 code in libSystem for the NSObjectFileImage*() APIs
435 * does not ignore unknown load commands if MH_BUNDLE files are built with
436 * two-level namespace hints the LC_TWOLEVEL_HINTS load command will produce a
437 * "malformed object" errors. So to make the MacOS X 10.1 ld(1) produce
438 * MH_BUNDLE files that will work on MacOS X 10.0 the hints table is not
439 * produced by default for MH_BUNDLE files.
441 #ifndef RLD
442 static enum bool twolevel_namespace_hints_specified = FALSE;
443 #endif
444 __private_extern__ enum bool twolevel_namespace_hints = TRUE;
446 #ifdef DEBUG
447 __private_extern__ unsigned long debug = 0; /* link-editor debugging */
448 #endif /* DEBUG */
450 #ifdef RLD
451 /* the cleanup routine for fatal errors to remove the output file */
452 __private_extern__ void cleanup(void);
453 #else /* !defined(RLD) */
454 static void cleanup(void);
455 static void ld_exit(int exit_value);
457 /* The signal hander routine for SIGINT, SIGTERM, SIGBUS & SIGSEGV */
458 static void handler(int sig);
460 /* Static routines to help parse arguments */
461 static enum bool ispoweroftwo(unsigned long x);
462 static vm_prot_t getprot(char *prot, char **endp);
463 static enum bool check_max_init_prot(vm_prot_t maxprot, vm_prot_t initprot);
465 /* apple_version is in ld_vers.c which is created by the Makefile */
466 extern char apple_version[];
469 * main() parses the command line arguments and drives the link-edit process.
472 main(
473 int argc,
474 char *argv[],
475 char *envp[])
477 int i;
478 unsigned long j, symbols_created, objects_specified, sections_created;
479 uint32_t table_size;
480 int fd;
481 char *p, *symbol_name, *indr_symbol_name, *endp, *file_name;
482 char *filelist, *dirname, *addr, *env_seg_addr_table_name;
483 struct seg_addr_table *seg_addr_table, *seg_addr_table_entry;
484 struct segment_spec *seg_spec;
485 struct section_spec *sect_spec;
486 unsigned long align, tmp;
487 struct stat stat_buf;
488 kern_return_t r;
489 const struct arch_flag *family_arch_flag;
490 enum undefined_check_level new_undefined_flag;
491 enum multiply_defined_check_level new_multiply_defined_flag,
492 new_multiply_defined_unused_flag;
493 enum read_only_reloc_check_level new_read_only_reloc_flag;
494 enum sect_diff_reloc_check_level new_sect_diff_reloc_flag;
495 enum weak_reference_mismatches_handling new_weak_reference_mismatches;
496 enum bool is_framework;
497 char *has_suffix;
498 struct symbol_list *sp;
499 char *exported_symbols_list, *unexported_symbols_list;
500 enum bool missing_syms;
501 enum bool vflag;
502 enum bool prebinding_via_LD_PREBIND;
503 enum bool hash_instrument_specified;
504 char *ld_library_path;
506 #ifdef __MWERKS__
507 char **dummy;
508 dummy = envp;
509 #endif
511 vflag = FALSE;
512 exported_symbols_list = NULL;
513 unexported_symbols_list = NULL;
514 seg_addr_table_entry = NULL;
515 hash_instrument_specified = FALSE;
517 progname = argv[0];
518 #ifndef BINARY_COMPARE
519 host_pagesize = 0x2000;
520 #else
521 host_pagesize = getpagesize();
522 #endif
523 host_byte_sex = get_host_byte_sex();
525 if(argc == 1)
526 fatal("Usage: %s [options] file [...]", progname);
529 * If interrupt and termination signal are not being ignored catch
530 * them so things can be cleaned up.
532 if(signal(SIGINT, SIG_IGN) != SIG_IGN)
533 signal(SIGINT, handler);
534 if(signal(SIGTERM, SIG_IGN) != SIG_IGN)
535 signal(SIGTERM, handler);
536 if(signal(SIGBUS, SIG_IGN) != SIG_IGN)
537 signal(SIGBUS, handler);
538 if(signal(SIGSEGV, SIG_IGN) != SIG_IGN)
539 signal(SIGSEGV, handler);
541 /* This needs to be here so that we test the environment variable before
542 the rest of options parsing. */
543 if (getenv("LD_PRINT_OPTIONS") != NULL)
544 ld_print_options = TRUE;
547 * Parse the command line options in this pass and skip the object files
548 * and symbol creation flags in this pass. This will make sure optionsd
549 * like -Ldir are not position dependent relative to -lx options (the
550 * same for -ysymbol relative to object files, etc).
552 for(i = 1 ; i < argc ; i++){
553 if(*argv[i] != '-'){
554 /* object file argv[i] processed in the next pass of
555 parsing arguments */
556 continue;
558 else{
559 if (ld_print_options == TRUE)
560 print("[Logging ld options]\t%s\n", argv[i]);
562 p = &(argv[i][1]);
563 switch(*p){
564 case 'l':
565 if(p[1] == '\0')
566 fatal("-l: argument missing");
567 /* path searched abbrevated file name, processed in the
568 next pass of parsing arguments */
569 break;
571 /* Flags effecting search path of -lx arguments */
572 case 'L':
573 if(p[1] == '\0')
574 fatal("-L: directory name missing");
575 /* add a pathname to the list of search paths */
576 search_dirs = reallocate(search_dirs,
577 (nsearch_dirs + 1) * sizeof(char *));
578 search_dirs[nsearch_dirs++] = &(p[1]);
579 if(stat(&(p[1]), &stat_buf) == -1)
580 warning("-L: directory name (%s) does not exist",
581 &(p[1]));
582 break;
583 case 'Z':
584 if(p[1] != '\0')
585 goto unknown_flag;
586 /* do not use the standard search path */
587 standard_dirs[0] = NULL;
588 standard_framework_dirs[0] = NULL;
589 break;
591 /* File format flags */
592 case 'M':
593 if(strcmp(p, "Mach") == 0){
594 if(filetype_specified == TRUE && filetype != MH_EXECUTE)
595 fatal("more than one output filetype specified");
596 filetype_specified = TRUE;
597 filetype = MH_EXECUTE;
599 else if(strcmp(p, "M") == 0){
600 /* produce load map */
601 load_map = TRUE;
603 else
604 goto unknown_flag;
605 break;
606 case 'p':
607 if(strcmp(p, "preload") == 0 || p[1] == '\0'){
608 if(filetype_specified == TRUE && filetype != MH_PRELOAD)
609 fatal("more than one output filetype specified");
610 filetype_specified = TRUE;
611 filetype = MH_PRELOAD;
613 else if(strcmp(p, "pagezero_size") == 0){
614 if(i + 1 >= argc)
615 fatal("-pagezero_size: argument missing");
616 if(pagezero_size != 0)
617 fatal("-pagezero_size: multiply specified");
618 pagezero_size = strtoul(argv[i+1], &endp, 16);
619 if(*endp != '\0')
620 fatal("size for -pagezero_size %s not a proper "
621 "hexadecimal number", argv[i+1]);
622 if(pagezero_size == 0)
623 fatal("size for -pagezero_size %s must not be zero",
624 argv[i+1]);
625 i += 1;
627 else if(strcmp(p, "prebind") == 0){
628 if(prebinding_flag_specified == TRUE &&
629 prebinding == FALSE)
630 fatal("both -prebind and -noprebind can't "
631 "be specified");
632 prebinding_flag_specified = TRUE;
633 prebinding = TRUE;
635 else if(strcmp(p, "prebind_allow_overlap") == 0){
636 prebind_allow_overlap = TRUE;
638 else if(strcmp(p, "prebind_all_twolevel_modules") == 0){
639 if(prebind_all_twolevel_modules_specified == TRUE &&
640 prebind_all_twolevel_modules == FALSE)
641 fatal("both -prebind_all_twolevel_modules and "
642 "-noprebind_all_twolevel_modules can't be "
643 "specified");
644 prebind_all_twolevel_modules = TRUE;
645 prebind_all_twolevel_modules_specified = TRUE;
647 else if(strcmp(p, "private_bundle") == 0){
648 private_bundle = TRUE;
650 else
651 goto unknown_flag;
652 break;
653 case 'f':
654 if(p[1] == '\0')
655 fatal("use of old flag -f (old version of mkshlib(1) "
656 "will not work with this version of ld(1))");
657 else if(strcmp(p, "fvmlib") == 0){
658 if(filetype_specified == TRUE && filetype != MH_FVMLIB)
659 fatal("more than one output filetype specified");
660 filetype_specified = TRUE;
661 filetype = MH_FVMLIB;
663 else if(strcmp(p, "force_cpusubtype_ALL") == 0){
664 force_cpusubtype_ALL = TRUE;
666 else if(strcmp(p, "framework") == 0){
667 if(i + 1 >= argc)
668 fatal("-framework: argument missing");
669 /* path searched abbrevated framework name, processed
670 in the next pass of parsing arguments */
671 i += 1;
673 else if(strcmp(p, "filelist") == 0){
674 if(i + 1 >= argc)
675 fatal("-filelist: argument missing");
676 /* filelist of object names, processed
677 in the next pass of parsing arguments */
678 i += 1;
680 else if(strcmp(p, "flat_namespace") == 0){
681 if(namespace_specified == TRUE &&
682 twolevel_namespace == TRUE)
683 fatal("can't specify both -flat_namespace and "
684 "-twolevel_namespace");
685 namespace_specified = TRUE;
686 twolevel_namespace = FALSE;
688 else if(strcmp(p, "force_flat_namespace") == 0){
689 if(namespace_specified == TRUE &&
690 twolevel_namespace == TRUE)
691 fatal("can't specify both -force_flat_namespace "
692 "and -twolevel_namespace");
693 force_flat_namespace = TRUE;
694 twolevel_namespace = FALSE;
696 else if(strcmp(p, "final_output") == 0){
697 if(i + 1 >= argc)
698 fatal("-final_output: argument missing");
699 if(final_output != NULL)
700 fatal("-final_output multiply specified");
701 final_output = argv[i+1];
702 i += 1;
704 else
705 goto unknown_flag;
706 break;
708 case 'F':
709 if(p[1] == '\0')
710 fatal("-F: directory name missing");
711 /* add a pathname to the list of framework search paths */
712 framework_dirs = reallocate(framework_dirs,
713 (nframework_dirs + 1) * sizeof(char *));
714 framework_dirs[nframework_dirs++] = &(p[1]);
715 if(stat(&(p[1]), &stat_buf) == -1)
716 warning("-F: directory name (%s) does not exist",
717 &(p[1]));
718 break;
720 case 'r':
721 if(strcmp(p, "read_only_relocs") == 0){
722 if(++i >= argc)
723 fatal("-read_only_relocs: argument missing");
724 if(strcmp(argv[i], "error") == 0)
725 new_read_only_reloc_flag = READ_ONLY_RELOC_ERROR;
726 else if(strcmp(argv[i], "warning") == 0)
727 new_read_only_reloc_flag = READ_ONLY_RELOC_WARNING;
728 else if(strcmp(argv[i], "suppress") == 0)
729 new_read_only_reloc_flag = READ_ONLY_RELOC_SUPPRESS;
730 else{
731 fatal("-read_only_relocs: unknown argument: %s",
732 argv[i]);
733 new_read_only_reloc_flag = READ_ONLY_RELOC_ERROR;
735 if(read_only_reloc_flag_specified == TRUE &&
736 new_read_only_reloc_flag != read_only_reloc_flag)
737 fatal("more than one value specified for "
738 "-read_only_relocs");
739 read_only_reloc_flag_specified = TRUE;
740 read_only_reloc_flag = new_read_only_reloc_flag;
741 break;
743 else if(strcmp(p, "run_init_lazily") == 0){
744 warning("-run_init_lazily is obsolete");
745 break;
747 if(p[1] != '\0')
748 goto unknown_flag;
749 /* save relocation information, and produce a relocatable
750 object */
751 save_reloc = TRUE;
752 if(filetype_specified == FALSE)
753 filetype = MH_OBJECT;
754 if(dflag_specified == FALSE)
755 define_comldsyms = FALSE;
756 break;
757 case 'A':
758 if(p[1] != '\0')
759 goto unknown_flag;
760 if(++i >= argc)
761 fatal("-A: argument missing");
762 /* object file argv[i] processed in the next pass of
763 parsing arguments */
764 Aflag_specified = TRUE;
765 break;
766 case 'd':
767 if(strcmp(p, "d") == 0){
768 /* define common symbols and loader defined symbols
769 reguardless of file format */
770 dflag_specified = TRUE;
771 define_comldsyms = TRUE;
773 else if(strcmp(p, "dynamic") == 0){
774 if(static_specified)
775 fatal("only one of -dynamic or -static can be "
776 "specified");
778 dynamic = TRUE;
779 dynamic_specified = TRUE;
781 else if(strcmp(p, "dylib") == 0){
782 if(filetype_specified == TRUE && filetype != MH_DYLIB)
783 fatal("more than one output filetype specified");
784 filetype_specified = TRUE;
785 filetype = MH_DYLIB;
786 output_for_dyld = TRUE;
788 else if(strcmp(p, "dylib_install_name") == 0){
789 if(i + 1 >= argc)
790 fatal("-dylib_install_name: argument missing");
791 dylib_install_name = argv[i + 1];
792 i += 1;
794 else if(strcmp(p, "dylib_current_version") == 0){
795 if(i + 1 >= argc)
796 fatal("-dylib_current_version: argument missing");
797 if(get_version_number("-dylib_current_version",
798 argv[i+1], &dylib_current_version) == FALSE)
799 cleanup();
800 if(dylib_current_version == 0)
801 fatal("-dylib_current_version must be greater than "
802 "zero");
803 i += 1;
805 else if(strcmp(p, "dylib_compatibility_version") == 0){
806 if(i + 1 >= argc)
807 fatal("-dylib_compatibility_version: argument "
808 "missing");
809 if(get_version_number("-dylib_compatibility_version",
810 argv[i+1], &dylib_compatibility_version) == FALSE)
811 cleanup();
812 if(dylib_compatibility_version == 0)
813 fatal("-dylib_compatibility_version must be "
814 "greater than zero");
815 i += 1;
817 else if(strcmp(p, "dylib_file") == 0){
818 if(++i >= argc)
819 fatal("-dylib_file: argument missing");
820 file_name = strchr(argv[i], ':');
821 if(file_name == NULL ||
822 file_name[1] == '\0' || argv[i][0] == ':')
823 fatal("-dylib_file argument: %s must have a ':' "
824 "between its file names", argv[i]);
825 dylib_files = reallocate(dylib_files,
826 (ndylib_files + 1) * sizeof(char *));
827 dylib_files[ndylib_files++] = argv[i];
829 else if(strcmp(p, "dylinker") == 0){
830 if(filetype_specified == TRUE &&
831 filetype != MH_DYLINKER)
832 fatal("more than one output filetype specified");
833 filetype_specified = TRUE;
834 filetype = MH_DYLINKER;
835 output_for_dyld = TRUE;
837 else if(strcmp(p, "dylinker_install_name") == 0){
838 if(i + 1 >= argc)
839 fatal("-dylinker_install_name: argument missing");
840 if(dylinker_install_name != NULL)
841 fatal("-dylinker_install_name multiply specified");
842 dylinker_install_name = argv[i + 1];
843 i += 1;
845 else if(strcmp(p, "dead_strip") == 0){
846 dead_strip = TRUE;
848 else if(strcmp(p, "dead_strip_times") == 0){
849 dead_strip_times = TRUE;
851 #ifdef DEBUG
852 else if(strcmp(p, "debug") == 0){
853 if(++i >= argc)
854 fatal("-debug: argument missing");
855 debug |= 1 << strtoul(argv[i], &endp, 10);
856 if(*endp != '\0' || strtoul(argv[i], &endp, 10) > 32)
857 fatal("argument for -debug %s not a proper "
858 "decimal number less than 32", argv[i]);
860 #endif /* DEBUG */
861 else
862 goto unknown_flag;
863 break;
865 case 'n':
866 if(strcmp(p, "noflush") == 0){
867 flush = FALSE;
869 else if(strcmp(p, "nofixprebinding") == 0){
870 no_fix_prebinding = TRUE;
872 else if(strcmp(p, "no_arch_warnings") == 0){
873 no_arch_warnings = TRUE;
875 else if(strcmp(p, "noseglinkedit") == 0){
876 if(seglinkedit_specified && seglinkedit == TRUE)
877 fatal("both -seglinkedit and -noseglinkedit can't "
878 "be specified");
879 seglinkedit = FALSE;
880 seglinkedit_specified = TRUE;
882 else if(strcmp(p, "noprebind") == 0){
883 if(prebinding_flag_specified == TRUE &&
884 prebinding == TRUE)
885 fatal("both -prebind and -noprebind can't "
886 "be specified");
887 prebinding_flag_specified = TRUE;
888 prebinding = FALSE;
890 else if(strcmp(p, "nomultidefs") == 0){
891 nomultidefs = TRUE;
893 else if(strcmp(p, "noprebind_all_twolevel_modules") == 0){
894 if(prebind_all_twolevel_modules_specified == TRUE &&
895 prebind_all_twolevel_modules == TRUE)
896 fatal("both -prebind_all_twolevel_modules and "
897 "-noprebind_all_twolevel_modules can't be "
898 "specified");
899 prebind_all_twolevel_modules = FALSE;
900 prebind_all_twolevel_modules_specified = TRUE;
902 else if(strcmp(p, "no_dead_strip_inits_and_terms") == 0){
903 no_dead_strip_inits_and_terms = TRUE;
905 else if(strcmp(p, "no_uuid") == 0){
906 output_uuid_info.suppress = TRUE;
908 else if(strcmp(p, "noall_load") == 0){
909 /* Ignore the flag. */
912 else
913 goto unknown_flag;
914 break;
916 case 'b':
917 if(strcmp(p, "bundle") == 0){
918 if(filetype_specified == TRUE && filetype != MH_BUNDLE)
919 fatal("more than one output filetype specified");
920 filetype_specified = TRUE;
921 filetype = MH_BUNDLE;
922 output_for_dyld = TRUE;
924 else if(strcmp(p, "bind_at_load") == 0){
925 bind_at_load = TRUE;
927 else if(strcmp(p, "bundle_loader") == 0){
928 if(i + 1 >= argc)
929 fatal("-bundle_loader: argument missing");
930 if(bundle_loader != NULL)
931 fatal("-bundle_loader multiply specified");
932 bundle_loader = argv[i + 1];
933 i += 1;
935 /* Strip the base file symbols (the -A argument's symbols)*/
936 else if(p[1] == '\0')
937 strip_base_symbols = TRUE;
938 else
939 goto unknown_flag;
940 break;
943 * Stripping level flags, in increasing level of stripping. The
944 * level of stripping is set to the maximum level specified.
946 case 'X':
947 if(p[1] != '\0')
948 goto unknown_flag;
949 if(strip_level < STRIP_L_SYMBOLS)
950 strip_level = STRIP_L_SYMBOLS;
951 break;
952 case 'S':
953 if(strcmp(p, "Sn") == 0){
954 strip_level = STRIP_NONE;
956 else if(strcmp(p, "Si") == 0){
957 if(strip_level < STRIP_DUP_INCLS)
958 strip_level = STRIP_DUP_INCLS;
960 else if(strcmp(p, "Sp") == 0){
961 if(strip_level < STRIP_MIN_DEBUG)
962 strip_level = STRIP_MIN_DEBUG;
964 else if(p[1] == '\0'){
965 if(strip_level < STRIP_DEBUG)
966 strip_level = STRIP_DEBUG;
968 else{
969 goto unknown_flag;
971 break;
972 case 'x':
973 if(p[1] != '\0')
974 goto unknown_flag;
975 if(strip_level < STRIP_NONGLOBALS)
976 strip_level = STRIP_NONGLOBALS;
977 break;
978 case 's':
979 if(strcmp(p, "s") == 0){
980 strip_level = STRIP_ALL;
982 else if(strcmp(p, "static") == 0){
983 if(dynamic_specified)
984 fatal("only one of -static or -dynamic can be "
985 "specified");
986 dynamic = FALSE;
987 static_specified = TRUE;
988 twolevel_namespace = FALSE;
990 else if(strcmp(p, "search_paths_first") == 0){
991 search_paths_first = TRUE;
994 * Flags for specifing information about sections.
996 /* create a section from the contents of a file
997 -sectcreate <segname> <sectname> <filename> */
998 else if(strcmp(p, "sectcreate") == 0 ||
999 strcmp(p, "segcreate") == 0){ /* the old name */
1000 if(i + 3 >= argc)
1001 fatal("%s: arguments missing", argv[i]);
1002 seg_spec = create_segment_spec(argv[i+1]);
1003 sect_spec = create_section_spec(seg_spec, argv[i+2]);
1004 if(sect_spec->contents_filename != NULL)
1005 fatal("section (%s,%s) multiply specified with a "
1006 "%s option", argv[i+1], argv[i+2], argv[i]);
1007 if((fd = open(argv[i+3], O_RDONLY, 0)) == -1)
1008 system_fatal("Can't open: %s for %s %s %s",
1009 argv[i+3], argv[i], argv[i+1], argv[i+2]);
1010 if(fstat(fd, &stat_buf) == -1)
1011 system_fatal("Can't stat file: %s for %s %s %s",
1012 argv[i+3], argv[i], argv[i+1], argv[i+2]);
1014 * For some reason mapping files with zero size fails
1015 * so it has to be handled specially.
1017 if(stat_buf.st_size != 0){
1018 if((r = map_fd((int)fd, (vm_offset_t)0,
1019 (vm_offset_t *)&(sect_spec->file_addr),
1020 (boolean_t)TRUE, (vm_size_t)stat_buf.st_size)
1021 ) != KERN_SUCCESS)
1022 mach_fatal(r, "can't map file: %s for %s %s %s",
1023 argv[i+3], argv[i], argv[i+1], argv[i+2]);
1025 else{
1026 sect_spec->file_addr = NULL;
1028 close(fd);
1029 sect_spec->file_size = stat_buf.st_size;
1030 sect_spec->contents_filename = argv[i+3];
1031 i += 3;
1033 /* specify the alignment of a section as a hexadecimal
1034 power of 2
1035 -sectalign <segname> <sectname> <number> */
1036 else if(strcmp(p, "sectalign") == 0){
1037 if(i + 3 >= argc)
1038 fatal("-sectalign arguments missing");
1039 seg_spec = create_segment_spec(argv[i+1]);
1040 sect_spec = create_section_spec(seg_spec, argv[i+2]);
1041 if(sect_spec->align_specified)
1042 fatal("alignment for section (%s,%s) multiply "
1043 "specified", argv[i+1], argv[i+2]);
1044 sect_spec->align_specified = TRUE;
1045 align = strtoul(argv[i+3], &endp, 16);
1046 if(*endp != '\0')
1047 fatal("argument for -sectalign %s %s: %s not a "
1048 "proper hexadecimal number", argv[i+1],
1049 argv[i+2], argv[i+3]);
1050 if(!ispoweroftwo(align))
1051 fatal("argument to -sectalign %s %s: %lx (hex) must"
1052 " be a power of two", argv[i+1], argv[i+2],
1053 align);
1054 if(align != 0)
1055 for(tmp = align; (tmp & 1) == 0; tmp >>= 1)
1056 sect_spec->align++;
1057 if(sect_spec->align > MAXSECTALIGN)
1058 fatal("argument to -sectalign %s %s: %lx (hex) must"
1059 " equal to or less than %x (hex)", argv[i+1],
1060 argv[i+2], align,
1061 (unsigned int)(1 << MAXSECTALIGN));
1062 i += 3;
1064 /* specify that section object symbols are to be created
1065 for the specified section
1066 -sectobjectsymbols <segname> <sectname> */
1067 else if(strcmp(p, "sectobjectsymbols") == 0){
1068 if(i + 2 >= argc)
1069 fatal("-sectobjectsymbols arguments missing");
1070 if(sect_object_symbols.specified &&
1071 (strcmp(sect_object_symbols.segname,
1072 argv[i+1]) != 0 ||
1073 strcmp(sect_object_symbols.sectname,
1074 argv[i+2]) != 0) )
1075 fatal("-sectobjectsymbols multiply specified (it "
1076 "can only be specified for one section)");
1077 sect_object_symbols.specified = TRUE;
1078 sect_object_symbols.segname = argv[i+1];
1079 sect_object_symbols.sectname = argv[i+2];
1080 i += 2;
1082 /* layout a section in the order the symbols appear in file
1083 -sectorder <segname> <sectname> <filename> */
1084 else if(strcmp(p, "sectorder") == 0){
1085 if(i + 3 >= argc)
1086 fatal("%s: arguments missing", argv[i]);
1087 seg_spec = create_segment_spec(argv[i+1]);
1088 sect_spec = create_section_spec(seg_spec, argv[i+2]);
1089 if(sect_spec->order_filename != NULL)
1090 fatal("section (%s,%s) multiply specified with a "
1091 "%s option", argv[i+1], argv[i+2], argv[i]);
1092 if((fd = open(argv[i+3], O_RDONLY, 0)) == -1)
1093 system_fatal("Can't open: %s for %s %s %s",
1094 argv[i+3], argv[i], argv[i+1], argv[i+2]);
1095 if(fstat(fd, &stat_buf) == -1)
1096 system_fatal("Can't stat file: %s for %s %s %s",
1097 argv[i+3], argv[i], argv[i+1], argv[i+2]);
1099 * For some reason mapping files with zero size fails
1100 * so it has to be handled specially.
1102 if(stat_buf.st_size != 0){
1103 if((r = map_fd((int)fd, (vm_offset_t)0,
1104 (vm_offset_t *)&(sect_spec->order_addr),
1105 (boolean_t)TRUE, (vm_size_t)stat_buf.st_size)
1106 ) != KERN_SUCCESS)
1107 mach_fatal(r, "can't map file: %s for %s %s %s",
1108 argv[i+3], argv[i], argv[i+1], argv[i+2]);
1110 else{
1111 sect_spec->order_addr = NULL;
1113 close(fd);
1114 sect_spec->order_size = stat_buf.st_size;
1115 sect_spec->order_filename = argv[i+3];
1116 i += 3;
1118 else if(strcmp(p, "sectorder_detail") == 0){
1119 sectorder_detail = TRUE;
1121 else if(strcmp(p, "sect_diff_relocs") == 0){
1122 if(++i >= argc)
1123 fatal("-sect_diff_relocs: argument missing");
1124 if(strcmp(argv[i], "error") == 0)
1125 new_sect_diff_reloc_flag = SECT_DIFF_RELOC_ERROR;
1126 else if(strcmp(argv[i], "warning") == 0)
1127 new_sect_diff_reloc_flag = SECT_DIFF_RELOC_WARNING;
1128 else if(strcmp(argv[i], "suppress") == 0)
1129 new_sect_diff_reloc_flag = SECT_DIFF_RELOC_SUPPRESS;
1130 else{
1131 fatal("-sect_diff_relocs: unknown argument: %s",
1132 argv[i]);
1133 new_sect_diff_reloc_flag = SECT_DIFF_RELOC_SUPPRESS;
1135 if(sect_diff_reloc_flag_specified == TRUE &&
1136 new_sect_diff_reloc_flag != sect_diff_reloc_flag)
1137 fatal("more than one value specified for "
1138 "-sect_diff_relocs");
1139 sect_diff_reloc_flag_specified = TRUE;
1140 sect_diff_reloc_flag = new_sect_diff_reloc_flag;
1141 break;
1144 * Flags for specifing information about segments.
1146 /* specify the address (in hex) of a segment
1147 -segaddr <segname> <address> */
1148 else if(strcmp(p, "segaddr") == 0){
1149 if(i + 2 >= argc)
1150 fatal("-segaddr: arguments missing");
1151 seg_spec = create_segment_spec(argv[i+1]);
1152 if(seg_spec->addr_specified == TRUE)
1153 fatal("address of segment %s multiply specified",
1154 argv[i+1]);
1155 segaddr_specified = TRUE;
1156 seg_spec->addr_specified = TRUE;
1157 seg_spec->addr = strtoul(argv[i+2], &endp, 16);
1158 if(*endp != '\0')
1159 fatal("address for -segaddr %s %s not a proper "
1160 "hexadecimal number", argv[i+1], argv[i+2]);
1161 i += 2;
1163 /* specify the protection for a segment
1164 -segprot <segname> <maxprot> <initprot>
1165 where the protections are specified with "rwx" with a
1166 "-" for no protection. */
1167 else if(strcmp(p, "segprot") == 0){
1168 if(i + 3 >= argc)
1169 fatal("-segprot: arguments missing");
1170 seg_spec = create_segment_spec(argv[i+1]);
1171 if(seg_spec->prot_specified == TRUE)
1172 fatal("protection of segment %s multiply "
1173 "specified", argv[i]);
1174 seg_spec->maxprot = getprot(argv[i+2], &endp);
1175 if(*endp != '\0')
1176 fatal("bad character: '%c' in maximum protection: "
1177 "%s for segment %s", *endp, argv[i+2],
1178 argv[i+1]);
1179 seg_spec->initprot = getprot(argv[i+3], &endp);
1180 if(*endp != '\0')
1181 fatal("bad character: '%c' in initial protection: "
1182 "%s for segment %s", *endp, argv[i+3],
1183 argv[i+1]);
1184 if(check_max_init_prot(seg_spec->maxprot,
1185 seg_spec->initprot) == FALSE)
1186 fatal("maximum protection: %s for segment: %s "
1187 "doesn't include all initial protections: %s",
1188 argv[i+2], argv[i+1], argv[i+3]);
1189 seg_spec->prot_specified = TRUE;
1190 i += 3;
1192 /* specify the address (in hex) of the first segment
1193 -seg1addr <address> */
1194 else if(strcmp(p, "seg1addr") == 0){
1195 if(i + 1 >= argc)
1196 fatal("%s: argument missing", argv[i]);
1197 if(seg1addr_specified == TRUE)
1198 fatal("%s: multiply specified", argv[i]);
1199 seg1addr = strtoul(argv[i+1], &endp, 16);
1200 if(*endp != '\0')
1201 fatal("address for %s %s not a proper "
1202 "hexadecimal number", argv[i], argv[i+1]);
1203 seg1addr_specified = TRUE;
1204 i += 1;
1206 /* specify the address (in hex) of the read-only segments
1207 -segs_read_only_addr <address> */
1208 else if(strcmp(p, "segs_read_only_addr") == 0){
1209 if(i + 1 >= argc)
1210 fatal("%s: argument missing", argv[i]);
1211 if(segs_read_only_addr_specified == TRUE)
1212 fatal("%s: multiply specified", argv[i]);
1213 segs_read_only_addr = strtoul(argv[i+1], &endp, 16);
1214 if(*endp != '\0')
1215 fatal("address for %s %s not a proper "
1216 "hexadecimal number", argv[i], argv[i+1]);
1217 segs_read_only_addr_specified = TRUE;
1218 i += 1;
1220 /* specify the address (in hex) of the read-write segments
1221 -segs_read_write_addr <address> */
1222 else if(strcmp(p, "segs_read_write_addr") == 0){
1223 if(i + 1 >= argc)
1224 fatal("%s: argument missing", argv[i]);
1225 if(segs_read_write_addr_specified == TRUE)
1226 fatal("%s: multiply specified", argv[i]);
1227 segs_read_write_addr = strtoul(argv[i+1], &endp, 16);
1228 if(*endp != '\0')
1229 fatal("address for %s %s not a proper "
1230 "hexadecimal number", argv[i], argv[i+1]);
1231 segs_read_write_addr_specified = TRUE;
1232 i += 1;
1234 /* specify the name of the segment address table */
1235 else if(strcmp(p, "seg_addr_table") == 0){
1236 if(i + 1 >= argc)
1237 fatal("%s: argument missing", argv[i]);
1238 if(seg_addr_table_name != NULL)
1239 fatal("%s: multiply specified", argv[i]);
1240 seg_addr_table_name = argv[i+1];
1241 i += 1;
1243 /* specify the file system path name to be used instead of
1244 the install name in the segment address table */
1245 else if(strcmp(p, "seg_addr_table_filename") == 0){
1246 if(i + 1 >= argc)
1247 fatal("%s: argument missing", argv[i]);
1248 if(seg_addr_table_filename != NULL)
1249 fatal("%s: multiply specified", argv[i]);
1250 seg_addr_table_filename = argv[i+1];
1251 i += 1;
1253 /* specify the segment alignment as a hexadecimal power of 2
1254 -segalign <number> */
1255 else if(strcmp(p, "segalign") == 0){
1256 if(segalign_specified)
1257 fatal("-segalign: multiply specified");
1258 if(++i >= argc)
1259 fatal("-segalign: argument missing");
1260 segalign = strtoul(argv[i], &endp, 16);
1261 if(*endp != '\0')
1262 fatal("argument for -segalign %s not a proper "
1263 "hexadecimal number", argv[i]);
1264 if(!ispoweroftwo(segalign) || segalign == 0)
1265 fatal("argument to -segalign: %lx (hex) must be a "
1266 "non-zero power of two", segalign);
1267 if(segalign > MAXSEGALIGN)
1268 fatal("argument to -segalign: %lx (hex) must equal "
1269 "to or less than %x (hex)", segalign,
1270 (unsigned int)MAXSEGALIGN);
1271 segalign_specified = TRUE;
1272 if(segalign < (1 << DEFAULTSECTALIGN)){
1273 defaultsectalign = 0;
1274 align = segalign;
1275 while((align & 0x1) != 1){
1276 defaultsectalign++;
1277 align >>= 1;
1281 else if(strcmp(p, "seglinkedit") == 0){
1282 if(seglinkedit_specified && seglinkedit == FALSE)
1283 fatal("both -seglinkedit and -noseglinkedit can't "
1284 "be specified");
1285 seglinkedit = TRUE;
1286 seglinkedit_specified = TRUE;
1288 /* specify the stack address as a hexadecimal number
1289 -stack_addr <address> */
1290 else if(strcmp(p, "stack_addr") == 0){
1291 if(i + 1 >= argc)
1292 fatal("%s: argument missing", argv[i]);
1293 if(stack_addr_specified == TRUE)
1294 fatal("%s: multiply specified", argv[i]);
1295 stack_addr = strtoul(argv[i+1], &endp, 16);
1296 if(*endp != '\0')
1297 fatal("address for %s %s not a proper "
1298 "hexadecimal number", argv[i], argv[i+1]);
1299 stack_addr_specified = TRUE;
1300 i += 1;
1302 /* specify the stack size as a hexadecimal number
1303 -stack_size <address> */
1304 else if(strcmp(p, "stack_size") == 0){
1305 if(i + 1 >= argc)
1306 fatal("%s: argument missing", argv[i]);
1307 if(stack_size_specified == TRUE)
1308 fatal("%s: multiply specified", argv[i]);
1309 stack_size = strtoul(argv[i+1], &endp, 16);
1310 if(*endp != '\0')
1311 fatal("address for %s %s not a proper "
1312 "hexadecimal number", argv[i], argv[i+1]);
1313 stack_size_specified = TRUE;
1314 i += 1;
1316 /* specify a sub_umbrella
1317 -sub_umbrella <name> */
1318 else if(strcmp(p, "sub_umbrella") == 0){
1319 if(i + 1 >= argc)
1320 fatal("%s: argument missing", argv[i]);
1321 sub_umbrellas = reallocate(sub_umbrellas,
1322 (nsub_umbrellas + 1) * sizeof(char *));
1323 sub_umbrellas[nsub_umbrellas++] = argv[i+1];
1324 i += 1;
1326 /* specify a sub_library
1327 -sub_library <name> */
1328 else if(strcmp(p, "sub_library") == 0){
1329 if(i + 1 >= argc)
1330 fatal("%s: argument missing", argv[i]);
1331 sub_librarys = reallocate(sub_librarys,
1332 (nsub_librarys + 1) * sizeof(char *));
1333 sub_librarys[nsub_librarys++] = argv[i+1];
1334 i += 1;
1336 /* -single_module for MH_DYLIB output */
1337 else if(strcmp(p, "single_module") == 0){
1338 if(moduletype_specified == TRUE &&
1339 multi_module_dylib == TRUE)
1340 fatal("can't specify both -single_module and "
1341 "-multi_module");
1342 moduletype_specified = TRUE;
1343 multi_module_dylib = FALSE;
1345 else if(strcmp(p, "syslibroot") == 0){
1346 if(i + 1 >= argc)
1347 fatal("%s: argument missing", argv[i]);
1348 if(syslibroot_specified == TRUE && strcmp(next_root, argv[i+1]) != 0)
1349 fatal("%s: multiply specified", argv[i]);
1350 next_root = argv[i+1];
1351 syslibroot_specified = TRUE;
1352 i += 1;
1354 else
1355 goto unknown_flag;
1356 break;
1358 case 't':
1359 /* trace flag */
1360 if(strcmp(p, "twolevel_namespace") == 0){
1361 if(namespace_specified == TRUE &&
1362 twolevel_namespace == FALSE)
1363 fatal("can't specify both -twolevel_namespace and "
1364 "-flat_namespace");
1365 namespace_specified = TRUE;
1366 twolevel_namespace = TRUE;
1368 else if(strcmp(p, "twolevel_namespace_hints") == 0){
1369 if(namespace_specified == TRUE &&
1370 twolevel_namespace == FALSE)
1371 fatal("can't specify both -twolevel_namespace_hints"
1372 " and -flat_namespace");
1373 twolevel_namespace_hints_specified = TRUE;
1375 else if(p[1] == '\0')
1376 trace = TRUE;
1377 else
1378 goto unknown_flag;
1379 break;
1381 case 'o':
1382 if(strcmp(p, "object") == 0){
1383 if(filetype_specified == TRUE && filetype != MH_OBJECT)
1384 fatal("more than one output filetype specified");
1385 filetype_specified = TRUE;
1386 filetype = MH_OBJECT;
1387 break;
1389 /* specify the output file name */
1390 if(p[1] != '\0')
1391 goto unknown_flag;
1392 if(outputfile != NULL)
1393 fatal("-o: multiply specified");
1394 if(++i >= argc)
1395 fatal("-o: argument missing");
1396 outputfile = argv[i];
1397 break;
1399 case 'a':
1400 if(strcmp(p, "all_load") == 0)
1401 archive_all = TRUE;
1402 else if(strcmp(p, "arch_multiple") == 0)
1403 arch_multiple = TRUE;
1404 else if(strcmp(p, "arch_errors_fatal") == 0)
1405 arch_errors_fatal = TRUE;
1406 else if(strcmp(p, "allow_stack_execute") == 0)
1407 allow_stack_execute = TRUE;
1408 else if(strcmp(p, "arch") == 0){
1409 if(++i >= argc)
1410 fatal("-arch: argument missing");
1411 if(arch_flag.name != NULL &&
1412 strcmp(arch_flag.name, argv[i]) != 0)
1413 fatal("-arch: multiply specified");
1414 if(get_arch_from_flag(argv[i], &arch_flag) == 0){
1415 error("unknown architecture specification flag: "
1416 "-arch %s", argv[i]);
1417 fatal("Usage: %s [options] file [...]", progname);
1419 /* Default to -single_module on ARM. */
1420 if(arch_flag.cputype == CPU_TYPE_ARM){
1421 multi_module_dylib = FALSE;
1423 target_byte_sex = get_byte_sex_from_flag(&arch_flag);
1425 /* specify an allowable client of this subframework
1426 -allowable_client client_name */
1427 else if(strcmp(p, "allowable_client") == 0){
1428 if(i + 1 >= argc)
1429 fatal("%s: argument missing", argv[i]);
1430 allowable_clients = reallocate(allowable_clients,
1431 (nallowable_clients + 1) * sizeof(char *));
1432 allowable_clients[nallowable_clients++] = argv[i+1];
1433 i += 1;
1434 break;
1436 else
1437 goto unknown_flag;
1438 break;
1440 case 'c':
1441 /* specify this client's name which is using a subframework
1442 -client_name client_name */
1443 if(strcmp(p, "client_name") == 0){
1444 if(i + 1 >= argc)
1445 fatal("%s: argument missing", argv[i]);
1446 if(client_name != NULL)
1447 fatal("%s: multiply specified", argv[i]);
1448 client_name = argv[i+1];
1449 i += 1;
1450 break;
1452 else if(strcmp(p, "compatibility_version") == 0){
1453 if(i + 1 >= argc)
1454 fatal("-compatibility_version: argument "
1455 "missing");
1456 if(get_version_number("-compatibility_version",
1457 argv[i+1], &dylib_compatibility_version) == FALSE)
1458 cleanup();
1459 if(dylib_compatibility_version == 0)
1460 fatal("-compatibility_version must be "
1461 "greater than zero");
1462 i += 1;
1463 break;
1465 else if(strcmp(p, "current_version") == 0){
1466 if(i + 1 >= argc)
1467 fatal("-current_version: argument missing");
1468 if(get_version_number("-current_version",
1469 argv[i+1], &dylib_current_version) == FALSE)
1470 cleanup();
1471 if(dylib_current_version == 0)
1472 fatal("-current_version must be greater than "
1473 "zero");
1474 i += 1;
1475 break;
1477 if(p[1] != '\0')
1478 goto unknown_flag;
1479 break;
1482 /* Flags dealing with symbols */
1483 case 'i':
1484 if(strcmp(p, "image_base") == 0){
1485 if(i + 1 >= argc)
1486 fatal("%s: argument missing", argv[i]);
1487 if(seg1addr_specified == TRUE)
1488 fatal("%s: argument missing", argv[i]);
1489 seg1addr = strtoul(argv[i+1], &endp, 16);
1490 if(*endp != '\0')
1491 fatal("address for %s %s not a proper "
1492 "hexadecimal number", argv[i], argv[i+1]);
1493 seg1addr_specified = TRUE;
1494 i += 1;
1496 else if(strcmp(p, "init") == 0){
1497 /* check to see if the pointer is not already set */
1498 if(init_name != NULL)
1499 fatal("-init: multiply specified");
1500 if(++i >= argc)
1501 fatal("-init: argument missing");
1502 init_name = argv[i];
1504 else if(strcmp(p, "install_name") == 0){
1505 if(i + 1 >= argc)
1506 fatal("-install_name: argument missing");
1507 dylib_install_name = argv[i + 1];
1508 i += 1;
1510 else{
1511 /* create an indirect symbol, symbol_name, to be an
1512 indirect symbol for indr_symbol_name */
1513 symbol_name = p + 1;
1514 indr_symbol_name = strchr(p + 1, ':');
1515 if(indr_symbol_name == NULL ||
1516 indr_symbol_name[1] == '\0' || *symbol_name == ':')
1517 fatal("-i argument: %s must have a ':' between "
1518 "its symbol names", p + 1);
1519 /* the creating of the symbol is done in the next pass
1520 of parsing arguments */
1522 break;
1524 case 'm':
1525 if(strcmp(p, "multiply_defined") == 0){
1526 if(++i >= argc)
1527 fatal("-multiply_defined: argument missing");
1528 if(strcmp(argv[i], "error") == 0)
1529 new_multiply_defined_flag = MULTIPLY_DEFINED_ERROR;
1530 else if(strcmp(argv[i], "warning") == 0)
1531 new_multiply_defined_flag =MULTIPLY_DEFINED_WARNING;
1532 else if(strcmp(argv[i], "suppress") == 0)
1533 new_multiply_defined_flag=MULTIPLY_DEFINED_SUPPRESS;
1534 else{
1535 fatal("-multiply_defined: unknown argument: %s",
1536 argv[i]);
1537 new_multiply_defined_flag =MULTIPLY_DEFINED_WARNING;
1539 if(multiply_defined_flag_specified == TRUE &&
1540 new_multiply_defined_flag != multiply_defined_flag)
1541 fatal("more than one value specified for "
1542 "-multiply_defined");
1543 multiply_defined_flag_specified = TRUE;
1544 multiply_defined_flag = new_multiply_defined_flag;
1545 break;
1547 else if(strcmp(p, "multiply_defined_unused") == 0){
1548 if(++i >= argc)
1549 fatal("-multiply_defined_unused: argument missing");
1550 if(strcmp(argv[i], "error") == 0)
1551 new_multiply_defined_unused_flag =
1552 MULTIPLY_DEFINED_ERROR;
1553 else if(strcmp(argv[i], "warning") == 0)
1554 new_multiply_defined_unused_flag =
1555 MULTIPLY_DEFINED_WARNING;
1556 else if(strcmp(argv[i], "suppress") == 0)
1557 new_multiply_defined_unused_flag =
1558 MULTIPLY_DEFINED_SUPPRESS;
1559 else{
1560 fatal("-multiply_defined_unused: unknown argument: "
1561 "%s", argv[i]);
1562 new_multiply_defined_unused_flag =
1563 MULTIPLY_DEFINED_SUPPRESS;
1565 if(multiply_defined_unused_flag_specified == TRUE &&
1566 new_multiply_defined_unused_flag !=
1567 multiply_defined_unused_flag)
1568 fatal("more than one value specified for "
1569 "-multiply_defined_unused");
1570 multiply_defined_unused_flag_specified = TRUE;
1571 multiply_defined_unused_flag =
1572 new_multiply_defined_unused_flag;
1573 break;
1575 /* -multi_module for MH_DYLIB output */
1576 else if(strcmp(p, "multi_module") == 0){
1577 if(moduletype_specified == TRUE &&
1578 multi_module_dylib == FALSE)
1579 fatal("can't specify both -single_module and "
1580 "-multi_module");
1581 moduletype_specified = TRUE;
1582 multi_module_dylib = TRUE;
1583 break;
1585 /* -macosx_version_min for overriding
1586 MACOSX_DEPLOYMENT_TARGET on command line */
1587 else if(strcmp (p, "macosx_version_min") == 0){
1588 if(++i >= argc)
1589 fatal("-macosx_version_min: argument missing");
1590 put_macosx_deployment_target (argv[i]);
1591 break;
1593 /* treat multiply defined symbols as a warning not a
1594 hard error */
1595 if(p[1] != '\0')
1596 goto unknown_flag;
1597 allow_multiply_defined_symbols = TRUE;
1598 break;
1600 case 'u':
1601 if(strcmp(p, "undefined") == 0){
1602 if(++i >= argc)
1603 fatal("-undefined: argument missing");
1604 if(strcmp(argv[i], "error") == 0)
1605 new_undefined_flag = UNDEFINED_ERROR;
1606 else if(strcmp(argv[i], "warning") == 0)
1607 new_undefined_flag = UNDEFINED_WARNING;
1608 else if(strcmp(argv[i], "suppress") == 0)
1609 new_undefined_flag = UNDEFINED_SUPPRESS;
1610 else if(strcmp(argv[i], "dynamic_lookup") == 0)
1611 new_undefined_flag = UNDEFINED_DYNAMIC_LOOKUP;
1612 else if(strcmp(argv[i], "define_a_way") == 0){
1613 new_undefined_flag = UNDEFINED_DEFINE_A_WAY;
1614 warning("suggest the use of -dead_strip instead of "
1615 "-undefined define_a_way");
1617 else{
1618 fatal("-undefined: unknown argument: %s", argv[i]);
1619 new_undefined_flag = UNDEFINED_ERROR;
1621 if(undefined_flag_specified == TRUE &&
1622 new_undefined_flag != undefined_flag)
1623 fatal("more than one value specified for "
1624 "-undefined");
1625 undefined_flag_specified = TRUE;
1626 undefined_flag = new_undefined_flag;
1627 break;
1629 /* specify this dynamic library as a subframework
1630 -umbrella umbrella_framework_name */
1631 else if(strcmp(p, "umbrella") == 0){
1632 if(i + 1 >= argc)
1633 fatal("%s: argument missing", argv[i]);
1634 if(sub_framework == TRUE)
1635 fatal("%s: multiply specified", argv[i]);
1636 umbrella_framework_name = argv[i+1];
1637 sub_framework = TRUE;
1638 i += 1;
1639 break;
1641 else if(strcmp(p, "unexported_symbols_list") == 0){
1642 if(i + 1 >= argc)
1643 fatal("%s: argument missing", argv[i]);
1644 if(remove_symbols != NULL)
1645 fatal("%s: multiply specified", argv[i]);
1646 setup_symbol_list(argv[i+1], &remove_symbols,
1647 &nremove_symbols);
1648 unexported_symbols_list = argv[i+1];
1649 i += 1;
1650 break;
1652 if(p[1] != '\0')
1653 goto unknown_flag;
1654 /* cause the specified symbol name to be undefined */
1655 if(++i >= argc)
1656 fatal("-u: argument missing");
1657 /* the creating of the symbol is done in the next pass of
1658 parsing arguments */
1659 break;
1661 case 'e':
1662 if(strcmp(p, "execute") == 0){
1663 if(filetype_specified == TRUE && filetype != MH_EXECUTE)
1664 fatal("more than one output filetype specified");
1665 filetype_specified = TRUE;
1666 filetype = MH_EXECUTE;
1667 break;
1669 else if(strcmp(p, "exported_symbols_list") == 0){
1670 if(i + 1 >= argc)
1671 fatal("%s: argument missing", argv[i]);
1672 if(save_symbols != NULL)
1673 fatal("%s: multiply specified", argv[i]);
1674 setup_symbol_list(argv[i+1], &save_symbols,
1675 &nsave_symbols);
1676 exported_symbols_list = argv[i+1];
1677 i += 1;
1678 break;
1680 else if(strcmp(p, "executable_path") == 0){
1681 if(i + 1 >= argc)
1682 fatal("%s: argument missing", argv[i]);
1683 if(executable_path != NULL)
1684 fatal("%s: multiply specified", argv[i]);
1685 executable_path = argv[i+1];
1686 i += 1;
1687 break;
1689 /* specify the entry point, the symbol who's value to be
1690 used as the program counter in the unix thread */
1691 if(p[1] != '\0')
1692 goto unknown_flag;
1693 /* check to see if the pointer is not already set */
1694 if(entry_point_name != NULL)
1695 fatal("-e: multiply specified");
1696 if(++i >= argc)
1697 fatal("-e: argument missing");
1698 entry_point_name = argv[i];
1699 break;
1701 case 'U':
1702 if(p[1] != '\0')
1703 goto unknown_flag;
1704 /* allow the specified symbol name to be undefined */
1705 if(++i >= argc)
1706 fatal("-U: argument missing");
1707 undef_syms = reallocate(undef_syms,
1708 (nundef_syms + 1) * sizeof(char *));
1709 undef_syms[nundef_syms++] = argv[i];
1710 break;
1712 case 'w':
1713 if(strcmp(p, "w") == 0)
1714 nowarnings = TRUE;
1715 else if(strcmp(p, "whyload") == 0)
1716 whyload = TRUE;
1717 else if(strcmp(p, "whatsloaded") == 0)
1718 whatsloaded = TRUE;
1719 else if(strcmp(p, "weak_reference_mismatches") == 0){
1720 if(++i >= argc)
1721 fatal("-weak_reference_mismatches: "
1722 "argument missing");
1723 if(strcmp(argv[i], "error") == 0)
1724 new_weak_reference_mismatches =
1725 WEAK_REFS_MISMATCH_ERROR;
1726 else if(strcmp(argv[i], "weak") == 0)
1727 new_weak_reference_mismatches =
1728 WEAK_REFS_MISMATCH_WEAK;
1729 else if(strcmp(argv[i], "non-weak") == 0)
1730 new_weak_reference_mismatches =
1731 WEAK_REFS_MISMATCH_NON_WEAK;
1732 else{
1733 fatal("-weak_reference_mismatches: unknown "
1734 "argument: %s", argv[i]);
1735 new_weak_reference_mismatches =
1736 WEAK_REFS_MISMATCH_ERROR;
1738 if(weak_reference_mismatches_specified == TRUE &&
1739 new_weak_reference_mismatches !=
1740 weak_reference_mismatches)
1741 fatal("more than one value specified for "
1742 "-weak_reference_mismatches");
1743 weak_reference_mismatches_specified = TRUE;
1744 weak_reference_mismatches =
1745 new_weak_reference_mismatches;
1746 break;
1748 else if(strcmp(p, "weak_library") == 0){
1749 if(i + 1 >= argc)
1750 fatal("-weak_library: argument missing");
1751 /* object file argv[i] processed in the next pass of
1752 parsing arguments */
1753 i += 1;
1755 else if(strncmp(p, "weak-l", sizeof("weak-l") - 1) == 0){
1756 if(p[sizeof("weak-l") - 1] == '\0')
1757 fatal("-weak-l: argument missing");
1758 /* path searched abbrevated file name, processed in the
1759 next pass of parsing arguments */
1761 else if(strcmp(p, "weak_framework") == 0){
1762 if(i + 1 >= argc)
1763 fatal("-weak_framework: argument missing");
1764 /* path searched abbrevated framework name, processed
1765 in the next pass of parsing arguments */
1766 i += 1;
1768 else
1769 goto unknown_flag;
1770 break;
1772 case 'O':
1773 if(strcmp(p, "ObjC") == 0)
1774 archive_ObjC = TRUE;
1775 else
1776 goto unknown_flag;
1777 break;
1779 case 'y':
1780 /* symbol tracing */
1781 if(p[1] == '\0')
1782 fatal("-y: symbol name missing");
1783 trace_syms = reallocate(trace_syms,
1784 (ntrace_syms + 1) * sizeof(char *));
1785 trace_syms[ntrace_syms++] = &(p[1]);
1786 break;
1788 case 'Y':
1789 /* undefined reference symbol tracing */
1790 if(strcmp(p, "Y") == 0){
1791 if(i + 1 >= argc)
1792 fatal("-Y: argument missing");
1793 Yflag = strtoul(argv[i+1], &endp, 10);
1794 if(*endp != '\0')
1795 fatal("reference count for -Y %s not a proper "
1796 "decimal number", argv[i+1]);
1798 else
1799 goto unknown_flag;
1800 break;
1802 case 'h':
1803 /* specify the header pad (in hex)
1804 -headerpad <value> */
1805 if(strcmp(p, "headerpad") == 0){
1806 if(i + 1 >= argc)
1807 fatal("-headerpad: argument missing");
1808 if(headerpad_specified == TRUE)
1809 fatal("-headerpad: multiply specified");
1810 headerpad = strtoul(argv[i+1], &endp, 16);
1811 if(*endp != '\0')
1812 fatal("address for -headerpad %s not a proper "
1813 "hexadecimal number", argv[i+1]);
1814 headerpad_specified = TRUE;
1815 i += 1;
1817 else if(strcmp(p, "headerpad_max_install_names") == 0){
1818 headerpad_max_install_names = TRUE;
1820 else if(strcmp(p, "hash_instrument") == 0){
1821 hash_instrument_specified = TRUE;
1823 else
1824 goto unknown_flag;
1825 break;
1827 case 'k':
1828 if(strcmp(p, "keep_private_externs") == 0)
1829 keep_private_externs = TRUE;
1830 else if(strcmp(p, "k") == 0)
1831 dynamic = TRUE;
1832 else
1833 goto unknown_flag;
1834 break;
1836 case 'N':
1837 if(strcmp(p, "NEXTSTEP-deployment-target") == 0){
1838 if(i + 1 >= argc)
1839 fatal("-NEXTSTEP-deployment-target: argument "
1840 "missing");
1841 if(dynamic_specified == TRUE ||
1842 static_specified == TRUE)
1843 fatal("-NEXTSTEP-deployment-target, -dynamic or "
1844 "-static : multiply specified");
1845 if(strcmp(argv[i+1], "3.3") == 0){
1846 if(static_specified)
1847 fatal("only one of -NEXTSTEP-deployment-target "
1848 "3.3 or -static can be specified");
1849 dynamic = TRUE;
1850 dynamic_specified = TRUE;
1852 else if(strcmp(argv[i+1], "3.2") == 0){
1853 if(dynamic_specified)
1854 fatal("only one of -NEXTSTEP-deployment-target "
1855 "3.2 or -dynamic can be specified");
1856 dynamic = FALSE;
1857 static_specified = TRUE;
1859 else
1860 fatal("unknown deployment release flag: "
1861 "-NEXTSTEP-deployment-target %s", argv[i+1]);
1862 i += 1;
1864 else
1865 goto unknown_flag;
1866 break;
1868 case 'v':
1869 if(strcmp(p, "v") == 0){
1870 vflag = TRUE;
1871 printf("Apple Computer, Inc. version %s\n",
1872 apple_version);
1874 else
1875 goto unknown_flag;
1876 break;
1878 default:
1879 unknown_flag:
1880 fatal("unknown flag: %s", argv[i]);
1886 * -sub_umbrella and -sub_library are not supported on ARM.
1887 * See <rdar://problem/4771657>.
1889 if(arch_flag.cputype == CPU_TYPE_ARM){
1890 if(sub_umbrellas != NULL){
1891 fatal("-sub_umbrella is not supported on ARM");
1893 if(sub_librarys != NULL){
1894 fatal("-sub_library is not supported on ARM");
1899 * If either -syslibroot or the environment variable NEXT_ROOT is set
1900 * prepend it to the standard paths for library searches. This was
1901 * added to ease cross build environments.
1903 p = getenv("NEXT_ROOT");
1904 if(syslibroot_specified == TRUE){
1905 if(p != NULL && strcmp(p, next_root) != 0)
1906 warning("NEXT_ROOT environment variable ignored because "
1907 "-syslibroot specified");
1909 else{
1910 next_root = p;
1912 if(next_root != NULL){
1913 for(i = 0; standard_dirs[i] != NULL; i++){
1914 p = allocate(strlen(next_root) +
1915 strlen(standard_dirs[i]) + 1);
1916 strcpy(p, next_root);
1917 strcat(p, standard_dirs[i]);
1918 standard_dirs[i] = p;
1920 for(i = 0; standard_framework_dirs[i] != NULL; i++){
1921 p = allocate(strlen(next_root) +
1922 strlen(standard_framework_dirs[i]) + 1);
1923 strcpy(p, next_root);
1924 strcat(p, standard_framework_dirs[i]);
1925 standard_framework_dirs[i] = p;
1929 * If -syslibroot is specified, prepend it to the user-specified
1930 * paths *if* the prepended version exists.
1932 if(syslibroot_specified == TRUE){
1933 for(i = 0; i < nsearch_dirs; i++){
1934 if(search_dirs[i][0] == '/'){
1935 p = mkstr(next_root, search_dirs[i], NULL);
1936 if(stat(p, &stat_buf) == 0)
1937 search_dirs[i] = p;
1938 else
1939 free(p);
1942 for(i = 0; i < nframework_dirs; i++){
1943 if(framework_dirs[i][0] == '/'){
1944 p = mkstr(next_root, framework_dirs[i], NULL);
1945 if(stat(p, &stat_buf) == 0)
1946 framework_dirs[i] = p;
1947 else
1948 free(p);
1954 * Test to see if the various RC_* or XBS_* environment variables
1955 * are set.
1957 if((getenv("LD_TRACE_ARCHIVES") != NULL) ||
1958 getenv("RC_TRACE_ARCHIVES") != NULL)
1959 ld_trace_archives = TRUE;
1960 if((getenv("LD_TRACE_DYLIBS") != NULL) ||
1961 (getenv("RC_TRACE_DYLIBS") != NULL))
1962 ld_trace_dylibs = TRUE;
1963 if((getenv("LD_TRACE_PREBINDING_DISABLED") != NULL) ||
1964 getenv("RC_TRACE_PREBINDING_DISABLED") != NULL)
1965 ld_trace_prebinding_disabled = TRUE;
1966 if(ld_trace_archives || ld_trace_dylibs)
1967 trace_file_path = getenv("LD_TRACE_FILE");
1968 if(getenv("LD_TRACE_BUNDLE_LOADER") != NULL &&
1969 bundle_loader != NULL)
1970 print("[Logging for XBS] Referenced bundle loader: %s\n",
1971 bundle_loader);
1973 if(save_reloc == FALSE){
1974 if(getenv("LD_DEAD_STRIP") != NULL)
1975 dead_strip = TRUE;
1976 if(getenv("LD_NO_DEAD_STRIP_INITS_AND_TERMS") != NULL)
1977 no_dead_strip_inits_and_terms = TRUE;
1979 if(getenv("LD_DEAD_STRIP_DYLIB") != NULL && filetype == MH_DYLIB)
1980 dead_strip = TRUE;
1982 prebinding_via_LD_PREBIND = FALSE;
1984 * The LD_FORCE_NO_PREBIND environment variable overrides the command
1985 * line and the LD_PREBIND environment variable.
1987 if(getenv("LD_FORCE_NO_PREBIND") != NULL){
1988 if(prebinding_flag_specified == TRUE &&
1989 prebinding == TRUE){
1990 warning("-prebind ignored because LD_FORCE_NO_PREBIND "
1991 "environment variable specified");
1992 prebinding_flag_specified = TRUE;
1993 prebinding = FALSE;
1997 * The -prebind flag can also be specified with the LD_PREBIND
1998 * environment variable. We quitely ignore this when -r is on or
1999 * if this is a fixed shared library output.
2001 else if(getenv("LD_PREBIND") != NULL &&
2002 save_reloc == FALSE &&
2003 filetype != MH_FVMLIB){
2004 if(prebinding_flag_specified == TRUE &&
2005 prebinding == FALSE){
2006 warning("LD_PREBIND environment variable ignored because "
2007 "-noprebind specified");
2009 else{
2010 if(prebinding_flag_specified == FALSE)
2011 prebinding_via_LD_PREBIND = TRUE;
2012 prebinding_flag_specified = TRUE;
2013 prebinding = TRUE;
2016 if(getenv("LD_PREBIND_ALLOW_OVERLAP") != NULL)
2017 prebind_allow_overlap = TRUE;
2018 if(prebind_all_twolevel_modules_specified == FALSE &&
2019 getenv("LD_PREBIND_ALL_TWOLEVEL_MODULES") != NULL)
2020 prebind_all_twolevel_modules = TRUE;
2023 * The -twolevel_namespace flag can also be specified with the
2024 * LD_TWOLEVEL_NAMESPACE environment variable. We quitely ignore this
2025 * when -flat_namespace or -static is specified.
2027 if(getenv("LD_TWOLEVEL_NAMESPACE") != NULL &&
2028 namespace_specified == FALSE &&
2029 static_specified == FALSE){
2030 namespace_specified = TRUE;
2031 twolevel_namespace = TRUE;
2035 * See if LD_LIBRARY_PATH is set. And if so parse out the colon
2036 * separated set of paths.
2038 ld_library_path = getenv("LD_LIBRARY_PATH");
2039 if(ld_library_path != NULL){
2040 nld_library_paths = 1;
2041 for(i = 0; ld_library_path[i] != '\0'; i++){
2042 if(ld_library_path[i] == ':')
2043 nld_library_paths++;
2045 ld_library_paths = allocate(sizeof(char *) * nld_library_paths);
2046 j = 0;
2047 ld_library_paths[j] = ld_library_path;
2048 j++;
2049 for(i = 0; ld_library_path[i] != '\0'; i++){
2050 if(ld_library_path[i] == ':'){
2051 ld_library_path[i] = '\0';
2052 ld_library_paths[j] = ld_library_path + i + 1;
2053 j++;
2059 * If there was a -arch flag two things needed to be done in reguard to
2060 * the handling of the cpusubtypes.
2062 if(arch_flag.name != NULL){
2065 * 64-bit architectures are an error.
2067 if(arch_flag.cputype & CPU_ARCH_ABI64)
2068 fatal("does not support 64-bit architectures");
2070 family_arch_flag = get_arch_family_from_cputype(arch_flag.cputype);
2071 if(family_arch_flag == NULL)
2072 fatal("internal error: unknown cputype (%d) for -arch %s (this "
2073 "program out of sync with get_arch_family_from_cputype())"
2074 ,arch_flag.cputype, arch_flag.name);
2076 * Pick up the Mac OS X deployment target.
2078 get_macosx_deployment_target(&macosx_deployment_target);
2080 * If for this cputype we are to always output the ALL cpusubtype
2081 * then set force_cpusubtype_ALL.
2083 if(force_cpusubtype_ALL_for_cputype(arch_flag.cputype) == TRUE)
2084 force_cpusubtype_ALL = TRUE;
2086 * First, if -force_cpusubtype_ALL is set and an -arch flag was
2087 * specified set the cpusubtype to the _ALL type for that cputype
2088 * since the specified flag may not have the _ALL type and the
2089 * -force_cpusubtype_ALL has precedence over an -arch flags for a
2090 * specific implementation of an architecture.
2092 if(force_cpusubtype_ALL == TRUE){
2093 arch_flag.cpusubtype = family_arch_flag->cpusubtype;
2095 else{
2097 * Second, if no -force_cpusubtype_ALL is specified and an -arch
2098 * flag for a specific implementation of an architecture was
2099 * specified then the resulting cpusubtype will be for that
2100 * specific implementation of that architecture and all
2101 * cpusubtypes must combine with the cpusubtype for the -arch
2102 * flag to the cpusubtype for the -arch flag else an error must
2103 * be flaged. This is done check_cur_obj() where cpusubtypes
2104 * are combined. What needs to be done here is to determine if
2105 * the -arch flag is for a specific implementation of an
2106 * architecture.
2108 if(arch_flag.cpusubtype != family_arch_flag->cpusubtype)
2109 specific_arch_flag = TRUE;
2112 else{
2114 * We need to pick up the Mac OS X deployment target even if the
2115 * target architecture is not yet known so we can check to see if
2116 * the flags specified are valid.
2118 if(macosx_deployment_target.major == 0)
2119 get_macosx_deployment_target(&macosx_deployment_target);
2123 * If the -sect_diff_relocs is specified check to see it can be used
2124 * else pick up the LD_SECT_DIFF_RELOC if that can be used.
2126 if(sect_diff_reloc_flag_specified == TRUE){
2127 if(filetype != MH_EXECUTE || dynamic == FALSE)
2128 fatal("can't use -sect_diff_relocs unless both -execute and "
2129 "-dynamic are in effect");
2131 else{
2133 * The -sect_diff_relocs flag was not specified on the command
2134 * line, so if both -execute and -dynamic are in effect see if
2135 * LD_SECT_DIFF_RELOCS is specified as an environment variable and
2136 * use that value.
2138 if(filetype == MH_EXECUTE && dynamic == TRUE){
2139 p = getenv("LD_SECT_DIFF_RELOCS");
2140 if(p != NULL){
2141 if(strcmp(p, "error") == 0)
2142 sect_diff_reloc_flag = SECT_DIFF_RELOC_ERROR;
2143 else if(strcmp(p, "warning") == 0)
2144 sect_diff_reloc_flag = SECT_DIFF_RELOC_WARNING;
2145 else if(strcmp(p, "suppress") == 0)
2146 sect_diff_reloc_flag = SECT_DIFF_RELOC_SUPPRESS;
2147 else{
2148 fatal("Unknown LD_SECT_DIFF_RELOCS environment variable"
2149 " %s value", p);
2156 * Check for flag combinations that would result in a bad output file.
2158 if(save_reloc && strip_level == STRIP_ALL)
2159 fatal("can't use -s with -r (resulting file would not be "
2160 "relocatable)");
2161 if(save_reloc && strip_level == STRIP_MIN_DEBUG)
2162 fatal("can't use -Sp with -r (only allowed for fully linked "
2163 "images)");
2164 if(save_reloc && strip_base_symbols == TRUE)
2165 fatal("can't use -b with -r (resulting file would not be "
2166 "relocatable)");
2167 if(save_reloc && dead_strip == TRUE)
2168 fatal("can't use -dead_strip with -r (only allowed for fully "
2169 "linked images)");
2170 if(keep_private_externs == TRUE){
2171 if(save_symbols != NULL)
2172 fatal("can't use both -keep_private_externs and "
2173 "-exported_symbols_list");
2174 if(remove_symbols != NULL)
2175 fatal("can't use both -keep_private_externs and "
2176 "-unexported_symbols_list");
2178 if(save_symbols != NULL && remove_symbols != NULL){
2179 for(j = 0; j < nremove_symbols ; j++){
2180 sp = bsearch(remove_symbols[j].name,
2181 save_symbols, nsave_symbols,
2182 sizeof(struct symbol_list),
2183 (int (*)(const void *, const void *))
2184 symbol_list_bsearch);
2185 if(sp != NULL){
2186 error("symbol name: %s is listed in both "
2187 "-exported_symbols_list and -unexported_symbols_list "
2188 "(can't be both exported and unexported)",
2189 remove_symbols[j].name);
2192 if(errors != 0)
2193 ld_exit(1);
2195 if(filetype_specified == TRUE && filetype == MH_OBJECT){
2196 if(dynamic == TRUE)
2197 fatal("incompatible to specifiy -object when -dynamic is used "
2198 "(use -execute (the default) with -dynamic or -static "
2199 "with -object)");
2201 if(filetype == MH_DYLINKER){
2202 if(dynamic == FALSE)
2203 fatal("incompatible flag -dylinker used (must specify "
2204 "\"-dynamic\" to be used)");
2206 if(filetype == MH_DYLIB){
2207 if(dynamic == FALSE)
2208 fatal("incompatible flag -dylib used (must specify "
2209 "\"-dynamic\" to be used)");
2210 if(save_reloc)
2211 fatal("can't use -r and -dylib (file format produced with "
2212 "-dylib is not a relocatable format)");
2213 if(strip_level == STRIP_ALL)
2214 fatal("can't use -s with -dylib (file must contain at least "
2215 "global symbols, for maximum stripping use -x)");
2216 if(Aflag_specified)
2217 fatal("can't use -A and -dylib");
2218 if(keep_private_externs == TRUE)
2219 fatal("can't use -keep_private_externs and -dylib");
2220 if(segaddr_specified)
2221 fatal("can't use -segaddr options with -dylib (use seg1addr to "
2222 "specify the starting address)");
2223 if(seg1addr_specified && segs_read_only_addr_specified)
2224 fatal("can't use both the -seg1addr option and "
2225 "-segs_read_only_addr option");
2226 if(seg1addr_specified && segs_read_write_addr_specified)
2227 fatal("can't use both the -seg1addr option and "
2228 "-segs_read_write_addr option");
2229 if(seg1addr_specified && seg_addr_table_name != NULL)
2230 fatal("can't use both the -seg1addr option and "
2231 "-seg_addr_table option");
2232 if(seg_addr_table_name != NULL && segs_read_only_addr_specified)
2233 fatal("can't use both the -seg_addr_table option and "
2234 "-segs_read_only_addr option");
2235 if(seg_addr_table_name != NULL && segs_read_write_addr_specified)
2236 fatal("can't use both the -seg_addr_table option and "
2237 "-segs_read_only_addr option");
2238 if(seg_addr_table_name != NULL && dylib_install_name == NULL)
2239 fatal("must also specify -dylib_install_name when using "
2240 "-seg_addr_table");
2241 if(segs_read_only_addr_specified &&
2242 read_only_reloc_flag != READ_ONLY_RELOC_ERROR)
2243 fatal("can't used -read_only_relocs %s with format produced "
2244 "with the -segs_read_only_addr option\n",
2245 read_only_reloc_flag == READ_ONLY_RELOC_WARNING ?
2246 "warning" : "suppress");
2247 if(segs_read_write_addr_specified &&
2248 !segs_read_only_addr_specified)
2249 fatal("must also specify -segs_read_only_addr when using "
2250 "-segs_read_write_addr");
2251 if(seglinkedit_specified && seglinkedit == FALSE)
2252 fatal("can't use -noseglinkedit with -dylib (resulting file "
2253 "must have a link edit segment to access symbols)");
2254 if(bind_at_load == TRUE){
2255 warning("-bind_at_load is meaningless with -dylib");
2256 bind_at_load = FALSE;
2258 /* use a segment address table if specified */
2259 env_seg_addr_table_name = getenv("LD_SEG_ADDR_TABLE");
2260 if(seg_addr_table_name != NULL ||
2261 (env_seg_addr_table_name != NULL && dylib_install_name != NULL)){
2262 if(seg_addr_table_name != NULL &&
2263 env_seg_addr_table_name != NULL &&
2264 strcmp(seg_addr_table_name, env_seg_addr_table_name) != 0){
2265 warning("-seg_addr_table %s ignored, LD_SEG_ADDR_TABLE "
2266 "environment variable: %s used instead",
2267 seg_addr_table_name, env_seg_addr_table_name);
2269 if(env_seg_addr_table_name != NULL){
2270 seg_addr_table_name = env_seg_addr_table_name;
2271 seg_addr_table = parse_seg_addr_table(seg_addr_table_name,
2272 "LD_SEG_ADDR_TABLE", "environment variable",
2273 &table_size);
2275 else
2276 seg_addr_table = parse_seg_addr_table(seg_addr_table_name,
2277 "-seg_addr_table", seg_addr_table_name, &table_size);
2278 if(seg_addr_table_filename != NULL)
2279 seg_addr_table_entry = search_seg_addr_table(seg_addr_table,
2280 seg_addr_table_filename);
2281 else
2282 seg_addr_table_entry = search_seg_addr_table(seg_addr_table,
2283 dylib_install_name);
2284 if(seg_addr_table_entry != NULL){
2285 if(seg_addr_table_entry->split == TRUE){
2286 if(read_only_reloc_flag != READ_ONLY_RELOC_ERROR){
2287 warning("-read_only_relocs %s ignored, when using "
2288 "with format produced with the "
2289 "-segs_read_only_addr option (via the "
2290 "segment address table: %s %s line %u)",
2291 read_only_reloc_flag ==
2292 READ_ONLY_RELOC_WARNING ?
2293 "warning" : "suppress",
2294 env_seg_addr_table_name != NULL ?
2295 "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2296 seg_addr_table_name,
2297 seg_addr_table_entry->line);
2298 read_only_reloc_flag = READ_ONLY_RELOC_ERROR;
2300 if(seg1addr_specified){
2301 warning("-seg1addr 0x%x ignored, using "
2302 "-segs_read_only_addr 0x%x and "
2303 "-segs_read_write_addr 0x%x from segment "
2304 "address table: %s %s line %u",
2305 (unsigned int)seg1addr,
2306 (unsigned int)seg_addr_table_entry->
2307 segs_read_only_addr,
2308 (unsigned int)seg_addr_table_entry->
2309 segs_read_write_addr,
2310 env_seg_addr_table_name != NULL ?
2311 "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2312 seg_addr_table_name,
2313 seg_addr_table_entry->line);
2315 if(segs_read_only_addr_specified &&
2316 segs_read_only_addr !=
2317 seg_addr_table_entry->segs_read_only_addr){
2318 warning("-segs_read_only_addr 0x%x ignored, using "
2319 "-segs_read_only_addr 0x%x from segment "
2320 "address table: %s %s line %u",
2321 (unsigned int)segs_read_only_addr,
2322 (unsigned int)seg_addr_table_entry->
2323 segs_read_only_addr,
2324 env_seg_addr_table_name != NULL ?
2325 "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2326 seg_addr_table_name,
2327 seg_addr_table_entry->line);
2329 if(segs_read_write_addr_specified &&
2330 segs_read_write_addr !=
2331 seg_addr_table_entry->segs_read_write_addr){
2332 warning("-segs_read_write_addr 0x%x ignored, using "
2333 "-segs_read_write_addr 0x%x from segment "
2334 "address table: %s %s line %u",
2335 (unsigned int)segs_read_write_addr,
2336 (unsigned int)seg_addr_table_entry->
2337 segs_read_write_addr,
2338 env_seg_addr_table_name != NULL ?
2339 "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2340 seg_addr_table_name,
2341 seg_addr_table_entry->line);
2343 seg1addr_specified = FALSE;
2344 seg1addr = 0;
2345 segs_read_only_addr_specified = TRUE;
2346 segs_read_only_addr =
2347 seg_addr_table_entry->segs_read_only_addr;
2348 segs_read_write_addr_specified = TRUE;
2349 segs_read_write_addr =
2350 seg_addr_table_entry->segs_read_write_addr;
2351 if(segs_read_only_addr == 0 &&
2352 segs_read_write_addr == 0){
2353 segs_read_write_addr = get_shared_region_size_from_flag(&arch_flag);
2354 warning("-segs_read_write_addr 0x0 ignored from "
2355 "segment address table: %s %s line %u "
2356 "using -segs_read_write_addr 0x%x",
2357 env_seg_addr_table_name != NULL ?
2358 "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2359 seg_addr_table_name,
2360 seg_addr_table_entry->line,
2361 (unsigned int)segs_read_write_addr);
2364 else{
2365 if(seg1addr_specified &&
2366 seg1addr != seg_addr_table_entry->seg1addr){
2367 warning("-seg1addr 0x%x ignored, using "
2368 "-seg1addr 0x%x from segment address "
2369 "table: %s %s line %u",
2370 (unsigned int)seg1addr,
2371 (unsigned int)seg_addr_table_entry->
2372 seg1addr,
2373 env_seg_addr_table_name != NULL ?
2374 "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2375 seg_addr_table_name,
2376 seg_addr_table_entry->line);
2378 if(segs_read_only_addr_specified){
2379 warning("-segs_read_only_addr 0x%x ignored, using "
2380 "-seg1addr 0x%x from segment address "
2381 "table: %s %s line %u",
2382 (unsigned int)segs_read_only_addr,
2383 (unsigned int)seg_addr_table_entry->
2384 seg1addr,
2385 env_seg_addr_table_name != NULL ?
2386 "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2387 seg_addr_table_name,
2388 seg_addr_table_entry->line);
2390 if(segs_read_write_addr_specified){
2391 warning("-segs_read_write_addr 0x%x ignored, using "
2392 "-seg1addr 0x%x from segment address "
2393 "table: %s %s line %u",
2394 (unsigned int)segs_read_write_addr,
2395 (unsigned int)seg_addr_table_entry->
2396 seg1addr,
2397 env_seg_addr_table_name != NULL ?
2398 "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2399 seg_addr_table_name,
2400 seg_addr_table_entry->line);
2402 seg1addr_specified = TRUE;
2403 seg1addr = seg_addr_table_entry->seg1addr;
2404 segs_read_only_addr_specified = FALSE;
2405 segs_read_only_addr = 0;
2406 segs_read_write_addr_specified = FALSE;
2407 segs_read_write_addr = 0;
2410 else{
2411 warning("%s %s not found in segment address table %s %s",
2412 seg_addr_table_filename != NULL ?
2413 "-seg_addr_table_filename" : "-dylib_install_name",
2414 seg_addr_table_filename != NULL ?
2415 seg_addr_table_filename : dylib_install_name,
2416 env_seg_addr_table_name != NULL ?
2417 "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2418 seg_addr_table_name);
2422 * If this is not a subframework then if it has an install name
2423 * then guess its implied umbrella framework name from the
2424 * install name. Then if its install name is a framework name use
2425 * that as the umbrella framework name. Otherwise it is not
2426 * considered an umbrella framework.
2428 if(sub_framework == FALSE && dylib_install_name != NULL){
2429 umbrella_framework_name = guess_short_name(dylib_install_name,
2430 &is_framework, &has_suffix);
2431 if(umbrella_framework_name != NULL && is_framework == TRUE)
2432 umbrella_framework = TRUE;
2433 else
2434 umbrella_framework_name = NULL;
2436 if(nallowable_clients != 0 && sub_framework == FALSE)
2437 fatal("-allowable_client flags can only be used when -umbrella "
2438 "is also specified");
2440 else{
2441 if(segs_read_only_addr_specified)
2442 fatal("-segs_read_only_addr can only be used when -dylib "
2443 "is also specified");
2444 if(segs_read_write_addr_specified)
2445 fatal("-segs_read_write_addr can only be used when -dylib "
2446 "is also specified");
2447 if(seg_addr_table_name != NULL)
2448 fatal("-seg_addr_table can only be used when -dylib "
2449 "is also specified");
2450 if(sub_framework == TRUE)
2451 fatal("-umbrella %s can only be used when -dylib "
2452 "is also specified", umbrella_framework_name);
2453 if(nsub_umbrellas != 0)
2454 fatal("-sub_umbrella flags can only be used when -dylib "
2455 "is also specified");
2456 if(nsub_librarys != 0)
2457 fatal("-sub_library flags can only be used when -dylib "
2458 "is also specified");
2459 if(nallowable_clients != 0)
2460 fatal("-allowable_client flags can only be used when -dylib "
2461 "is also specified");
2462 if(moduletype_specified == TRUE)
2463 fatal("-single_module or -multi_module flags can only be used "
2464 "when -dylib is also specified");
2468 * For Mac OS X 10.4 and later, prebinding will be limited to split
2469 * shared libraries. So if this is not a split library then turn off
2470 * prebinding.
2472 if(macosx_deployment_target.major >= 4){
2473 if(filetype != MH_DYLIB){
2475 * If this is arm* or xscale, we want to prebind executables
2476 * too, not just dylibs and frameworks.
2478 if (!((arch_flag.name != NULL) &&
2479 ((strncmp(arch_flag.name, "arm", 3) == 0) ||
2480 (strcmp(arch_flag.name, "xscale") == 0))))
2482 if(prebinding_via_LD_PREBIND == FALSE &&
2483 prebinding_flag_specified == TRUE &&
2484 prebinding == TRUE){
2485 warning("-prebind ignored because MACOSX_DEPLOYMENT_TARGET "
2486 "environment variable greater or equal to 10.4");
2488 prebinding = FALSE;
2492 * This is an MH_DYLIB. First see if it is on the list of libraries
2493 * not to be prebound. Then see if was specified to be built as a
2494 * split, if not check LD_SPLITSEGS_NEW_LIBRARIES to see if we are
2495 * forcing it to be a split library.
2497 else{
2499 * If this library was not in the seg_addr_table see if it is
2500 * on the list of libraries not to be prebound. And if so turn
2501 * off prebinding. Note this list is only ever used when
2502 * macosx_deployment_target.major >= 4 .
2504 if(seg_addr_table_entry == NULL &&
2505 unprebound_library(dylib_install_name,
2506 seg_addr_table_filename) == TRUE){
2507 if(prebinding_flag_specified == TRUE &&
2508 prebinding == TRUE){
2509 warning("-prebind ignored because -install_name %s "
2510 "listed in LD_UNPREBOUND_LIBRARIES environment "
2511 "variable file: %s", dylib_install_name,
2512 getenv("LD_UNPREBOUND_LIBRARIES"));
2514 prebinding = FALSE;
2516 else{
2518 * This is not on the list of libraries not to be prebound,
2519 * and if there was no seg_addr_table entry for this then
2520 * force this to be a split library. Note even if
2521 * prebinding was not specified we will still force this to
2522 * be a split library.
2524 if(seg_addr_table_entry == NULL &&
2525 getenv("LD_SPLITSEGS_NEW_LIBRARIES") != NULL){
2526 unsigned long arch_rw_addr =
2527 get_shared_region_size_from_flag(&arch_flag);
2529 if(seg1addr_specified){
2530 warning("-seg1addr 0x%x ignored, using "
2531 "-segs_read_only_addr 0x%x and "
2532 "-segs_read_write_addr 0x%x because "
2533 "LD_SPLITSEGS_NEW_LIBRARIES environment is "
2534 "set",(unsigned int)seg1addr, 0,
2535 (unsigned int)arch_rw_addr);
2537 seg1addr_specified = FALSE;
2538 seg1addr = 0;
2539 segs_read_only_addr_specified = TRUE;
2540 segs_read_only_addr = 0;
2541 segs_read_write_addr = arch_rw_addr;
2544 * Finally if this is not a split library then turn off
2545 * prebinding.
2547 if(segs_read_only_addr_specified == FALSE){
2548 if(prebinding_via_LD_PREBIND == FALSE &&
2549 prebinding_flag_specified == TRUE &&
2550 prebinding == TRUE){
2551 warning("-prebind ignored because "
2552 "MACOSX_DEPLOYMENT_TARGET environment "
2553 "variable greater or equal to 10.4");
2555 prebinding = FALSE;
2561 if(filetype == MH_BUNDLE){
2562 if(dynamic == FALSE)
2563 fatal("incompatible flag -bundle used (must specify "
2564 "\"-dynamic\" to be used)");
2565 if(save_reloc)
2566 fatal("can't use -r and -bundle (flags are mutually "
2567 "exclusive, only one or the other can be used)");
2568 if(strip_level == STRIP_ALL)
2569 fatal("can't use -s with -bundle (file must contain "
2570 "at least global symbols, for maximum stripping use -x)");
2571 if(Aflag_specified)
2572 fatal("can't use -A and -bundle");
2573 if(keep_private_externs == TRUE)
2574 fatal("can't use -keep_private_externs and -bundle");
2575 if(segaddr_specified)
2576 fatal("can't use -segaddr options with -bundle (use "
2577 "seg1addr to specify the starting address)");
2578 if(seglinkedit_specified && seglinkedit == FALSE)
2579 fatal("can't use -noseglinkedit with -bundle "
2580 "(resulting file must have a link edit segment to access "
2581 "symbols)");
2582 if(prebinding == TRUE){
2583 if(prebinding_flag_specified == TRUE)
2584 warning("-prebind has no effect with -bundle");
2585 prebinding = FALSE;
2587 if(private_bundle == TRUE && twolevel_namespace == TRUE)
2588 warning("-private_bundle has no effect when "
2589 "-twolevel_namespace is in effect");
2590 if(twolevel_namespace_hints_specified != TRUE)
2591 twolevel_namespace_hints = FALSE;
2593 else{
2594 if(client_name != NULL)
2595 fatal("-client_name %s flag can only be used with -bundle",
2596 client_name);
2597 if(bundle_loader != NULL)
2598 fatal("-bundle_loader %s flag can only be used with -bundle",
2599 bundle_loader);
2600 if(private_bundle == TRUE)
2601 fatal("-private_bundle flag can only be used with -bundle");
2603 if(filetype != MH_DYLINKER){
2604 if(dylinker_install_name != NULL)
2605 warning("flag: -dylinker_install_name %s ignored (-dylinker "
2606 "was not specified", dylinker_install_name);
2608 if(filetype != MH_DYLIB){
2609 if(dylib_install_name != NULL)
2610 warning("flag: -dylib_install_name %s ignored (-dylib "
2611 "was not specified", dylib_install_name);
2612 if(dylib_current_version != 0)
2613 warning("flag: -dylib_current_version %u ignored (-dylib "
2614 "was not specified", dylib_current_version);
2615 if(dylib_compatibility_version != 0)
2616 warning("flag: -dylib_compatibility_version %u ignored (-dylib"
2617 " was not specified", dylib_compatibility_version);
2618 if(init_name != NULL)
2619 warning("flag: -init %s ignored (-dylib was not specified",
2620 init_name);
2622 if(twolevel_namespace == TRUE &&
2623 undefined_flag != UNDEFINED_ERROR &&
2624 undefined_flag != UNDEFINED_DYNAMIC_LOOKUP &&
2625 undefined_flag != UNDEFINED_DEFINE_A_WAY){
2626 if(macosx_deployment_target.major >= 3)
2627 fatal("-undefined error, -undefined dynamic_lookup or "
2628 "-undefined define_a_way must be used when "
2629 "-twolevel_namespace is in effect");
2630 else
2631 fatal("-undefined error or -undefined define_a_way must be "
2632 "used when -twolevel_namespace is in effect");
2634 if(undefined_flag == UNDEFINED_DYNAMIC_LOOKUP){
2635 if(dynamic == FALSE)
2636 fatal("incompatible flag -undefined dynamic_lookup used (must "
2637 "specify \"-dynamic\" to be used)");
2638 if(macosx_deployment_target.major < 3)
2639 fatal("flag: -undefined dynamic_lookup can't be used with "
2640 "MACOSX_DEPLOYMENT_TARGET environment variable set to: "
2641 "%s", macosx_deployment_target.name);
2643 if(twolevel_namespace == TRUE && nundef_syms != 0){
2644 fatal("can't use -U flags when -twolevel_namespace is in effect");
2646 if(nomultidefs == TRUE){
2647 if(multiply_defined_flag_specified == TRUE &&
2648 multiply_defined_flag != MULTIPLY_DEFINED_ERROR)
2649 fatal("-multiply_defined error must be used when -nomultidefs "
2650 "is specified");
2651 multiply_defined_flag = MULTIPLY_DEFINED_ERROR;
2653 if(prebinding == TRUE && undefined_flag == UNDEFINED_SUPPRESS){
2654 if(prebinding_flag_specified == TRUE)
2655 warning("-undefined suppress disables -prebind");
2656 prebinding = FALSE;
2658 if(prebinding == TRUE && save_reloc){
2659 if(prebinding_flag_specified == TRUE)
2660 warning("-r disables -prebind");
2661 prebinding = FALSE;
2663 if(prebinding == TRUE && dynamic == FALSE){
2664 prebinding = FALSE;
2668 * If the output file name as not specified set it to the default name
2669 * "a.out". This needs to be done before any segments are merged
2670 * because this is used when merging them (the 'filename' field in a
2671 * merged_segment is set to it).
2673 if(outputfile == NULL)
2674 outputfile = "a.out";
2676 * If the -A flag is specified and the file type has not been specified
2677 * then make the output file type MH_OBJECT.
2679 if(Aflag_specified == TRUE && filetype_specified == FALSE)
2680 filetype = MH_OBJECT;
2683 * If neither the -seglinkedit or -noseglinkedit has been specified then
2684 * set creation of this segment if the output file type can have one.
2685 * If -seglinkedit has been specified make sure the output file type
2686 * can have one.
2688 if(seglinkedit_specified == FALSE){
2689 if(filetype == MH_EXECUTE || filetype == MH_BUNDLE ||
2690 filetype == MH_FVMLIB ||
2691 filetype == MH_DYLIB || filetype == MH_DYLINKER)
2692 seglinkedit = TRUE;
2693 else
2694 seglinkedit = FALSE;
2696 else{
2697 if(seglinkedit &&
2698 (filetype != MH_EXECUTE && filetype != MH_BUNDLE &&
2699 filetype != MH_FVMLIB &&
2700 filetype != MH_DYLIB && filetype != MH_DYLINKER))
2701 fatal("link edit segment can't be created (wrong output file "
2702 "type, file type must be MH_EXECUTE, MH_BUNDLE, "
2703 "MH_DYLIB, MH_DYLINKER or MH_FVMLIB)");
2705 if(allow_stack_execute == TRUE && filetype != MH_EXECUTE)
2706 fatal("-allow_stack_execute can only be used when output file type "
2707 "is MH_EXECUTE");
2709 if(trace)
2710 print("%s: Pass 1\n", progname);
2712 * This pass of parsing arguments only processes object files
2713 * and creation of symbols now that all the options are set.
2714 * This are order dependent and must be processed as they appear
2715 * on the command line.
2717 symbols_created = 0;
2718 objects_specified = 0;
2719 sections_created = 0;
2721 * If a -bundle_loader is specified and this is a flat_namespace
2722 * output force the bundle_loader to be loaded first.
2724 if(bundle_loader != NULL && twolevel_namespace == FALSE){
2725 pass1(bundle_loader, FALSE, FALSE, FALSE, TRUE, FALSE);
2727 for(i = 1 ; i < argc ; i++){
2728 if(*argv[i] != '-'){
2729 /* just a normal object file name */
2730 pass1(argv[i], FALSE, FALSE, FALSE, FALSE, FALSE);
2731 objects_specified++;
2733 else{
2734 p = &(argv[i][1]);
2735 switch(*p){
2736 case 'b':
2737 if(strcmp(p, "bundle_loader") == 0){
2739 * If a -bundle_loader was specified and this is a
2740 * flat_namespace output force the bundle_loader was
2741 * loaded first above.
2743 if(twolevel_namespace == TRUE)
2744 pass1(argv[i+1], FALSE, FALSE, FALSE, TRUE, FALSE);
2745 i++;
2746 break;
2748 break;
2749 case 'l':
2750 /* path searched abbrevated file name */
2751 pass1(argv[i], TRUE, FALSE, FALSE, FALSE, FALSE);
2752 objects_specified++;
2753 break;
2754 case 'A':
2755 if(base_obj != NULL)
2756 fatal("only one -A argument can be specified");
2757 pass1(argv[++i], FALSE, TRUE, FALSE, FALSE, FALSE);
2758 objects_specified++;
2759 break;
2760 case 'f':
2761 if(strcmp(p, "framework") == 0){
2762 if(dynamic == FALSE)
2763 fatal("incompatible flag -framework used (must "
2764 "specify \"-dynamic\" to be used)");
2765 pass1(argv[++i], FALSE, FALSE, TRUE, FALSE, FALSE);
2766 objects_specified++;
2768 if(strcmp(p, "filelist") == 0){
2769 filelist = argv[++i];
2770 dirname = strrchr(filelist, ',');
2771 if(dirname != NULL){
2772 *dirname = '\0';
2773 dirname++;
2775 else
2776 dirname = "";
2777 if((fd = open(filelist, O_RDONLY, 0)) == -1)
2778 system_fatal("can't open file list file: %s",
2779 filelist);
2780 if(fstat(fd, &stat_buf) == -1)
2781 system_fatal("can't stat file list file: %s",
2782 filelist);
2784 * For some reason mapping files with zero size fails
2785 * so it has to be handled specially.
2787 if(stat_buf.st_size != 0){
2788 if((r = map_fd((int)fd, (vm_offset_t)0,
2789 (vm_offset_t *)&(addr), (boolean_t)TRUE,
2790 (vm_size_t)stat_buf.st_size)) != KERN_SUCCESS)
2791 mach_fatal(r, "can't map file list file: %s",
2792 filelist);
2794 else{
2795 fatal("file list file: %s is empty", filelist);
2797 close(fd);
2798 file_name = addr;
2799 for(j = 0; j < stat_buf.st_size; j++){
2800 if(addr[j] == '\n'){
2801 addr[j] = '\0';
2802 if(*dirname != '\0'){
2803 file_name = mkstr(dirname, "/",
2804 file_name, NULL);
2806 pass1(file_name, FALSE, FALSE, FALSE, FALSE,
2807 FALSE);
2808 objects_specified++;
2809 file_name = addr + j + 1;
2813 if(strcmp(p, "final_output") == 0)
2814 i++;
2815 break;
2816 case 'm':
2817 if(strcmp(p, "multiply_defined") == 0 ||
2818 strcmp(p, "multiply_defined_unused") == 0 ||
2819 strcmp(p, "macosx_version_min") == 0){
2820 i++;
2821 break;
2823 break;
2824 case 'u':
2825 if(strcmp(p, "undefined") == 0 ||
2826 strcmp(p, "umbrella") == 0 ||
2827 strcmp(p, "unexported_symbols_list") == 0){
2828 i++;
2829 break;
2831 /* cause the specified symbol name to be undefined */
2832 (void)command_line_symbol(argv[++i]);
2833 symbols_created++;
2834 break;
2835 case 'i':
2836 if(strcmp(p, "image_base") == 0){
2837 i++;
2838 break;
2840 else if(strcmp(p, "init") == 0){
2841 i++;
2842 break;
2844 else if(strcmp(p, "install_name") == 0){
2845 i++;
2846 break;
2848 /* create an indirect symbol, symbol_name, to be an indirect
2849 symbol for indr_symbol_name */
2850 symbol_name = p + 1;
2851 indr_symbol_name = strchr(p + 1, ':');
2852 *indr_symbol_name = '\0';
2853 indr_symbol_name++;
2854 command_line_indr_symbol(symbol_name, indr_symbol_name);
2855 symbols_created++;
2856 break;
2858 /* multi argument flags */
2859 case 'a':
2860 if(strcmp(p, "all_load") == 0 ||
2861 strcmp(p, "arch_multiple") == 0 ||
2862 strcmp(p, "arch_errors_fatal") == 0 ||
2863 strcmp(p, "allow_stack_execute") == 0)
2864 break;
2865 i++;
2866 break;
2867 case 'c':
2868 i++;
2869 break;
2870 case 'p':
2871 if(strcmp(p, "pagezero_size") == 0){
2872 i++;
2873 break;
2875 break;
2876 case 's':
2877 if(strcmp(p, "sectcreate") == 0 ||
2878 strcmp(p, "segcreate") == 0){
2879 sections_created++;
2880 i += 3;
2882 else if(strcmp(p, "sectalign") == 0 ||
2883 strcmp(p, "segprot") == 0 ||
2884 strcmp(p, "sectorder") == 0)
2885 i += 3;
2886 else if(strcmp(p, "segaddr") == 0 ||
2887 strcmp(p, "sect_diff_relocs") == 0 ||
2888 strcmp(p, "sectobjectsymbols") == 0)
2889 i += 2;
2890 else if(strcmp(p, "seg1addr") == 0 ||
2891 strcmp(p, "stack_addr") == 0 ||
2892 strcmp(p, "stack_size") == 0 ||
2893 strcmp(p, "segalign") == 0 ||
2894 strcmp(p, "segs_read_only_addr") == 0 ||
2895 strcmp(p, "segs_read_write_addr") == 0 ||
2896 strcmp(p, "seg_addr_table") == 0 ||
2897 strcmp(p, "seg_addr_table_filename") == 0 ||
2898 strcmp(p, "sub_umbrella") == 0 ||
2899 strcmp(p, "sub_library") == 0 ||
2900 strcmp(p, "syslibroot") == 0)
2901 i++;
2902 break;
2903 case 'r':
2904 if(strcmp(p, "r") == 0 ||
2905 strcmp(p, "run_init_lazily") == 0)
2906 break;
2907 i++;
2908 break;
2909 case 'o':
2910 if(strcmp(p, "object") == 0)
2911 break;
2912 i++;
2913 break;
2914 case 'e':
2915 if(strcmp(p, "execute") == 0)
2916 break;
2917 i++;
2918 break;
2919 case 'd':
2920 if(strcmp(p, "d") == 0 ||
2921 strcmp(p, "dylib") == 0 ||
2922 strcmp(p, "dylinker") == 0 ||
2923 strcmp(p, "dynamic") == 0 ||
2924 strcmp(p, "dead_strip") == 0)
2925 break;
2926 i++;
2927 break;
2928 case 'h':
2929 if(strcmp(p, "headerpad_max_install_names") == 0)
2930 break;
2931 i++;
2932 break;
2933 case 'U':
2934 case 'N':
2935 case 'Y':
2936 i++;
2937 break;
2938 case 'w':
2939 if(strcmp(p, "weak_reference_mismatches") == 0)
2940 i++;
2941 else if(strcmp(p, "weak_library") == 0){
2942 pass1(argv[++i], FALSE, FALSE, FALSE, FALSE, TRUE);
2943 objects_specified++;
2945 else if(strncmp(p, "weak-l", sizeof("weak-l") - 1) == 0){
2946 /* path searched abbrevated file name */
2947 pass1(argv[i] + sizeof("weak"), TRUE, FALSE, FALSE,
2948 FALSE, TRUE);
2949 objects_specified++;
2951 else if(strcmp(p, "weak_framework") == 0){
2952 if(dynamic == FALSE)
2953 fatal("incompatible flag -weak_framework used (must"
2954 " specify \"-dynamic\" to be used)");
2955 pass1(argv[++i], FALSE, FALSE, TRUE, FALSE, TRUE);
2956 objects_specified++;
2958 break;
2964 * If the architecture was not specified, and was inferred
2965 * from the object files, if it is a 64-bit architecture it is an error.
2967 if(arch_flag.cputype != 0 &&
2968 arch_flag.cputype & CPU_ARCH_ABI64){
2969 fatal("does not support 64-bit architectures");
2973 * Now search the libraries on the dynamic shared libraries search list
2975 search_dynamic_libs();
2978 * Check to see that the output file will have something in it.
2980 if(objects_specified == 0){
2981 if(symbols_created != 0 || sections_created != 0){
2982 warning("no object files specified, only command line created "
2983 "symbols and/or sections created from files will "
2984 "appear in the output file");
2985 if(arch_flag.name == NULL)
2986 target_byte_sex = host_byte_sex;
2987 segalign = host_pagesize;
2989 else{
2990 if(vflag == TRUE)
2991 ld_exit(0);
2992 fatal("no object files specified");
2995 else if(base_obj != NULL && nobjects == 1){
2996 if(symbols_created != 0 || sections_created != 0)
2997 warning("no object files loaded other than base file, only "
2998 "additional command line created symbols and/or "
2999 "sections created from files will appear in the output "
3000 "file");
3001 else{
3002 if(vflag == TRUE)
3003 ld_exit(0);
3004 fatal("no object files loaded other than base file");
3007 else if(nobjects == 0){
3008 if(symbols_created != 0 || sections_created != 0)
3009 warning("no object files loaded, only command line created "
3010 "symbols and/or sections created from files will "
3011 "appear in the output file");
3012 else{
3013 if(vflag == TRUE)
3014 ld_exit(0);
3015 fatal("no object files loaded");
3019 #ifdef DEBUG
3020 if(debug & (1 < 0))
3021 print_object_list();
3022 if(debug & (1 << 1))
3023 print_merged_sections("after pass1");
3024 if(debug & (1 << 2))
3025 print_symbol_list("after pass1", TRUE);
3026 if(debug & (1 << 3))
3027 print_undefined_list();
3028 if(debug & (1 << 4))
3029 print_segment_specs();
3030 if(debug & (1 << 5))
3031 print_load_fvmlibs_list();
3032 if(debug & (1 << 6))
3033 print_fvmlib_segments();
3034 if(debug & (1 << 9)){
3035 print("Number of objects loaded = %lu\n", nobjects);
3036 print("Number of merged symbols = %lu\n", nmerged_symbols);
3038 #endif /* DEBUG */
3041 * If there were any errors from pass1() then don't continue.
3043 if(errors != 0)
3044 ld_exit(1);
3047 * Print which files are loaded if requested.
3049 if(whatsloaded == TRUE)
3050 print_whatsloaded();
3053 * Clean up any data structures not need for layout() or pass2().
3055 if(nsearch_dirs != 0){
3056 free(search_dirs);
3057 nsearch_dirs = 0;
3061 * Layout the output object file.
3063 layout();
3066 * Check to that the exported or unexported symbols listed were seen.
3068 if(save_symbols != NULL){
3069 missing_syms = FALSE;
3070 for(j = 0; j < nsave_symbols ; j++){
3071 if(save_symbols[j].seen == FALSE){
3072 if(missing_syms == FALSE){
3073 error("symbols names listed in "
3074 "-exported_symbols_list: %s not in linked "
3075 "objects", exported_symbols_list);
3076 missing_syms = TRUE;
3078 printf("%s\n", save_symbols[j].name);
3084 * If there were any errors from layout() then don't continue.
3086 if(errors != 0)
3087 ld_exit(1);
3090 * Clean up any data structures not need for pass2().
3092 free_pass1_symbol_data();
3093 if(ntrace_syms != 0){
3094 free(trace_syms);
3095 ntrace_syms = 0;
3097 if(nundef_syms != 0){
3098 free(undef_syms);
3099 nundef_syms = 0;
3103 * Write the output object file doing relocation on the sections.
3105 if(trace)
3106 print("%s: Pass 2\n", progname);
3107 pass2();
3109 * If there were any errors from pass2() make sure the output file is
3110 * removed and exit non-zero.
3112 if(errors != 0)
3113 cleanup();
3115 if(hash_instrument_specified == TRUE)
3116 hash_instrument();
3118 ld_exit(0);
3120 /* this is to remove the compiler warning, it never gets here */
3121 return(0);
3125 * unprebound_library() checks the file for the environment variable
3126 * LD_UNPREBOUND_LIBRARIES to see if the dynamic library is one listed as to
3127 * not be prebound. The dynamic library is specified with the
3128 * dylib_install_name unless seg_addr_table_filename is not NULL then
3129 * seg_addr_table_filename is used. If it is found on the list then TRUE is
3130 * returned. If not FALSE is returned.
3132 static
3133 enum bool
3134 unprebound_library(
3135 char *dylib_install_name,
3136 char *seg_addr_table_filename)
3138 int fd;
3139 kern_return_t r;
3140 struct stat stat_buf;
3141 unsigned long j, file_size, line;
3142 char *file_name, *library_name, *file_addr, *name, *end;
3145 * If there is no file name then it is not on the list and return FALSE.
3147 file_name = getenv("LD_UNPREBOUND_LIBRARIES");
3148 if(file_name == NULL)
3149 return(FALSE);
3152 * If there is no library name then it is not on the list and return
3153 * FALSE.
3155 if(seg_addr_table_filename != NULL)
3156 library_name = dylib_install_name;
3157 else if(dylib_install_name != NULL)
3158 library_name = dylib_install_name;
3159 else
3160 return(FALSE);
3163 if((fd = open(file_name, O_RDONLY, 0)) == -1)
3164 system_fatal("Can't open: %s for LD_UNPREBOUND_LIBRARIES "
3165 "environment variable", file_name);
3166 if(fstat(fd, &stat_buf) == -1)
3167 system_fatal("Can't stat file: %s for LD_UNPREBOUND_LIBRARIES "
3168 "environment variable", file_name);
3170 * For some reason mapping files with zero size fails
3171 * so it has to be handled specially.
3173 if(stat_buf.st_size != 0){
3174 if((r = map_fd((int)fd, (vm_offset_t)0,
3175 (vm_offset_t *)&file_addr, (boolean_t)TRUE,
3176 (vm_size_t)stat_buf.st_size)) != KERN_SUCCESS)
3177 mach_fatal(r, "can't map file: %s for LD_UNPREBOUND_LIBRARIES "
3178 "environment variable", file_name);
3180 else
3181 fatal("Empty file: %s for LD_UNPREBOUND_LIBRARIES environment "
3182 "variable", file_name);
3183 close(fd);
3184 file_size = stat_buf.st_size;
3187 * Got the file mapped now parse it.
3189 if(file_addr[file_size - 1] != '\n')
3190 fatal("file: %s for LD_UNPREBOUND_LIBRARIES environment variable "
3191 "does not end in new line", file_name);
3193 line = 1;
3194 for(j = 0; j < file_size; /* no increment expression */ ){
3195 /* Skip lines that start with '#' */
3196 if(file_addr[j] == '#'){
3197 j++;
3198 while(file_addr[j] != '\n')
3199 j++;
3200 continue;
3202 /* Skip blank lines and leading white space */
3203 while(file_addr[j] == ' ' || file_addr[j] == '\t')
3204 j++;
3205 if(file_addr[j] == '\n'){
3206 j++;
3207 line++;
3208 continue;
3210 if(j == file_size)
3211 fatal("missing library install name on line %lu in file: "
3212 "%s for LD_UNPREBOUND_LIBRARIES environment variable",
3213 line, file_name);
3215 name = file_addr + j;
3216 while(file_addr[j] != '\n')
3217 j++;
3218 file_addr[j] = '\0';
3219 end = file_addr + j;
3220 line++;
3221 j++;
3223 /* Trim trailing spaces */
3224 end--;
3225 while(end > name && (*end == ' ' || *end == '\t')){
3226 *end = '\0';
3227 end--;
3230 /* finally compare the name on this line with the library name */
3231 if(strcmp(library_name, name) == 0)
3232 return(TRUE);
3235 return(FALSE);
3239 * ispoweroftwo() returns TRUE or FALSE depending if x is a power of two.
3241 static
3242 enum
3243 bool
3244 ispoweroftwo(
3245 unsigned long x)
3247 if(x == 0)
3248 return(TRUE);
3249 while((x & 0x1) != 0x1){
3250 x >>= 1;
3252 if((x & ~0x1) != 0)
3253 return(FALSE);
3254 else
3255 return(TRUE);
3259 * getprot() returns the vm_prot for the specified string passed to it. The
3260 * string may contain any of the following characters: 'r', 'w', 'x' and '-'
3261 * representing read, write, execute and no protections. The pointer pointed
3262 * to by endp is set to the first character that is not one of the above
3263 * characters.
3265 static
3266 vm_prot_t
3267 getprot(
3268 char *prot,
3269 char **endp)
3271 vm_prot_t vm_prot;
3273 vm_prot = VM_PROT_NONE;
3274 while(*prot){
3275 switch(*prot){
3276 case 'r':
3277 case 'R':
3278 vm_prot |= VM_PROT_READ;
3279 break;
3280 case 'w':
3281 case 'W':
3282 vm_prot |= VM_PROT_WRITE;
3283 break;
3284 case 'x':
3285 case 'X':
3286 vm_prot |= VM_PROT_EXECUTE;
3287 break;
3288 case '-':
3289 break;
3290 default:
3291 *endp = prot;
3292 return(vm_prot);
3294 prot++;
3296 *endp = prot;
3297 return(vm_prot);
3301 * check_max_init_prot() checks to make sure that all protections in the initial
3302 * protection are also in the maximum protection.
3304 static
3305 enum bool
3306 check_max_init_prot(
3307 vm_prot_t maxprot,
3308 vm_prot_t initprot)
3310 if(((initprot & VM_PROT_READ) && !(maxprot & VM_PROT_READ)) ||
3311 ((initprot & VM_PROT_WRITE) && !(maxprot & VM_PROT_WRITE)) ||
3312 ((initprot & VM_PROT_EXECUTE) && !(maxprot & VM_PROT_EXECUTE)) )
3313 return(FALSE);
3314 return(TRUE);
3318 * ld_exit() is use for all exit()s from the link editor.
3320 static
3321 void
3322 ld_exit(
3323 int exit_value)
3325 exit(exit_value);
3329 * cleanup() is called by all routines handling fatal errors to remove the
3330 * output file if it had been created by the link editor and exit non-zero.
3332 static
3333 void
3334 cleanup(void)
3336 if(output_addr != NULL)
3337 unlink(outputfile);
3338 ld_exit(1);
3342 * handler() is the routine for catching SIGINT, SIGTERM, SIGBUG & SIGSEGV
3343 * signals. It cleans up and exit()'s non-zero.
3345 static
3346 void
3347 handler(
3348 int sig)
3350 #ifdef __MWERKS__
3351 int dummy;
3352 dummy = sig;
3353 #endif
3354 if(output_addr != NULL)
3355 unlink(outputfile);
3356 _exit(1);
3360 * allocate() is just a wrapper around malloc that prints and error message and
3361 * exits if the malloc fails.
3363 __private_extern__
3364 void *
3365 allocate(
3366 unsigned long size)
3368 void *p;
3370 if(size == 0)
3371 return(NULL);
3372 if((p = malloc(size)) == NULL)
3373 system_fatal("virtual memory exhausted (malloc failed)");
3374 return(p);
3378 * reallocate() is just a wrapper around realloc that prints and error message
3379 * and exits if the realloc fails.
3381 __private_extern__
3382 void *
3383 reallocate(
3384 void *p,
3385 unsigned long size)
3387 if(p == NULL)
3388 return(allocate(size));
3389 if((p = realloc(p, size)) == NULL)
3390 system_fatal("virtual memory exhausted (realloc failed)");
3391 return(p);
3395 * savestr() malloc's space for the string passed to it, copys the string into
3396 * the space and returns a pointer to that space.
3398 __private_extern__
3399 char *
3400 savestr(
3401 const char *s)
3403 long len;
3404 char *r;
3406 len = strlen(s) + 1;
3407 r = (char *)allocate(len);
3408 strcpy(r, s);
3409 return(r);
3413 * Mkstr() creates a string that is the concatenation of a variable number of
3414 * strings. It is pass a variable number of pointers to strings and the last
3415 * pointer is NULL. It returns the pointer to the string it created. The
3416 * storage for the string is malloc()'ed can be free()'ed when nolonger needed.
3418 static
3419 char *
3420 mkstr(
3421 const char *args,
3422 ...)
3424 va_list ap;
3425 char *s, *p;
3426 unsigned long size;
3428 size = 0;
3429 if(args != NULL){
3430 size += strlen(args);
3431 va_start(ap, args);
3432 p = (char *)va_arg(ap, char *);
3433 while(p != NULL){
3434 size += strlen(p);
3435 p = (char *)va_arg(ap, char *);
3438 s = allocate(size + 1);
3439 *s = '\0';
3441 if(args != NULL){
3442 (void)strcat(s, args);
3443 va_start(ap, args);
3444 p = (char *)va_arg(ap, char *);
3445 while(p != NULL){
3446 (void)strcat(s, p);
3447 p = (char *)va_arg(ap, char *);
3449 va_end(ap);
3451 return(s);
3453 #endif /* !defined(RLD) */
3456 * rnd() rounds v to a multiple of r.
3458 __private_extern__
3459 unsigned long
3460 rnd(
3461 unsigned long v,
3462 unsigned long r)
3464 r--;
3465 v += r;
3466 v &= ~(long)r;
3467 return(v);
3470 #ifndef RLD
3471 #include "stuff/unix_standard_mode.h"
3473 * All printing of all messages goes through this function.
3475 __private_extern__
3476 void
3477 vprint(
3478 const char *format,
3479 va_list ap)
3481 if(get_unix_standard_mode() == TRUE)
3482 vfprintf(stderr, format, ap);
3483 else
3484 vprintf(format, ap);
3486 #endif /* !defined(RLD) */
3489 * The print function that just calls the above vprint() function.
3491 __private_extern__
3492 void
3493 print(
3494 const char *format,
3495 ...)
3497 va_list ap;
3499 va_start(ap, format);
3500 vprint(format, ap);
3501 va_end(ap);
3505 * The ld_trace function that logs things for B&I.
3507 __private_extern__
3508 void
3509 ld_trace(
3510 const char *format,
3511 ...)
3513 #ifdef KLD
3514 va_list ap;
3516 va_start(ap, format);
3517 vprint(format, ap);
3518 va_end(ap);
3519 #else
3520 static int trace_file = -1;
3521 char trace_buffer[MAXPATHLEN * 2];
3522 char *buffer_ptr;
3523 int length;
3524 ssize_t amount_written;
3526 if(trace_file == -1){
3527 if(trace_file_path != NULL){
3528 trace_file = open(trace_file_path, O_WRONLY | O_APPEND | O_CREAT, 0666);
3529 if(trace_file == -1)
3530 fatal("Could not open or create trace file: %s\n", trace_file_path);
3532 else{
3533 trace_file = fileno(stderr);
3536 va_list ap;
3538 va_start(ap, format);
3539 length = vsnprintf(trace_buffer, sizeof(trace_buffer), format, ap);
3540 va_end(ap);
3541 buffer_ptr = trace_buffer;
3542 while(length > 0){
3543 amount_written = write(trace_file, buffer_ptr, length);
3544 if(amount_written == -1)
3545 /* Failure to write shouldn't fail the build. */
3546 return;
3547 buffer_ptr += amount_written;
3548 length -= amount_written;
3550 #endif
3553 static
3554 void
3555 print_architecture_banner(void)
3557 static enum bool printed = FALSE;
3559 if(arch_multiple == TRUE && printed == FALSE && arch_flag.name != NULL){
3560 print("%s: for architecture %s\n", progname, arch_flag.name);
3561 printed = TRUE;
3566 * Print the warning message. This is non-fatal and does not set 'errors'.
3568 __private_extern__
3569 void
3570 warning(
3571 const char *format,
3572 ...)
3574 va_list ap;
3576 if(nowarnings == TRUE)
3577 return;
3578 if(arch_multiple)
3579 print_architecture_banner();
3580 va_start(ap, format);
3581 print("%s: warning ", progname);
3582 vprint(format, ap);
3583 print("\n");
3584 va_end(ap);
3588 * Print the error message and set the 'error' indication.
3590 __private_extern__
3591 void
3592 error(
3593 const char *format,
3594 ...)
3596 va_list ap;
3598 if(arch_multiple)
3599 print_architecture_banner();
3600 va_start(ap, format);
3601 print("%s: ", progname);
3602 vprint(format, ap);
3603 print("\n");
3604 va_end(ap);
3605 errors = 1;
3609 * Print the fatal error message, and exit non-zero.
3611 __private_extern__
3612 void
3613 fatal(
3614 const char *format,
3615 ...)
3617 va_list ap;
3619 if(arch_multiple)
3620 print_architecture_banner();
3621 va_start(ap, format);
3622 print("%s: ", progname);
3623 vprint(format, ap);
3624 print("\n");
3625 va_end(ap);
3626 cleanup();
3630 * Print the current object file name and warning message.
3632 __private_extern__
3633 void
3634 warning_with_cur_obj(
3635 const char *format,
3636 ...)
3638 va_list ap;
3640 if(nowarnings == TRUE)
3641 return;
3642 if(arch_multiple)
3643 print_architecture_banner();
3644 va_start(ap, format);
3645 print("%s: warning ", progname);
3646 print_obj_name(cur_obj);
3647 vprint(format, ap);
3648 print("\n");
3649 va_end(ap);
3653 * Print the current object file name and error message, set the non-fatal
3654 * error indication.
3656 __private_extern__
3657 void
3658 error_with_cur_obj(
3659 const char *format,
3660 ...)
3662 va_list ap;
3664 if(arch_multiple)
3665 print_architecture_banner();
3666 va_start(ap, format);
3667 print("%s: ", progname);
3668 print_obj_name(cur_obj);
3669 vprint(format, ap);
3670 print("\n");
3671 va_end(ap);
3672 errors = 1;
3675 #if !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__))
3677 * Print the warning message along with the system error message.
3679 __private_extern__
3680 void
3681 system_warning(
3682 const char *format,
3683 ...)
3685 va_list ap;
3686 int errnum;
3688 if(arch_multiple)
3689 print_architecture_banner();
3690 errnum = errno;
3691 va_start(ap, format);
3692 print("%s: warning ", progname);
3693 vprint(format, ap);
3694 print(" (%s, errno = %d)\n", strerror(errnum), errnum);
3695 va_end(ap);
3699 * Print the error message along with the system error message, set the
3700 * non-fatal error indication.
3702 __private_extern__
3703 void
3704 system_error(
3705 const char *format,
3706 ...)
3708 va_list ap;
3709 int errnum;
3711 if(arch_multiple)
3712 print_architecture_banner();
3713 errnum = errno;
3714 va_start(ap, format);
3715 print("%s: ", progname);
3716 vprint(format, ap);
3717 print(" (%s, errno = %d)\n", strerror(errnum), errnum);
3718 va_end(ap);
3719 errors = 1;
3723 * Print the fatal message along with the system error message, and exit
3724 * non-zero.
3726 __private_extern__
3727 void
3728 system_fatal(
3729 const char *format,
3730 ...)
3732 va_list ap;
3733 int errnum;
3735 if(arch_multiple)
3736 print_architecture_banner();
3737 errnum = errno;
3738 va_start(ap, format);
3739 print("%s: ", progname);
3740 vprint(format, ap);
3741 print(" (%s, errno = %d)\n", strerror(errnum), errnum);
3742 va_end(ap);
3743 cleanup();
3745 #endif /* !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) */
3748 * Print the fatal error message along with the mach error string, and exit
3749 * non-zero.
3751 __private_extern__
3752 void
3753 mach_fatal(
3754 kern_return_t r,
3755 char *format,
3756 ...)
3758 va_list ap;
3760 if(arch_multiple)
3761 print_architecture_banner();
3762 va_start(ap, format);
3763 print("%s: ", progname);
3764 vprint(format, ap);
3765 print(" (%s)\n", mach_error_string(r));
3766 va_end(ap);
3767 cleanup();