1/*
2 * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23#ifdef SHLIB
24#include "shlib.h"
25#endif /* SHLIB */
26/*
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.
31 */
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__)) */
68
69#include "ld.h"
70#ifndef RLD
71static 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"
84
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;
94
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
102static enum bool filetype_specified = FALSE;
103static enum bool moduletype_specified = FALSE;
104/* if the -A flag is specified use to set the object file type */
105static enum bool Aflag_specified = FALSE;
106#endif /* !defined(RLD) */
107/*
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.
112 */
113__private_extern__ struct arch_flag arch_flag =
114#if defined(KLD) && defined(__STATIC__)
115
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
125
126#else /* !(defined(KLD) && defined(__STATIC__)) */
127    { 0 };
128#endif /* defined(KLD) && defined(__STATIC__) */
129__private_extern__ enum bool specific_arch_flag = FALSE;
130
131/*
132 * The -force_cpusubtype_ALL flag.
133 */
134__private_extern__ enum bool force_cpusubtype_ALL = FALSE;
135
136/* the byte sex of the output file */
137__private_extern__ enum byte_sex target_byte_sex = UNKNOWN_BYTE_SEX;
138static enum bool arch_multiple = FALSE;	/* print one arch message before error*/
139
140__private_extern__
141enum bool trace = FALSE;		/* print stages of link-editing */
142__private_extern__
143enum bool save_reloc = FALSE;		/* save relocation information */
144__private_extern__
145enum bool output_for_dyld = FALSE;	/* produce output for use with dyld */
146__private_extern__
147enum bool bind_at_load = FALSE;		/* mark the output for dyld to be bound
148					   when loaded */
149__private_extern__
150enum bool no_fix_prebinding = FALSE;	/* mark the output for dyld to never
151					   run fix_prebinding */
152__private_extern__
153enum bool load_map = FALSE;		/* print a load map */
154__private_extern__
155enum bool define_comldsyms = TRUE;	/* define common and link-editor defined
156					   symbol reguardless of file type */
157#ifndef RLD
158static enum bool
159    dflag_specified = FALSE;		/* the -d flag has been specified */
160#endif /* !defined(RLD) */
161__private_extern__
162enum bool seglinkedit = FALSE;		/* create the link edit segment */
163#ifndef RLD
164static enum bool
165    seglinkedit_specified = FALSE;	/* if either -seglinkedit or */
166					/*  -noseglinkedit was specified */
167#endif /* !defined(RLD) */
168__private_extern__
169enum bool whyload = FALSE;		/* print why archive members are
170					   loaded */
171#ifndef RLD
172static enum bool whatsloaded = FALSE;	/* print which object files are loaded*/
173#endif /* !defined(RLD) */
174__private_extern__
175enum bool flush = TRUE;			/* Use the output_flush routine to flush
176					   output file by pages */
177__private_extern__
178enum bool sectorder_detail = FALSE;	/* print sectorder warnings in detail */
179__private_extern__
180enum bool nowarnings = FALSE;		/* suppress warnings */
181__private_extern__
182enum bool no_arch_warnings = FALSE;	/* suppress wrong arch warnings */
183__private_extern__
184enum bool arch_errors_fatal = FALSE;	/* cause wrong arch errors to be fatal*/
185__private_extern__
186enum bool archive_ObjC = FALSE;		/* objective-C archive semantics */
187__private_extern__
188enum bool archive_all = FALSE;		/* always load everything in archives */
189__private_extern__
190enum 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__
194enum bool dynamic = TRUE;
195#ifndef RLD
196static enum bool dynamic_specified = FALSE;
197static enum bool static_specified = FALSE;
198#endif
199
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;
204
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;
211
212#ifndef RLD
213/*
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
217 */
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;
222
223/*
224 * -executable_path option's argument, executable_path is used to replace
225 * @executable_path for dependent libraries.
226 */
227__private_extern__ char *executable_path = NULL;
228#endif /* RLD */
229
230
231/* The list of symbols to be traced */
232__private_extern__ char **trace_syms = NULL;
233__private_extern__ unsigned long ntrace_syms = 0;
234
235/* The number of references of undefined symbols to print */
236__private_extern__ unsigned long Yflag = 0;
237
238/* The list of allowed undefined symbols */
239__private_extern__ char **undef_syms = NULL;
240__private_extern__ unsigned long nundef_syms = 0;
241
242/* The list of -dylib_file arguments */
243__private_extern__ char **dylib_files = NULL;
244__private_extern__ unsigned long ndylib_files = 0;
245
246/* The checking for undefined symbols */
247__private_extern__ enum undefined_check_level undefined_flag = UNDEFINED_ERROR;
248#ifndef RLD
249static enum bool undefined_flag_specified = FALSE;
250#endif
251
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
260static enum bool multiply_defined_flag_specified = FALSE;
261static enum bool multiply_defined_unused_flag_specified = FALSE;
262#endif
263
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;
267
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;
271
272/* The handling for weak reference mismatches */
273__private_extern__ enum weak_reference_mismatches_handling
274    weak_reference_mismatches = WEAK_REFS_MISMATCH_ERROR;
275
276/* The Mac OS X deployment target */
277__private_extern__ struct macosx_deployment_target
278	macosx_deployment_target = { 0 };
279
280/* The prebinding optimization */
281#ifndef RLD
282static 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
288static enum bool read_only_reloc_flag_specified = FALSE;
289static enum bool sect_diff_reloc_flag_specified = FALSE;
290static enum bool weak_reference_mismatches_specified = FALSE;
291static enum bool prebind_all_twolevel_modules_specified = FALSE;
292static enum bool unprebound_library(
293    char *dylib_install_name,
294    char *seg_addr_table_filename);
295#endif
296
297/* True if -m is specified to allow multiply symbols, as a warning */
298__private_extern__ enum bool allow_multiply_defined_symbols = FALSE;
299
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.
302 */
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;
308
309/* The default section alignment */
310__private_extern__ unsigned long defaultsectalign = DEFAULTSECTALIGN;
311
312/* The first segment address */
313__private_extern__ unsigned long seg1addr = 0;
314__private_extern__ enum bool seg1addr_specified = FALSE;
315
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;
321
322#ifndef RLD
323/* file name of the segment address table */
324static char *seg_addr_table_name = NULL;
325/* the file system path name to use instead of the install name */
326static char *seg_addr_table_filename = NULL;
327#endif /* !defined(RLD) */
328
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;
334
335/* TRUE if -allow_stack_execute is specified */
336__private_extern__ enum bool allow_stack_execute = FALSE;
337
338#ifndef RLD
339/* A -segaddr option was specified */
340static enum bool segaddr_specified = FALSE;
341#endif /* !defined(RLD) */
342
343/*
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.
347 */
348__private_extern__ unsigned long headerpad = sizeof(struct section) * 2;
349#ifndef RLD
350static enum bool headerpad_specified = FALSE;
351#endif /* !defined(RLD) */
352/*
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.
355 */
356__private_extern__ enum bool headerpad_max_install_names = FALSE;
357
358/* The name of the specified entry point */
359__private_extern__ char *entry_point_name = NULL;
360
361/* The name of the specified library initialization routine */
362__private_extern__ char *init_name = NULL;
363
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;
368
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;
377
378/* The list of sub_umbrella frameworks */
379__private_extern__ char **sub_umbrellas = NULL;
380__private_extern__ unsigned long nsub_umbrellas = 0;
381
382/* The list of sub_library dynamic libraries */
383__private_extern__ char **sub_librarys = NULL;
384__private_extern__ unsigned long nsub_librarys = 0;
385
386/* The dylinker information */
387__private_extern__ char *dylinker_install_name = NULL;
388
389#ifndef RLD
390/* set to the -bundle_loader argument if specified */
391static char *bundle_loader = NULL;
392#endif
393
394/* set to TRUE if -private_bundle is specified */
395__private_extern__ enum bool private_bundle = FALSE;
396
397/* The value of the environment variable NEXT_ROOT or the -syslibroot argument*/
398__private_extern__ char *next_root = NULL;
399#ifndef RLD
400static enum bool syslibroot_specified = FALSE;
401#endif
402
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;
406
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;
410
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;
414
415#ifndef KLD
416/* The file LD_TRACE_FILE references, or NULL if none is set */
417static const char *trace_file_path = NULL;
418#endif
419
420/* the argument to -final_output if any */
421__private_extern__ char *final_output = NULL;
422
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;
427
428#ifndef RLD
429/* Variable to support options logging.  */
430static enum bool ld_print_options = FALSE;
431#endif
432
433/*
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.
440 */
441#ifndef RLD
442static enum bool twolevel_namespace_hints_specified = FALSE;
443#endif
444__private_extern__ enum bool twolevel_namespace_hints = TRUE;
445
446#ifdef DEBUG
447__private_extern__ unsigned long debug = 0;	/* link-editor debugging */
448#endif /* DEBUG */
449
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) */
454static void cleanup(void);
455static void ld_exit(int exit_value);
456
457/* The signal hander routine for SIGINT, SIGTERM, SIGBUS & SIGSEGV */
458static void handler(int sig);
459
460/* Static routines to help parse arguments */
461static enum bool ispoweroftwo(unsigned long x);
462static vm_prot_t getprot(char *prot, char **endp);
463static enum bool check_max_init_prot(vm_prot_t maxprot, vm_prot_t initprot);
464
465/* apple_version is created by the libstuff/Makefile */
466extern char apple_version[];
467
468/*
469 * main() parses the command line arguments and drives the link-edit process.
470 */
471int
472main(
473int argc,
474char *argv[],
475char *envp[])
476{
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;
505
506#ifdef __MWERKS__
507    char **dummy;
508        dummy = envp;
509#endif
510
511	vflag = FALSE;
512	exported_symbols_list = NULL;
513	unexported_symbols_list = NULL;
514	seg_addr_table_entry = NULL;
515	hash_instrument_specified = FALSE;
516
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();
524
525	if(argc == 1)
526	    fatal("Usage: %s [options] file [...]", progname);
527
528	/*
529	 * If interrupt and termination signal are not being ignored catch
530	 * them so things can be cleaned up.
531	 */
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);
540
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;
545
546	/*
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).
551	 */
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;
557	    }
558	    else{
559	        if (ld_print_options == TRUE)
560		  print("[Logging ld options]\t%s\n", argv[i]);
561
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;
570
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;
590
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;
598		    }
599		    else if(strcmp(p, "M") == 0){
600			/* produce load map */
601			load_map = TRUE;
602		    }
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;
612		    }
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;
626		    }
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;
634		    }
635		    else if(strcmp(p, "prebind_allow_overlap") == 0){
636			prebind_allow_overlap = TRUE;
637		    }
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;
646		    }
647		    else if(strcmp(p, "private_bundle") == 0){
648			private_bundle = TRUE;
649		    }
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;
662		    }
663		    else if(strcmp(p, "force_cpusubtype_ALL") == 0){
664			force_cpusubtype_ALL = TRUE;
665		    }
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;
672		    }
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;
679		    }
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;
687		    }
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;
695		    }
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;
703		    }
704		    else
705			goto unknown_flag;
706		    break;
707
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;
719
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;
734			}
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;
742		    }
743		    else if(strcmp(p, "run_init_lazily") == 0){
744			warning("-run_init_lazily is obsolete");
745			break;
746		    }
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;
772		    }
773		    else if(strcmp(p, "dynamic") == 0){
774			if(static_specified)
775			    fatal("only one of -dynamic or -static can be "
776				  "specified");
777
778			dynamic = TRUE;
779			dynamic_specified = TRUE;
780		    }
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;
787		    }
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;
793		    }
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;
804		    }
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;
816		    }
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];
828		    }
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;
836		    }
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;
844		    }
845		    else if(strcmp(p, "dead_strip") == 0){
846			dead_strip = TRUE;
847		    }
848		    else if(strcmp(p, "dead_strip_times") == 0){
849			dead_strip_times = TRUE;
850		    }
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]);
859		    }
860#endif /* DEBUG */
861		    else
862			goto unknown_flag;
863		    break;
864
865		case 'n':
866		    if(strcmp(p, "noflush") == 0){
867			flush = FALSE;
868		    }
869		    else if(strcmp(p, "nofixprebinding") == 0){
870			no_fix_prebinding = TRUE;
871		    }
872		    else if(strcmp(p, "no_arch_warnings") == 0){
873			no_arch_warnings = TRUE;
874		    }
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;
881		    }
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;
889		    }
890		    else if(strcmp(p, "nomultidefs") == 0){
891			nomultidefs = TRUE;
892		    }
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;
901		    }
902		    else if(strcmp(p, "no_dead_strip_inits_and_terms") == 0){
903			no_dead_strip_inits_and_terms = TRUE;
904		    }
905		    else if(strcmp(p, "no_uuid") == 0){
906			 output_uuid_info.suppress = TRUE;
907		    }
908		    else if(strcmp(p, "noall_load") == 0){
909		      /* Ignore the flag.  */
910		      ;
911		    }
912		    else
913			goto unknown_flag;
914		    break;
915
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;
923		    }
924		    else if(strcmp(p, "bind_at_load") == 0){
925			bind_at_load = TRUE;
926		    }
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;
934		    }
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;
941
942		/*
943		 * Stripping level flags, in increasing level of stripping.  The
944		 * level of stripping is set to the maximum level specified.
945		 */
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;
955		    }
956		    else if(strcmp(p, "Si") == 0){
957			if(strip_level < STRIP_DUP_INCLS)
958			    strip_level = STRIP_DUP_INCLS;
959		    }
960		    else if(strcmp(p, "Sp") == 0){
961			if(strip_level < STRIP_MIN_DEBUG)
962			    strip_level = STRIP_MIN_DEBUG;
963		    }
964		    else if(p[1] == '\0'){
965			if(strip_level < STRIP_DEBUG)
966			    strip_level = STRIP_DEBUG;
967		    }
968		    else{
969			goto unknown_flag;
970		    }
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;
981		    }
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;
989		    }
990		    else if(strcmp(p, "search_paths_first") == 0){
991			search_paths_first = TRUE;
992		    }
993		    /*
994		     * Flags for specifing information about sections.
995		     */
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]);
1013			/*
1014			 * For some reason mapping files with zero size fails
1015			 * so it has to be handled specially.
1016			 */
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]);
1024			}
1025			else{
1026			    sect_spec->file_addr = NULL;
1027			}
1028			close(fd);
1029			sect_spec->file_size = stat_buf.st_size;
1030			sect_spec->contents_filename = argv[i+3];
1031			i += 3;
1032		    }
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;
1063		    }
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;
1081		    }
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]);
1098			/*
1099			 * For some reason mapping files with zero size fails
1100			 * so it has to be handled specially.
1101			 */
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]);
1109			}
1110			else{
1111			    sect_spec->order_addr = NULL;
1112			}
1113			close(fd);
1114			sect_spec->order_size = stat_buf.st_size;
1115			sect_spec->order_filename = argv[i+3];
1116			i += 3;
1117		    }
1118		    else if(strcmp(p, "sectorder_detail") == 0){
1119			sectorder_detail = TRUE;
1120		    }
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;
1134			}
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;
1142		    }
1143		    /*
1144		     * Flags for specifing information about segments.
1145		     */
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;
1162		    }
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;
1191		    }
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;
1205		    }
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;
1219		    }
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;
1233		    }
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;
1242		    }
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;
1252		    }
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;
1278			    }
1279			}
1280		    }
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;
1287		    }
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;
1301		    }
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;
1315		    }
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;
1325		    }
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;
1335		    }
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;
1344		    }
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;
1353		    }
1354		    else
1355			goto unknown_flag;
1356		    break;
1357
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;
1367		    }
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;
1374		    }
1375		    else if(p[1] == '\0')
1376			trace = TRUE;
1377		    else
1378			goto unknown_flag;
1379		    break;
1380
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;
1388		    }
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;
1398
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);
1418			}
1419			/* Default to -single_module on ARM. */
1420			if(arch_flag.cputype == CPU_TYPE_ARM){
1421			    multi_module_dylib = FALSE;
1422			}
1423			target_byte_sex = get_byte_sex_from_flag(&arch_flag);
1424		    }
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;
1435		    }
1436		    else
1437			goto unknown_flag;
1438		    break;
1439
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;
1451		    }
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;
1464		    }
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;
1476		    }
1477		    if(p[1] != '\0')
1478			goto unknown_flag;
1479		    break;
1480
1481
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;
1495		    }
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];
1503		    }
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;
1509		    }
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 */
1521		    }
1522		    break;
1523
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;
1538			}
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;
1546		    }
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;
1564			}
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;
1574		    }
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;
1584		    }
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;
1592		    }
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;
1599
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");
1616			}
1617			else{
1618			    fatal("-undefined: unknown argument: %s", argv[i]);
1619			    new_undefined_flag = UNDEFINED_ERROR;
1620			}
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;
1628		    }
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;
1640		    }
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;
1651		    }
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;
1660
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;
1668		    }
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;
1679		    }
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;
1688		    }
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;
1700
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;
1711
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;
1737			}
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;
1747		    }
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;
1754		    }
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 */
1760		    }
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;
1767		    }
1768		    else
1769			goto unknown_flag;
1770		    break;
1771
1772		case 'O':
1773		    if(strcmp(p, "ObjC") == 0)
1774			archive_ObjC = TRUE;
1775		    else
1776			goto unknown_flag;
1777		    break;
1778
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;
1787
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]);
1797		    }
1798		    else
1799			goto unknown_flag;
1800		    break;
1801
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;
1816		    }
1817		    else if(strcmp(p, "headerpad_max_install_names") == 0){
1818			headerpad_max_install_names = TRUE;
1819		    }
1820		    else if(strcmp(p, "hash_instrument") == 0){
1821			hash_instrument_specified = TRUE;
1822		    }
1823		    else
1824			goto unknown_flag;
1825		    break;
1826
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;
1835
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;
1851			}
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;
1858			}
1859			else
1860			    fatal("unknown deployment release flag: "
1861				"-NEXTSTEP-deployment-target %s", argv[i+1]);
1862			i += 1;
1863		    }
1864		    else
1865			goto unknown_flag;
1866		    break;
1867
1868		case 'v':
1869		    if(strcmp(p, "v") == 0){
1870			vflag = TRUE;
1871			printf("Apple Inc. version %s\n", apple_version);
1872		    }
1873		    else
1874			goto unknown_flag;
1875		    break;
1876
1877		default:
1878unknown_flag:
1879		    fatal("unknown flag: %s", argv[i]);
1880		}
1881	    }
1882	}
1883
1884	/*
1885	 * -sub_umbrella and -sub_library are not supported on ARM.
1886	 * See <rdar://problem/4771657>.
1887	 */
1888	if(arch_flag.cputype == CPU_TYPE_ARM){
1889	    if(sub_umbrellas != NULL){
1890	        fatal("-sub_umbrella is not supported on ARM");
1891	    }
1892	    if(sub_librarys != NULL){
1893	        fatal("-sub_library is not supported on ARM");
1894	    }
1895	}
1896
1897	/*
1898	 * If either -syslibroot or the environment variable NEXT_ROOT is set
1899	 * prepend it to the standard paths for library searches.  This was
1900	 * added to ease cross build environments.
1901	 */
1902	p = getenv("NEXT_ROOT");
1903	if(syslibroot_specified == TRUE){
1904	    if(p != NULL && strcmp(p, next_root) != 0)
1905		warning("NEXT_ROOT environment variable ignored because "
1906			"-syslibroot specified");
1907	}
1908	else{
1909	    next_root = p;
1910	}
1911	if(next_root != NULL){
1912	    for(i = 0; standard_dirs[i] != NULL; i++){
1913		p = allocate(strlen(next_root) +
1914			     strlen(standard_dirs[i]) + 1);
1915		strcpy(p, next_root);
1916		strcat(p, standard_dirs[i]);
1917		standard_dirs[i] = p;
1918	    }
1919	    for(i = 0; standard_framework_dirs[i] != NULL; i++){
1920		p = allocate(strlen(next_root) +
1921			     strlen(standard_framework_dirs[i]) + 1);
1922		strcpy(p, next_root);
1923		strcat(p, standard_framework_dirs[i]);
1924		standard_framework_dirs[i] = p;
1925	    }
1926	}
1927 	/*
1928	 * If -syslibroot is specified, prepend it to the user-specified
1929	 * paths *if* the prepended version exists.
1930	 */
1931	if(syslibroot_specified == TRUE){
1932	    for(i = 0; i < nsearch_dirs; i++){
1933		if(search_dirs[i][0] == '/'){
1934		    p = mkstr(next_root, search_dirs[i], NULL);
1935		    if(stat(p, &stat_buf) == 0)
1936			search_dirs[i] = p;
1937		    else
1938			free(p);
1939		}
1940	    }
1941	    for(i = 0; i < nframework_dirs; i++){
1942		if(framework_dirs[i][0] == '/'){
1943		    p = mkstr(next_root, framework_dirs[i], NULL);
1944		    if(stat(p, &stat_buf) == 0)
1945			framework_dirs[i] = p;
1946		    else
1947			free(p);
1948		}
1949	    }
1950	}
1951
1952	/*
1953         * Test to see if the various RC_* or XBS_* environment variables
1954	 * are set.
1955         */
1956        if((getenv("LD_TRACE_ARCHIVES") != NULL) ||
1957	   getenv("RC_TRACE_ARCHIVES") != NULL)
1958	  ld_trace_archives = TRUE;
1959        if((getenv("LD_TRACE_DYLIBS") != NULL) ||
1960	   (getenv("RC_TRACE_DYLIBS") != NULL))
1961	  ld_trace_dylibs = TRUE;
1962        if((getenv("LD_TRACE_PREBINDING_DISABLED") != NULL) ||
1963	   getenv("RC_TRACE_PREBINDING_DISABLED") != NULL)
1964	  ld_trace_prebinding_disabled = TRUE;
1965	if(ld_trace_archives || ld_trace_dylibs)
1966	  trace_file_path = getenv("LD_TRACE_FILE");
1967        if(getenv("LD_TRACE_BUNDLE_LOADER") != NULL &&
1968	   bundle_loader != NULL)
1969	    print("[Logging for XBS] Referenced bundle loader: %s\n",
1970		  bundle_loader);
1971
1972	if(save_reloc == FALSE){
1973	    if(getenv("LD_DEAD_STRIP") != NULL)
1974		dead_strip = TRUE;
1975	    if(getenv("LD_NO_DEAD_STRIP_INITS_AND_TERMS") != NULL)
1976		no_dead_strip_inits_and_terms = TRUE;
1977	}
1978	if(getenv("LD_DEAD_STRIP_DYLIB") != NULL && filetype == MH_DYLIB)
1979	    dead_strip = TRUE;
1980
1981	prebinding_via_LD_PREBIND = FALSE;
1982	/*
1983	 * The LD_FORCE_NO_PREBIND environment variable overrides the command
1984	 * line and the LD_PREBIND environment variable.
1985	 */
1986	if(getenv("LD_FORCE_NO_PREBIND") != NULL){
1987	    if(prebinding_flag_specified == TRUE &&
1988	       prebinding == TRUE){
1989		warning("-prebind ignored because LD_FORCE_NO_PREBIND "
1990			"environment variable specified");
1991		prebinding_flag_specified = TRUE;
1992		prebinding = FALSE;
1993	    }
1994	}
1995	/*
1996	 * The -prebind flag can also be specified with the LD_PREBIND
1997	 * environment variable.  We quitely ignore this when -r is on or
1998	 * if this is a fixed shared library output.
1999	 */
2000	else if(getenv("LD_PREBIND") != NULL &&
2001	   save_reloc == FALSE &&
2002	   filetype != MH_FVMLIB){
2003	    if(prebinding_flag_specified == TRUE &&
2004	       prebinding == FALSE){
2005		warning("LD_PREBIND environment variable ignored because "
2006			"-noprebind specified");
2007	    }
2008	    else{
2009		if(prebinding_flag_specified == FALSE)
2010		    prebinding_via_LD_PREBIND = TRUE;
2011		prebinding_flag_specified = TRUE;
2012		prebinding = TRUE;
2013	    }
2014	}
2015	if(getenv("LD_PREBIND_ALLOW_OVERLAP") != NULL)
2016	    prebind_allow_overlap = TRUE;
2017	if(prebind_all_twolevel_modules_specified == FALSE &&
2018	   getenv("LD_PREBIND_ALL_TWOLEVEL_MODULES") != NULL)
2019	    prebind_all_twolevel_modules = TRUE;
2020
2021	/*
2022	 * The -twolevel_namespace flag can also be specified with the
2023	 * LD_TWOLEVEL_NAMESPACE environment variable.  We quitely ignore this
2024	 * when -flat_namespace or -static is specified.
2025	 */
2026	if(getenv("LD_TWOLEVEL_NAMESPACE") != NULL &&
2027	   namespace_specified == FALSE &&
2028	   static_specified == FALSE){
2029		namespace_specified = TRUE;
2030		twolevel_namespace = TRUE;
2031	}
2032
2033	/*
2034	 * See if LD_LIBRARY_PATH is set.  And if so parse out the colon
2035	 * separated set of paths.
2036	 */
2037	ld_library_path = getenv("LD_LIBRARY_PATH");
2038	if(ld_library_path != NULL){
2039	    nld_library_paths = 1;
2040	    for(i = 0; ld_library_path[i] != '\0'; i++){
2041		if(ld_library_path[i] == ':')
2042		     nld_library_paths++;
2043	    }
2044	    ld_library_paths = allocate(sizeof(char *) * nld_library_paths);
2045	    j = 0;
2046	    ld_library_paths[j] = ld_library_path;
2047	    j++;
2048	    for(i = 0; ld_library_path[i] != '\0'; i++){
2049		if(ld_library_path[i] == ':'){
2050		    ld_library_path[i] = '\0';
2051		    ld_library_paths[j] = ld_library_path + i + 1;
2052		    j++;
2053		}
2054	    }
2055	}
2056
2057	/*
2058	 * If there was a -arch flag two things needed to be done in reguard to
2059	 * the handling of the cpusubtypes.
2060	 */
2061	if(arch_flag.name != NULL){
2062
2063	    /*
2064	     * 64-bit architectures are an error.
2065	     */
2066	    if(arch_flag.cputype & CPU_ARCH_ABI64)
2067		fatal("does not support 64-bit architectures");
2068
2069	    family_arch_flag = get_arch_family_from_cputype(arch_flag.cputype);
2070	    if(family_arch_flag == NULL)
2071		fatal("internal error: unknown cputype (%d) for -arch %s (this "
2072		      "program out of sync with get_arch_family_from_cputype())"
2073		      ,arch_flag.cputype, arch_flag.name);
2074	    /*
2075	     * Pick up the Mac OS X deployment target.
2076	     */
2077	    get_macosx_deployment_target(&macosx_deployment_target);
2078	    /*
2079	     * If for this cputype we are to always output the ALL cpusubtype
2080	     * then set force_cpusubtype_ALL.
2081	     */
2082	    if(force_cpusubtype_ALL_for_cputype(arch_flag.cputype) == TRUE)
2083		force_cpusubtype_ALL = TRUE;
2084	    /*
2085	     * First, if -force_cpusubtype_ALL is set and an -arch flag was
2086	     * specified set the cpusubtype to the _ALL type for that cputype
2087	     * since the specified flag may not have the _ALL type and the
2088	     * -force_cpusubtype_ALL has precedence over an -arch flags for a
2089	     * specific implementation of an architecture.
2090	     */
2091	    if(force_cpusubtype_ALL == TRUE){
2092		arch_flag.cpusubtype = family_arch_flag->cpusubtype;
2093	    }
2094	    else{
2095		/*
2096		 * Second, if no -force_cpusubtype_ALL is specified and an -arch
2097		 * flag for a specific implementation of an architecture was
2098		 * specified then the resulting cpusubtype will be for that
2099		 * specific implementation of that architecture and all
2100		 * cpusubtypes must combine with the cpusubtype for the -arch
2101		 * flag to the cpusubtype for the -arch flag else an error must
2102		 * be flaged.  This is done check_cur_obj() where cpusubtypes
2103		 * are combined.  What needs to be done here is to determine if
2104		 * the -arch flag is for a specific implementation of an
2105		 * architecture.
2106		 */
2107		if(arch_flag.cpusubtype != family_arch_flag->cpusubtype)
2108		    specific_arch_flag = TRUE;
2109	    }
2110	}
2111	else{
2112	    /*
2113	     * We need to pick up the Mac OS X deployment target even if the
2114	     * target architecture is not yet known so we can check to see if
2115	     * the flags specified are valid.
2116	     */
2117	    if(macosx_deployment_target.major == 0)
2118		get_macosx_deployment_target(&macosx_deployment_target);
2119	}
2120
2121	/*
2122	 * If the -sect_diff_relocs is specified check to see it can be used
2123	 * else pick up the LD_SECT_DIFF_RELOC if that can be used.
2124	 */
2125	if(sect_diff_reloc_flag_specified == TRUE){
2126	    if(filetype != MH_EXECUTE || dynamic == FALSE)
2127		fatal("can't use -sect_diff_relocs unless both -execute and "
2128		      "-dynamic are in effect");
2129	}
2130	else{
2131	    /*
2132	     * The -sect_diff_relocs flag was not specified on the command
2133	     * line, so if both -execute and -dynamic are in effect see if
2134	     * LD_SECT_DIFF_RELOCS is specified as an environment variable and
2135	     * use that value.
2136	     */
2137	    if(filetype == MH_EXECUTE && dynamic == TRUE){
2138		p = getenv("LD_SECT_DIFF_RELOCS");
2139		if(p != NULL){
2140		    if(strcmp(p, "error") == 0)
2141			sect_diff_reloc_flag = SECT_DIFF_RELOC_ERROR;
2142		    else if(strcmp(p, "warning") == 0)
2143			sect_diff_reloc_flag = SECT_DIFF_RELOC_WARNING;
2144		    else if(strcmp(p, "suppress") == 0)
2145			sect_diff_reloc_flag = SECT_DIFF_RELOC_SUPPRESS;
2146		    else{
2147			fatal("Unknown LD_SECT_DIFF_RELOCS environment variable"
2148			      " %s value", p);
2149		    }
2150		}
2151	    }
2152	}
2153
2154	/*
2155	 * Check for flag combinations that would result in a bad output file.
2156	 */
2157	if(save_reloc && strip_level == STRIP_ALL)
2158	    fatal("can't use -s with -r (resulting file would not be "
2159		  "relocatable)");
2160	if(save_reloc && strip_level == STRIP_MIN_DEBUG)
2161	    fatal("can't use -Sp with -r (only allowed for fully linked "
2162		  "images)");
2163	if(save_reloc && strip_base_symbols == TRUE)
2164	    fatal("can't use -b with -r (resulting file would not be "
2165		  "relocatable)");
2166	if(save_reloc && dead_strip == TRUE)
2167	    fatal("can't use -dead_strip with -r (only allowed for fully "
2168		  "linked images)");
2169	if(keep_private_externs == TRUE){
2170	    if(save_symbols != NULL)
2171		fatal("can't use both -keep_private_externs and "
2172		      "-exported_symbols_list");
2173	    if(remove_symbols != NULL)
2174		fatal("can't use both -keep_private_externs and "
2175		      "-unexported_symbols_list");
2176	}
2177	if(save_symbols != NULL && remove_symbols != NULL){
2178	    for(j = 0; j < nremove_symbols ; j++){
2179		sp = bsearch(remove_symbols[j].name,
2180			     save_symbols, nsave_symbols,
2181			     sizeof(struct symbol_list),
2182			     (int (*)(const void *, const void *))
2183				symbol_list_bsearch);
2184		if(sp != NULL){
2185		    error("symbol name: %s is listed in both "
2186			  "-exported_symbols_list and -unexported_symbols_list "
2187			  "(can't be both exported and unexported)",
2188			  remove_symbols[j].name);
2189		}
2190	    }
2191	    if(errors != 0)
2192		ld_exit(1);
2193	}
2194	if(filetype_specified == TRUE && filetype == MH_OBJECT){
2195	    if(dynamic == TRUE)
2196		fatal("incompatible to specifiy -object when -dynamic is used "
2197		      "(use -execute (the default) with -dynamic or -static "
2198		      "with -object)");
2199	}
2200	if(filetype == MH_DYLINKER){
2201	    if(dynamic == FALSE)
2202		fatal("incompatible flag -dylinker used (must specify "
2203		      "\"-dynamic\" to be used)");
2204	}
2205	if(filetype == MH_DYLIB){
2206	    if(dynamic == FALSE)
2207		fatal("incompatible flag -dylib used (must specify "
2208		      "\"-dynamic\" to be used)");
2209	    if(save_reloc)
2210		fatal("can't use -r and -dylib (file format produced with "
2211		      "-dylib is not a relocatable format)");
2212	    if(strip_level == STRIP_ALL)
2213		fatal("can't use -s with -dylib (file must contain at least "
2214		      "global symbols, for maximum stripping use -x)");
2215	    if(Aflag_specified)
2216		fatal("can't use -A and -dylib");
2217	    if(keep_private_externs == TRUE)
2218		fatal("can't use -keep_private_externs and -dylib");
2219	    if(segaddr_specified)
2220		fatal("can't use -segaddr options with -dylib (use seg1addr to "
2221		      "specify the starting address)");
2222	    if(seg1addr_specified && segs_read_only_addr_specified)
2223		fatal("can't use both the -seg1addr option and "
2224		      "-segs_read_only_addr option");
2225	    if(seg1addr_specified && segs_read_write_addr_specified)
2226		fatal("can't use both the -seg1addr option and "
2227		      "-segs_read_write_addr option");
2228	    if(seg1addr_specified && seg_addr_table_name != NULL)
2229		fatal("can't use both the -seg1addr option and "
2230		      "-seg_addr_table option");
2231	    if(seg_addr_table_name != NULL && segs_read_only_addr_specified)
2232		fatal("can't use both the -seg_addr_table option and "
2233		      "-segs_read_only_addr option");
2234	    if(seg_addr_table_name != NULL && segs_read_write_addr_specified)
2235		fatal("can't use both the -seg_addr_table option and "
2236		      "-segs_read_only_addr option");
2237	    if(seg_addr_table_name != NULL && dylib_install_name == NULL)
2238		fatal("must also specify -dylib_install_name when using "
2239		      "-seg_addr_table");
2240	    if(segs_read_only_addr_specified &&
2241	       read_only_reloc_flag != READ_ONLY_RELOC_ERROR)
2242		fatal("can't used -read_only_relocs %s with format produced "
2243		      "with the -segs_read_only_addr option\n",
2244		      read_only_reloc_flag == READ_ONLY_RELOC_WARNING ?
2245		      "warning" : "suppress");
2246	    if(segs_read_write_addr_specified &&
2247	       !segs_read_only_addr_specified)
2248		fatal("must also specify -segs_read_only_addr when using "
2249		      "-segs_read_write_addr");
2250	    if(seglinkedit_specified && seglinkedit == FALSE)
2251		fatal("can't use -noseglinkedit with -dylib (resulting file "
2252		      "must have a link edit segment to access symbols)");
2253	    if(bind_at_load == TRUE){
2254		warning("-bind_at_load is meaningless with -dylib");
2255		bind_at_load = FALSE;
2256	    }
2257	    /* use a segment address table if specified */
2258	    env_seg_addr_table_name = getenv("LD_SEG_ADDR_TABLE");
2259	    if(seg_addr_table_name != NULL ||
2260	       (env_seg_addr_table_name != NULL && dylib_install_name != NULL)){
2261		if(seg_addr_table_name != NULL &&
2262		   env_seg_addr_table_name != NULL &&
2263		   strcmp(seg_addr_table_name, env_seg_addr_table_name) != 0){
2264		    warning("-seg_addr_table %s ignored, LD_SEG_ADDR_TABLE "
2265			    "environment variable: %s used instead",
2266			    seg_addr_table_name, env_seg_addr_table_name);
2267		}
2268		if(env_seg_addr_table_name != NULL){
2269		    seg_addr_table_name = env_seg_addr_table_name;
2270		    seg_addr_table = parse_seg_addr_table(seg_addr_table_name,
2271			"LD_SEG_ADDR_TABLE", "environment variable",
2272			&table_size);
2273		}
2274		else
2275		    seg_addr_table = parse_seg_addr_table(seg_addr_table_name,
2276			"-seg_addr_table", seg_addr_table_name, &table_size);
2277		if(seg_addr_table_filename != NULL)
2278		    seg_addr_table_entry = search_seg_addr_table(seg_addr_table,
2279						     seg_addr_table_filename);
2280		else
2281		    seg_addr_table_entry = search_seg_addr_table(seg_addr_table,
2282						     dylib_install_name);
2283		if(seg_addr_table_entry != NULL){
2284		    if(seg_addr_table_entry->split == TRUE){
2285	       		if(read_only_reloc_flag != READ_ONLY_RELOC_ERROR){
2286			    warning("-read_only_relocs %s ignored, when using "
2287				    "with format produced with the "
2288				    "-segs_read_only_addr option (via the "
2289				    "segment address table: %s %s line %u)",
2290		      		    read_only_reloc_flag ==
2291					READ_ONLY_RELOC_WARNING ?
2292				    "warning" : "suppress",
2293				    env_seg_addr_table_name != NULL ?
2294				    "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2295				    seg_addr_table_name,
2296				    seg_addr_table_entry->line);
2297			    read_only_reloc_flag = READ_ONLY_RELOC_ERROR;
2298			}
2299			if(seg1addr_specified){
2300			    warning("-seg1addr 0x%x ignored, using "
2301				    "-segs_read_only_addr 0x%x and "
2302				    "-segs_read_write_addr 0x%x from segment "
2303				    "address table: %s %s line %u",
2304				    (unsigned int)seg1addr,
2305				    (unsigned int)seg_addr_table_entry->
2306					    segs_read_only_addr,
2307				    (unsigned int)seg_addr_table_entry->
2308					    segs_read_write_addr,
2309				    env_seg_addr_table_name != NULL ?
2310				    "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2311				    seg_addr_table_name,
2312				    seg_addr_table_entry->line);
2313			}
2314			if(segs_read_only_addr_specified &&
2315			   segs_read_only_addr !=
2316				    seg_addr_table_entry->segs_read_only_addr){
2317			    warning("-segs_read_only_addr 0x%x ignored, using "
2318				    "-segs_read_only_addr 0x%x from segment "
2319				    "address table: %s %s line %u",
2320				    (unsigned int)segs_read_only_addr,
2321				    (unsigned int)seg_addr_table_entry->
2322					    segs_read_only_addr,
2323				    env_seg_addr_table_name != NULL ?
2324				    "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2325				    seg_addr_table_name,
2326				    seg_addr_table_entry->line);
2327			}
2328			if(segs_read_write_addr_specified &&
2329			   segs_read_write_addr !=
2330				    seg_addr_table_entry->segs_read_write_addr){
2331			    warning("-segs_read_write_addr 0x%x ignored, using "
2332				    "-segs_read_write_addr 0x%x from segment "
2333				    "address table: %s %s line %u",
2334				    (unsigned int)segs_read_write_addr,
2335				    (unsigned int)seg_addr_table_entry->
2336					    segs_read_write_addr,
2337				    env_seg_addr_table_name != NULL ?
2338				    "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2339				    seg_addr_table_name,
2340				    seg_addr_table_entry->line);
2341			}
2342			seg1addr_specified = FALSE;
2343			seg1addr = 0;
2344			segs_read_only_addr_specified = TRUE;
2345			segs_read_only_addr =
2346				seg_addr_table_entry->segs_read_only_addr;
2347			segs_read_write_addr_specified = TRUE;
2348			segs_read_write_addr =
2349				seg_addr_table_entry->segs_read_write_addr;
2350			if(segs_read_only_addr == 0 &&
2351			   segs_read_write_addr == 0){
2352			    segs_read_write_addr = get_shared_region_size_from_flag(&arch_flag);
2353			    warning("-segs_read_write_addr 0x0 ignored from "
2354				    "segment address table: %s %s line %u "
2355				    "using -segs_read_write_addr 0x%x",
2356				    env_seg_addr_table_name != NULL ?
2357				    "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2358				    seg_addr_table_name,
2359				    seg_addr_table_entry->line,
2360				    (unsigned int)segs_read_write_addr);
2361			}
2362		    }
2363		    else{
2364			if(seg1addr_specified &&
2365			   seg1addr != seg_addr_table_entry->seg1addr){
2366			    warning("-seg1addr 0x%x ignored, using "
2367				    "-seg1addr 0x%x from segment address "
2368				    "table: %s %s line %u",
2369				    (unsigned int)seg1addr,
2370				    (unsigned int)seg_addr_table_entry->
2371					    seg1addr,
2372				    env_seg_addr_table_name != NULL ?
2373				    "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2374				    seg_addr_table_name,
2375				    seg_addr_table_entry->line);
2376			}
2377			if(segs_read_only_addr_specified){
2378			    warning("-segs_read_only_addr 0x%x ignored, using "
2379				    "-seg1addr 0x%x from segment address "
2380				    "table: %s %s line %u",
2381				    (unsigned int)segs_read_only_addr,
2382				    (unsigned int)seg_addr_table_entry->
2383					    seg1addr,
2384				    env_seg_addr_table_name != NULL ?
2385				    "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2386				    seg_addr_table_name,
2387				    seg_addr_table_entry->line);
2388			}
2389			if(segs_read_write_addr_specified){
2390			    warning("-segs_read_write_addr 0x%x ignored, using "
2391				    "-seg1addr 0x%x from segment address "
2392				    "table: %s %s line %u",
2393				    (unsigned int)segs_read_write_addr,
2394				    (unsigned int)seg_addr_table_entry->
2395					    seg1addr,
2396				    env_seg_addr_table_name != NULL ?
2397				    "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2398				    seg_addr_table_name,
2399				    seg_addr_table_entry->line);
2400			}
2401			seg1addr_specified = TRUE;
2402			seg1addr = seg_addr_table_entry->seg1addr;
2403			segs_read_only_addr_specified = FALSE;
2404			segs_read_only_addr = 0;
2405			segs_read_write_addr_specified = FALSE;
2406			segs_read_write_addr = 0;
2407		    }
2408		}
2409		else{
2410		    warning("%s %s not found in segment address table %s %s",
2411			    seg_addr_table_filename != NULL ?
2412			    "-seg_addr_table_filename" : "-dylib_install_name",
2413			    seg_addr_table_filename != NULL ?
2414			    seg_addr_table_filename : dylib_install_name,
2415			    env_seg_addr_table_name != NULL ?
2416			    "LD_SEG_ADDR_TABLE" : "-seg_addr_table",
2417			    seg_addr_table_name);
2418		}
2419	    }
2420	    /*
2421	     * If this is not a subframework then if it has an install name
2422	     * then guess its implied umbrella framework name from the
2423	     * install name.  Then if its install name is a framework name use
2424	     * that as the umbrella framework name.  Otherwise it is not
2425	     * considered an umbrella framework.
2426	     */
2427	    if(sub_framework == FALSE && dylib_install_name != NULL){
2428		umbrella_framework_name = guess_short_name(dylib_install_name,
2429			&is_framework, &has_suffix);
2430		if(umbrella_framework_name != NULL && is_framework == TRUE)
2431		    umbrella_framework = TRUE;
2432		else
2433		    umbrella_framework_name = NULL;
2434	    }
2435	    if(nallowable_clients != 0 && sub_framework == FALSE)
2436		fatal("-allowable_client flags can only be used when -umbrella "
2437		      "is also specified");
2438	}
2439	else{
2440	    if(segs_read_only_addr_specified)
2441		fatal("-segs_read_only_addr can only be used when -dylib "
2442		      "is also specified");
2443	    if(segs_read_write_addr_specified)
2444		fatal("-segs_read_write_addr can only be used when -dylib "
2445		      "is also specified");
2446	    if(seg_addr_table_name != NULL)
2447		fatal("-seg_addr_table can only be used when -dylib "
2448		      "is also specified");
2449	    if(sub_framework == TRUE)
2450		fatal("-umbrella %s can only be used when -dylib "
2451		      "is also specified", umbrella_framework_name);
2452	    if(nsub_umbrellas != 0)
2453		fatal("-sub_umbrella flags can only be used when -dylib "
2454		      "is also specified");
2455	    if(nsub_librarys != 0)
2456		fatal("-sub_library flags can only be used when -dylib "
2457		      "is also specified");
2458	    if(nallowable_clients != 0)
2459		fatal("-allowable_client flags can only be used when -dylib "
2460		      "is also specified");
2461	    if(moduletype_specified == TRUE)
2462		fatal("-single_module or -multi_module flags can only be used "
2463		      "when -dylib is also specified");
2464	}
2465
2466	/*
2467	 * For Mac OS X 10.4 and later, prebinding will be limited to split
2468	 * shared libraries. So if this is not a split library then turn off
2469	 * prebinding.
2470	 */
2471	if(macosx_deployment_target.major >= 4){
2472	    if(filetype != MH_DYLIB){
2473		/*
2474		 * If this is arm* or xscale, we want to prebind executables
2475		 * too, not just dylibs and frameworks.
2476		 */
2477		if (!((arch_flag.name != NULL) &&
2478		      ((strncmp(arch_flag.name, "arm", 3) == 0) ||
2479		       (strcmp(arch_flag.name, "xscale") == 0))))
2480		{
2481		    if(prebinding_via_LD_PREBIND == FALSE &&
2482		       prebinding_flag_specified == TRUE &&
2483		       prebinding == TRUE){
2484			warning("-prebind ignored because MACOSX_DEPLOYMENT_TARGET "
2485				"environment variable greater or equal to 10.4");
2486		    }
2487		    prebinding = FALSE;
2488		}
2489	    }
2490	    /*
2491	     * This is an MH_DYLIB.  First see if it is on the list of libraries
2492	     * not to be prebound.  Then see if was specified to be built as a
2493	     * split, if not check LD_SPLITSEGS_NEW_LIBRARIES to see if we are
2494	     * forcing it to be a split library.
2495	     */
2496	    else{
2497		/*
2498		 * If this library was not in the seg_addr_table see if it is
2499		 * on the list of libraries not to be prebound. And if so turn
2500		 * off prebinding.  Note this list is only ever used when
2501		 * macosx_deployment_target.major >= 4 .
2502		 */
2503		if(seg_addr_table_entry == NULL &&
2504		   unprebound_library(dylib_install_name,
2505				      seg_addr_table_filename) == TRUE){
2506		    if(prebinding_flag_specified == TRUE &&
2507		       prebinding == TRUE){
2508			warning("-prebind ignored because -install_name %s "
2509				"listed in LD_UNPREBOUND_LIBRARIES environment "
2510				"variable file: %s", dylib_install_name,
2511				getenv("LD_UNPREBOUND_LIBRARIES"));
2512		    }
2513		    prebinding = FALSE;
2514		}
2515		else{
2516		    /*
2517		     * This is not on the list of libraries not to be prebound,
2518		     * and if there was no seg_addr_table entry for this then
2519		     * force this to be a split library.  Note even if
2520		     * prebinding was not specified we will still force this to
2521		     * be a split library.
2522		     */
2523		    if(seg_addr_table_entry == NULL &&
2524		       getenv("LD_SPLITSEGS_NEW_LIBRARIES") != NULL){
2525		    unsigned long arch_rw_addr =
2526			get_shared_region_size_from_flag(&arch_flag);
2527
2528			if(seg1addr_specified){
2529			    warning("-seg1addr 0x%x ignored, using "
2530				    "-segs_read_only_addr 0x%x and "
2531				    "-segs_read_write_addr 0x%x because "
2532				    "LD_SPLITSEGS_NEW_LIBRARIES environment is "
2533				    "set",(unsigned int)seg1addr, 0,
2534				    (unsigned int)arch_rw_addr);
2535			}
2536			seg1addr_specified = FALSE;
2537			seg1addr = 0;
2538			segs_read_only_addr_specified = TRUE;
2539			segs_read_only_addr = 0;
2540			segs_read_write_addr = arch_rw_addr;
2541		    }
2542		    /*
2543		     * Finally if this is not a split library then turn off
2544		     * prebinding.
2545		     */
2546		    if(segs_read_only_addr_specified == FALSE){
2547			if(prebinding_via_LD_PREBIND == FALSE &&
2548			   prebinding_flag_specified == TRUE &&
2549			   prebinding == TRUE){
2550			    warning("-prebind ignored because "
2551				    "MACOSX_DEPLOYMENT_TARGET environment "
2552				    "variable greater or equal to 10.4");
2553			}
2554			prebinding = FALSE;
2555		    }
2556		}
2557	    }
2558	}
2559
2560	if(filetype == MH_BUNDLE){
2561	    if(dynamic == FALSE)
2562		fatal("incompatible flag -bundle used (must specify "
2563		      "\"-dynamic\" to be used)");
2564	    if(save_reloc)
2565		fatal("can't use -r and -bundle (flags are mutually "
2566		      "exclusive, only one or the other can be used)");
2567	    if(strip_level == STRIP_ALL)
2568		fatal("can't use -s with -bundle (file must contain "
2569		      "at least global symbols, for maximum stripping use -x)");
2570	    if(Aflag_specified)
2571		fatal("can't use -A and -bundle");
2572	    if(keep_private_externs == TRUE)
2573		fatal("can't use -keep_private_externs and -bundle");
2574	    if(segaddr_specified)
2575		fatal("can't use -segaddr options with -bundle (use "
2576		      "seg1addr to specify the starting address)");
2577	    if(seglinkedit_specified && seglinkedit == FALSE)
2578		fatal("can't use -noseglinkedit with -bundle "
2579		      "(resulting file must have a link edit segment to access "
2580		      "symbols)");
2581	    if(prebinding == TRUE){
2582		if(prebinding_flag_specified == TRUE)
2583		    warning("-prebind has no effect with -bundle");
2584		prebinding = FALSE;
2585	    }
2586	    if(private_bundle == TRUE && twolevel_namespace == TRUE)
2587		warning("-private_bundle has no effect when "
2588			"-twolevel_namespace is in effect");
2589	    if(twolevel_namespace_hints_specified != TRUE)
2590		twolevel_namespace_hints = FALSE;
2591	}
2592	else{
2593	    if(client_name != NULL)
2594		fatal("-client_name %s flag can only be used with -bundle",
2595		      client_name);
2596	    if(bundle_loader != NULL)
2597		fatal("-bundle_loader %s flag can only be used with -bundle",
2598		      bundle_loader);
2599	    if(private_bundle == TRUE)
2600		fatal("-private_bundle flag can only be used with -bundle");
2601	}
2602	if(filetype != MH_DYLINKER){
2603	    if(dylinker_install_name != NULL)
2604		warning("flag: -dylinker_install_name %s ignored (-dylinker "
2605			"was not specified", dylinker_install_name);
2606	}
2607	if(filetype != MH_DYLIB){
2608	    if(dylib_install_name != NULL)
2609		warning("flag: -dylib_install_name %s ignored (-dylib "
2610			"was not specified", dylib_install_name);
2611	    if(dylib_current_version != 0)
2612		warning("flag: -dylib_current_version %u ignored (-dylib "
2613			"was not specified", dylib_current_version);
2614	    if(dylib_compatibility_version != 0)
2615		warning("flag: -dylib_compatibility_version %u ignored (-dylib"
2616			" was not specified", dylib_compatibility_version);
2617	    if(init_name != NULL)
2618		warning("flag: -init %s ignored (-dylib was not specified",
2619			init_name);
2620	}
2621	if(twolevel_namespace == TRUE &&
2622	   undefined_flag != UNDEFINED_ERROR &&
2623	   undefined_flag != UNDEFINED_DYNAMIC_LOOKUP &&
2624	   undefined_flag != UNDEFINED_DEFINE_A_WAY){
2625	    if(macosx_deployment_target.major >= 3)
2626		fatal("-undefined error, -undefined dynamic_lookup or "
2627		      "-undefined define_a_way must be used when "
2628		      "-twolevel_namespace is in effect");
2629	    else
2630		fatal("-undefined error or -undefined define_a_way must be "
2631		      "used when -twolevel_namespace is in effect");
2632	}
2633	if(undefined_flag == UNDEFINED_DYNAMIC_LOOKUP){
2634	    if(dynamic == FALSE)
2635		fatal("incompatible flag -undefined dynamic_lookup used (must "
2636		      "specify \"-dynamic\" to be used)");
2637	    if(macosx_deployment_target.major < 3)
2638		fatal("flag: -undefined dynamic_lookup can't be used with "
2639		      "MACOSX_DEPLOYMENT_TARGET environment variable set to: "
2640		      "%s", macosx_deployment_target.name);
2641	}
2642	if(twolevel_namespace == TRUE && nundef_syms != 0){
2643	    fatal("can't use -U flags when -twolevel_namespace is in effect");
2644	}
2645	if(nomultidefs == TRUE){
2646	    if(multiply_defined_flag_specified == TRUE &&
2647	       multiply_defined_flag != MULTIPLY_DEFINED_ERROR)
2648		fatal("-multiply_defined error must be used when -nomultidefs "
2649		      "is specified");
2650	   multiply_defined_flag = MULTIPLY_DEFINED_ERROR;
2651	}
2652	if(prebinding == TRUE && undefined_flag == UNDEFINED_SUPPRESS){
2653	    if(prebinding_flag_specified == TRUE)
2654		warning("-undefined suppress disables -prebind");
2655	    prebinding = FALSE;
2656	}
2657	if(prebinding == TRUE && save_reloc){
2658	    if(prebinding_flag_specified == TRUE)
2659		warning("-r disables -prebind");
2660	    prebinding = FALSE;
2661	}
2662	if(prebinding == TRUE && dynamic == FALSE){
2663	    prebinding = FALSE;
2664	}
2665
2666	/*
2667	 * If the output file name as not specified set it to the default name
2668	 * "a.out".  This needs to be done before any segments are merged
2669	 * because this is used when merging them (the 'filename' field in a
2670	 * merged_segment is set to it).
2671	 */
2672	if(outputfile == NULL)
2673	    outputfile = "a.out";
2674	/*
2675	 * If the -A flag is specified and the file type has not been specified
2676	 * then make the output file type MH_OBJECT.
2677	 */
2678	if(Aflag_specified == TRUE && filetype_specified == FALSE)
2679	    filetype = MH_OBJECT;
2680
2681	/*
2682	 * If neither the -seglinkedit or -noseglinkedit has been specified then
2683	 * set creation of this segment if the output file type can have one.
2684	 * If -seglinkedit has been specified make sure the output file type
2685	 * can have one.
2686	 */
2687	if(seglinkedit_specified == FALSE){
2688	    if(filetype == MH_EXECUTE || filetype == MH_BUNDLE ||
2689	       filetype == MH_FVMLIB ||
2690	       filetype == MH_DYLIB || filetype == MH_DYLINKER)
2691		seglinkedit = TRUE;
2692	    else
2693		seglinkedit = FALSE;
2694	}
2695	else{
2696	    if(seglinkedit &&
2697	       (filetype != MH_EXECUTE && filetype != MH_BUNDLE &&
2698		filetype != MH_FVMLIB &&
2699		filetype != MH_DYLIB && filetype != MH_DYLINKER))
2700		fatal("link edit segment can't be created (wrong output file "
2701		      "type, file type must be MH_EXECUTE, MH_BUNDLE, "
2702		      "MH_DYLIB, MH_DYLINKER or MH_FVMLIB)");
2703	}
2704	if(allow_stack_execute == TRUE && filetype != MH_EXECUTE)
2705	    fatal("-allow_stack_execute can only be used when output file type "
2706		  "is MH_EXECUTE");
2707
2708	if(trace)
2709	    print("%s: Pass 1\n", progname);
2710	/*
2711	 * This pass of parsing arguments only processes object files
2712	 * and creation of symbols now that all the options are set.
2713	 * This are order dependent and must be processed as they appear
2714	 * on the command line.
2715	 */
2716	symbols_created = 0;
2717	objects_specified = 0;
2718	sections_created = 0;
2719	/*
2720	 * If a -bundle_loader is specified and this is a flat_namespace
2721	 * output force the bundle_loader to be loaded first.
2722	 */
2723	if(bundle_loader != NULL && twolevel_namespace == FALSE){
2724	    pass1(bundle_loader, FALSE, FALSE, FALSE, TRUE, FALSE);
2725	}
2726	for(i = 1 ; i < argc ; i++){
2727	    if(*argv[i] != '-'){
2728		/* just a normal object file name */
2729		pass1(argv[i], FALSE, FALSE, FALSE, FALSE, FALSE);
2730		objects_specified++;
2731	    }
2732	    else{
2733		p = &(argv[i][1]);
2734		switch(*p){
2735		case 'b':
2736		    if(strcmp(p, "bundle_loader") == 0){
2737			/*
2738			 * If a -bundle_loader was specified and this is a
2739			 * flat_namespace output force the bundle_loader was
2740			 * loaded first above.
2741			 */
2742			if(twolevel_namespace == TRUE)
2743			    pass1(argv[i+1], FALSE, FALSE, FALSE, TRUE, FALSE);
2744			i++;
2745			break;
2746		    }
2747		    break;
2748		case 'l':
2749		    /* path searched abbrevated file name */
2750		    pass1(argv[i], TRUE, FALSE, FALSE, FALSE, FALSE);
2751		    objects_specified++;
2752		    break;
2753		case 'A':
2754		    if(base_obj != NULL)
2755			fatal("only one -A argument can be specified");
2756		    pass1(argv[++i], FALSE, TRUE, FALSE, FALSE, FALSE);
2757		    objects_specified++;
2758		    break;
2759		case 'f':
2760		    if(strcmp(p, "framework") == 0){
2761			if(dynamic == FALSE)
2762			    fatal("incompatible flag -framework used (must "
2763				  "specify \"-dynamic\" to be used)");
2764			pass1(argv[++i], FALSE, FALSE, TRUE, FALSE, FALSE);
2765			objects_specified++;
2766		    }
2767		    if(strcmp(p, "filelist") == 0){
2768			filelist = argv[++i];
2769			dirname = strrchr(filelist, ',');
2770			if(dirname != NULL){
2771			    *dirname = '\0';
2772			    dirname++;
2773			}
2774			else
2775			    dirname = "";
2776			if((fd = open(filelist, O_RDONLY, 0)) == -1)
2777			    system_fatal("can't open file list file: %s",
2778				         filelist);
2779			if(fstat(fd, &stat_buf) == -1)
2780			    system_fatal("can't stat file list file: %s",
2781					 filelist);
2782			/*
2783			 * For some reason mapping files with zero size fails
2784			 * so it has to be handled specially.
2785			 */
2786			if(stat_buf.st_size != 0){
2787			    if((r = map_fd((int)fd, (vm_offset_t)0,
2788				(vm_offset_t *)&(addr), (boolean_t)TRUE,
2789				(vm_size_t)stat_buf.st_size)) != KERN_SUCCESS)
2790				mach_fatal(r, "can't map file list file: %s",
2791				    filelist);
2792			}
2793			else{
2794			    fatal("file list file: %s is empty", filelist);
2795			}
2796			close(fd);
2797			file_name = addr;
2798			for(j = 0; j < stat_buf.st_size; j++){
2799			    if(addr[j] == '\n'){
2800				addr[j] = '\0';
2801				if(*dirname != '\0'){
2802				    file_name = mkstr(dirname, "/",
2803						      file_name, NULL);
2804				}
2805				pass1(file_name, FALSE, FALSE, FALSE, FALSE,
2806				      FALSE);
2807				objects_specified++;
2808				file_name = addr + j + 1;
2809			    }
2810			}
2811		    }
2812		    if(strcmp(p, "final_output") == 0)
2813			i++;
2814		    break;
2815		case 'm':
2816		    if(strcmp(p, "multiply_defined") == 0 ||
2817		       strcmp(p, "multiply_defined_unused") == 0 ||
2818		       strcmp(p, "macosx_version_min") == 0){
2819			i++;
2820			break;
2821		    }
2822		    break;
2823		case 'u':
2824		    if(strcmp(p, "undefined") == 0 ||
2825		       strcmp(p, "umbrella") == 0 ||
2826		       strcmp(p, "unexported_symbols_list") == 0){
2827			i++;
2828			break;
2829		    }
2830		    /* cause the specified symbol name to be undefined */
2831		    (void)command_line_symbol(argv[++i]);
2832		    symbols_created++;
2833		    break;
2834		case 'i':
2835		    if(strcmp(p, "image_base") == 0){
2836			i++;
2837			break;
2838		    }
2839		    else if(strcmp(p, "init") == 0){
2840			i++;
2841			break;
2842		    }
2843		    else if(strcmp(p, "install_name") == 0){
2844		        i++;
2845			break;
2846		    }
2847		    /* create an indirect symbol, symbol_name, to be an indirect
2848		       symbol for indr_symbol_name */
2849		    symbol_name = p + 1;
2850	  	    indr_symbol_name = strchr(p + 1, ':');
2851		    *indr_symbol_name = '\0';
2852		    indr_symbol_name++;
2853		    command_line_indr_symbol(symbol_name, indr_symbol_name);
2854		    symbols_created++;
2855		    break;
2856
2857		/* multi argument flags */
2858		case 'a':
2859		    if(strcmp(p, "all_load") == 0 ||
2860		       strcmp(p, "arch_multiple") == 0 ||
2861		       strcmp(p, "arch_errors_fatal") == 0 ||
2862		       strcmp(p, "allow_stack_execute") == 0)
2863			break;
2864		    i++;
2865		    break;
2866		case 'c':
2867		    i++;
2868		    break;
2869		case 'p':
2870		    if(strcmp(p, "pagezero_size") == 0){
2871			i++;
2872			break;
2873		    }
2874		    break;
2875		case 's':
2876		    if(strcmp(p, "sectcreate") == 0 ||
2877		       strcmp(p, "segcreate") == 0){
2878			sections_created++;
2879			i += 3;
2880		    }
2881		    else if(strcmp(p, "sectalign") == 0 ||
2882		            strcmp(p, "segprot") == 0 ||
2883		            strcmp(p, "sectorder") == 0)
2884			i += 3;
2885		    else if(strcmp(p, "segaddr") == 0 ||
2886			    strcmp(p, "sect_diff_relocs") == 0 ||
2887		            strcmp(p, "sectobjectsymbols") == 0)
2888			i += 2;
2889		    else if(strcmp(p, "seg1addr") == 0 ||
2890		            strcmp(p, "stack_addr") == 0 ||
2891		            strcmp(p, "stack_size") == 0 ||
2892		            strcmp(p, "segalign") == 0 ||
2893			    strcmp(p, "segs_read_only_addr") == 0 ||
2894			    strcmp(p, "segs_read_write_addr") == 0 ||
2895			    strcmp(p, "seg_addr_table") == 0 ||
2896			    strcmp(p, "seg_addr_table_filename") == 0 ||
2897			    strcmp(p, "sub_umbrella") == 0 ||
2898			    strcmp(p, "sub_library") == 0 ||
2899			    strcmp(p, "syslibroot") == 0)
2900			i++;
2901		    break;
2902		case 'r':
2903		    if(strcmp(p, "r") == 0 ||
2904		       strcmp(p, "run_init_lazily") == 0)
2905			break;
2906		    i++;
2907		    break;
2908		case 'o':
2909		    if(strcmp(p, "object") == 0)
2910			break;
2911		    i++;
2912		    break;
2913		case 'e':
2914		    if(strcmp(p, "execute") == 0)
2915			break;
2916		    i++;
2917		    break;
2918		case 'd':
2919		    if(strcmp(p, "d") == 0 ||
2920		       strcmp(p, "dylib") == 0 ||
2921		       strcmp(p, "dylinker") == 0 ||
2922		       strcmp(p, "dynamic") == 0 ||
2923		       strcmp(p, "dead_strip") == 0)
2924			break;
2925		    i++;
2926		    break;
2927		case 'h':
2928		    if(strcmp(p, "headerpad_max_install_names") == 0)
2929			break;
2930		    i++;
2931		    break;
2932		case 'U':
2933		case 'N':
2934		case 'Y':
2935		    i++;
2936		    break;
2937		case 'w':
2938		    if(strcmp(p, "weak_reference_mismatches") == 0)
2939			i++;
2940		    else if(strcmp(p, "weak_library") == 0){
2941			pass1(argv[++i], FALSE, FALSE, FALSE, FALSE, TRUE);
2942			objects_specified++;
2943		    }
2944		    else if(strncmp(p, "weak-l", sizeof("weak-l") - 1) == 0){
2945			/* path searched abbrevated file name */
2946			pass1(argv[i] + sizeof("weak"), TRUE, FALSE, FALSE,
2947			      FALSE, TRUE);
2948			objects_specified++;
2949		    }
2950		    else if(strcmp(p, "weak_framework") == 0){
2951			if(dynamic == FALSE)
2952			    fatal("incompatible flag -weak_framework used (must"
2953				  " specify \"-dynamic\" to be used)");
2954			pass1(argv[++i], FALSE, FALSE, TRUE, FALSE, TRUE);
2955			objects_specified++;
2956		    }
2957		    break;
2958		}
2959	    }
2960	}
2961
2962 	/*
2963	 * If the architecture was not specified, and was inferred
2964	 * from the object files, if it is a 64-bit architecture it is an error.
2965	 */
2966	if(arch_flag.cputype != 0 &&
2967	    arch_flag.cputype & CPU_ARCH_ABI64){
2968	    fatal("does not support 64-bit architectures");
2969	}
2970
2971	/*
2972	 * Now search the libraries on the dynamic shared libraries search list
2973	 */
2974	search_dynamic_libs();
2975
2976	/*
2977	 * Check to see that the output file will have something in it.
2978	 */
2979	if(objects_specified == 0){
2980	    if(symbols_created != 0 || sections_created != 0){
2981		warning("no object files specified, only command line created "
2982			"symbols and/or sections created from files will "
2983			"appear in the output file");
2984		if(arch_flag.name == NULL)
2985		    target_byte_sex = host_byte_sex;
2986		segalign = host_pagesize;
2987	    }
2988	    else{
2989		if(vflag == TRUE)
2990		    ld_exit(0);
2991		fatal("no object files specified");
2992	    }
2993	}
2994	else if(base_obj != NULL && nobjects == 1){
2995	    if(symbols_created != 0 || sections_created != 0)
2996		warning("no object files loaded other than base file, only "
2997			"additional command line created symbols and/or "
2998			"sections created from files will appear in the output "
2999			"file");
3000	    else{
3001		if(vflag == TRUE)
3002		    ld_exit(0);
3003		fatal("no object files loaded other than base file");
3004	    }
3005	}
3006	else if(nobjects == 0){
3007	    if(symbols_created != 0 || sections_created != 0)
3008		warning("no object files loaded, only command line created "
3009			"symbols and/or sections created from files will "
3010			"appear in the output file");
3011	    else{
3012		if(vflag == TRUE)
3013		    ld_exit(0);
3014		fatal("no object files loaded");
3015	    }
3016	}
3017
3018#ifdef DEBUG
3019	if(debug & (1 < 0))
3020	    print_object_list();
3021	if(debug & (1 << 1))
3022	    print_merged_sections("after pass1");
3023	if(debug & (1 << 2))
3024	    print_symbol_list("after pass1", TRUE);
3025	if(debug & (1 << 3))
3026	    print_undefined_list();
3027	if(debug & (1 << 4))
3028	    print_segment_specs();
3029	if(debug & (1 << 5))
3030	    print_load_fvmlibs_list();
3031	if(debug & (1 << 6))
3032	    print_fvmlib_segments();
3033	if(debug & (1 << 9)){
3034	    print("Number of objects loaded = %lu\n", nobjects);
3035	    print("Number of merged symbols = %lu\n", nmerged_symbols);
3036	}
3037#endif /* DEBUG */
3038
3039	/*
3040	 * If there were any errors from pass1() then don't continue.
3041	 */
3042	if(errors != 0)
3043	    ld_exit(1);
3044
3045	/*
3046	 * Print which files are loaded if requested.
3047	 */
3048	if(whatsloaded == TRUE)
3049	    print_whatsloaded();
3050
3051	/*
3052	 * Clean up any data structures not need for layout() or pass2().
3053	 */
3054	if(nsearch_dirs != 0){
3055	    free(search_dirs);
3056	    nsearch_dirs = 0;
3057	}
3058
3059	/*
3060	 * Layout the output object file.
3061	 */
3062	layout();
3063
3064	/*
3065	 * Check to that the exported or unexported symbols listed were seen.
3066	 */
3067	if(save_symbols != NULL){
3068	    missing_syms = FALSE;
3069	    for(j = 0; j < nsave_symbols ; j++){
3070		if(save_symbols[j].seen == FALSE){
3071		    if(missing_syms == FALSE){
3072			error("symbols names listed in "
3073			      "-exported_symbols_list: %s not in linked "
3074			      "objects", exported_symbols_list);
3075			missing_syms = TRUE;
3076		    }
3077		    printf("%s\n", save_symbols[j].name);
3078		}
3079	    }
3080	}
3081
3082	/*
3083	 * If there were any errors from layout() then don't continue.
3084	 */
3085	if(errors != 0)
3086	    ld_exit(1);
3087
3088	/*
3089	 * Clean up any data structures not need for pass2().
3090	 */
3091	free_pass1_symbol_data();
3092	if(ntrace_syms != 0){
3093	    free(trace_syms);
3094	    ntrace_syms = 0;
3095	}
3096	if(nundef_syms != 0){
3097	    free(undef_syms);
3098	    nundef_syms = 0;
3099	}
3100
3101	/*
3102	 * Write the output object file doing relocation on the sections.
3103	 */
3104	if(trace)
3105	    print("%s: Pass 2\n", progname);
3106	pass2();
3107	/*
3108	 * If there were any errors from pass2() make sure the output file is
3109	 * removed and exit non-zero.
3110	 */
3111	if(errors != 0)
3112	    cleanup();
3113
3114	if(hash_instrument_specified == TRUE)
3115	    hash_instrument();
3116
3117	ld_exit(0);
3118
3119	/* this is to remove the compiler warning, it never gets here */
3120	return(0);
3121}
3122
3123/*
3124 * unprebound_library() checks the file for the environment variable
3125 * LD_UNPREBOUND_LIBRARIES to see if the dynamic library is one listed as to
3126 * not be prebound.  The dynamic library is specified with the
3127 * dylib_install_name unless seg_addr_table_filename is not NULL then
3128 * seg_addr_table_filename is used.  If it is found on the list then TRUE is
3129 * returned.  If not FALSE is returned.
3130 */
3131static
3132enum bool
3133unprebound_library(
3134char *dylib_install_name,
3135char *seg_addr_table_filename)
3136{
3137    int fd;
3138    kern_return_t r;
3139    struct stat stat_buf;
3140    unsigned long j, file_size, line;
3141    char *file_name, *library_name, *file_addr, *name, *end;
3142
3143	/*
3144	 * If there is no file name then it is not on the list and return FALSE.
3145	 */
3146	file_name = getenv("LD_UNPREBOUND_LIBRARIES");
3147	if(file_name == NULL)
3148	    return(FALSE);
3149
3150	/*
3151	 * If there is no library name then it is not on the list and return
3152	 * FALSE.
3153	 */
3154	if(seg_addr_table_filename != NULL)
3155	    library_name = dylib_install_name;
3156	else if(dylib_install_name != NULL)
3157	    library_name = dylib_install_name;
3158	else
3159	    return(FALSE);
3160
3161
3162	if((fd = open(file_name, O_RDONLY, 0)) == -1)
3163	    system_fatal("Can't open: %s for LD_UNPREBOUND_LIBRARIES "
3164			 "environment variable", file_name);
3165	if(fstat(fd, &stat_buf) == -1)
3166	    system_fatal("Can't stat file: %s for LD_UNPREBOUND_LIBRARIES "
3167		    	 "environment variable", file_name);
3168	/*
3169	 * For some reason mapping files with zero size fails
3170	 * so it has to be handled specially.
3171	 */
3172	if(stat_buf.st_size != 0){
3173	    if((r = map_fd((int)fd, (vm_offset_t)0,
3174		(vm_offset_t *)&file_addr, (boolean_t)TRUE,
3175		(vm_size_t)stat_buf.st_size)) != KERN_SUCCESS)
3176		mach_fatal(r, "can't map file: %s for LD_UNPREBOUND_LIBRARIES "
3177			   "environment variable", file_name);
3178	}
3179	else
3180	    fatal("Empty file: %s for LD_UNPREBOUND_LIBRARIES environment "
3181		  "variable", file_name);
3182	close(fd);
3183	file_size = stat_buf.st_size;
3184
3185	/*
3186	 * Got the file mapped now parse it.
3187	 */
3188	if(file_addr[file_size - 1] != '\n')
3189	    fatal("file: %s for LD_UNPREBOUND_LIBRARIES environment variable "
3190		  "does not end in new line", file_name);
3191
3192	line = 1;
3193	for(j = 0; j < file_size; /* no increment expression */ ){
3194	    /* Skip lines that start with '#' */
3195	    if(file_addr[j] == '#'){
3196		j++;
3197		while(file_addr[j] != '\n')
3198		    j++;
3199		continue;
3200	    }
3201	    /* Skip blank lines and leading white space */
3202	    while(file_addr[j] == ' ' || file_addr[j] == '\t')
3203		j++;
3204	    if(file_addr[j] == '\n'){
3205		j++;
3206		line++;
3207		continue;
3208	    }
3209	    if(j == file_size)
3210		fatal("missing library install name on line %lu in file: "
3211		      "%s for LD_UNPREBOUND_LIBRARIES environment variable",
3212		      line, file_name);
3213
3214	    name = file_addr + j;
3215	    while(file_addr[j] != '\n')
3216		j++;
3217	    file_addr[j] = '\0';
3218	    end = file_addr + j;
3219	    line++;
3220	    j++;
3221
3222	    /* Trim trailing spaces */
3223	    end--;
3224	    while(end > name && (*end == ' ' || *end == '\t')){
3225		*end = '\0';
3226		end--;
3227	    }
3228
3229	    /* finally compare the name on this line with the library name */
3230	    if(strcmp(library_name, name) == 0)
3231		return(TRUE);
3232	}
3233
3234	return(FALSE);
3235}
3236
3237/*
3238 * ispoweroftwo() returns TRUE or FALSE depending if x is a power of two.
3239 */
3240static
3241enum
3242bool
3243ispoweroftwo(
3244unsigned long x)
3245{
3246	if(x == 0)
3247	    return(TRUE);
3248	while((x & 0x1) != 0x1){
3249	    x >>= 1;
3250	}
3251	if((x & ~0x1) != 0)
3252	    return(FALSE);
3253	else
3254	    return(TRUE);
3255}
3256
3257/*
3258 * getprot() returns the vm_prot for the specified string passed to it.  The
3259 * string may contain any of the following characters: 'r', 'w', 'x' and '-'
3260 * representing read, write, execute and no protections.  The pointer pointed
3261 * to by endp is set to the first character that is not one of the above
3262 * characters.
3263 */
3264static
3265vm_prot_t
3266getprot(
3267char *prot,
3268char **endp)
3269{
3270    vm_prot_t vm_prot;
3271
3272	vm_prot = VM_PROT_NONE;
3273	while(*prot){
3274	    switch(*prot){
3275	    case 'r':
3276	    case 'R':
3277		vm_prot |= VM_PROT_READ;
3278		break;
3279	    case 'w':
3280	    case 'W':
3281		vm_prot |= VM_PROT_WRITE;
3282		break;
3283	    case 'x':
3284	    case 'X':
3285		vm_prot |= VM_PROT_EXECUTE;
3286		break;
3287	    case '-':
3288		break;
3289	    default:
3290		*endp = prot;
3291		return(vm_prot);
3292	    }
3293	    prot++;
3294	}
3295	*endp = prot;
3296	return(vm_prot);
3297}
3298
3299/*
3300 * check_max_init_prot() checks to make sure that all protections in the initial
3301 * protection are also in the maximum protection.
3302 */
3303static
3304enum bool
3305check_max_init_prot(
3306vm_prot_t maxprot,
3307vm_prot_t initprot)
3308{
3309	if(((initprot & VM_PROT_READ)    && !(maxprot & VM_PROT_READ)) ||
3310	   ((initprot & VM_PROT_WRITE)   && !(maxprot & VM_PROT_WRITE)) ||
3311	   ((initprot & VM_PROT_EXECUTE) && !(maxprot & VM_PROT_EXECUTE)) )
3312	return(FALSE);
3313	return(TRUE);
3314}
3315
3316/*
3317 * ld_exit() is use for all exit()s from the link editor.
3318 */
3319static
3320void
3321ld_exit(
3322int exit_value)
3323{
3324	exit(exit_value);
3325}
3326
3327/*
3328 * cleanup() is called by all routines handling fatal errors to remove the
3329 * output file if it had been created by the link editor and exit non-zero.
3330 */
3331static
3332void
3333cleanup(void)
3334{
3335	if(output_addr != NULL)
3336	    unlink(outputfile);
3337	ld_exit(1);
3338}
3339
3340/*
3341 * handler() is the routine for catching SIGINT, SIGTERM, SIGBUG & SIGSEGV
3342 *  signals. It cleans up and exit()'s non-zero.
3343 */
3344static
3345void
3346handler(
3347int sig)
3348{
3349#ifdef __MWERKS__
3350    int dummy;
3351        dummy = sig;
3352#endif
3353	if(output_addr != NULL)
3354	    unlink(outputfile);
3355	_exit(1);
3356}
3357
3358/*
3359 * allocate() is just a wrapper around malloc that prints and error message and
3360 * exits if the malloc fails.
3361 */
3362__private_extern__
3363void *
3364allocate(
3365unsigned long size)
3366{
3367    void *p;
3368
3369	if(size == 0)
3370	    return(NULL);
3371	if((p = malloc(size)) == NULL)
3372	    system_fatal("virtual memory exhausted (malloc failed)");
3373	return(p);
3374}
3375
3376/*
3377 * reallocate() is just a wrapper around realloc that prints and error message
3378 * and exits if the realloc fails.
3379 */
3380__private_extern__
3381void *
3382reallocate(
3383void *p,
3384unsigned long size)
3385{
3386	if(p == NULL)
3387	    return(allocate(size));
3388	if((p = realloc(p, size)) == NULL)
3389	    system_fatal("virtual memory exhausted (realloc failed)");
3390	return(p);
3391}
3392
3393/*
3394 * savestr() malloc's space for the string passed to it, copys the string into
3395 * the space and returns a pointer to that space.
3396 */
3397__private_extern__
3398char *
3399savestr(
3400const char *s)
3401{
3402    long len;
3403    char *r;
3404
3405	len = strlen(s) + 1;
3406	r = (char *)allocate(len);
3407	strcpy(r, s);
3408	return(r);
3409}
3410
3411/*
3412 * Mkstr() creates a string that is the concatenation of a variable number of
3413 * strings.  It is pass a variable number of pointers to strings and the last
3414 * pointer is NULL.  It returns the pointer to the string it created.  The
3415 * storage for the string is malloc()'ed can be free()'ed when nolonger needed.
3416 */
3417static
3418char *
3419mkstr(
3420const char *args,
3421...)
3422{
3423    va_list ap;
3424    char *s, *p;
3425    unsigned long size;
3426
3427	size = 0;
3428	if(args != NULL){
3429	    size += strlen(args);
3430	    va_start(ap, args);
3431	    p = (char *)va_arg(ap, char *);
3432	    while(p != NULL){
3433		size += strlen(p);
3434		p = (char *)va_arg(ap, char *);
3435	    }
3436	}
3437	s = allocate(size + 1);
3438	*s = '\0';
3439
3440	if(args != NULL){
3441	    (void)strcat(s, args);
3442	    va_start(ap, args);
3443	    p = (char *)va_arg(ap, char *);
3444	    while(p != NULL){
3445		(void)strcat(s, p);
3446		p = (char *)va_arg(ap, char *);
3447	    }
3448	    va_end(ap);
3449	}
3450	return(s);
3451}
3452#endif /* !defined(RLD) */
3453
3454/*
3455 * rnd() rounds v to a multiple of r.
3456 */
3457__private_extern__
3458unsigned long
3459rnd(
3460unsigned long v,
3461unsigned long r)
3462{
3463	r--;
3464	v += r;
3465	v &= ~(long)r;
3466	return(v);
3467}
3468
3469#ifndef RLD
3470#include "stuff/unix_standard_mode.h"
3471/*
3472 * All printing of all messages goes through this function.
3473 */
3474__private_extern__
3475void
3476vprint(
3477const char *format,
3478va_list ap)
3479{
3480	if(get_unix_standard_mode() == TRUE)
3481	    vfprintf(stderr, format, ap);
3482	else
3483	    vprintf(format, ap);
3484}
3485#endif /* !defined(RLD) */
3486
3487/*
3488 * The print function that just calls the above vprint() function.
3489 */
3490__private_extern__
3491void
3492print(
3493const char *format,
3494...)
3495{
3496    va_list ap;
3497
3498	va_start(ap, format);
3499	vprint(format, ap);
3500	va_end(ap);
3501}
3502
3503/*
3504 * The ld_trace function that logs things for B&I.
3505 */
3506__private_extern__
3507void
3508ld_trace(
3509const char *format,
3510...)
3511{
3512#ifdef KLD
3513    va_list ap;
3514
3515	va_start(ap, format);
3516	vprint(format, ap);
3517	va_end(ap);
3518#else
3519	static int trace_file = -1;
3520	char trace_buffer[MAXPATHLEN * 2];
3521	char *buffer_ptr;
3522	int length;
3523	ssize_t amount_written;
3524
3525	if(trace_file == -1){
3526		if(trace_file_path != NULL){
3527			trace_file = open(trace_file_path, O_WRONLY | O_APPEND | O_CREAT, 0666);
3528			if(trace_file == -1)
3529				fatal("Could not open or create trace file: %s\n", trace_file_path);
3530		}
3531		else{
3532			trace_file = fileno(stderr);
3533		}
3534	}
3535    va_list ap;
3536
3537	va_start(ap, format);
3538	length = vsnprintf(trace_buffer, sizeof(trace_buffer), format, ap);
3539	va_end(ap);
3540	buffer_ptr = trace_buffer;
3541	while(length > 0){
3542		amount_written = write(trace_file, buffer_ptr, length);
3543		if(amount_written == -1)
3544			/* Failure to write shouldn't fail the build. */
3545			return;
3546		buffer_ptr += amount_written;
3547		length -= amount_written;
3548	}
3549#endif
3550}
3551
3552static
3553void
3554print_architecture_banner(void)
3555{
3556    static enum bool printed = FALSE;
3557
3558	if(arch_multiple == TRUE && printed == FALSE && arch_flag.name != NULL){
3559	    print("%s: for architecture %s\n", progname, arch_flag.name);
3560	    printed = TRUE;
3561	}
3562}
3563
3564/*
3565 * Print the warning message.  This is non-fatal and does not set 'errors'.
3566 */
3567__private_extern__
3568void
3569warning(
3570const char *format,
3571...)
3572{
3573    va_list ap;
3574
3575	if(nowarnings == TRUE)
3576	    return;
3577	if(arch_multiple)
3578	    print_architecture_banner();
3579	va_start(ap, format);
3580        print("%s: warning ", progname);
3581	vprint(format, ap);
3582        print("\n");
3583	va_end(ap);
3584}
3585
3586/*
3587 * Print the error message and set the 'error' indication.
3588 */
3589__private_extern__
3590void
3591error(
3592const char *format,
3593...)
3594{
3595    va_list ap;
3596
3597	if(arch_multiple)
3598	    print_architecture_banner();
3599	va_start(ap, format);
3600        print("%s: ", progname);
3601	vprint(format, ap);
3602        print("\n");
3603	va_end(ap);
3604	errors = 1;
3605}
3606
3607/*
3608 * Print the fatal error message, and exit non-zero.
3609 */
3610__private_extern__
3611void
3612fatal(
3613const char *format,
3614...)
3615{
3616    va_list ap;
3617
3618	if(arch_multiple)
3619	    print_architecture_banner();
3620	va_start(ap, format);
3621        print("%s: ", progname);
3622	vprint(format, ap);
3623        print("\n");
3624	va_end(ap);
3625	cleanup();
3626}
3627
3628/*
3629 * Print the current object file name and warning message.
3630 */
3631__private_extern__
3632void
3633warning_with_cur_obj(
3634const char *format,
3635...)
3636{
3637    va_list ap;
3638
3639	if(nowarnings == TRUE)
3640	    return;
3641	if(arch_multiple)
3642	    print_architecture_banner();
3643	va_start(ap, format);
3644        print("%s: warning ", progname);
3645	print_obj_name(cur_obj);
3646	vprint(format, ap);
3647        print("\n");
3648	va_end(ap);
3649}
3650
3651/*
3652 * Print the current object file name and error message, set the non-fatal
3653 * error indication.
3654 */
3655__private_extern__
3656void
3657error_with_cur_obj(
3658const char *format,
3659...)
3660{
3661    va_list ap;
3662
3663	if(arch_multiple)
3664	    print_architecture_banner();
3665	va_start(ap, format);
3666        print("%s: ", progname);
3667	print_obj_name(cur_obj);
3668	vprint(format, ap);
3669        print("\n");
3670	va_end(ap);
3671	errors = 1;
3672}
3673
3674#if !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__))
3675/*
3676 * Print the warning message along with the system error message.
3677 */
3678__private_extern__
3679void
3680system_warning(
3681const char *format,
3682...)
3683{
3684    va_list ap;
3685    int errnum;
3686
3687	if(arch_multiple)
3688	    print_architecture_banner();
3689	errnum = errno;
3690	va_start(ap, format);
3691        print("%s: warning ", progname);
3692	vprint(format, ap);
3693	print(" (%s, errno = %d)\n", strerror(errnum), errnum);
3694	va_end(ap);
3695}
3696
3697/*
3698 * Print the error message along with the system error message, set the
3699 * non-fatal error indication.
3700 */
3701__private_extern__
3702void
3703system_error(
3704const char *format,
3705...)
3706{
3707    va_list ap;
3708    int errnum;
3709
3710	if(arch_multiple)
3711	    print_architecture_banner();
3712	errnum = errno;
3713	va_start(ap, format);
3714        print("%s: ", progname);
3715	vprint(format, ap);
3716	print(" (%s, errno = %d)\n", strerror(errnum), errnum);
3717	va_end(ap);
3718	errors = 1;
3719}
3720
3721/*
3722 * Print the fatal message along with the system error message, and exit
3723 * non-zero.
3724 */
3725__private_extern__
3726void
3727system_fatal(
3728const char *format,
3729...)
3730{
3731    va_list ap;
3732    int errnum;
3733
3734	if(arch_multiple)
3735	    print_architecture_banner();
3736	errnum = errno;
3737	va_start(ap, format);
3738        print("%s: ", progname);
3739	vprint(format, ap);
3740	print(" (%s, errno = %d)\n", strerror(errnum), errnum);
3741	va_end(ap);
3742	cleanup();
3743}
3744#endif /* !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__)) */
3745
3746/*
3747 * Print the fatal error message along with the mach error string, and exit
3748 * non-zero.
3749 */
3750__private_extern__
3751void
3752mach_fatal(
3753kern_return_t r,
3754char *format,
3755...)
3756{
3757    va_list ap;
3758
3759	if(arch_multiple)
3760	    print_architecture_banner();
3761	va_start(ap, format);
3762        print("%s: ", progname);
3763	vprint(format, ap);
3764	print(" (%s)\n", mach_error_string(r));
3765	va_end(ap);
3766	cleanup();
3767}
3768