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/*
24 * The NeXT Computer, Inc. libtool(1) program that handles fat files, archives
25 * and Mach-O objects files (no 4.3bsd a.out files).  This is also the ranlib(1)
26 * program.
27 */
28#include <mach/mach.h>
29#include "stuff/openstep_mach.h"
30#include <libc.h>
31#ifndef __OPENSTEP__
32#include <utime.h>
33#endif
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <signal.h>
38#include <ar.h>
39#include <mach-o/ranlib.h>
40#include <sys/types.h>
41#include <sys/stat.h>
42#include <sys/mman.h>
43#include "stuff/bool.h"
44#include "stuff/ofile.h"
45#include "stuff/rnd.h"
46#include "stuff/errors.h"
47#include "stuff/allocate.h"
48#include "stuff/execute.h"
49#include "stuff/version_number.h"
50#include "stuff/unix_standard_mode.h"
51#ifdef LTO_SUPPORT
52#include "stuff/lto.h"
53#endif /* LTO_SUPPORT */
54
55#include <mach/mach_init.h>
56#if defined(__OPENSTEP__) || defined(__GONZO_BUNSEN_BEAKER__)
57#include <servers/netname.h>
58#else
59#include <servers/bootstrap.h>
60#endif
61
62/*
63 * This is used internally to build the table of contents.
64 */
65struct toc {
66    char *name;		/* symbol defined by */
67    int32_t index1;	/* library member at this index plus 1 */
68};
69
70/* used by error routines as the name of the program */
71char *progname = NULL;
72
73/* the bytesex of the host this program is running on */
74static enum byte_sex host_byte_sex = UNKNOWN_BYTE_SEX;
75
76/*
77 * The time the table of contents' are set to and the time to base the
78 * modification time of the output file to be set to.
79 */
80static time_t toc_time = 0;
81
82/*
83 * The environment variable ZERO_AR_DATE is used here and other places that
84 * write archives to allow testing and comparing things for exact binary
85 * equality.
86 */
87static enum bool zero_ar_date = FALSE;
88
89/*
90 * The mode of the table of contents member (S_IFREG | (0666 & ~umask))
91 */
92static u_short toc_mode = 0;
93
94/* flags set from the command line arguments */
95struct cmd_flags {
96    char **files;	/* array of file name arguments */
97    uint32_t
98	nfiles;		/* number of file name arguments */
99    char **filelist;	/* filelist argument the file name argument came from */
100    enum bool
101	no_files_ok;	/* ok to see no files */
102    enum bool ranlib;	/* set if this is run as ranlib not libtool */
103    enum bool s;	/* sort the table of contents */
104    enum bool a;	/* don't sort the table of contents (original form) */
105    enum bool c;	/* include commmon symbols in the table of contents */
106    enum bool t;	/* just "touch" the archives to get the date right */
107    enum bool f;	/* warn if the output archive is fat,used by ar(1) -s */
108    enum bool q;	/* only write archive if NOT fat, used by ar(1) */
109    char *output;	/* the output file specified by -o */
110    enum bool final_output_specified; /* if -final_output is specified */
111    enum bool dynamic;	/* create a dynamic shared library, static by default */
112    char *compatibility;/* compatibility version if specified, NULL otherwise */
113    char *current;	/* current version if specified, NULL otherwise */
114    char *install_name; /* install name if specified, NULL otherwise */
115    char *seg1addr;	/* seg1addr if specified, NULL otherwise */
116    char *segs_read_only_addr;	/* segs_read_only_addr if specified, or NULL */
117    char *segs_read_write_addr;	/* segs_read_write_addr if specified, or NULL */
118    char *seg_addr_table;	/* seg_addr_table if specified, or NULL */
119    char *seg_addr_table_filename;
120			/* seg_addr_table_filename if specified, or NULL */
121    char **Ldirs;	/* array of -Ldir arguments */
122    uint32_t
123	nLdirs;		/* number of -Ldir arguments */
124    char **ldflags;	/* other ld(1) flags to pass */
125    uint32_t
126	nldflags;	/* number of ld(1) flags for above */
127    enum bool verbose;	/* print exec(2) commands run */
128    struct arch_flag
129	arch_only_flag;	/* the -arch_only flag if specified */
130    enum bool		/* set if either -prebind or -noprebind is seen */
131	prebinding_flag_specified;
132    enum bool		/* set if -prebind is seen or the LD_PREBIND */
133	prebinding;	/*  environment variable is set (and -noprebind isn't)*/
134    enum bool		/* set if either -all_load or -noall_load is seen */
135	all_load_flag_specified;
136    enum bool		/* set if -all_load is seen (and -noall_load isn't) */
137	all_load;
138    enum bool		/* set with -L (the default) off with -T, for -static */
139	use_long_names; /* use 4.4bsd extended format 1 for long names */
140    enum bool L_or_T_specified;
141    enum bool		/* set if the environ var LD_TRACE_ARCHIVES is set */
142	ld_trace_archives;
143	const char *	/* LD_TRACE_FILE if set and LD_TRACE_ARCHIVES is set, or NULL */
144	trace_file_path;
145    enum bool		/* set if -search_paths_first is specified */
146	search_paths_first;
147    enum bool noflush;	/* don't use the output_flush routine to flush the
148			   static library output file by pages */
149    uint32_t debug;	/* debug value to debug output_flush() routine */
150};
151static struct cmd_flags cmd_flags = { 0 };
152
153/* The value of the environment variable NEXT_ROOT */
154static char *next_root = NULL;
155
156/* the standard directories to search for -lx names */
157char *standard_dirs[] = {
158    "/lib/",
159    "/usr/lib/",
160    "/usr/local/lib/",
161    NULL
162};
163
164/*
165 * The input files are broken down in to their object files and then placed in
166 * these structures.  They are sorted by architecture type and then each object
167 * has a member struct created for it in one of the arch structs.  All of these
168 * structs hang off of 'archs'.
169 */
170static struct arch *archs = NULL;
171static uint32_t narchs = 0;
172
173struct arch {
174    struct arch_flag arch_flag;	/* the identifing info of this architecture */
175    uint64_t size;		/* current working size and final size */
176
177    /* the table of contents (toc) stuff for this architecture in the library */
178    uint32_t  toc_size;	/* total size of the toc including ar_hdr */
179    struct ar_hdr  toc_ar_hdr;	/* the archive header for this member */
180    enum bool toc_long_name;    /* use the long name in the output */
181    char *toc_name;		/* name of toc member */
182    uint32_t toc_name_size;/* size of name of toc member */
183    struct toc    *tocs;	/* internal table of contents */
184    struct ranlib *toc_ranlibs;	/* ranlib structs for output */
185    uint32_t       toc_nranlibs;/* number of ranlib structs */
186    char	  *toc_strings;	/* strings of symbol names for ranlib structs */
187    uint32_t       toc_strsize;	/* number of bytes for the strings above */
188
189    /* the members of this architecture in the library */
190    struct member *members;	/* the members of the library for this arch */
191    uint32_t nmembers;	/* the number of the above members */
192};
193
194struct member {
195    uint32_t offset;	    	    /* current working offset and final offset*/
196    struct ar_hdr ar_hdr;	    /* the archive header for this member */
197    char null_byte;		    /* space to write '\0' for ar_hdr */
198    char *object_addr;		    /* the address of the object file */
199    uint32_t object_size;	    /* the size of the object file */
200    enum byte_sex object_byte_sex;  /* the byte sex of the object file */
201    struct mach_header *mh;	    /* the mach_header of 32-bit object files */
202    struct mach_header_64 *mh64;    /* the mach_header of 64-bit object files */
203    struct load_command		    /* the start of the load commands */
204	*load_commands;
205    struct symtab_command *st;	    /* the symbol table command */
206    struct section **sections;	    /* array of section structs for 32-bit */
207    struct section_64 **sections64; /* array of section structs for 64-bit */
208#ifdef LTO_SUPPORT
209    void *lto;			    /* lto module */
210#endif /* LTO_SUPPORT */
211
212    /* the name of the member in the output */
213    char         *member_name;	    /* the member name */
214    uint32_t member_name_size;	    /* the size of the member name */
215    enum bool output_long_name;	    /* use the extended format #1 for the
216				       member name in the output */
217
218    /* info recorded from the input file this member came from */
219    char	  *input_file_name;	/* the input file name */
220    char	  *input_base_name;     /* the base name in the input file */
221    uint32_t  input_base_name_size;	/* the size of the base name */
222    struct ar_hdr *input_ar_hdr;
223    uint32_t      input_member_offset;  /* if from a thin archive */
224};
225
226static void usage(
227    void);
228static void process(
229    void);
230static char *file_name_from_l_flag(
231    char *l_flag);
232static char *search_for_file(
233    char *base_name);
234static char * search_paths_for_lname(
235    const char *lname_argument);
236static char * search_path_for_lname(
237    const char *dir,
238    const char *lname_argument);
239static void add_member(
240    struct ofile *ofile);
241static void free_archs(
242    void);
243static void create_library(
244    char *output,
245    struct ofile *ofile);
246static enum byte_sex get_target_byte_sex(
247    struct arch *arch,
248    enum byte_sex host_byte_sex);
249static char *put_toc_member(
250    char *p,
251    struct arch *arch,
252    enum byte_sex host_byte_sex,
253    enum byte_sex target_byte_sex);
254static void create_dynamic_shared_library(
255    char *output);
256static void create_dynamic_shared_library_cleanup(
257    int sig);
258static void make_table_of_contents(
259    struct arch *arch,
260    char *output);
261static int toc_name_qsort(
262    const struct toc *toc1,
263    const struct toc *toc2);
264static int toc_index1_qsort(
265    const struct toc *toc1,
266    const struct toc *toc2);
267static enum bool toc_symbol(
268    struct nlist *symbol,
269    struct section **sections);
270static enum bool toc_symbol_64(
271    struct nlist_64 *symbol64,
272    struct section_64 **sections64);
273static enum bool toc(
274    uint32_t n_strx,
275    uint8_t n_type,
276    uint64_t n_value,
277    enum bool attr_no_toc);
278static enum bool check_sort_tocs(
279    struct arch *arch,
280    char *output,
281    enum bool library_warnings);
282static void warn_duplicate_member_names(
283    void);
284static int member_name_qsort(
285    const struct member *member1,
286    const struct member *member2);
287static int member_offset_qsort(
288    const struct member *member1,
289    const struct member *member2);
290static void warn_member(
291    struct arch *arch,
292    struct member *member,
293    const char *format, ...) __attribute__ ((format (printf, 3, 4)));
294static void ld_trace(
295    const char *format, ...) __attribute__ ((format (printf, 1, 2)));
296
297/*
298 * This structure is used to describe blocks of the output file that are flushed
299 * to the disk file with output_flush.  It is kept in an ordered list starting
300 * with output_blocks.
301 */
302static struct block {
303    uint64_t offset;	/* starting offset of this block */
304    uint64_t size;		/* size of this block */
305    uint64_t written_offset;/* first page offset after starting offset */
306    uint64_t written_size;	/* size of written area from written_offset */
307    struct block *next; /* next block in the list */
308} *output_blocks;
309
310static void output_flush(
311    char *library,
312    uint64_t library_size,
313    int fd,
314    uint64_t offset,
315    uint64_t size);
316static void final_output_flush(
317    char *library,
318    int fd);
319#ifdef DEBUG
320static void print_block_list(void);
321#endif /* DEBUG */
322static struct block *get_block(void);
323static void remove_block(
324    struct block *block);
325static uint32_t trnc(
326    uint32_t v,
327    uint32_t r);
328
329/* apple_version is in vers.c which is created by the libstuff/Makefile */
330extern char apple_version[];
331
332int
333main(
334int argc,
335char **argv,
336char **envp)
337{
338    char *p, *endp, *filelist, *dirname, *addr;
339    int fd, i;
340    struct stat stat_buf;
341    uint32_t j, nfiles, maxfiles;
342    uint32_t temp;
343    int oumask, numask;
344    enum bool lflags_seen, bad_flag_seen, Vflag;
345
346	lflags_seen = FALSE;
347	Vflag = FALSE;
348	progname = argv[0];
349
350	host_byte_sex = get_host_byte_sex();
351
352	/*
353	 * The environment variable ZERO_AR_DATE is used here and other
354	 * places that write archives to allow testing and comparing
355	 * things for exact binary equality.
356	 */
357	if(getenv("ZERO_AR_DATE") == NULL)
358	    zero_ar_date = FALSE;
359	else
360	    zero_ar_date = TRUE;
361	if(zero_ar_date == FALSE)
362	    toc_time = time(0);
363	else
364	    toc_time = 0;
365
366	numask = 0;
367	oumask = umask(numask);
368	toc_mode = S_IFREG | (0666 & ~oumask);
369	(void)umask(oumask);
370
371	/* see if this is being run as ranlib */
372	p = strrchr(argv[0], '/');
373	if(p != NULL)
374	    p++;
375	else
376	    p = argv[0];
377	if(strncmp(p, "ranlib", sizeof("ranlib") - 1) == 0)
378	    cmd_flags.ranlib = TRUE;
379
380	/* The default is to used long names */
381	cmd_flags.use_long_names = TRUE;
382
383	/* process the command line arguments and collect the files */
384	maxfiles = argc;
385        cmd_flags.files = allocate(sizeof(char *) * maxfiles);
386        cmd_flags.filelist = allocate(sizeof(char *) * maxfiles);
387        memset(cmd_flags.filelist, '\0', sizeof(char *) * maxfiles);
388	for(i = 1; i < argc; i++){
389	    if(argv[i][0] == '-'){
390		if(argv[i][1] == '\0'){
391		    for(i += 1 ; i < argc; i++)
392			cmd_flags.files[cmd_flags.nfiles++] = argv[i];
393		    break;
394		}
395		if(strcmp(argv[i], "-o") == 0){
396		    if(cmd_flags.ranlib == TRUE){
397			error("unknown option: %s", argv[i]);
398			usage();
399		    }
400		    if(i + 1 == argc){
401			error("missing argument to: %s option", argv[i]);
402			usage();
403		    }
404		    if(cmd_flags.output != NULL){
405			error("more than one: %s option specified", argv[i]);
406			usage();
407		    }
408		    cmd_flags.output = argv[i+1];
409		    i++;
410		}
411		else if(strcmp(argv[i], "-arch_only") == 0){
412		    if(cmd_flags.ranlib == TRUE){
413			error("unknown option: %s", argv[i]);
414			usage();
415		    }
416		    if(i + 1 == argc){
417			error("missing argument to %s option", argv[i]);
418			usage();
419		    }
420		    if(cmd_flags.arch_only_flag.name != NULL){
421			error("more than one: %s option specified", argv[i]);
422			usage();
423		    }
424		    else{
425			if(get_arch_from_flag(argv[i+1],
426					      &cmd_flags.arch_only_flag) == 0){
427			    error("unknown architecture specification flag: "
428				  "%s %s", argv[i], argv[i+1]);
429			    arch_usage();
430			    usage();
431			}
432		    }
433		    i++;
434		}
435		else if(strcmp(argv[i], "-dynamic") == 0){
436		    if(cmd_flags.ranlib == TRUE){
437			error("unknown option: %s", argv[i]);
438			usage();
439		    }
440		    cmd_flags.dynamic = TRUE;
441		}
442		else if(strcmp(argv[i], "-static") == 0){
443		    if(cmd_flags.ranlib == TRUE){
444			error("unknown option: %s", argv[i]);
445			usage();
446		    }
447		    cmd_flags.dynamic = FALSE;
448		}
449		else if(strcmp(argv[i], "-filelist") == 0){
450		    if(cmd_flags.ranlib == TRUE){
451			error("unknown option: %s", argv[i]);
452			usage();
453		    }
454		    if(i + 1 == argc){
455			error("missing argument to: %s option", argv[i]);
456			usage();
457		    }
458		    filelist = argv[i + 1];
459		    dirname = strrchr(filelist, ',');
460		    if(dirname != NULL){
461			*dirname = '\0';
462			dirname++;
463		    }
464		    else
465			dirname = "";
466		    if((fd = open(filelist, O_RDONLY, 0)) == -1)
467			system_fatal("can't open file list file: %s", filelist);
468		    if(fstat(fd, &stat_buf) == -1)
469			system_fatal("can't stat file list file: %s", filelist);
470		    /*
471		     * For some reason mapping files with zero size fails
472		     * so it has to be handled specially.
473		     */
474		    addr = NULL;
475		    if(stat_buf.st_size != 0){
476			addr = mmap(0, stat_buf.st_size, PROT_READ|PROT_WRITE,
477				    MAP_FILE|MAP_PRIVATE, fd, 0);
478			if((intptr_t)addr == -1)
479			    system_error("can't map file list file: %s",
480				         filelist);
481		    }
482		    else{
483			fatal("file list file: %s is empty", filelist);
484		    }
485		    if(*dirname != '\0')
486			dirname[-1] = ',';
487		    close(fd);
488		    nfiles = 0;
489		    for(j = 0; j < stat_buf.st_size; j++){
490			if(addr[j] == '\n')
491			    nfiles++;
492		    }
493		    if(addr[stat_buf.st_size - 1] != '\n')
494			nfiles++;
495		    p = allocate((strlen(dirname) + 1) * nfiles +
496				 stat_buf.st_size);
497		    cmd_flags.files = reallocate(cmd_flags.files,
498					sizeof(char *) * (maxfiles + nfiles));
499        	    cmd_flags.filelist = reallocate(cmd_flags.filelist,
500					sizeof(char *) * (maxfiles + nfiles));
501        	    memset(cmd_flags.filelist + maxfiles, '\0',
502			   sizeof(char *) * nfiles);
503		    maxfiles += nfiles;
504
505		    cmd_flags.files[cmd_flags.nfiles] = p;
506		    cmd_flags.filelist[cmd_flags.nfiles] = filelist;
507		    cmd_flags.nfiles++;
508		    if(*dirname != '\0'){
509			strcpy(p, dirname);
510			p += strlen(dirname);
511			*p++ = '/';
512		    }
513		    for(j = 0; j < stat_buf.st_size; j++){
514			if(addr[j] != '\n')
515			    *p++ = addr[j];
516			else{
517			    *p++ = '\0';
518			    if(j != stat_buf.st_size - 1){
519				cmd_flags.files[cmd_flags.nfiles] = p;
520				cmd_flags.filelist[cmd_flags.nfiles] =argv[i+1];
521				cmd_flags.nfiles++;
522				if(*dirname != '\0'){
523				    strcpy(p, dirname);
524				    p += strlen(dirname);
525				    *p++ = '/';
526				}
527			    }
528			}
529		    }
530		    if(addr[stat_buf.st_size - 1] != '\n')
531			*p = '\0';
532		    i++;
533		}
534		else if(strcmp(argv[i], "-compatibility_version") == 0){
535		    if(cmd_flags.ranlib == TRUE){
536			error("unknown option: %s", argv[i]);
537			usage();
538		    }
539		    if(i + 1 == argc){
540			error("missing argument to: %s option", argv[i]);
541			usage();
542		    }
543		    if(cmd_flags.compatibility != NULL){
544			error("more than one: %s option specified", argv[i]);
545			usage();
546		    }
547		    if(get_version_number(argv[i], argv[i+1], &temp) == FALSE){
548			usage();
549		    }
550		    cmd_flags.compatibility = argv[i+1];
551		    i++;
552		}
553		else if(strcmp(argv[i], "-current_version") == 0){
554		    if(cmd_flags.ranlib == TRUE){
555			error("unknown option: %s", argv[i]);
556			usage();
557		    }
558		    if(i + 1 == argc){
559			error("missing argument to: %s option", argv[i]);
560			usage();
561		    }
562		    if(cmd_flags.current != NULL){
563			error("more than one: %s option specified", argv[i]);
564			usage();
565		    }
566		    if(get_version_number(argv[i], argv[i+1], &temp) == FALSE){
567			usage();
568		    }
569		    cmd_flags.current = argv[i+1];
570		    i++;
571		}
572		else if(strcmp(argv[i], "-install_name") == 0){
573		    if(cmd_flags.ranlib == TRUE){
574			error("unknown option: %s", argv[i]);
575			usage();
576		    }
577		    if(i + 1 == argc){
578			error("missing argument to: %s option", argv[i]);
579			usage();
580		    }
581		    if(cmd_flags.install_name != NULL){
582			error("more than one: %s option specified", argv[i]);
583			usage();
584		    }
585		    cmd_flags.install_name = argv[i+1];
586		    i++;
587		}
588		else if(strcmp(argv[i], "-seg1addr") == 0 ||
589			strcmp(argv[i], "-image_base") == 0){
590		    if(cmd_flags.ranlib == TRUE){
591			error("unknown option: %s", argv[i]);
592			usage();
593		    }
594		    if(i + 1 == argc){
595			error("missing argument to: %s option", argv[i]);
596			usage();
597		    }
598		    if(cmd_flags.seg1addr != NULL){
599			error("more than one: %s option specified", argv[i]);
600			usage();
601		    }
602		    temp = strtoul(argv[i + 1], &endp, 16);
603		    if(*endp != '\0'){
604			error("address for -seg1addr %s not a proper "
605			      "hexadecimal number", argv[i+1]);
606			usage();
607		    }
608		    cmd_flags.seg1addr = argv[i+1];
609		    i++;
610		}
611		else if(strcmp(argv[i], "-segs_read_only_addr") == 0){
612		    if(cmd_flags.ranlib == TRUE){
613			error("unknown option: %s", argv[i]);
614			usage();
615		    }
616		    if(i + 1 == argc){
617			error("missing argument to: %s option", argv[i]);
618			usage();
619		    }
620		    if(cmd_flags.segs_read_only_addr != NULL){
621			error("more than one: %s option specified", argv[i]);
622			usage();
623		    }
624		    temp = strtoul(argv[i + 1], &endp, 16);
625		    if(*endp != '\0'){
626			error("address for -segs_read_only_addr %s not a "
627			      "proper hexadecimal number", argv[i+1]);
628			usage();
629		    }
630		    cmd_flags.segs_read_only_addr = argv[i+1];
631		    i++;
632		}
633		else if(strcmp(argv[i], "-segs_read_write_addr") == 0){
634		    if(cmd_flags.ranlib == TRUE){
635			error("unknown option: %s", argv[i]);
636			usage();
637		    }
638		    if(i + 1 == argc){
639			error("missing argument to: %s option", argv[i]);
640			usage();
641		    }
642		    if(cmd_flags.segs_read_write_addr != NULL){
643			error("more than one: %s option specified", argv[i]);
644			usage();
645		    }
646		    temp = strtoul(argv[i + 1], &endp, 16);
647		    if(*endp != '\0'){
648			error("address for -segs_read_write_addr %s not a "
649			      "proper hexadecimal number", argv[i+1]);
650			usage();
651		    }
652		    cmd_flags.segs_read_write_addr = argv[i+1];
653		    i++;
654		}
655		else if(strcmp(argv[i], "-seg_addr_table") == 0){
656		    if(cmd_flags.ranlib == TRUE){
657			error("unknown option: %s", argv[i]);
658			usage();
659		    }
660		    if(i + 1 == argc){
661			error("missing argument to: %s option", argv[i]);
662			usage();
663		    }
664		    if(cmd_flags.seg_addr_table != NULL){
665			error("more than one: %s option specified", argv[i]);
666			usage();
667		    }
668		    cmd_flags.seg_addr_table = argv[i+1];
669		    i++;
670		}
671		else if(strcmp(argv[i], "-seg_addr_table_filename") == 0){
672		    if(cmd_flags.ranlib == TRUE){
673			error("unknown option: %s", argv[i]);
674			usage();
675		    }
676		    if(i + 1 == argc){
677			error("missing argument to: %s option", argv[i]);
678			usage();
679		    }
680		    if(cmd_flags.seg_addr_table_filename != NULL){
681			error("more than one: %s option specified", argv[i]);
682			usage();
683		    }
684		    cmd_flags.seg_addr_table_filename = argv[i+1];
685		    i++;
686		}
687		else if(strcmp(argv[i], "-syslibroot") == 0){
688		    if(cmd_flags.ranlib == TRUE){
689			error("unknown option: %s", argv[i]);
690			usage();
691		    }
692		    if(i + 1 == argc){
693			error("missing argument to: %s option", argv[i]);
694			usage();
695		    }
696		    if(next_root != NULL && strcmp(next_root, argv[i+1]) != 0){
697			error("more than one: %s option specified", argv[i]);
698			usage();
699		    }
700		    next_root = argv[i+1];
701		    cmd_flags.ldflags = reallocate(cmd_flags.ldflags,
702				sizeof(char *) * (cmd_flags.nldflags + 2));
703		    cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i];
704		    cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i+1];
705		    i++;
706		}
707		else if(strcmp(argv[i], "-sectcreate") == 0 ||
708		        strcmp(argv[i], "-segcreate") == 0 ||
709		        strcmp(argv[i], "-sectorder") == 0 ||
710		        strcmp(argv[i], "-sectalign") == 0 ||
711		        strcmp(argv[i], "-segprot") == 0){
712		    if(cmd_flags.ranlib == TRUE){
713			error("unknown option: %s", argv[i]);
714			usage();
715		    }
716		    if(i + 3 >= argc){
717			error("not enough arguments follow %s", argv[i]);
718			usage();
719		    }
720		    cmd_flags.ldflags = reallocate(cmd_flags.ldflags,
721				sizeof(char *) * (cmd_flags.nldflags + 4));
722		    cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i];
723		    cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i+1];
724		    cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i+2];
725		    cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i+3];
726		    if(strcmp(argv[i], "-sectcreate") == 0 ||
727		       strcmp(argv[i], "-segcreate") == 0)
728			cmd_flags.no_files_ok = TRUE;
729		    i += 3;
730		}
731		else if(strcmp(argv[i], "-segalign") == 0 ||
732		        strcmp(argv[i], "-undefined") == 0 ||
733		        strcmp(argv[i], "-macosx_version_min") == 0 ||
734		        strcmp(argv[i], "-multiply_defined") == 0 ||
735		        strcmp(argv[i], "-multiply_defined_unused") == 0 ||
736		        strcmp(argv[i], "-umbrella") == 0 ||
737			strcmp(argv[i], "-sub_umbrella") == 0 ||
738			strcmp(argv[i], "-sub_library") == 0 ||
739			strcmp(argv[i], "-allowable_client") == 0 ||
740		        strcmp(argv[i], "-read_only_relocs") == 0 ||
741		        strcmp(argv[i], "-init") == 0 ||
742		        strcmp(argv[i], "-U") == 0 ||
743		        strcmp(argv[i], "-Y") == 0 ||
744		        strcmp(argv[i], "-dylib_file") == 0 ||
745		        strcmp(argv[i], "-final_output") == 0 ||
746		        strcmp(argv[i], "-headerpad") == 0 ||
747		        strcmp(argv[i], "-weak_reference_mismatches") == 0 ||
748		        strcmp(argv[i], "-u") == 0 ||
749		        strcmp(argv[i], "-exported_symbols_list") == 0 ||
750		        strcmp(argv[i], "-unexported_symbols_list") == 0 ||
751		        strcmp(argv[i], "-executable_path") == 0){
752		    if(cmd_flags.ranlib == TRUE){
753			error("unknown option: %s", argv[i]);
754			usage();
755		    }
756		    if(i + 1 >= argc){
757			error("not enough arguments follow %s", argv[i]);
758			usage();
759		    }
760		    cmd_flags.ldflags = reallocate(cmd_flags.ldflags,
761				sizeof(char *) * (cmd_flags.nldflags + 2));
762		    cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i];
763		    cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i+1];
764		    if(strcmp(argv[i], "-final_output") == 0)
765			cmd_flags.final_output_specified = TRUE;
766		    i += 1;
767		}
768		else if(strcmp(argv[i], "-sectorder_detail") == 0 ||
769		        strcmp(argv[i], "-Sn") == 0 ||
770		        strcmp(argv[i], "-Si") == 0 ||
771		        strcmp(argv[i], "-Sp") == 0 ||
772		        strcmp(argv[i], "-S") == 0 ||
773		        strcmp(argv[i], "-X") == 0 ||
774		        strcmp(argv[i], "-x") == 0 ||
775		        strcmp(argv[i], "-whatsloaded") == 0 ||
776			strcmp(argv[i], "-whyload") == 0 ||
777			strcmp(argv[i], "-arch_errors_fatal") == 0 ||
778			strcmp(argv[i], "-run_init_lazily") == 0 ||
779			strcmp(argv[i], "-twolevel_namespace") == 0 ||
780			strcmp(argv[i], "-twolevel_namespace_hints") == 0 ||
781			strcmp(argv[i], "-flat_namespace") == 0 ||
782			strcmp(argv[i], "-nomultidefs") == 0 ||
783			strcmp(argv[i], "-headerpad_max_install_names") == 0 ||
784			strcmp(argv[i], "-prebind_all_twolevel_modules") == 0 ||
785			strcmp(argv[i], "-prebind_allow_overlap") == 0 ||
786			strcmp(argv[i], "-ObjC") == 0 ||
787			strcmp(argv[i], "-M") == 0 ||
788			strcmp(argv[i], "-t") == 0 ||
789			strcmp(argv[i], "-single_module") == 0 ||
790			strcmp(argv[i], "-multi_module") == 0 ||
791			strcmp(argv[i], "-m") == 0 ||
792			strcmp(argv[i], "-dead_strip") == 0 ||
793			strcmp(argv[i], "-no_uuid") == 0 ||
794			strcmp(argv[i], "-no_dead_strip_inits_and_terms") == 0){
795		    if(cmd_flags.ranlib == TRUE){
796			error("unknown option: %s", argv[i]);
797			usage();
798		    }
799		    cmd_flags.ldflags = reallocate(cmd_flags.ldflags,
800				sizeof(char *) * (cmd_flags.nldflags + 1));
801		    cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i];
802		}
803		else if(strcmp(argv[i], "-no_arch_warnings") == 0){
804		    if(cmd_flags.ranlib == TRUE){
805			error("unknown option: %s", argv[i]);
806			usage();
807		    }
808		    /* ignore this flag */
809		}
810		else if(strcmp(argv[i], "-prebind") == 0){
811		    if(cmd_flags.ranlib == TRUE){
812			error("unknown option: %s", argv[i]);
813			usage();
814		    }
815		    if(cmd_flags.prebinding_flag_specified == TRUE &&
816		       cmd_flags.prebinding == FALSE){
817			error("both -prebind and -noprebind can't be "
818			      "specified");
819			usage();
820		    }
821		    cmd_flags.prebinding_flag_specified = TRUE;
822		    cmd_flags.prebinding = TRUE;
823		    cmd_flags.ldflags = reallocate(cmd_flags.ldflags,
824				sizeof(char *) * (cmd_flags.nldflags + 1));
825		    cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i];
826		}
827		else if(strcmp(argv[i], "-noprebind") == 0){
828		    if(cmd_flags.ranlib == TRUE){
829			error("unknown option: %s", argv[i]);
830			usage();
831		    }
832		    if(cmd_flags.prebinding_flag_specified == TRUE &&
833		       cmd_flags.prebinding == TRUE){
834			error("both -prebind and -noprebind can't be "
835			      "specified");
836			usage();
837		    }
838		    cmd_flags.prebinding_flag_specified = TRUE;
839		    cmd_flags.prebinding = FALSE;
840		    cmd_flags.ldflags = reallocate(cmd_flags.ldflags,
841				sizeof(char *) * (cmd_flags.nldflags + 1));
842		    cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i];
843		}
844		else if(strcmp(argv[i], "-all_load") == 0){
845		    if(cmd_flags.ranlib == TRUE){
846			error("unknown option: %s", argv[i]);
847			usage();
848		    }
849		    if(cmd_flags.all_load_flag_specified == TRUE &&
850		       cmd_flags.all_load == FALSE){
851			error("both -all_load and -noall_load can't be "
852			      "specified");
853			usage();
854		    }
855		    cmd_flags.all_load_flag_specified = TRUE;
856		    cmd_flags.all_load = TRUE;
857		}
858		else if(strcmp(argv[i], "-noall_load") == 0){
859		    if(cmd_flags.ranlib == TRUE){
860			error("unknown option: %s", argv[i]);
861			usage();
862		    }
863		    if(cmd_flags.all_load_flag_specified == TRUE &&
864		       cmd_flags.all_load == TRUE){
865			error("both -all_load and -noall_load can't be "
866			      "specified");
867			usage();
868		    }
869		    cmd_flags.all_load_flag_specified = TRUE;
870		    cmd_flags.all_load = FALSE;
871		}
872		else if(strncmp(argv[i], "-y", 2) == 0 ||
873		        strncmp(argv[i], "-i", 2) == 0){
874		    if(cmd_flags.ranlib == TRUE){
875			error("unknown option: %s", argv[i]);
876			usage();
877		    }
878		    if(strncmp(argv[i], "-i", 2) == 0)
879			cmd_flags.no_files_ok = TRUE;
880		    cmd_flags.ldflags = reallocate(cmd_flags.ldflags,
881				sizeof(char *) * (cmd_flags.nldflags + 1));
882		    cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i];
883		}
884		else if(argv[i][1] == 'l'){
885		    if(cmd_flags.ranlib == TRUE){
886			error("unknown option: %s", argv[i]);
887			usage();
888		    }
889		    if(argv[i][2] == '\0'){
890			error("-l: name missing");
891			usage();
892		    }
893		    cmd_flags.files[cmd_flags.nfiles++] = argv[i];
894		    lflags_seen = TRUE;
895		}
896		else if(strncmp(argv[i], "-weak-l", 7) == 0){
897		    if(cmd_flags.ranlib == TRUE){
898			error("unknown option: %s", argv[i]);
899			usage();
900		    }
901		    if(argv[i][7] == '\0'){
902			error("-weak-l: name missing");
903			usage();
904		    }
905		    cmd_flags.files[cmd_flags.nfiles++] = argv[i];
906		    lflags_seen = TRUE;
907		}
908		else if(strcmp(argv[i], "-framework") == 0 ||
909		        strcmp(argv[i], "-weak_framework") == 0 ||
910		        strcmp(argv[i], "-weak_library") == 0){
911		    if(cmd_flags.ranlib == TRUE){
912			error("unknown option: %s", argv[i]);
913			usage();
914		    }
915		    if(i + 1 >= argc){
916			error("not enough arguments follow %s", argv[i]);
917			usage();
918		    }
919		    cmd_flags.files[cmd_flags.nfiles++] = argv[i];
920		    cmd_flags.files[cmd_flags.nfiles++] = argv[i+1];
921		    lflags_seen = TRUE;
922		    i += 1;
923		}
924		else if(strcmp(argv[i], "-T") == 0){
925		    if(cmd_flags.L_or_T_specified == TRUE){
926			error("both -T and -L can't be specified");
927			usage();
928		    }
929		    cmd_flags.L_or_T_specified = TRUE;
930		    cmd_flags.use_long_names = FALSE;
931		}
932		else if(argv[i][1] == 'L' || argv[i][1] == 'F'){
933		    if(argv[i][1] == 'L' && argv[i][2] == '\0'){
934			if(cmd_flags.L_or_T_specified == TRUE){
935			    error("both -T and -L can't be specified");
936			    usage();
937			}
938			cmd_flags.L_or_T_specified = TRUE;
939			cmd_flags.use_long_names = TRUE;
940		    }
941		    else{
942			if(cmd_flags.ranlib == TRUE){
943			    error("unknown option: %s", argv[i]);
944			    usage();
945			}
946			cmd_flags.Ldirs = realloc(cmd_flags.Ldirs,
947				    sizeof(char *) * (cmd_flags.nLdirs + 1));
948			cmd_flags.Ldirs[cmd_flags.nLdirs++] = argv[i];
949		    }
950		}
951		else if(argv[i][1] == 'g'){
952		    if(cmd_flags.ranlib == TRUE){
953			error("unknown option: %s", argv[i]);
954			usage();
955		    }
956		    /* We need to ignore -g[gdb,codeview,stab][number] flags */
957			;
958		}
959		else if(strcmp(argv[i], "-pg") == 0){
960		    if(cmd_flags.ranlib == TRUE){
961			error("unknown option: %s", argv[i]);
962			usage();
963		    }
964		    /* We need to ignore -pg */
965			;
966		}
967		else if(strcmp(argv[i], "-search_paths_first") == 0){
968		    if(cmd_flags.ranlib == TRUE){
969			error("unknown option: %s", argv[i]);
970			usage();
971		    }
972		    cmd_flags.search_paths_first = TRUE;
973		    cmd_flags.ldflags = reallocate(cmd_flags.ldflags,
974				sizeof(char *) * (cmd_flags.nldflags + 1));
975		    cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i];
976		}
977		else if(strcmp(argv[i], "-noflush") == 0){
978		    cmd_flags.noflush = TRUE;
979		}
980#ifdef DEBUG
981		else if(strcmp(argv[i], "-debug") == 0){
982		    if(i + 1 >= argc){
983			error("not enough arguments follow %s", argv[i]);
984			usage();
985		    }
986		    i++;
987		    cmd_flags.debug |= 1 << strtoul(argv[i], &endp, 10);
988		    if(*endp != '\0' || strtoul(argv[i], &endp, 10) > 32)
989			fatal("argument for -debug %s not a proper "
990			      "decimal number less than 32", argv[i]);
991		}
992#endif /* DEBUG */
993		else{
994		    for(j = 1; argv[i][j] != '\0'; j++){
995			switch(argv[i][j]){
996			case 's':
997			    cmd_flags.s = TRUE;
998			    break;
999			case 'a':
1000			    cmd_flags.a = TRUE;
1001			    break;
1002			case 'c':
1003			    cmd_flags.c = TRUE;
1004			    break;
1005			case 'v':
1006			    if(cmd_flags.ranlib == TRUE){
1007				error("unknown option character `%c' in: %s",
1008				      argv[i][j], argv[i]);
1009				usage();
1010			    }
1011			    cmd_flags.verbose= TRUE;
1012			    break;
1013			case 'V':
1014			    printf("Apple Inc. version %s\n", apple_version);
1015			    Vflag = TRUE;
1016			    break;
1017			case 't':
1018			    if(cmd_flags.ranlib == TRUE){
1019				warning("touch option (`%c' in: %s) ignored "
1020					"(table of contents rebuilt anyway)",
1021					argv[i][j], argv[i]);
1022				cmd_flags.t = TRUE;
1023				break;
1024			    }
1025			    else {
1026				error("unknown option character `%c' in: %s",
1027				      argv[i][j], argv[i]);
1028				usage();
1029			    }
1030			case 'f':
1031			    if(cmd_flags.ranlib == TRUE){
1032				cmd_flags.f = TRUE;
1033				break;
1034			    }
1035			    else {
1036				error("unknown option character `%c' in: %s",
1037				      argv[i][j], argv[i]);
1038				usage();
1039			    }
1040			case 'q':
1041			    if(cmd_flags.ranlib == TRUE){
1042				cmd_flags.q = TRUE;
1043				break;
1044			    }
1045			    else {
1046				error("unknown option character `%c' in: %s",
1047				      argv[i][j], argv[i]);
1048				usage();
1049			    }
1050			default:
1051			    error("unknown option character `%c' in: %s",
1052				  argv[i][j], argv[i]);
1053			    usage();
1054			}
1055		    }
1056		}
1057	    }
1058	    else
1059		cmd_flags.files[cmd_flags.nfiles++] = argv[i];
1060	}
1061	/*
1062         * Test to see if the environment variable LD_TRACE_ARCHIVES is set.
1063         */
1064        if((getenv("RC_TRACE_ARCHIVES") != NULL) ||
1065	   (getenv("LD_TRACE_ARCHIVES") != NULL)) {
1066	     cmd_flags.ld_trace_archives = TRUE;
1067	     cmd_flags.trace_file_path = getenv("LD_TRACE_FILE");
1068	   }
1069
1070	/*
1071	 * If either -syslibroot or the environment variable NEXT_ROOT is set
1072	 * prepend it to the standard paths for library searches.  This was
1073	 * added to ease cross build environments.
1074	 */
1075	if(next_root != NULL){
1076	    if(getenv("NEXT_ROOT") != NULL)
1077		warning("NEXT_ROOT environment variable ignored because "
1078			"-syslibroot specified");
1079	}
1080	else{
1081	    next_root = getenv("NEXT_ROOT");
1082	}
1083	if(next_root != NULL){
1084	    for(i = 0; standard_dirs[i] != NULL; i++){
1085		p = allocate(strlen(next_root) +
1086			     strlen(standard_dirs[i]) + 1);
1087		strcpy(p, next_root);
1088		strcat(p, standard_dirs[i]);
1089		standard_dirs[i] = p;
1090	    }
1091	    for(i = 0; i < cmd_flags.nLdirs ; i++){
1092		if(cmd_flags.Ldirs[i][1] != 'L')
1093		    continue;
1094		if(cmd_flags.Ldirs[i][2] == '/'){
1095		    p = makestr(next_root, cmd_flags.Ldirs[i] + 2, NULL);
1096		    if(access(p, F_OK) != -1){
1097			free(p);
1098			p = makestr("-L", next_root, cmd_flags.Ldirs[i] + 2,
1099				    NULL);
1100			cmd_flags.Ldirs[i] = p;
1101		    }
1102		    else{
1103			free(p);
1104		    }
1105		}
1106	    }
1107	}
1108
1109	/* check the command line arguments for correctness */
1110	if(cmd_flags.ranlib == FALSE && cmd_flags.dynamic == TRUE){
1111	    if(cmd_flags.s == TRUE){
1112		warning("-static not specified, -s invalid");
1113	    }
1114	    if(cmd_flags.a == TRUE){
1115		warning("-static not specified, -a invalid");
1116	    }
1117	    if(cmd_flags.c == TRUE){
1118		warning("-static not specified, -c invalid");
1119	    }
1120	    if(cmd_flags.L_or_T_specified == TRUE){
1121		if(cmd_flags.use_long_names == TRUE)
1122		    warning("-static not specified, -L invalid");
1123		else
1124		    warning("-static not specified, -T invalid");
1125	    }
1126	}
1127	if(cmd_flags.s == TRUE && cmd_flags.a == TRUE){
1128	    error("only one of -s or -a can be specified");
1129	    usage();
1130	}
1131	if(cmd_flags.ranlib == FALSE && cmd_flags.output == NULL){
1132	    if(Vflag == TRUE)
1133		exit(EXIT_SUCCESS);
1134	    error("no output file specified (specify with -o output)");
1135	    usage();
1136	}
1137	if(cmd_flags.dynamic == FALSE){
1138	    if(cmd_flags.compatibility != NULL){
1139		warning("-dynamic not specified, -compatibility_version %s "
1140		      "invalid", cmd_flags.compatibility);
1141	    }
1142	    if(cmd_flags.current != NULL){
1143		warning("-dynamic not specified, -current_version %s invalid",
1144		      cmd_flags.current);
1145	    }
1146	    if(cmd_flags.install_name != NULL){
1147		warning("-dynamic not specified, -install_name %s invalid",
1148		      cmd_flags.install_name);
1149	    }
1150	    if(cmd_flags.seg1addr != NULL){
1151		warning("-dynamic not specified, -seg1addr %s invalid",
1152		      cmd_flags.seg1addr);
1153	    }
1154	    if(cmd_flags.segs_read_only_addr != NULL){
1155		warning("-dynamic not specified, -segs_read_only_addr %s "
1156			"invalid", cmd_flags.segs_read_only_addr);
1157	    }
1158	    if(cmd_flags.segs_read_write_addr != NULL){
1159		warning("-dynamic not specified, -segs_read_write_addr %s "
1160			"invalid", cmd_flags.segs_read_write_addr);
1161	    }
1162	    if(cmd_flags.seg_addr_table != NULL){
1163		warning("-dynamic not specified, -seg_addr_table %s "
1164			"invalid", cmd_flags.seg_addr_table);
1165	    }
1166	    if(cmd_flags.seg_addr_table_filename != NULL){
1167		warning("-dynamic not specified, -seg_addr_table_filename %s "
1168			"invalid", cmd_flags.seg_addr_table_filename);
1169	    }
1170	    if(cmd_flags.all_load_flag_specified == TRUE){
1171		if(cmd_flags.all_load == TRUE)
1172		    warning("-dynamic not specified, -all_load invalid");
1173		else
1174		    warning("-dynamic not specified, -noall_load invalid");
1175	    }
1176	    if(cmd_flags.nldflags != 0){
1177		bad_flag_seen = FALSE;
1178		for(j = 0; j < cmd_flags.nldflags; j++){
1179		    if(strcmp(cmd_flags.ldflags[j], "-syslibroot") == 0){
1180			j++;
1181			continue;
1182		    }
1183		    if(bad_flag_seen == FALSE){
1184			fprintf(stderr, "%s: -dynamic not specified the "
1185				"following flags are invalid: ", progname);
1186			bad_flag_seen = TRUE;
1187		    }
1188		    fprintf(stderr, "%s ", cmd_flags.ldflags[j]);
1189		}
1190		if(bad_flag_seen == TRUE)
1191		    fprintf(stderr, "\n");
1192	    }
1193	    if(cmd_flags.nLdirs != 0){
1194		/* Note: both -L and -F flags are in cmd_flags.Ldirs to keep the
1195		   search order right. */
1196		bad_flag_seen = FALSE;
1197		for(j = 0; j < cmd_flags.nLdirs; j++){
1198		    if(strncmp(cmd_flags.Ldirs[j], "-L", 2) == 0)
1199			continue;
1200		    if(bad_flag_seen == FALSE){
1201			fprintf(stderr, "%s: -dynamic not specified the "
1202				"following flags are invalid: ", progname);
1203			bad_flag_seen = TRUE;
1204		    }
1205		    fprintf(stderr, "%s ", cmd_flags.Ldirs[j]);
1206		}
1207		if(bad_flag_seen == TRUE)
1208		    fprintf(stderr, "\n");
1209	    }
1210	}
1211	else{
1212	    /*
1213	     * The -prebind flag can also be specified with the LD_PREBIND
1214	     * environment variable.
1215	     */
1216	    if(getenv("LD_PREBIND") != NULL){
1217		if(cmd_flags.prebinding_flag_specified == TRUE &&
1218		   cmd_flags.prebinding == FALSE){
1219		    warning("LD_PREBIND environment variable ignored because "
1220			    "-noprebind specified");
1221		}
1222		else{
1223		    cmd_flags.prebinding_flag_specified = TRUE;
1224		    cmd_flags.prebinding = TRUE;
1225		}
1226	    }
1227	}
1228	if(cmd_flags.nfiles == 0){
1229	    if(cmd_flags.ranlib == TRUE){
1230		error("no archives specified");
1231		usage();
1232	    }
1233	    else{
1234		if(cmd_flags.dynamic == TRUE && cmd_flags.no_files_ok == TRUE)
1235		    warning("warning no files specified");
1236		else{
1237		    error("no files specified");
1238		    usage();
1239		}
1240	    }
1241	}
1242
1243	/* set the defaults if not specified */
1244	if(cmd_flags.a == FALSE)
1245	    cmd_flags.s = TRUE; /* sort table of contents by default */
1246
1247	process();
1248
1249	if(errors == 0)
1250	    return(EXIT_SUCCESS);
1251	else
1252	    return(EXIT_FAILURE);
1253}
1254
1255/*
1256 * usage() prints the current usage message and exits indicating failure.
1257 */
1258static
1259void
1260usage(
1261void)
1262{
1263	if(cmd_flags.ranlib)
1264	    fprintf(stderr, "Usage: %s [-sactfqLT] [-] archive [...]\n",
1265		    progname);
1266	else{
1267	    fprintf(stderr, "Usage: %s -static [-] file [...] "
1268		    "[-filelist listfile[,dirname]] [-arch_only arch] "
1269		    "[-sacLT]\n", progname);
1270	    fprintf(stderr, "Usage: %s -dynamic [-] file [...] "
1271		    "[-filelist listfile[,dirname]] [-arch_only arch] "
1272		    "[-o output] [-install_name name] "
1273		    "[-compatibility_version #] [-current_version #] "
1274		    "[-seg1addr 0x#] [-segs_read_only_addr 0x#] "
1275		    "[-segs_read_write_addr 0x#] [-seg_addr_table <filename>] "
1276		    "[-seg_addr_table_filename <file_system_path>] "
1277		    "[-all_load] [-noall_load]\n",
1278		    progname);
1279	}
1280	exit(EXIT_FAILURE);
1281}
1282
1283/*
1284 * process() the input files into libraries based on the command flags.
1285 */
1286static
1287void
1288process(
1289void)
1290{
1291    uint32_t i, j, k, previous_errors;
1292    struct ofile *ofiles;
1293    char *file_name;
1294    enum bool flag, ld_trace_archive_printed;
1295
1296	/*
1297	 * For libtool processing put all input files in the specified output
1298	 * file.  For ranlib processing all input files should be archives or
1299	 * fat files with archives in them and each is processed by itself and
1300	 * not combined with anything else.  The format of fat object files in
1301	 * a thin archive is supported here also.
1302	 */
1303	ofiles = allocate(sizeof(struct ofile) * cmd_flags.nfiles);
1304	for(i = 0; i < cmd_flags.nfiles; i++){
1305	    if(strncmp(cmd_flags.files[i], "-l", 2) == 0 ||
1306	       strncmp(cmd_flags.files[i], "-weak-l", 7) == 0){
1307		file_name = file_name_from_l_flag(cmd_flags.files[i]);
1308		if(file_name != NULL)
1309		    if(ofile_map(file_name, NULL, NULL, ofiles + i, TRUE) ==
1310		       FALSE)
1311			continue;
1312	    }
1313	    else if(strcmp(cmd_flags.files[i], "-framework") == 0 ||
1314		    strcmp(cmd_flags.files[i], "-weak_framework") == 0 ||
1315		    strcmp(cmd_flags.files[i], "-weak_library") == 0){
1316		i++;
1317		continue;
1318	    }
1319	    else{
1320		if(ofile_map(cmd_flags.files[i], NULL, NULL, ofiles + i,
1321			     TRUE) == FALSE)
1322		    continue;
1323	    }
1324
1325	    previous_errors = errors;
1326	    errors = 0;
1327	    ld_trace_archive_printed = FALSE;
1328
1329	    if(ofiles[i].file_type == OFILE_FAT){
1330		(void)ofile_first_arch(ofiles + i);
1331		do{
1332		    if(ofiles[i].arch_type == OFILE_ARCHIVE){
1333			if(cmd_flags.ld_trace_archives == TRUE &&
1334			   cmd_flags.dynamic == FALSE &&
1335			   ld_trace_archive_printed == FALSE){
1336			    char resolvedname[MAXPATHLEN];
1337                	    if(realpath(ofiles[i].file_name, resolvedname) !=
1338			       NULL)
1339				ld_trace("[Logging for XBS] Used static "
1340					 "archive: %s\n", resolvedname);
1341			    else
1342				ld_trace("[Logging for XBS] Used static "
1343					 "archive: %s\n", ofiles[i].file_name);
1344			    ld_trace_archive_printed = TRUE;
1345			}
1346			/* loop through archive */
1347			if((flag = ofile_first_member(ofiles + i)) == TRUE){
1348			    if(ofiles[i].member_ar_hdr != NULL &&
1349			       strncmp(ofiles[i].member_name, SYMDEF,
1350				       sizeof(SYMDEF) - 1) == 0)
1351				flag = ofile_next_member(ofiles + i);
1352			    while(flag == TRUE){
1353				/* No fat members in a fat file */
1354				if(ofiles[i].mh != NULL ||
1355				   ofiles[i].mh64 != NULL ||
1356				   ofiles[i].lto != NULL ||
1357				   cmd_flags.ranlib == TRUE)
1358				    add_member(ofiles + i);
1359				else{
1360				    error("for architecture: %s file: %s(%.*s) "
1361					  "is not an object file (not allowed "
1362					  "in a library)",
1363					  ofiles[i].arch_flag.name,
1364					  cmd_flags.files[i],
1365					  (int)ofiles[i].member_name_size,
1366					  ofiles[i].member_name);
1367				}
1368				flag = ofile_next_member(ofiles + i);
1369			    }
1370			}
1371		    }
1372		    else if(ofiles[i].arch_type == OFILE_Mach_O ||
1373		            ofiles[i].arch_type == OFILE_LLVM_BITCODE){
1374			if(cmd_flags.ranlib == TRUE){
1375			    error("for architecture: %s file: %s is not an "
1376				  "archive (no processing done on this file)",
1377				  ofiles[i].arch_flag.name, cmd_flags.files[i]);
1378			    goto ranlib_fat_error;
1379			}
1380			else
1381			    add_member(ofiles + i);
1382		    }
1383		    else if(ofiles[i].arch_type == OFILE_UNKNOWN){
1384			if(cmd_flags.ranlib == TRUE){
1385			    error("for architecture: %s file: %s is not an "
1386				  "archive (no processing done on this file)",
1387				  ofiles[i].arch_flag.name, cmd_flags.files[i]);
1388			    goto ranlib_fat_error;
1389			}
1390			else{
1391			    error("for architecture: %s file: %s is not an "
1392				  "object file (not allowed in a library)",
1393				  ofiles[i].arch_flag.name, cmd_flags.files[i]);
1394			}
1395		    }
1396		}while(ofile_next_arch(ofiles + i) == TRUE);
1397	    }
1398	    else if(ofiles[i].file_type == OFILE_ARCHIVE){
1399		if(cmd_flags.ld_trace_archives == TRUE &&
1400		   cmd_flags.dynamic == FALSE &&
1401		   ld_trace_archive_printed == FALSE){
1402		    char resolvedname[MAXPATHLEN];
1403		    if(realpath(ofiles[i].file_name, resolvedname) != NULL)
1404			ld_trace("[Logging for XBS] Used static archive: "
1405				 "%s\n", resolvedname);
1406		    else
1407			ld_trace("[Logging for XBS] Used static archive: "
1408				 "%s\n", ofiles[i].file_name);
1409		    ld_trace_archive_printed = TRUE;
1410		}
1411		/* loop through archive */
1412		if((flag = ofile_first_member(ofiles + i)) == TRUE){
1413		    if(ofiles[i].member_ar_hdr != NULL &&
1414		       strncmp(ofiles[i].member_name, SYMDEF,
1415			       sizeof(SYMDEF) - 1) == 0){
1416			flag = ofile_next_member(ofiles + i);
1417		    }
1418		    while(flag == TRUE){
1419			/* incorrect form: archive with fat object members */
1420			if(ofiles[i].member_type == OFILE_FAT){
1421			    (void)ofile_first_arch(ofiles + i);
1422			    do{
1423				if(ofiles[i].mh != NULL ||
1424				   ofiles[i].mh64 != NULL ||
1425				   ofiles[i].lto != NULL ||
1426				   cmd_flags.ranlib == TRUE){
1427				    add_member(ofiles + i);
1428				}
1429				else{
1430				    /*
1431				     * Can't really get here because ofile_*()
1432				     * routines will refuse to process this
1433				     * type of file (but I'll leave it here).
1434				     */
1435				    error("file: %s(%.*s) for architecture: %s "
1436					"is not an object file (not allowed in "
1437					"a library)", cmd_flags.files[i],
1438					(int)ofiles[i].member_name_size,
1439					ofiles[i].member_name,
1440					ofiles[i].arch_flag.name);
1441				}
1442
1443			    }while(ofile_next_arch(ofiles + i) == TRUE);
1444			}
1445			else if(ofiles[i].mh != NULL ||
1446			        ofiles[i].mh64 != NULL ||
1447#ifdef LTO_SUPPORT
1448			        ofiles[i].lto != NULL ||
1449#endif /* LTO_SUPPORT */
1450				cmd_flags.ranlib == TRUE){
1451			    add_member(ofiles + i);
1452			}
1453			else{
1454			    error("file: %s(%.*s) is not an object file (not "
1455				  "allowed in a library)", cmd_flags.files[i],
1456				  (int)ofiles[i].member_name_size,
1457				  ofiles[i].member_name);
1458			}
1459			flag = ofile_next_member(ofiles + i);
1460		    }
1461		}
1462	    }
1463	    else if(ofiles[i].file_type == OFILE_Mach_O){
1464		if(cmd_flags.ranlib == TRUE){
1465		    error("file: %s is not an archive", cmd_flags.files[i]);
1466		    continue;
1467		}
1468		add_member(ofiles + i);
1469	    }
1470#ifdef LTO_SUPPORT
1471	    else if(ofiles[i].file_type == OFILE_LLVM_BITCODE){
1472		if(cmd_flags.ranlib == TRUE){
1473		    error("file: %s is not an archive", cmd_flags.files[i]);
1474		    continue;
1475		}
1476		add_member(ofiles + i);
1477	    }
1478#endif /* LTO_SUPPORT */
1479	    else{ /* ofiles[i].file_type == OFILE_UNKNOWN */
1480		if(cmd_flags.ranlib == TRUE){
1481		    error("file: %s is not an archive", cmd_flags.files[i]);
1482		    continue;
1483		}
1484		else{
1485		    error("file: %s is not an object file (not allowed in a "
1486			  "library)", cmd_flags.files[i]);
1487		}
1488	    }
1489
1490	    if(cmd_flags.ranlib == TRUE){
1491		/*
1492		 * In the case where ranlib is being used on an archive that
1493		 * contains fat object files with multiple members and non-
1494		 * object members this has to be treated as an error because
1495		 * it is not known which architecture(s) the non-object file
1496		 * belong to.
1497		 */
1498		if(narchs > 1){
1499		    for(j = 0; j < narchs; j++){
1500			for(k = 0; k < archs[j].nmembers; k++){
1501			    if(archs[j].members[k].mh == NULL &&
1502#ifdef LTO_SUPPORT
1503			       archs[j].members[k].lto == NULL &&
1504#endif /* LTO_SUPPORT */
1505			       archs[j].members[k].mh64 == NULL){
1506				error("library member: %s(%.*s) is not an "
1507				      "object file (not allowed in a library "
1508				      "with multiple architectures)",
1509				      cmd_flags.files[i],
1510				      (int)archs[j].members[k].
1511					input_base_name_size,
1512				      archs[j].members[k].input_base_name);
1513			    }
1514			}
1515		    }
1516		}
1517		if(errors == 0)
1518		    create_library(cmd_flags.files[i], ofiles + i);
1519		if(cmd_flags.nfiles > 1){
1520ranlib_fat_error:
1521		    free_archs();
1522		    ofile_unmap(ofiles + i);
1523		}
1524	    }
1525	    errors += previous_errors;
1526	}
1527	if(cmd_flags.ranlib == FALSE && errors == 0)
1528	    create_library(cmd_flags.output, NULL);
1529
1530	/*
1531	 * Clean-up of ofiles[] and archs could be done here but since this
1532	 * program is now done it is faster to just exit.
1533	 */
1534}
1535
1536/*
1537 * file_name_from_l_flag() is passed a "-lx" or "-weak-lx" flag and returns a
1538 * name of a file for this flag.  The flag "-lx" and "-weak-lx" are the same
1539 * flags as used in the link editor to refer to file names.  If it can't find a
1540 * file name for the flag it prints an error and returns NULL.
1541 */
1542static
1543char *
1544file_name_from_l_flag(
1545char *l_flag)
1546{
1547    char *file_name, *p, *start;
1548
1549	if(strncmp(l_flag, "-weak-l", 7) == 0)
1550	    start = &l_flag[7];
1551	else
1552	    start = &l_flag[2];
1553	p = strrchr(start, '.');
1554	if(p != NULL && strcmp(p, ".o") == 0){
1555	    p = start;
1556	    file_name = search_for_file(p);
1557	}
1558	else{
1559	    file_name = NULL;
1560	    if(cmd_flags.dynamic == TRUE){
1561		if(cmd_flags.search_paths_first == TRUE){
1562		    file_name = search_paths_for_lname(start);
1563		}
1564		else{
1565		    p = makestr("lib", start, ".dylib", NULL);
1566		    file_name = search_for_file(p);
1567		    free(p);
1568		    if(file_name == NULL){
1569			p = makestr("lib", start, ".a", NULL);
1570			file_name = search_for_file(p);
1571			free(p);
1572		    }
1573		}
1574	    }
1575	    else{
1576		p = makestr("lib", start, ".a", NULL);
1577		file_name = search_for_file(p);
1578		free(p);
1579	    }
1580	}
1581	if(file_name == NULL)
1582	    error("can't locate file for: %s", l_flag);
1583	return(file_name);
1584}
1585
1586/*
1587 * search_for_file() takes base_name and trys to find a file with that base name
1588 * is the -L search directories and in the standard directories.  If it is
1589 * sucessful it returns a pointer to the file name else it returns NULL.
1590 */
1591static
1592char *
1593search_for_file(
1594char *base_name)
1595{
1596    uint32_t i;
1597    char *file_name;
1598
1599	for(i = 0; i < cmd_flags.nLdirs ; i++){
1600	    if(cmd_flags.Ldirs[i][1] != 'L')
1601		continue;
1602	    file_name = makestr(cmd_flags.Ldirs[i] + 2, "/", base_name, NULL);
1603	    if(access(file_name, R_OK) != -1)
1604		return(file_name);
1605	    free(file_name);
1606	}
1607	for(i = 0; standard_dirs[i] != NULL ; i++){
1608	    file_name = makestr(standard_dirs[i], base_name, NULL);
1609	    if(access(file_name, R_OK) != -1)
1610		return(file_name);
1611	    free(file_name);
1612	}
1613	return(NULL);
1614}
1615
1616/*
1617 * search_paths_for_lname() takes the argument to a -lx option and and trys to
1618 * find a file with the name libx.dylib or libx.a.  This routine is only used
1619 * when the -search_paths_first option is specified and -dynamic is in effect.
1620 * And looks for a file name ending in .dylib then .a in each directory before
1621 * looking in the next directory.  The list of the -L search directories and in
1622 * the standard directories are searched in that order.  If this is sucessful
1623 * it returns a pointer to the file name else NULL.
1624 */
1625static
1626char *
1627search_paths_for_lname(
1628const char *lname_argument)
1629{
1630    uint32_t i;
1631    char *file_name, *dir;
1632
1633	for(i = 0; i < cmd_flags.nLdirs ; i++){
1634	    if(cmd_flags.Ldirs[i][1] != 'L')
1635		continue;
1636	    dir = makestr(cmd_flags.Ldirs[i] + 2, "/", NULL);
1637	    file_name = search_path_for_lname(dir, lname_argument);
1638	    free(dir);
1639	    if(file_name != NULL)
1640		return(file_name);
1641	}
1642	for(i = 0; standard_dirs[i] != NULL ; i++){
1643	    file_name = search_path_for_lname(standard_dirs[i], lname_argument);
1644	    if(file_name != NULL)
1645		return(file_name);
1646	}
1647	return(NULL);
1648}
1649
1650/*
1651 * search_path_for_lname() takes the argument to a -lx option and and trys to
1652 * find a file with the name libx.dylib then libx.a in the specified directory
1653 * name.  This routine is only used when the -search_paths_first option is
1654 * specified and -dynamic is in effect.  If this is sucessful it returns a
1655 * pointer to the file name else NULL.
1656 */
1657static
1658char *
1659search_path_for_lname(
1660const char *dir,
1661const char *lname_argument)
1662{
1663    char *file_name;
1664
1665	file_name = makestr(dir, "/", "lib", lname_argument, ".dylib", NULL);
1666	if(access(file_name, R_OK) != -1)
1667	    return(file_name);
1668	free(file_name);
1669
1670	file_name = makestr(dir, "/", "lib", lname_argument, ".a", NULL);
1671	if(access(file_name, R_OK) != -1)
1672	    return(file_name);
1673	free(file_name);
1674
1675	return(NULL);
1676}
1677
1678/*
1679 * add_member() add the specified ofile as a member to the library.  The
1680 * specified ofile must be either an object file (libtool or ranlib) or an
1681 * archive member with an unknown file type (ranlib only).
1682 */
1683static
1684void
1685add_member(
1686struct ofile *ofile)
1687{
1688    uint32_t i, j, size, ar_name_size;
1689    struct arch *arch;
1690    struct member *member;
1691    struct stat stat_buf;
1692    char *p, c, ar_name_buf[sizeof(ofile->member_ar_hdr->ar_name) + 1];
1693    char ar_size_buf[sizeof(ofile->member_ar_hdr->ar_size) + 1];
1694    const struct arch_flag *family_arch_flag;
1695
1696	/*
1697	 * If this did not come from an archive get the stat info which is
1698	 * needed to fill in the archive header for this member.
1699	 */
1700	if(ofile->member_ar_hdr == NULL){
1701	    if(stat(ofile->file_name, &stat_buf) == -1){
1702		system_error("can't stat file: %s", ofile->file_name);
1703		return;
1704	    }
1705	}
1706
1707	/*
1708	 * Determine the size this member will have in the library which
1709	 * includes the padding as a result of rounding the size of the
1710	 * member.  To get all members on an 8 byte boundary (so that mapping
1711	 * in object files can be used directly) the size of the member is
1712	 * CHANGED to reflect this padding.  In the UNIX definition of archives
1713	 * the size of the member is never changed but the offset to the next
1714	 * member is defined to be the offset of the previous member plus
1715	 * the size of the previous member rounded to 2.  So to get 8 byte
1716	 * boundaries without breaking the UNIX definition of archives the
1717	 * size is changed here.  As with the UNIX ar(1) program the padded
1718	 * bytes are set to the character '\n'.
1719	 */
1720	if(ofile->mh != NULL || ofile->mh64 != NULL)
1721	    size = rnd(ofile->object_size, 8);
1722#ifdef LTO_SUPPORT
1723	else if(ofile->lto != NULL && ofile->file_type == OFILE_LLVM_BITCODE)
1724	    size = rnd(ofile->file_size, 8);
1725#endif /* LTO_SUPPORT */
1726	else
1727	    size = rnd(ofile->member_size, 8);
1728
1729	/* select or create an arch type to put this in */
1730	i = 0;
1731	if(ofile->mh != NULL ||
1732	   ofile->mh64 != NULL){
1733	    if(ofile->mh_cputype == 0){
1734		if(ofile->member_ar_hdr != NULL){
1735		    error("file: %s(%.*s) cputype is zero (a reserved value)",
1736			  ofile->file_name, (int)ofile->member_name_size,
1737			  ofile->member_name);
1738		}
1739		else
1740		    error("file: %s cputype is zero (a reserved value)",
1741			  ofile->file_name);
1742		return;
1743	    }
1744	    /*
1745	     * If we are building a dynamic library then don't add dynamic
1746	     * shared libraries to the archs.  This is so that a dependent
1747	     * dynamic shared library that happens to be fat will not cause the
1748	     * library to be created fat unless there are object going into
1749	     * the library that are fat.
1750	     */
1751	    if(ofile->mh_filetype == MH_DYLIB ||
1752	       ofile->mh_filetype == MH_DYLIB_STUB){
1753		/*
1754		 * If we are building a static library we should not put a
1755		 * dynamic library Mach-O file into the static library.  This
1756		 * can happen if a libx.a file is really a dynamic library and
1757		 * someone is using -lx when creating a static library.
1758		 */
1759		if(cmd_flags.dynamic != TRUE){
1760		    if(ofile->member_ar_hdr != NULL){
1761			warning("file: %s(%.*s) is a dynamic library, not "
1762				"added to the static library",
1763			        ofile->file_name, (int)ofile->member_name_size,
1764			        ofile->member_name);
1765		    }
1766		    else
1767			warning("file: %s is a dynamic library, not added to "
1768				"the static library", ofile->file_name);
1769		}
1770		return;
1771	    }
1772	    /*
1773	     * If -arch_only is specified then only add this file if it matches
1774	     * the architecture specified.
1775	     */
1776	    if(cmd_flags.arch_only_flag.name != NULL){
1777		if(cmd_flags.arch_only_flag.cputype != ofile->mh_cputype)
1778		    return;
1779		if(cmd_flags.arch_only_flag.cputype == CPU_TYPE_ARM){
1780		    if(cmd_flags.arch_only_flag.cpusubtype !=
1781							ofile->mh_cpusubtype)
1782			return;
1783		}
1784	    }
1785
1786	    for( ; i < narchs; i++){
1787		if(archs[i].arch_flag.cputype == ofile->mh_cputype){
1788		    if(archs[i].arch_flag.cputype == CPU_TYPE_ARM &&
1789		       archs[i].arch_flag.cpusubtype != ofile->mh_cpusubtype)
1790			continue;
1791		    break;
1792		}
1793	    }
1794	}
1795#ifdef LTO_SUPPORT
1796	else if(ofile->lto != NULL){
1797	    /*
1798	     * If -arch_only is specified then only add this file if it matches
1799	     * the architecture specified.
1800	     */
1801	    if(cmd_flags.arch_only_flag.name != NULL &&
1802	       cmd_flags.arch_only_flag.cputype != ofile->lto_cputype)
1803		return;
1804
1805	    for( ; i < narchs; i++){
1806		if(archs[i].arch_flag.cputype == ofile->lto_cputype){
1807		    if(archs[i].arch_flag.cputype == CPU_TYPE_ARM &&
1808		       archs[i].arch_flag.cpusubtype != ofile->lto_cpusubtype)
1809			continue;
1810		    break;
1811		}
1812	    }
1813	}
1814#endif /* LTO_SUPPORT */
1815	if(narchs == 1 && archs[0].arch_flag.cputype == 0){
1816	    i = 0;
1817	}
1818	else if(i == narchs){
1819	    archs = reallocate(archs, sizeof(struct arch) * (narchs+1));
1820	    memset(archs + narchs, '\0', sizeof(struct arch));
1821	    if(ofile->mh != NULL ||
1822	       ofile->mh64 != NULL){
1823		if(ofile->mh_cputype == CPU_TYPE_ARM){
1824		    archs[narchs].arch_flag.name = (char *)
1825			get_arch_name_from_types(
1826				ofile->mh_cputype, ofile->mh_cpusubtype);
1827		    archs[narchs].arch_flag.cputype = ofile->mh_cputype;
1828		    archs[narchs].arch_flag.cpusubtype = ofile->mh_cpusubtype;
1829		}
1830		else{
1831		    family_arch_flag =
1832			    get_arch_family_from_cputype(ofile->mh_cputype);
1833		    if(family_arch_flag != NULL)
1834			archs[narchs].arch_flag = *family_arch_flag;
1835		}
1836	}
1837#ifdef LTO_SUPPORT
1838	    else if(ofile->lto != NULL){
1839		if(ofile->lto_cputype == CPU_TYPE_ARM){
1840		    archs[narchs].arch_flag.name = (char *)
1841			get_arch_name_from_types(
1842				ofile->lto_cputype, ofile->lto_cpusubtype);
1843		    archs[narchs].arch_flag.cputype = ofile->lto_cputype;
1844		    archs[narchs].arch_flag.cpusubtype = ofile->lto_cpusubtype;
1845		}
1846		else{
1847		    family_arch_flag =
1848			    get_arch_family_from_cputype(ofile->lto_cputype);
1849		    if(family_arch_flag != NULL)
1850			archs[narchs].arch_flag = *family_arch_flag;
1851		}
1852	    }
1853#endif /* LTO_SUPPORT */
1854	    else
1855		archs[narchs].arch_flag.name = "unknown";
1856	    narchs++;
1857	}
1858	arch = archs + i;
1859
1860	/*
1861	 * If the cputype of this arch is not yet known then see if this new
1862	 * member can determine it.
1863	 */
1864	if(arch->arch_flag.cputype == 0 &&
1865	   (ofile->mh != NULL || ofile->mh64 != NULL)){
1866	    family_arch_flag = get_arch_family_from_cputype(ofile->mh_cputype);
1867	    if(family_arch_flag != NULL){
1868		arch->arch_flag = *family_arch_flag;
1869	    }
1870            else{
1871                arch->arch_flag.name =
1872                    savestr("cputype 1234567890 cpusubtype 1234567890");
1873                if(arch->arch_flag.name != NULL)
1874                    sprintf(arch->arch_flag.name, "cputype %u cpusubtype %u",
1875                            ofile->mh_cputype, ofile->mh_cpusubtype &
1876			    ~CPU_SUBTYPE_MASK);
1877                    arch->arch_flag.cputype = ofile->mh_cputype;
1878                    arch->arch_flag.cpusubtype = ofile->mh_cpusubtype;
1879	    }
1880	}
1881#ifdef LTO_SUPPORT
1882	if(arch->arch_flag.cputype == 0 &&
1883	   (ofile->lto != NULL)){
1884	    family_arch_flag = get_arch_family_from_cputype(ofile->lto_cputype);
1885	    if(family_arch_flag != NULL){
1886		arch->arch_flag = *family_arch_flag;
1887	    }
1888            else{
1889                arch->arch_flag.name =
1890                    savestr("cputype 1234567890 cpusubtype 1234567890");
1891                if(arch->arch_flag.name != NULL)
1892                    sprintf(arch->arch_flag.name, "cputype %u cpusubtype %u",
1893                            ofile->lto_cputype, ofile->lto_cpusubtype &
1894			    ~CPU_SUBTYPE_MASK);
1895                    arch->arch_flag.cputype = ofile->lto_cputype;
1896                    arch->arch_flag.cpusubtype = ofile->lto_cpusubtype;
1897	    }
1898	}
1899#endif /* LTO_SUPPORT */
1900
1901	/* create a member in this arch type for this member */
1902	arch->members = reallocate(arch->members, sizeof(struct member) *
1903				   (arch->nmembers + 1));
1904	member = arch->members + arch->nmembers;
1905	memset(member, '\0', sizeof(struct member));
1906	arch->nmembers++;
1907
1908	/* fill in the member for this ofile */
1909	member->input_file_name = ofile->file_name;
1910
1911	if(ofile->member_ar_hdr == NULL){
1912	    /*
1913	     * We are creating an archive member in the output file from a
1914	     * file (that is not archive member in an input file).  First get
1915	     * the base name the file_name for the member name.
1916	     */
1917	    p = strrchr(ofile->file_name, '/');
1918	    if(p != NULL)
1919		p++;
1920	    else
1921		p = ofile->file_name;
1922	    member->input_base_name = p;
1923	    member->input_base_name_size = strlen(p);
1924	    member->member_name = member->input_base_name;
1925	    /*
1926	     * If we can use long names then force using them to allow 64-bit
1927	     * objects to be aligned on an 8 byte boundary.  This is needed
1928	     * since the struct ar_hdr is not a multiple of 8.  This is normally
1929	     * done if the name does not fit in the archive header or contains
1930	     * a space character then we use the extened format #1.  The size
1931	     * of the name is rounded up so the object file after the name will
1932	     * be on an 8 byte boundary (including rounding the size of the
1933	     * struct ar_hdr).  The name will be padded with '\0's when it is
1934	     * written out.
1935	     */
1936	    if(cmd_flags.use_long_names == TRUE){
1937		member->output_long_name = TRUE;
1938		member->member_name_size = member->input_base_name_size;
1939		ar_name_size = rnd(member->input_base_name_size, 8) +
1940			       (rnd(sizeof(struct ar_hdr), 8) -
1941				sizeof(struct ar_hdr));
1942		sprintf(ar_name_buf, "%s%-*lu", AR_EFMT1,
1943			(int)(sizeof(member->ar_hdr.ar_name) -
1944			      (sizeof(AR_EFMT1) - 1)),
1945			(long unsigned int)ar_name_size);
1946		memcpy(member->ar_hdr.ar_name, ar_name_buf,
1947		      sizeof(member->ar_hdr.ar_name));
1948	    }
1949	    else{
1950		ar_name_size = 0;
1951		member->output_long_name = FALSE;
1952		/*
1953		 * Truncate the file_name if needed and place in archive header.
1954		 */
1955		c = '\0';
1956		if(strlen(p) > sizeof(member->ar_hdr.ar_name)){
1957		    c = p[sizeof(member->ar_hdr.ar_name)];
1958		    p[sizeof(member->ar_hdr.ar_name)] = '\0';
1959		}
1960		sprintf((char *)(&member->ar_hdr), "%-*s",
1961			(int)sizeof(member->ar_hdr.ar_name), p);
1962		if(c != '\0')
1963		    p[sizeof(member->ar_hdr.ar_name)] = c;
1964		member->member_name_size = size_ar_name(&member->ar_hdr);
1965	    }
1966	    if(zero_ar_date == TRUE)
1967		stat_buf.st_mtime = 0;
1968	    /*
1969	     * Create the rest of the archive header after the name.
1970	     */
1971	    sprintf((char *)(&member->ar_hdr) + sizeof(member->ar_hdr.ar_name),
1972	       "%-*ld%-*u%-*u%-*o%-*ld%-*s",
1973	       (int)sizeof(member->ar_hdr.ar_date),
1974		   (long int)stat_buf.st_mtime,
1975	       (int)sizeof(member->ar_hdr.ar_uid),
1976		   (unsigned short)stat_buf.st_uid,
1977	       (int)sizeof(member->ar_hdr.ar_gid),
1978		   (unsigned short)stat_buf.st_gid,
1979	       (int)sizeof(member->ar_hdr.ar_mode),
1980		   (unsigned int)stat_buf.st_mode,
1981	       (int)sizeof(member->ar_hdr.ar_size),
1982		   (long)size + ar_name_size,
1983	       (int)sizeof(member->ar_hdr.ar_fmag),
1984		   ARFMAG);
1985	}
1986	else{
1987	    /*
1988	     * We are creating an archive member in the output file from an
1989	     * archive member in an input file.  There can be some changes to
1990	     * the contents.  First the size might be changed and the contents
1991	     * padded with '\n's to round it to a multiple of 8
1992	     * Second we may take a member using extended format #1
1993	     * for it's name and truncate it then place the name in the archive
1994	     * header.  Or we may round the name size to a multiple of 8.
1995	     */
1996	    member->input_ar_hdr = ofile->member_ar_hdr;
1997	    member->input_base_name = ofile->member_name;
1998	    member->input_base_name_size = ofile->member_name_size;
1999	    member->input_member_offset = ofile->member_offset -
2000					  sizeof(struct ar_hdr);
2001	    if(strncmp(ofile->member_ar_hdr->ar_name, AR_EFMT1,
2002	       sizeof(AR_EFMT1) - 1) == 0)
2003		member->input_member_offset -= ofile->member_name_size;
2004
2005	    member->ar_hdr = *(ofile->member_ar_hdr);
2006	    member->member_name = ofile->member_name;
2007
2008	    if(cmd_flags.use_long_names == TRUE){
2009		/*
2010		 * We can use long names.  So if the input ofile is using the
2011		 * extended format #1 we need make sure the size of the name and
2012		 * the size of struct ar_hdr are rounded to 8 bytes. And write
2013		 * that size into the ar_name with the AR_EFMT1 string.  To
2014		 * avoid growing the size of names first trim the long name size
2015		 * before rounding up.
2016		 */
2017		if(ofile->member_name != ofile->member_ar_hdr->ar_name){
2018		    member->output_long_name = TRUE;
2019		    member->member_name_size = ofile->member_name_size;
2020		    for(ar_name_size = member->member_name_size;
2021			ar_name_size > 1 ;
2022			ar_name_size--){
2023			if(ofile->member_name[ar_name_size - 1] != '\0')
2024			   break;
2025		    }
2026		    member->member_name_size = ar_name_size;
2027		    ar_name_size = rnd(ar_name_size, 8) +
2028				   (rnd(sizeof(struct ar_hdr), 8) -
2029				    sizeof(struct ar_hdr));
2030		    sprintf(ar_name_buf, "%s%-*lu", AR_EFMT1,
2031			    (int)(sizeof(member->ar_hdr.ar_name) -
2032				  (sizeof(AR_EFMT1) - 1)),
2033			    (long unsigned int)ar_name_size);
2034		    memcpy(member->ar_hdr.ar_name, ar_name_buf,
2035			  sizeof(member->ar_hdr.ar_name));
2036		}
2037		else{
2038		    /*
2039		     * Since we can use long names force this to use extended
2040		     * format #1. And round the name size to 8 plus the size of
2041		     * struct ar_hdr rounded to 8 bytes.
2042		     */
2043		    member->member_name_size = size_ar_name(&member->ar_hdr);
2044		    ar_name_size = rnd(ofile->member_name_size, 8) +
2045				   (rnd(sizeof(struct ar_hdr), 8) -
2046				    sizeof(struct ar_hdr));
2047		    member->output_long_name = TRUE;
2048		    sprintf(ar_name_buf, "%s%-*lu", AR_EFMT1,
2049			    (int)(sizeof(member->ar_hdr.ar_name) -
2050				  (sizeof(AR_EFMT1) - 1)),
2051			    (long unsigned int)ar_name_size);
2052		    memcpy(member->ar_hdr.ar_name, ar_name_buf,
2053			  sizeof(member->ar_hdr.ar_name));
2054		}
2055	    }
2056	    else{
2057		/*
2058		 * We can't use long names.  So if the input ofile is using the
2059		 * extended format #1 we need to truncate the name and write it
2060		 * into the ar_name field.  Note the extended format is also
2061		 * used it the name has a space in it so it may be shorter than
2062		 * sizeof(ar_hdr.ar_name) .
2063		 */
2064		ar_name_size = 0;
2065		member->output_long_name = FALSE;
2066		if(ofile->member_name != ofile->member_ar_hdr->ar_name){
2067		    for(j = 0; j < sizeof(member->ar_hdr.ar_name) &&
2068			       j < ofile->member_name_size &&
2069			       ofile->member_name[j] != '\0'; j++)
2070			member->ar_hdr.ar_name[j] = ofile->member_name[j];
2071		    for( ; j < sizeof(member->ar_hdr.ar_name); j++)
2072			member->ar_hdr.ar_name[j] = ' ';
2073		}
2074		member->member_name_size = size_ar_name(&member->ar_hdr);
2075	    }
2076	    /*
2077	     * Since sprintf() writes a '\0' at the end of the string the
2078	     * memcpy is needed to preserve the ARFMAG string that follows.
2079	     */
2080	    sprintf(ar_size_buf, "%-*ld",
2081		    (int)sizeof(member->ar_hdr.ar_size),
2082		    (long)size + ar_name_size);
2083	    memcpy(member->ar_hdr.ar_size, ar_size_buf,
2084		   sizeof(member->ar_hdr.ar_size));
2085	}
2086
2087	member->offset = arch->size;
2088	arch->size += sizeof(struct ar_hdr) + size + ar_name_size;
2089
2090	if(ofile->mh != NULL ||
2091	   ofile->mh64 != NULL){
2092	    member->object_addr = ofile->object_addr;
2093	    member->object_size = ofile->object_size;
2094	    member->object_byte_sex = ofile->object_byte_sex;
2095	    member->mh = ofile->mh;
2096	    member->mh64 = ofile->mh64;
2097	    member->load_commands = ofile->load_commands;
2098	}
2099#ifdef LTO_SUPPORT
2100	else if(ofile->file_type == OFILE_LLVM_BITCODE){
2101	    member->object_addr = ofile->file_addr;
2102	    member->object_size = ofile->file_size;
2103	    member->lto = ofile->lto;
2104	    member->object_byte_sex = get_byte_sex_from_flag(&arch->arch_flag);
2105	}
2106#endif /* LTO_SUPPORT */
2107	else{
2108	    member->object_addr = ofile->member_addr;
2109	    member->object_size = ofile->member_size;
2110#ifdef LTO_SUPPORT
2111	    if(ofile->lto != NULL){
2112		member->lto = ofile->lto;
2113		member->object_byte_sex = get_byte_sex_from_flag(
2114							&arch->arch_flag);
2115	    }
2116#endif /* LTO_SUPPORT */
2117	}
2118}
2119
2120/*
2121 * free_archs() frees the memory allocated that is pointed to by archs.
2122 */
2123static
2124void
2125free_archs(
2126void)
2127{
2128    uint32_t i;
2129
2130	for(i = 0 ; i < narchs; i++){
2131	    /*
2132	     * Just leak memory on the arch_flag.name in some cases
2133	     * (unknown archiectures only where the space is malloced and
2134	     * a sprintf() is done into the memory)
2135	     */
2136	    if(archs[i].tocs != NULL)
2137		free(archs[i].tocs);
2138	    if(archs[i].toc_ranlibs != NULL)
2139		free(archs[i].toc_ranlibs);
2140	    if(archs[i].toc_strings != NULL)
2141		free(archs[i].toc_strings);
2142	    if(archs[i].members != NULL)
2143		free(archs[i].members);
2144	}
2145	if(archs != NULL)
2146	    free(archs);
2147	archs = NULL;
2148	narchs = 0;
2149}
2150
2151/*
2152 * create_library() creates a library from the data structure pointed to by
2153 * archs into the specified output file.  Only when more than one architecture
2154 * is in archs will a fat file be created.
2155 *
2156 * In the case of cmd_flags.ranlib == TRUE the ofile may not be NULL if it
2157 * from a thin archive.  If so and the toc_* fields are set and we may update
2158 * the table of contents in place if the new one fits where the old table of
2159 * contents was.
2160 */
2161static
2162void
2163create_library(
2164char *output,
2165struct ofile *ofile)
2166{
2167    uint32_t i, j, k, pad, *time_offsets;
2168    uint64_t library_size, offset;
2169    enum byte_sex target_byte_sex;
2170    char *library, *p, *flush_start;
2171    kern_return_t r;
2172    struct arch *arch;
2173    struct fat_header *fat_header;
2174    struct fat_arch *fat_arch;
2175    int fd;
2176#ifndef __OPENSTEP__
2177    struct utimbuf timep;
2178#else
2179    time_t timep[2];
2180#endif
2181    struct stat stat_buf;
2182    struct ar_hdr toc_ar_hdr;
2183    enum bool some_tocs, same_toc, different_offsets;
2184
2185	if(narchs == 0){
2186	    if(cmd_flags.ranlib == TRUE){
2187		if(cmd_flags.q == FALSE)
2188		    warning("empty library: %s (no table of contents added)",
2189			    output);
2190		return;
2191	    }
2192	    else{
2193		if(cmd_flags.dynamic == FALSE ||
2194		   cmd_flags.no_files_ok == FALSE){
2195		    if(cmd_flags.arch_only_flag.name != NULL)
2196			error("no library created (no object files in input "
2197			      "files matching -arch_only %s)",
2198			      cmd_flags.arch_only_flag.name);
2199		    else
2200			error("no library created (no object files in input "
2201			      "files)");
2202		    return;
2203		}
2204	    }
2205	}
2206
2207	if(cmd_flags.dynamic == TRUE){
2208	    create_dynamic_shared_library(output);
2209	    return;
2210	}
2211
2212	/* if this is libtool warn about duplicate member names */
2213	if(cmd_flags.ranlib == FALSE)
2214	    warn_duplicate_member_names();
2215
2216	/*
2217	 * Calculate the total size of the library and the final size of each
2218	 * architecture.
2219	 */
2220	if(narchs > 1){
2221	    library_size = sizeof(struct fat_header) +
2222			   sizeof(struct fat_arch) * narchs;
2223	    /*
2224	     * The ar(1) program uses the -q flag to ranlib(1) to add a table
2225	     * of contents only of the output is not a fat file.  This is done
2226	     * by default for UNIX standards conformance when the files are
2227	     * thin .o files.
2228	     */
2229	    if(cmd_flags.q == TRUE)
2230		exit(EXIT_SUCCESS);
2231	    /*
2232	     * The ar(1) program uses the -f to ranlib(1) when it see the 's'
2233	     * option.  And if we are creating a fat file issue a warning that
2234	     * ar(1) will not be able to use it.
2235	     */
2236	    if(cmd_flags.f == TRUE)
2237		warning("archive library: %s will be fat and ar(1) will not "
2238			"be able to operate on it", output);
2239	}
2240	else
2241	    library_size = 0;
2242	some_tocs = FALSE;
2243	for(i = 0; i < narchs; i++){
2244	    make_table_of_contents(archs + i, output);
2245	    if(errors != 0)
2246		return;
2247	    if(archs[i].toc_nranlibs != 0)
2248		some_tocs = TRUE;
2249	    archs[i].size += SARMAG + archs[i].toc_size;
2250	    library_size += archs[i].size;
2251	}
2252	/*
2253	 * The ar(1) program uses the -q flag to ranlib(1) to add a table of
2254	 * contents only of the output contains some object files.  This is
2255	 * done for UNIX standards conformance.
2256	 */
2257	if(cmd_flags.q == TRUE && some_tocs == FALSE)
2258	    exit(EXIT_SUCCESS);
2259
2260 	/*
2261	 * If this is ranlib(1) and we are running in UNIX standard mode and
2262	 * the file is not writeable just print and error message and return.
2263	 */
2264	if(cmd_flags.ranlib == TRUE &&
2265	   get_unix_standard_mode() == TRUE &&
2266	   access(output, W_OK) == -1){
2267	    system_error("file: %s is not writable", output);
2268	    return;
2269	}
2270
2271	/*
2272	 * If this is ranlib(1) and we have a thin archive that has an existing
2273	 * table of contents see if we have enough room to update it in place.
2274	 * Actually we check to see that we have the exact same number of
2275	 * ranlib structs and string size, as this is the most common case that
2276	 * the defined global symbols have not changed when rebuilding and it
2277	 * will just be the offset to archive members that will have changed.
2278	 */
2279	if(cmd_flags.ranlib == TRUE && narchs == 1 &&
2280	   ofile != NULL && ofile->toc_addr != NULL &&
2281	   ofile->toc_bad == FALSE &&
2282	   archs[0].toc_nranlibs == ofile->toc_nranlibs &&
2283	   archs[0].toc_strsize == ofile->toc_strsize){
2284
2285	    /*
2286	     * If the table of contents in the input does have a long name and
2287	     * the one we built does not (or vice a versa) then don't update it
2288	     * in place.
2289	     */
2290	    if(strcmp(ofile->toc_ar_hdr->ar_name, AR_EFMT1) == 0){
2291	       if(archs[0].toc_long_name != TRUE)
2292		goto fail_to_update_toc_in_place;
2293	    }
2294	    else{
2295	       if(archs[0].toc_long_name == TRUE)
2296		goto fail_to_update_toc_in_place;
2297	    }
2298
2299	    /*
2300	     * The existing thin archive may not be laid out the same way as
2301	     * libtool(1) would do it.  As ar(1) does not know to pad things
2302	     * so object files are on their natural alignment.  So check to
2303	     * see if the offsets are not the same and if the alignment is OK.
2304	     */
2305	    different_offsets = FALSE;
2306	    for(i = 0; i < archs[0].nmembers; i++){
2307		if(archs[0].members[i].input_member_offset !=
2308		   archs[0].members[i].offset){
2309		    different_offsets = TRUE;
2310		    /*
2311		     * For now we will allow alignments of 4 bytes offsets even
2312		     * though we would produce 8 byte alignments.
2313		     */
2314		    if(archs[0].members[i].input_member_offset % 4 != 0){
2315		        goto fail_to_update_toc_in_place;
2316		    }
2317		}
2318	    }
2319
2320	    /*
2321	     * The time_offsets array records the offsets to the table of
2322	     * contents archive header's ar_date fields.  In this case we just
2323	     * have one since this is a thin file (non-fat) file.
2324	     */
2325	    time_offsets = allocate(1 * sizeof(uint32_t));
2326	    /*
2327	     * Calculate the offset to the archive header's time field for the
2328	     * table of contents.
2329	     */
2330	    time_offsets[0] = SARMAG +
2331			 ((char *)&toc_ar_hdr.ar_date - (char *)&toc_ar_hdr);
2332
2333	    /*
2334	     * If we had different member offsets in the input thin archive
2335	     * we adjust the ranlib structs ran_off to use them.
2336	     */
2337	    if(different_offsets == TRUE){
2338		same_toc = FALSE;
2339		for(i = 0; i < archs[0].toc_nranlibs; i++){
2340		    for(j = 0; j < archs[0].nmembers; j++){
2341			if(archs[0].members[j].offset ==
2342			   archs[0].toc_ranlibs[i].ran_off){
2343			    archs[0].toc_ranlibs[i].ran_off =
2344				archs[0].members[j].input_member_offset;
2345			    break;
2346			}
2347		    }
2348		}
2349	    }
2350	    else{
2351		/*
2352		 * If the new table of contents and the new string table are the
2353		 * same as the old then the archive only needs to be "touched"
2354		 * and the time field of the toc needs to be updated.
2355		 */
2356		same_toc = TRUE;
2357		for(i = 0; i < archs[0].toc_nranlibs; i++){
2358		    if(archs[0].toc_ranlibs[i].ran_un.ran_strx !=
2359		       ofile->toc_ranlibs[i].ran_un.ran_strx ||
2360		       archs[0].toc_ranlibs[i].ran_off !=
2361		       ofile->toc_ranlibs[i].ran_off){
2362			same_toc = FALSE;
2363			break;
2364		    }
2365		}
2366		if(same_toc == TRUE){
2367		    for(i = 0; i < archs[0].toc_strsize; i++){
2368			if(archs[0].toc_strings[i] != ofile->toc_strings[i]){
2369			    same_toc = FALSE;
2370			    break;
2371			}
2372		    }
2373		}
2374	    }
2375
2376	    library_size = SARMAG;
2377	    if(same_toc == FALSE)
2378		library_size += archs[0].toc_size;
2379	    if((r = vm_allocate(mach_task_self(), (vm_address_t *)&library,
2380				library_size, TRUE)) != KERN_SUCCESS)
2381		mach_fatal(r, "can't vm_allocate() buffer for output file: %s "
2382			   "of size %llu", output, library_size);
2383
2384
2385	    /* put in the archive magic string in the buffer */
2386	    p = library;
2387	    memcpy(p, ARMAG, SARMAG);
2388	    p += SARMAG;
2389
2390	    /* put the table of contents in the buffer if needed */
2391	    target_byte_sex = get_target_byte_sex(archs + 0, host_byte_sex);
2392	    if(same_toc == FALSE)
2393		p = put_toc_member(p, archs+0, host_byte_sex, target_byte_sex);
2394
2395	    if((fd = open(output, O_WRONLY, 0)) == -1){
2396		system_error("can't open output file: %s", output);
2397		return;
2398	    }
2399	    if(write(fd, library, library_size) != (int)library_size){
2400		system_error("can't write output file: %s", output);
2401		return;
2402	    }
2403	    if(close(fd) == -1){
2404		system_fatal("can't close output file: %s", output);
2405		return;
2406	    }
2407	    goto update_toc_ar_dates;
2408	}
2409fail_to_update_toc_in_place:
2410
2411	/*
2412	 * This buffer is vm_allocate'ed to make sure all holes are filled with
2413	 * zero bytes.
2414	 */
2415	if((r = vm_allocate(mach_task_self(), (vm_address_t *)&library,
2416			    library_size, TRUE)) != KERN_SUCCESS)
2417	    mach_fatal(r, "can't vm_allocate() buffer for output file: %s of "
2418		       "size %llu", output, library_size);
2419
2420	/*
2421	 * Create the output file.  The unlink() is done to handle the problem
2422	 * when the outputfile is not writable but the directory allows the
2423	 * file to be removed (since the file may not be there the return code
2424	 * of the unlink() is ignored).
2425	 */
2426	(void)unlink(output);
2427	if((fd = open(output, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1){
2428	    system_error("can't create output file: %s", output);
2429	    return;
2430	}
2431#ifdef F_NOCACHE
2432        /* tell filesystem to NOT cache the file when reading or writing */
2433	(void)fcntl(fd, F_NOCACHE, 1);
2434#endif
2435
2436	/*
2437	 * If there is more than one architecture then fill in the fat file
2438	 * header and the fat_arch structures in the buffer.
2439	 */
2440	if(narchs > 1){
2441	    fat_header = (struct fat_header *)library;
2442	    fat_header->magic = FAT_MAGIC;
2443	    fat_header->nfat_arch = narchs;
2444	    offset = sizeof(struct fat_header) +
2445			    sizeof(struct fat_arch) * narchs;
2446	    fat_arch = (struct fat_arch *)(library + sizeof(struct fat_header));
2447	    for(i = 0; i < narchs; i++){
2448		fat_arch[i].cputype = archs[i].arch_flag.cputype;
2449		fat_arch[i].cpusubtype = archs[i].arch_flag.cpusubtype;
2450		if(offset > UINT32_MAX)
2451		    error("file too large to create as a fat file because "
2452			  "offset field in struct fat_arch is only 32-bits and "
2453			  "offset (%llu) to architecture %s exceeds that",
2454			  offset, archs[i].arch_flag.name);
2455		fat_arch[i].offset = offset;
2456		if(archs[i].size > UINT32_MAX)
2457		    error("file too large to create as a fat file because "
2458			  "size field in struct fat_arch is only 32-bits and "
2459			  "size (%llu) of architecture %s exceeds that",
2460			  archs[i].size, archs[i].arch_flag.name);
2461		fat_arch[i].size = archs[i].size;
2462		fat_arch[i].align = 2;
2463		offset += archs[i].size;
2464	    }
2465	    if(errors != 0){
2466		(void)unlink(output);
2467		return;
2468	    }
2469#ifdef __LITTLE_ENDIAN__
2470	    swap_fat_header(fat_header, BIG_ENDIAN_BYTE_SEX);
2471	    swap_fat_arch(fat_arch, narchs, BIG_ENDIAN_BYTE_SEX);
2472#endif /* __LITTLE_ENDIAN__ */
2473	    offset = sizeof(struct fat_header) +
2474			    sizeof(struct fat_arch) * narchs;
2475	}
2476	else
2477	    offset = 0;
2478
2479	/* flush out the fat headers if any */
2480	output_flush(library, library_size, fd, 0, offset);
2481
2482	/*
2483	 * The time_offsets array records the offsets to the table of conternts
2484	 * archive header's ar_date fields.
2485	 */
2486	time_offsets = allocate(narchs * sizeof(uint32_t));
2487
2488	/*
2489	 * Now put each arch in the buffer.
2490	 */
2491	for(i = 0; i < narchs; i++){
2492	    p = library + offset;
2493	    flush_start = p;
2494	    arch = archs + i;
2495
2496	    /*
2497	     * If the input files only contains non-object files then the
2498	     * byte sex of the output can't be determined which is needed for
2499	     * the two binary long's of the table of contents.  But since these
2500	     * will be zero (the same in both byte sexes) because there are no
2501	     * symbols in the table of contents if there are no object files.
2502	     */
2503
2504	    /* put in the archive magic string */
2505	    memcpy(p, ARMAG, SARMAG);
2506	    p += SARMAG;
2507
2508	    /*
2509	     * Warn for what really is a bad library that has an empty table of
2510	     * contents but this is allowed in the original ranlib.
2511	     */
2512	    if(arch->toc_nranlibs == 0 && cmd_flags.q == FALSE){
2513		if(narchs > 1)
2514		    warning("warning for library: %s for architecture: %s the "
2515			    "table of contents is empty (no object file members"
2516			    " in the library define global symbols)", output,
2517			    arch->arch_flag.name);
2518		else
2519		    warning("warning for library: %s the table of contents is "
2520			    "empty (no object file members in the library "
2521			    "define global symbols)", output);
2522	    }
2523
2524	    /*
2525	     * Pick the byte sex to write the table of contents in.
2526	     */
2527	    target_byte_sex = get_target_byte_sex(arch, host_byte_sex);
2528
2529	    /*
2530	     * Remember the offset to the archive header's time field for this
2531	     * arch's table of contents member.
2532	     */
2533	    time_offsets[i] =
2534			 (p - library) +
2535			 ((char *)&toc_ar_hdr.ar_date - (char *)&toc_ar_hdr);
2536
2537	    /*
2538	     * Put in the table of contents member in the output buffer.
2539	     */
2540	    p = put_toc_member(p, arch, host_byte_sex, target_byte_sex);
2541
2542	    output_flush(library, library_size, fd, flush_start - library,
2543			 p - flush_start);
2544
2545	    /*
2546	     * Put in the archive header and member contents for each member.
2547	     */
2548	    for(j = 0; j < arch->nmembers; j++){
2549		flush_start = p;
2550		memcpy(p, (char *)&(arch->members[j].ar_hdr),
2551		       sizeof(struct ar_hdr));
2552		p += sizeof(struct ar_hdr);
2553
2554		/*
2555		 * If we are using extended format #1 for long names write out
2556		 * the name.  Note the name is padded with '\0' and the
2557		 * member_name_size is the unrounded size.
2558		 */
2559		if(arch->members[j].output_long_name == TRUE){
2560		    strncpy(p, arch->members[j].member_name,
2561			    arch->members[j].member_name_size);
2562		    p += rnd(arch->members[j].member_name_size, 8) +
2563			       (rnd(sizeof(struct ar_hdr), 8) -
2564				sizeof(struct ar_hdr));
2565		}
2566
2567		/*
2568		 * ofile_map swaps the headers to the host_byte_sex if the
2569		 * object's byte sex is not the same as the host byte sex so
2570		 * if this is the case swap them back before writing them out.
2571		 */
2572		if(arch->members[j].mh != NULL &&
2573		   arch->members[j].object_byte_sex != host_byte_sex){
2574		    if(swap_object_headers(arch->members[j].mh,
2575		       arch->members[j].load_commands) == FALSE)
2576			fatal("internal error: swap_object_headers() failed");
2577		}
2578		else if(arch->members[j].mh64 != NULL &&
2579		   arch->members[j].object_byte_sex != host_byte_sex){
2580		    if(swap_object_headers(arch->members[j].mh64,
2581		       arch->members[j].load_commands) == FALSE)
2582			fatal("internal error: swap_object_headers() failed");
2583		}
2584		memcpy(p, arch->members[j].object_addr,
2585		       arch->members[j].object_size);
2586#ifdef VM_SYNC_DEACTIVATE
2587		vm_msync(mach_task_self(),
2588			 (vm_address_t)arch->members[j].object_addr,
2589			 (vm_size_t)arch->members[j].object_size,
2590			 VM_SYNC_DEACTIVATE);
2591#endif /* VM_SYNC_DEACTIVATE */
2592		p += arch->members[j].object_size;
2593		pad = rnd(arch->members[j].object_size, 8) -
2594		      arch->members[j].object_size;
2595		/* as with the UNIX ar(1) program pad with '\n' characters */
2596		for(k = 0; k < pad; k++)
2597		    *p++ = '\n';
2598
2599		output_flush(library, library_size, fd, flush_start - library,
2600			     p - flush_start);
2601	    }
2602	    offset += arch->size;
2603	}
2604
2605	/*
2606	 * Write the library to the file or flush the remaining buffer to the
2607	 * file.
2608	 */
2609	if(cmd_flags.noflush == TRUE){
2610	    if(write(fd, library, library_size) != (int)library_size){
2611		system_error("can't write output file: %s", output);
2612		return;
2613	    }
2614	}
2615	else{
2616	    final_output_flush(library, fd);
2617	}
2618	if(close(fd) == -1){
2619	    system_fatal("can't close output file: %s", output);
2620	    return;
2621	}
2622
2623update_toc_ar_dates:
2624	/*
2625	 * Now that the library is created on the file system it is written
2626	 * to get the time for the file on that file system.
2627	 */
2628	if(stat(output, &stat_buf) == -1){
2629	    system_fatal("can't stat file output file: %s", output);
2630	    return;
2631	}
2632	if((fd = open(output, O_WRONLY, 0)) == -1){
2633	    system_error("can't open output file: %s", output);
2634	    return;
2635	}
2636	if(zero_ar_date == TRUE)
2637	    stat_buf.st_mtime = 0;
2638	/*
2639         * With the time from the file system the library is on set the ar_date
2640	 * using the modification time returned by stat.  Then write this into
2641	 * all the ar_date's in the file.
2642	 */
2643	sprintf((char *)(&toc_ar_hdr), "%-*s%-*ld",
2644	   (int)sizeof(toc_ar_hdr.ar_name),
2645	       SYMDEF,
2646	   (int)sizeof(toc_ar_hdr.ar_date),
2647	       (long int)stat_buf.st_mtime + 5);
2648	for(i = 0; i < narchs; i++){
2649	    if(lseek(fd, time_offsets[i], L_SET) == -1){
2650		system_error("can't lseek in output file: %s", output);
2651		return;
2652	    }
2653	    if(write(fd, &toc_ar_hdr.ar_date, sizeof(toc_ar_hdr.ar_date)) !=
2654		     sizeof(toc_ar_hdr.ar_date)){
2655		system_error("can't write to output file: %s", output);
2656		return;
2657	    }
2658	}
2659	if(close(fd) == -1){
2660	    system_fatal("can't close output file: %s", output);
2661	    return;
2662	}
2663	/*
2664	 * Now set the modtime of the created library back to it's stat time
2665	 * when we first closed it.
2666	 */
2667#ifndef __OPENSTEP__
2668	timep.actime = stat_buf.st_mtime;
2669	timep.modtime = stat_buf.st_mtime;
2670	if(utime(output, &timep) == -1)
2671#else
2672	timep[0] = stat_buf.st_mtime;
2673	timep[1] = stat_buf.st_mtime;
2674	if(utime(output, timep) == -1)
2675#endif
2676	{
2677	    system_fatal("can't set the modifiy times in output file: %s",
2678			 output);
2679	    return;
2680	}
2681	if((r = vm_deallocate(mach_task_self(), (vm_address_t)library,
2682			      library_size)) != KERN_SUCCESS){
2683	    my_mach_error(r, "can't vm_deallocate() buffer for output file");
2684	    return;
2685	}
2686}
2687
2688/*
2689 * get_target_byte_sex() pick the byte sex to write the table of contents in
2690 * for the arch.
2691 */
2692static
2693enum byte_sex
2694get_target_byte_sex(
2695struct arch *arch,
2696enum byte_sex host_byte_sex)
2697{
2698    uint32_t i;
2699    enum byte_sex target_byte_sex;
2700
2701	target_byte_sex = UNKNOWN_BYTE_SEX;
2702	for(i = 0;
2703	    i < arch->nmembers && target_byte_sex == UNKNOWN_BYTE_SEX;
2704	    i++){
2705	    target_byte_sex = arch->members[i].object_byte_sex;
2706	}
2707	if(target_byte_sex == UNKNOWN_BYTE_SEX)
2708	    target_byte_sex = host_byte_sex;
2709	return(target_byte_sex);
2710}
2711
2712/*
2713 * put_toc_member() put the contents member for arch into the buffer p and
2714 * returns the pointer to the buffer after the table of contents.
2715 * The table of contents member is:
2716 *	the archive header
2717 *  the archive member name (if using a long name)
2718 *	a uint32_t for the number of bytes of the ranlib structs
2719 *	the ranlib structs
2720 *	a uint32_t for the number of bytes of the strings for the
2721 *    ranlibs
2722 *	the strings for the ranlib structs
2723 */
2724static
2725char *
2726put_toc_member(
2727char *p,
2728struct arch *arch,
2729enum byte_sex host_byte_sex,
2730enum byte_sex target_byte_sex)
2731{
2732    uint32_t l;
2733
2734	memcpy(p, (char *)&arch->toc_ar_hdr, sizeof(struct ar_hdr));
2735	p += sizeof(struct ar_hdr);
2736
2737	if(arch->toc_long_name == TRUE){
2738	    memcpy(p, arch->toc_name, arch->toc_name_size);
2739	    p += arch->toc_name_size +
2740		 (rnd(sizeof(struct ar_hdr), 8) -
2741		  sizeof(struct ar_hdr));
2742	}
2743
2744	l = arch->toc_nranlibs * sizeof(struct ranlib);
2745	if(target_byte_sex != host_byte_sex)
2746	    l = SWAP_INT(l);
2747	memcpy(p, (char *)&l, sizeof(uint32_t));
2748	p += sizeof(uint32_t);
2749
2750	if(target_byte_sex != host_byte_sex)
2751	    swap_ranlib(arch->toc_ranlibs, arch->toc_nranlibs,
2752			target_byte_sex);
2753	memcpy(p, (char *)arch->toc_ranlibs,
2754	       arch->toc_nranlibs * sizeof(struct ranlib));
2755	p += arch->toc_nranlibs * sizeof(struct ranlib);
2756
2757	l = arch->toc_strsize;
2758	if(target_byte_sex != host_byte_sex)
2759	    l = SWAP_INT(l);
2760	memcpy(p, (char *)&l, sizeof(uint32_t));
2761	p += sizeof(uint32_t);
2762
2763	memcpy(p, (char *)arch->toc_strings, arch->toc_strsize);
2764	p += arch->toc_strsize;
2765
2766	return(p);
2767}
2768
2769/*
2770 * output_flush() takes an offset and a size of part of the output library,
2771 * known in the comments as the new area, and causes any fully flushed pages to
2772 * be written to the library file the new area in combination with previous
2773 * areas created.  The data structure output_blocks has ordered blocks of areas
2774 * that have been flushed which are maintained by this routine.  Any area can
2775 * only be flushed once and an error will result is the new area overlaps with a
2776 * previously flushed area.
2777 */
2778static
2779void
2780output_flush(
2781char *library,
2782uint64_t library_size,
2783int fd,
2784uint64_t offset,
2785uint64_t size)
2786{
2787    uint64_t write_offset, write_size, host_pagesize;
2788    struct block **p, *block, *before, *after;
2789    kern_return_t r;
2790
2791	host_pagesize = 0x2000;
2792
2793	if(cmd_flags.noflush == TRUE)
2794	    return;
2795
2796	if(offset + size > library_size)
2797	    fatal("internal error: output_flush(offset = %llu, size = %llu) "
2798		  "out of range for library_size = %llu", offset, size,
2799		  library_size);
2800
2801#ifdef DEBUG
2802	if(cmd_flags.debug & (1 << 2))
2803	    print_block_list();
2804	if(cmd_flags.debug & (1 << 1))
2805	    printf("output_flush(offset = %llu, size %llu)", offset, size);
2806#endif /* DEBUG */
2807
2808	if(size == 0){
2809#ifdef DEBUG
2810	if(cmd_flags.debug & (1 << 1))
2811	    printf("\n");
2812#endif /* DEBUG */
2813	    return;
2814	}
2815
2816	/*
2817	 * Search through the ordered output blocks to find the block before the
2818	 * new area and after the new area if any exist.
2819	 */
2820	before = NULL;
2821	after = NULL;
2822	p = &(output_blocks);
2823	while(*p){
2824	    block = *p;
2825	    if(offset < block->offset){
2826		after = block;
2827		break;
2828	    }
2829	    else{
2830		before = block;
2831	    }
2832	    p = &(block->next);
2833	}
2834
2835	/*
2836	 * Check for overlap of the new area with the block before and after the
2837	 * new area if there are such blocks.
2838	 */
2839	if(before != NULL){
2840	    if(before->offset + before->size > offset){
2841		warning("internal error: output_flush(offset = %llu, size = "
2842			"%llu) overlaps with flushed block(offset = %llu, "
2843			"size = %llu)", offset, size, before->offset,
2844			before->size);
2845		printf("calling abort()\n");
2846		abort();
2847	    }
2848	}
2849	if(after != NULL){
2850	    if(offset + size > after->offset){
2851		warning("internal error: output_flush(offset = %llu, size = "
2852			"%llu) overlaps with flushed block(offset = %llu, "
2853			"size = %llu)", offset, size, after->offset,
2854			after->size);
2855		printf("calling abort()\n");
2856		abort();
2857	    }
2858	}
2859
2860	/*
2861	 * Now see how the new area fits in with the blocks before and after it
2862	 * (that is does it touch both, one or the other or neither blocks).
2863	 * For each case first the offset and size to write (write_offset and
2864	 * write_size) are set for the area of full pages that can now be
2865	 * written from the block.  Then the area written in the block
2866	 * (->written_offset and ->written_size) are set to reflect the total
2867	 * area in the block now written.  Then offset and size the block
2868	 * refers to (->offset and ->size) are set to total area of the block.
2869	 * Finally the links to others blocks in the list are adjusted if a
2870	 * block is added or removed.
2871	 *
2872	 * See if there is a block before the new area and the new area
2873	 * starts at the end of that block.
2874	 */
2875	if(before != NULL && before->offset + before->size == offset){
2876	    /*
2877	     * See if there is also a block after the new area and the new area
2878	     * ends at the start of that block.
2879	     */
2880	    if(after != NULL && offset + size == after->offset){
2881		/*
2882		 * This is the case where the new area exactly fill the area
2883		 * between two existing blocks.  The total area is folded into
2884		 * the block before the new area and the block after the new
2885		 * area is removed from the list.
2886		 */
2887		if(before->offset == 0 && before->written_size == 0){
2888		    write_offset = 0;
2889		    before->written_offset = 0;
2890		}
2891		else
2892		    write_offset =before->written_offset + before->written_size;
2893		if(after->written_size == 0)
2894		    write_size = trnc(after->offset + after->size -
2895				       write_offset, host_pagesize);
2896		else
2897		    write_size = trnc(after->written_offset - write_offset,
2898				       host_pagesize);
2899		if(write_size != 0){
2900		    before->written_size += write_size;
2901		}
2902		if(after->written_size != 0)
2903		    before->written_size += after->written_size;
2904		before->size += size + after->size;
2905
2906		/* remove the block after the new area */
2907		before->next = after->next;
2908		remove_block(after);
2909	    }
2910	    else{
2911		/*
2912		 * This is the case where the new area starts at the end of the
2913		 * block just before it but does not end where the block after
2914		 * it (if any) starts.  The new area is folded into the block
2915		 * before the new area.
2916		 */
2917		write_offset = before->written_offset + before->written_size;
2918		write_size = trnc(offset + size - write_offset, host_pagesize);
2919		if(write_size != 0)
2920		    before->written_size += write_size;
2921		before->size += size;
2922	    }
2923	}
2924	/*
2925	 * See if the new area and the new area ends at the start of the block
2926	 * after it (if any).
2927	 */
2928	else if(after != NULL && offset + size == after->offset){
2929	    /*
2930	     * This is the case where the new area ends at the begining of the
2931	     * block just after it but does not start where the block before it.
2932	     * (if any) ends.  The new area is folded into this block after the
2933	     * new area.
2934	     */
2935	    write_offset = rnd(offset, host_pagesize);
2936	    if(after->written_size == 0)
2937		write_size = trnc(after->offset + after->size - write_offset,
2938				   host_pagesize);
2939	    else
2940		write_size = trnc(after->written_offset - write_offset,
2941				   host_pagesize);
2942	    if(write_size != 0){
2943		after->written_offset = write_offset;
2944		after->written_size += write_size;
2945	    }
2946	    else if(write_offset != after->written_offset){
2947		after->written_offset = write_offset;
2948	    }
2949	    after->offset = offset;
2950	    after->size += size;
2951	}
2952	else{
2953	    /*
2954	     * This is the case where the new area neither starts at the end of
2955	     * the block just before it (if any) or ends where the block after
2956	     * it (if any) starts.  A new block is created and the new area is
2957	     * is placed in it.
2958	     */
2959	    write_offset = rnd(offset, host_pagesize);
2960	    write_size = trnc(offset + size - write_offset, host_pagesize);
2961	    block = get_block();
2962	    block->offset = offset;
2963	    block->size = size;
2964	    block->written_offset = write_offset;
2965	    block->written_size = write_size;
2966	    /*
2967	     * Insert this block in the ordered list in the correct place.
2968	     */
2969	    if(before != NULL){
2970		block->next = before->next;
2971		before->next = block;
2972	    }
2973	    else{
2974		block->next = output_blocks;
2975		output_blocks = block;
2976	    }
2977	}
2978
2979	/*
2980	 * Now if there are full pages to write write them to the output file.
2981	 */
2982	if(write_size != 0){
2983#ifdef DEBUG
2984	if((cmd_flags.debug & (1 << 1)) || (cmd_flags.debug & (1 << 0)))
2985	    printf(" writing (write_offset = %llu write_size = %llu)\n",
2986		   write_offset, write_size);
2987#endif /* DEBUG */
2988	    lseek(fd, write_offset, L_SET);
2989	    if(write(fd, library + write_offset, write_size) !=
2990	       (int)write_size)
2991		system_fatal("can't write to output file");
2992	    if((r = vm_deallocate(mach_task_self(), (vm_address_t)(library +
2993				  write_offset), write_size)) != KERN_SUCCESS)
2994		mach_fatal(r, "can't vm_deallocate() buffer for output file");
2995	}
2996#ifdef DEBUG
2997	else{
2998	    if(cmd_flags.debug & (1 << 1))
2999		printf(" no write\n");
3000	}
3001#endif /* DEBUG */
3002}
3003
3004/*
3005 * final_output_flush() flushes the last part of the last page of the object
3006 * file if it does not round out to exactly a page.
3007 */
3008static
3009void
3010final_output_flush(
3011char *library,
3012int fd)
3013{
3014    struct block *block;
3015    uint64_t write_offset, write_size;
3016    kern_return_t r;
3017
3018#ifdef DEBUG
3019	/* The compiler "warning: `write_offset' may be used uninitialized in */
3020	/* this function" can safely be ignored */
3021	write_offset = 0;
3022	if((cmd_flags.debug & (1 << 1)) || (cmd_flags.debug & (1 << 0))){
3023	    printf("final_output_flush block_list:\n");
3024	    print_block_list();
3025	}
3026#endif /* DEBUG */
3027
3028	write_size = 0;
3029	block = output_blocks;
3030	if(block != NULL){
3031	    if(block->offset != 0)
3032		fatal("internal error: first block not at offset 0");
3033	    if(block->written_size != 0){
3034		if(block->written_offset != 0)
3035		    fatal("internal error: first block written_offset not 0");
3036		write_offset = block->written_size;
3037		write_size = block->size - block->written_size;
3038	    }
3039	    else{
3040		write_offset = block->offset;
3041		write_size = block->size;
3042	    }
3043	    if(block->next != NULL)
3044		fatal("internal error: more than one block in final list");
3045	}
3046	if(write_size != 0){
3047#ifdef DEBUG
3048	    if((cmd_flags.debug & (1 << 1)) || (cmd_flags.debug & (1 << 1)))
3049		printf(" writing (write_offset = %llu write_size = %llu)\n",
3050		       write_offset, write_size);
3051#endif /* DEBUG */
3052	    lseek(fd, write_offset, L_SET);
3053	    if(write(fd, library + write_offset, write_size) !=
3054	       (int)write_size)
3055		system_fatal("can't write to output file");
3056	    if((r = vm_deallocate(mach_task_self(), (vm_address_t)(library +
3057				  write_offset), write_size)) != KERN_SUCCESS)
3058		mach_fatal(r, "can't vm_deallocate() buffer for output file");
3059	}
3060	output_blocks = NULL;
3061}
3062
3063#ifdef DEBUG
3064/*
3065 * print_block_list() prints the list of blocks.  Used for debugging.
3066 */
3067static
3068void
3069print_block_list(void)
3070{
3071    struct block **p, *block;
3072
3073	p = &(output_blocks);
3074	if(*p == NULL)
3075	    printf("Empty block list\n");
3076	while(*p){
3077	    block = *p;
3078	    printf("block 0x%x\n", (unsigned int)block);
3079	    printf("    offset %llu\n", block->offset);
3080	    printf("    size %llu\n", block->size);
3081	    printf("    written_offset %llu\n", block->written_offset);
3082	    printf("    written_size %llu\n", block->written_size);
3083	    printf("    next 0x%x\n", (unsigned int)(block->next));
3084	    p = &(block->next);
3085	}
3086}
3087#endif /* DEBUG */
3088
3089/*
3090 * get_block() returns a pointer to a new block.  This could be done by
3091 * allocating block of these placing them on a free list and and handing them
3092 * out.  For the initial release of this code this number is typicly low and not
3093 * a big win so each block just allocated and free'ed.
3094 */
3095static
3096struct block *
3097get_block(void)
3098{
3099    struct block *block;
3100
3101	block = allocate(sizeof(struct block));
3102	return(block);
3103}
3104
3105/*
3106 * remove_block() throws away the block specified.  See comments in get_block().
3107 */
3108static
3109void
3110remove_block(
3111struct block *block)
3112{
3113	free(block);
3114}
3115
3116/*
3117 * trnc() truncates the value 'v' to the power of two value 'r'.  If v is
3118 * less than zero it returns zero.
3119 */
3120static
3121uint32_t
3122trnc(
3123uint32_t v,
3124uint32_t r)
3125{
3126	if(((int32_t)v) < 0)
3127	    return(0);
3128	return(v & ~(r - 1));
3129}
3130
3131/*
3132 * create_dynamic_shared_library() creates a dynamic shared library from the
3133 * data structure pointed to by archs into the specified output file.  Only
3134 * when more than one architecture is in archs will a fat file be created.
3135 */
3136static
3137void
3138create_dynamic_shared_library(
3139char *output)
3140{
3141    uint32_t i, j;
3142    char *p, *filelist;
3143    struct stat stat_buf;
3144    enum bool use_force_cpusubtype_ALL;
3145    const struct arch_flag *family_arch_flag;
3146
3147	/*
3148	 * If there is more than one architecture setup a signal handler to
3149	 * clean up the temporary files in case we get a signal.
3150	 */
3151	if(narchs > 1)
3152	    signal(SIGINT, create_dynamic_shared_library_cleanup);
3153
3154	/*
3155	 * If -arch_only is specified with a specific cpusubtype other than the
3156	 * family cpusubtype do not use -force_cpusubtype_ALL as the user wants
3157	 * the output to be tagged with that cpusubtype.
3158	 */
3159	use_force_cpusubtype_ALL = TRUE;
3160	if(cmd_flags.arch_only_flag.name != NULL){
3161	    family_arch_flag = get_arch_family_from_cputype(
3162				    cmd_flags.arch_only_flag.cputype);
3163	    if(family_arch_flag != NULL){
3164		if((family_arch_flag->cpusubtype & ~CPU_SUBTYPE_MASK) !=
3165		   (cmd_flags.arch_only_flag.cpusubtype & ~CPU_SUBTYPE_MASK))
3166		    use_force_cpusubtype_ALL = FALSE;
3167	    }
3168	}
3169
3170	/*
3171	 * For each architecture run ld(1) -dylib to create the dynamic shared
3172	 * library.
3173	 */
3174	for(i = 0; i < narchs || (i == 0 && narchs == 0); i++){
3175	    reset_execute_list();
3176	    add_execute_list_with_prefix("ld");
3177	    if(narchs != 0 && cmd_flags.arch_only_flag.name == NULL)
3178		add_execute_list("-arch_multiple");
3179	    if(archs != NULL){
3180		add_execute_list("-arch");
3181		if(use_force_cpusubtype_ALL == TRUE)
3182		    add_execute_list(archs[i].arch_flag.name);
3183		else
3184		    add_execute_list(cmd_flags.arch_only_flag.name);
3185	    }
3186	    add_execute_list("-dylib");
3187	    add_execute_list("-dynamic");
3188	    if(cmd_flags.all_load_flag_specified == FALSE ||
3189	       cmd_flags.all_load == TRUE)
3190		add_execute_list("-all_load");
3191	    if(use_force_cpusubtype_ALL == TRUE)
3192		add_execute_list("-force_cpusubtype_ALL");
3193	    add_execute_list("-no_arch_warnings");
3194	    if(cmd_flags.seg1addr != NULL){
3195		add_execute_list("-seg1addr");
3196		add_execute_list(cmd_flags.seg1addr);
3197	    }
3198	    if(cmd_flags.segs_read_only_addr != NULL){
3199		add_execute_list("-segs_read_only_addr");
3200		add_execute_list(cmd_flags.segs_read_only_addr);
3201	    }
3202	    if(cmd_flags.segs_read_write_addr != NULL){
3203		add_execute_list("-segs_read_write_addr");
3204		add_execute_list(cmd_flags.segs_read_write_addr);
3205	    }
3206	    if(cmd_flags.seg_addr_table != NULL){
3207		add_execute_list("-seg_addr_table");
3208		add_execute_list(cmd_flags.seg_addr_table);
3209	    }
3210	    if(cmd_flags.seg_addr_table_filename != NULL){
3211		add_execute_list("-seg_addr_table_filename");
3212		add_execute_list(cmd_flags.seg_addr_table_filename);
3213	    }
3214	    if(cmd_flags.compatibility != NULL){
3215		add_execute_list("-dylib_compatibility_version");
3216		add_execute_list(cmd_flags.compatibility);
3217	    }
3218	    if(cmd_flags.current != NULL){
3219		add_execute_list("-dylib_current_version");
3220		add_execute_list(cmd_flags.current);
3221	    }
3222	    if(cmd_flags.install_name != NULL){
3223		add_execute_list("-dylib_install_name");
3224		add_execute_list(cmd_flags.install_name);
3225	    }
3226	    else{
3227		if(narchs > 1){
3228		    add_execute_list("-dylib_install_name");
3229		    add_execute_list(cmd_flags.output);
3230		}
3231	    }
3232	    for(j = 0; j < cmd_flags.nldflags; j++)
3233		add_execute_list(cmd_flags.ldflags[j]);
3234	    for(j = 0; j < cmd_flags.nLdirs; j++)
3235		add_execute_list(cmd_flags.Ldirs[j]);
3236	    add_execute_list("-ldylib1.o");
3237	    filelist = NULL;
3238	    for(j = 0; j < cmd_flags.nfiles; j++){
3239		if(cmd_flags.filelist[j] == NULL){
3240		    add_execute_list(cmd_flags.files[j]);
3241		}
3242		else{
3243		    if(cmd_flags.filelist[j] != filelist){
3244			add_execute_list("-filelist");
3245			add_execute_list(cmd_flags.filelist[j]);
3246			filelist = cmd_flags.filelist[j];
3247		    }
3248		}
3249	    }
3250	    if(narchs <= 1){
3251		add_execute_list("-o");
3252		add_execute_list(cmd_flags.output);
3253	    }
3254	    else{
3255		add_execute_list("-o");
3256		add_execute_list(makestr(cmd_flags.output, ".libtool.",
3257					 archs[i].arch_flag.name, NULL));
3258		if(cmd_flags.final_output_specified == FALSE){
3259		    add_execute_list("-final_output");
3260		    add_execute_list(cmd_flags.output);
3261		}
3262	    }
3263	    if(execute_list(cmd_flags.verbose) == 0)
3264		fatal("internal link edit command failed");
3265	}
3266	/*
3267	 * If there is more than one architecture then run lipo to put them
3268	 * in a fat file.
3269	 */
3270	if(narchs > 1){
3271	    reset_execute_list();
3272	    add_execute_list_with_prefix("lipo");
3273	    add_execute_list("-create");
3274	    add_execute_list("-output");
3275	    add_execute_list(cmd_flags.output);
3276	    for(i = 0; i < narchs; i++){
3277		add_execute_list(makestr(cmd_flags.output, ".libtool.",
3278					 archs[i].arch_flag.name, NULL));
3279	    }
3280	    if(execute_list(cmd_flags.verbose) == 0)
3281		fatal("internal lipo command failed");
3282	    for(i = 0; i < narchs; i++){
3283		p = makestr(cmd_flags.output, ".libtool.",
3284			    archs[i].arch_flag.name, NULL);
3285		if(unlink(p) == -1){
3286		    error("can't remove temporary file: %s", p);
3287		}
3288	    }
3289	}
3290	/*
3291	 * If we are doing prebinding then run objcunique on the
3292	 * output.
3293	 */
3294	if(cmd_flags.prebinding == TRUE){
3295	    if(stat("/usr/bin/objcunique", &stat_buf) != -1){
3296		reset_execute_list();
3297		add_execute_list_with_prefix("objcunique");
3298		add_execute_list(cmd_flags.output);
3299		add_execute_list("-prebind");
3300		for(j = 0; j < cmd_flags.nLdirs; j++)
3301		    add_execute_list(cmd_flags.Ldirs[j]);
3302		if(execute_list(cmd_flags.verbose) == 0)
3303		    fatal("internal objcunique command failed");
3304	    }
3305	}
3306}
3307
3308/*
3309 * create_dynamic_shared_library_cleanup() is the signal handler to remove the
3310 * temporary files if more than one arch is being used.
3311 */
3312static
3313void
3314create_dynamic_shared_library_cleanup(
3315int sig)
3316{
3317    uint32_t i;
3318
3319	for(i = 0; i < narchs; i++){
3320	    (void)unlink(makestr(cmd_flags.output, ".libtool.",
3321				 archs[i].arch_flag.name, NULL));
3322	}
3323	exit(EXIT_FAILURE);
3324}
3325
3326/*
3327 * make_table_of_contents() make the table of contents for the specified arch
3328 * and fills in the toc_* fields in the arch.  Output is the name of the output
3329 * file for error messages.
3330 */
3331static
3332void
3333make_table_of_contents(
3334struct arch *arch,
3335char *output)
3336{
3337    uint32_t i, j, k, r, s, nsects, ncmds, n_strx;
3338    struct member *member;
3339    struct load_command *lc;
3340    struct segment_command *sg;
3341    struct segment_command_64 *sg64;
3342    struct nlist *symbols;
3343    struct nlist_64 *symbols64;
3344    char *strings;
3345    enum bool sorted, is_toc_symbol;
3346    char *ar_name;
3347    struct section *section;
3348    struct section_64 *section64;
3349    uint8_t n_type, n_sect;
3350#ifdef LTO_SUPPORT
3351    uint32_t nsyms;
3352#endif /* LTO_SUPPORT */
3353
3354	symbols = NULL;
3355	symbols64 = NULL;
3356	/*
3357	 * First pass over the members to count how many ranlib structs are
3358	 * needed and the size of the strings in the toc that are needed.
3359	 */
3360	for(i = 0; i < arch->nmembers; i++){
3361	    member = arch->members + i;
3362	    if(member->mh != NULL || member->mh64 != NULL){
3363		nsects = 0;
3364		lc = member->load_commands;
3365		if(member->mh != NULL)
3366		    ncmds = member->mh->ncmds;
3367		else
3368		    ncmds = member->mh64->ncmds;
3369		for(j = 0; j < ncmds; j++){
3370		    if(lc->cmd == LC_SYMTAB){
3371			if(member->st == NULL)
3372			    member->st = (struct symtab_command *)lc;
3373		    }
3374		    else if(lc->cmd == LC_SEGMENT){
3375			sg = (struct segment_command *)lc;
3376			nsects += sg->nsects;
3377		    }
3378		    else if(lc->cmd == LC_SEGMENT_64){
3379			sg64 = (struct segment_command_64 *)lc;
3380			nsects += sg64->nsects;
3381		    }
3382		    lc = (struct load_command *)((char *)lc + lc->cmdsize);
3383		}
3384		if(member->mh != NULL)
3385		    member->sections = allocate(nsects *
3386						sizeof(struct section *));
3387		else
3388		    member->sections64 = allocate(nsects *
3389						  sizeof(struct section_64 *));
3390		nsects = 0;
3391		lc = member->load_commands;
3392		for(j = 0; j < ncmds; j++){
3393		    if(lc->cmd == LC_SEGMENT){
3394			sg = (struct segment_command *)lc;
3395			section = (struct section *)
3396				  ((char *)sg + sizeof(struct segment_command));
3397			for(k = 0; k < sg->nsects; k++){
3398			    member->sections[nsects++] = section++;
3399			}
3400		    }
3401		    else if(lc->cmd == LC_SEGMENT_64){
3402			sg64 = (struct segment_command_64 *)lc;
3403			section64 = (struct section_64 *)
3404			    ((char *)sg64 + sizeof(struct segment_command_64));
3405			for(k = 0; k < sg64->nsects; k++){
3406			    member->sections64[nsects++] = section64++;
3407			}
3408		    }
3409		    lc = (struct load_command *)((char *)lc + lc->cmdsize);
3410		}
3411		if(member->st != NULL && member->st->nsyms != 0){
3412		    if(member->mh != NULL){
3413			symbols = (struct nlist *)(member->object_addr +
3414					           member->st->symoff);
3415			if(member->object_byte_sex != get_host_byte_sex())
3416			    swap_nlist(symbols, member->st->nsyms,
3417				       get_host_byte_sex());
3418		    }
3419		    else{
3420			symbols64 = (struct nlist_64 *)(member->object_addr +
3421					                member->st->symoff);
3422			if(member->object_byte_sex != get_host_byte_sex())
3423			    swap_nlist_64(symbols64, member->st->nsyms,
3424				          get_host_byte_sex());
3425		    }
3426		    strings = member->object_addr + member->st->stroff;
3427		    for(j = 0; j < member->st->nsyms; j++){
3428			if(member->mh != NULL){
3429			    n_strx = symbols[j].n_un.n_strx;
3430			    n_type = symbols[j].n_type;
3431			    n_sect = symbols[j].n_sect;
3432			}
3433			else{
3434			    n_strx = symbols64[j].n_un.n_strx;
3435			    n_type = symbols64[j].n_type;
3436			    n_sect = symbols64[j].n_sect;
3437			}
3438			if(n_strx > member->st->strsize){
3439			    warn_member(arch, member, "malformed object "
3440				"(symbol %u n_strx field extends past the "
3441				"end of the string table)", j);
3442			    errors++;
3443			    continue;
3444			}
3445			if((n_type & N_TYPE) == N_SECT){
3446			    if(n_sect == NO_SECT){
3447				warn_member(arch, member, "malformed object "
3448				    "(symbol %u must not have NO_SECT for its "
3449				    "n_sect field given its type (N_SECT))", j);
3450				errors++;
3451				continue;
3452			    }
3453			    if(n_sect > nsects){
3454				warn_member(arch, member, "malformed object "
3455				    "(symbol %u n_sect field greater than the "
3456				    "number of sections in the file)", j);
3457				errors++;
3458				continue;
3459			    }
3460			}
3461			if(member->mh != NULL)
3462			    is_toc_symbol = toc_symbol(symbols + j,
3463						       member->sections);
3464			else
3465			    is_toc_symbol = toc_symbol_64(symbols64 + j,
3466						          member->sections64);
3467			if(is_toc_symbol == TRUE){
3468			    arch->toc_nranlibs++;
3469			    arch->toc_strsize += strlen(strings + n_strx) + 1;
3470			}
3471		    }
3472		}
3473		else
3474		    warn_member(arch, member, "has no symbols");
3475	    }
3476#ifdef LTO_SUPPORT
3477	    else if(member->lto != NULL){
3478		nsyms = lto_get_nsyms(member->lto);
3479		for(j = 0; j < nsyms; j++){
3480		    if(lto_toc_symbol(member->lto, j, cmd_flags.c) == TRUE){
3481			arch->toc_nranlibs++;
3482			arch->toc_strsize +=
3483			    strlen(lto_symbol_name(member->lto, j)) + 1;
3484		    }
3485		}
3486	    }
3487#endif /* LTO_SUPPORT */
3488	    else{
3489		if(cmd_flags.ranlib == FALSE){
3490		    warn_member(arch, member, "is not an object file");
3491		    errors++;
3492		}
3493	    }
3494	}
3495	if(errors != 0)
3496	    return;
3497
3498	/*
3499	 * Allocate the space for the ranlib structs and strings for the
3500	 * table of contents.
3501	 */
3502	arch->toc_ranlibs = allocate(sizeof(struct ranlib) *arch->toc_nranlibs);
3503	arch->tocs = allocate(sizeof(struct toc) * arch->toc_nranlibs);
3504	arch->toc_strsize = rnd(arch->toc_strsize, 8);
3505	arch->toc_strings = allocate(arch->toc_strsize);
3506
3507	/*
3508	 * Second pass over the members to fill in the ranlib structs and
3509	 * the strings for the table of contents.  The ran_name field is
3510	 * filled in with a pointer to a string contained in arch->toc_strings
3511	 * for easy sorting and conversion to an index.  The ran_off field is
3512	 * filled in with the member index plus one to allow marking with it's
3513	 * negative value by check_sort_tocs() and easy conversion to the
3514	 * real offset.
3515	 */
3516	r = 0;
3517	s = 0;
3518	for(i = 0; i < arch->nmembers; i++){
3519	    member = arch->members + i;
3520	    if(member->mh != NULL || member->mh64 != NULL){
3521		if(member->st != NULL && member->st->nsyms != 0){
3522		    if(member->mh != NULL)
3523			symbols = (struct nlist *)(member->object_addr +
3524					           member->st->symoff);
3525		    else
3526			symbols64 = (struct nlist_64 *)(member->object_addr +
3527					                member->st->symoff);
3528		    strings = member->object_addr + member->st->stroff;
3529		    for(j = 0; j < member->st->nsyms; j++){
3530			if(member->mh != NULL)
3531			    n_strx = symbols[j].n_un.n_strx;
3532			else
3533			    n_strx = symbols64[j].n_un.n_strx;
3534			if(n_strx > member->st->strsize)
3535			    continue;
3536			if(member->mh != NULL)
3537			    is_toc_symbol = toc_symbol(symbols + j,
3538						       member->sections);
3539			else
3540			    is_toc_symbol = toc_symbol_64(symbols64 + j,
3541						          member->sections64);
3542			if(is_toc_symbol == TRUE){
3543			    strcpy(arch->toc_strings + s,
3544				   strings + n_strx);
3545			    arch->tocs[r].name = arch->toc_strings + s;
3546			    arch->tocs[r].index1 = i + 1;
3547			    r++;
3548			    s += strlen(strings + n_strx) + 1;
3549			}
3550		    }
3551		    if(member->object_byte_sex != get_host_byte_sex()){
3552			if(member->mh != NULL)
3553			    swap_nlist(symbols, member->st->nsyms,
3554				       member->object_byte_sex);
3555			else
3556			    swap_nlist_64(symbols64, member->st->nsyms,
3557				          member->object_byte_sex);
3558		    }
3559		}
3560	    }
3561#ifdef LTO_SUPPORT
3562	    else if(member->lto != NULL){
3563		nsyms = lto_get_nsyms(member->lto);
3564		for(j = 0; j < nsyms; j++){
3565		    if(lto_toc_symbol(member->lto, j, cmd_flags.c) == TRUE){
3566			strcpy(arch->toc_strings + s,
3567			       lto_symbol_name(member->lto, j));
3568			arch->tocs[r].name = arch->toc_strings + s;
3569			arch->tocs[r].index1 = i + 1;
3570			r++;
3571			s += strlen(lto_symbol_name(member->lto, j)) + 1;
3572		    }
3573		}
3574	    }
3575#endif /* LTO_SUPPORT */
3576	}
3577
3578	/*
3579	 * If the table of contents is to be sorted by symbol name then try to
3580	 * sort it and leave it sorted if no duplicates.
3581	 */
3582	if(cmd_flags.s == TRUE){
3583	    qsort(arch->tocs, arch->toc_nranlibs, sizeof(struct toc),
3584		  (int (*)(const void *, const void *))toc_name_qsort);
3585	    sorted = check_sort_tocs(arch, output, FALSE);
3586	    if(sorted == FALSE){
3587		qsort(arch->tocs, arch->toc_nranlibs, sizeof(struct toc),
3588		      (int (*)(const void *, const void *))toc_index1_qsort);
3589		arch->toc_name = SYMDEF;
3590		arch->toc_name_size = sizeof(SYMDEF) - 1;
3591		if(cmd_flags.use_long_names == TRUE){
3592		    arch->toc_long_name = TRUE;
3593		    /*
3594		     * This  assumes that "__.SYMDEF\0\0\0\0\0\0\0" is 16 bytes
3595		     * and
3596		     * (rnd(sizeof(struct ar_hdr), 8) - sizeof(struct ar_hdr)
3597		     * is 4 bytes.
3598		     */
3599		    ar_name = AR_EFMT1 "20";
3600		    arch->toc_name_size = 16;
3601		    arch->toc_name = SYMDEF "\0\0\0\0\0\0\0";
3602		}
3603		else{
3604		    arch->toc_long_name = FALSE;
3605		    ar_name = arch->toc_name;
3606		}
3607	    }
3608	    else{
3609		/*
3610		 * Since the SYMDEF_SORTED is "__.SYMDEF SORTED" which contains
3611		 * a space, it should use extended format #1 if we can use long
3612		 * names.
3613		 */
3614		arch->toc_name = SYMDEF_SORTED;
3615		arch->toc_name_size = sizeof(SYMDEF_SORTED) - 1;
3616		if(cmd_flags.use_long_names == TRUE){
3617		    arch->toc_long_name = TRUE;
3618		    /*
3619		     * This assumes that "__.SYMDEF SORTED" is 16 bytes and
3620		     * (rnd(sizeof(struct ar_hdr), 8) - sizeof(struct ar_hdr)
3621		     * is 4 bytes.
3622		     */
3623		    ar_name = AR_EFMT1 "20";
3624		}
3625		else{
3626		    arch->toc_long_name = FALSE;
3627		    ar_name = arch->toc_name;
3628		}
3629	    }
3630	}
3631	else{
3632	    sorted = FALSE;
3633	    arch->toc_name = SYMDEF;
3634	    arch->toc_name_size = sizeof(SYMDEF) - 1;
3635	    if(cmd_flags.use_long_names == TRUE){
3636		arch->toc_long_name = TRUE;
3637		/*
3638		 * This  assumes that "__.SYMDEF\0\0\0\0\0\0\0" is 16 bytes and
3639		 * (rnd(sizeof(struct ar_hdr), 8) - sizeof(struct ar_hdr)
3640		 * is 4 bytes.
3641		 */
3642		ar_name = AR_EFMT1 "20";
3643		arch->toc_name_size = 16;
3644		arch->toc_name = SYMDEF "\0\0\0\0\0\0\0";
3645	    }
3646	    else{
3647		arch->toc_long_name = FALSE;
3648		ar_name = arch->toc_name;
3649	    }
3650	}
3651
3652	/*
3653	 * Now set the ran_off and ran_un.ran_strx fields of the ranlib structs.
3654	 * To do this the size of the toc member must be know because it comes
3655	 * first in the library.  The size of the toc member is made up of the
3656	 * sizeof an archive header struct (the size of the name if a long name
3657	 * is used) then the toc which is (as defined in ranlib.h):
3658	 *	a uint32_t for the number of bytes of the ranlib structs
3659	 *	the ranlib structures
3660	 *	a uint32_t for the number of bytes of the strings
3661	 *	the strings
3662	 */
3663	arch->toc_size = sizeof(struct ar_hdr) +
3664			 sizeof(uint32_t) +
3665			 arch->toc_nranlibs * sizeof(struct ranlib) +
3666			 sizeof(uint32_t) +
3667			 arch->toc_strsize;
3668	/* add the size of the name is a long name is used */
3669	if(arch->toc_long_name == TRUE)
3670	    arch->toc_size += arch->toc_name_size +
3671			      (rnd(sizeof(struct ar_hdr), 8) -
3672			       sizeof(struct ar_hdr));
3673	for(i = 0; i < arch->nmembers; i++)
3674	    arch->members[i].offset += SARMAG + arch->toc_size;
3675	for(i = 0; i < arch->toc_nranlibs; i++){
3676	    arch->toc_ranlibs[i].ran_un.ran_strx =
3677		arch->tocs[i].name - arch->toc_strings;
3678	    arch->toc_ranlibs[i].ran_off =
3679		arch->members[arch->tocs[i].index1 - 1].offset;
3680	}
3681
3682	sprintf((char *)(&arch->toc_ar_hdr), "%-*s%-*ld%-*u%-*u%-*o%-*ld",
3683	   (int)sizeof(arch->toc_ar_hdr.ar_name),
3684	       ar_name,
3685	   (int)sizeof(arch->toc_ar_hdr.ar_date),
3686	       toc_time,
3687	   (int)sizeof(arch->toc_ar_hdr.ar_uid),
3688	       (unsigned short)getuid(),
3689	   (int)sizeof(arch->toc_ar_hdr.ar_gid),
3690	       (unsigned short)getgid(),
3691	   (int)sizeof(arch->toc_ar_hdr.ar_mode),
3692	       (unsigned int)toc_mode,
3693	   (int)sizeof(arch->toc_ar_hdr.ar_size),
3694	       (long)(arch->toc_size - sizeof(struct ar_hdr)));
3695	/*
3696	 * This has to be done by hand because sprintf puts a null
3697	 * at the end of the buffer.
3698	 */
3699	memcpy(arch->toc_ar_hdr.ar_fmag, ARFMAG,
3700	       (int)sizeof(arch->toc_ar_hdr.ar_fmag));
3701}
3702
3703/*
3704 * Function for qsort() for comparing toc structures by name.
3705 */
3706static
3707int
3708toc_name_qsort(
3709const struct toc *toc1,
3710const struct toc *toc2)
3711{
3712	return(strcmp(toc1->name, toc2->name));
3713}
3714
3715/*
3716 * Function for qsort() for comparing toc structures by index1.
3717 */
3718static
3719int
3720toc_index1_qsort(
3721const struct toc *toc1,
3722const struct toc *toc2)
3723{
3724	if(toc1->index1 < toc2->index1)
3725	    return(-1);
3726	if(toc1->index1 > toc2->index1)
3727	    return(1);
3728	/* toc1->index1 == toc2->index1 */
3729	    return(0);
3730}
3731
3732/*
3733 * toc_symbol() returns TRUE if the symbol is to be included in the table of
3734 * contents otherwise it returns FALSE.
3735 */
3736static
3737enum bool
3738toc_symbol(
3739struct nlist *symbol,
3740struct section **sections)
3741{
3742	return(toc(symbol->n_un.n_strx,
3743		   symbol->n_type,
3744		   symbol->n_value,
3745		   (symbol->n_type & N_TYPE) == N_SECT &&
3746		       sections[symbol->n_sect - 1]->flags & S_ATTR_NO_TOC));
3747}
3748
3749static
3750enum bool
3751toc_symbol_64(
3752struct nlist_64 *symbol64,
3753struct section_64 **sections64)
3754{
3755	return(toc(symbol64->n_un.n_strx,
3756		   symbol64->n_type,
3757		   symbol64->n_value,
3758		   (symbol64->n_type & N_TYPE) == N_SECT &&
3759		       sections64[symbol64->n_sect-1]->flags & S_ATTR_NO_TOC));
3760}
3761
3762static
3763enum bool
3764toc(
3765uint32_t n_strx,
3766uint8_t n_type,
3767uint64_t n_value,
3768enum bool attr_no_toc)
3769{
3770	/* if the name is NULL then it won't be in the table of contents */
3771	if(n_strx == 0)
3772	    return(FALSE);
3773	/* if symbol is not external then it won't be in the toc */
3774	if((n_type & N_EXT) == 0)
3775	    return(FALSE);
3776	/* if symbol is undefined then it won't be in the toc */
3777	if((n_type & N_TYPE) == N_UNDF && n_value == 0)
3778	    return(FALSE);
3779	/* if symbol is common and the -c flag is not specified then ... */
3780	if((n_type & N_TYPE) == N_UNDF && n_value != 0 &&
3781	   cmd_flags.c == FALSE)
3782	    return(FALSE);
3783	/* if the symbols is in a section marked NO_TOC then ... */
3784	if(attr_no_toc != 0)
3785	    return(FALSE);
3786
3787	return(TRUE);
3788}
3789
3790/*
3791 * check_sort_tocs() checks the table of contents for the specified arch
3792 * which is sorted by name for more then one object defining the same symbol.
3793 * It this is the case it prints each symbol that is defined in more than one
3794 * object along with the object it is defined in.  It returns TRUE if there are
3795 * no multiple definitions and FALSE otherwise.
3796 */
3797static
3798enum bool
3799check_sort_tocs(
3800struct arch *arch,
3801char *output,
3802enum bool library_warnings)
3803{
3804    uint32_t i;
3805    enum bool multiple_defs;
3806    struct member *member;
3807
3808	if(arch->toc_nranlibs == 0)
3809	    return(TRUE);
3810	/*
3811	 * Since the symbol table is sorted by name look to any two adjcent
3812	 * entries with the same name.  If such entries are found print them
3813	 * only once (marked by changing the sign of their ran_off).
3814	 */
3815	multiple_defs = FALSE;
3816	for(i = 0; i < arch->toc_nranlibs - 1; i++){
3817	    if(strcmp(arch->tocs[i].name, arch->tocs[i+1].name) == 0){
3818		if(multiple_defs == FALSE){
3819		    if(library_warnings == FALSE)
3820			return(FALSE);
3821		    fprintf(stderr, "%s: same symbol defined in more than one "
3822			    "member ", progname);
3823		    if(narchs > 1)
3824			fprintf(stderr, "for architecture: %s ",
3825				arch->arch_flag.name);
3826		    fprintf(stderr, "in: %s (table of contents will not be "
3827			    "sorted)\n", output);
3828		    multiple_defs = TRUE;
3829		}
3830		if((int)(arch->tocs[i].index1) > 0){
3831		    member = arch->members + arch->tocs[i].index1 - 1;
3832		    warn_member(arch, member, "defines symbol: %s",
3833				arch->tocs[i].name);
3834		    arch->tocs[i].index1 =
3835				-(arch->tocs[i].index1);
3836		}
3837		if((int)(arch->tocs[i+1].index1) > 0){
3838		    member = arch->members + arch->tocs[i+1].index1 - 1;
3839		    warn_member(arch, member, "defines symbol: %s",
3840				arch->tocs[i+1].name);
3841		    arch->tocs[i+1].index1 =
3842				-(arch->tocs[i+1].index1);
3843		}
3844	    }
3845	}
3846
3847	if(multiple_defs == FALSE)
3848	    return(TRUE);
3849	else{
3850	    for(i = 0; i < arch->toc_nranlibs; i++)
3851		if(((int)arch->tocs[i].index1) < 0)
3852		    arch->tocs[i].index1 =
3853			-(arch->tocs[i].index1);
3854	    return(FALSE);
3855	}
3856}
3857
3858/*
3859 * warn_duplicate_member_names() generates a warning if two members end up with
3860 * the same ar_name.  This is only a warning because ld(1) and this program
3861 * has no problems with it.  Only if ar(1) were used to extract the files
3862 * would this be a problem (even the 4.4bsd ar(1) using long names can
3863 * get hosed by base names,  the 4.3bsd ar(1) can't handle full 16 character
3864 * ar_names).
3865 */
3866static
3867void
3868warn_duplicate_member_names(
3869void)
3870{
3871    uint32_t i, j, len, len1, len2;
3872
3873	for(i = 0; i < narchs; i++){
3874	    /* sort in order of ar_names */
3875	    qsort(archs[i].members, archs[i].nmembers, sizeof(struct member),
3876		  (int (*)(const void *, const void *))member_name_qsort);
3877
3878	    /* check for duplicate names */
3879	    for(j = 0; j < archs[i].nmembers - 1; j++){
3880		len1 = archs[i].members[j].member_name_size;
3881		len2 = archs[i].members[j+1].member_name_size;
3882		len = len1 > len2 ? len1 : len2;
3883		if(strncmp(archs[i].members[j].member_name,
3884			   archs[i].members[j+1].member_name,
3885			   len) == 0){
3886		    fprintf(stderr, "%s: warning ", progname);
3887		    if(narchs > 1)
3888			fprintf(stderr, "for architecture: %s ",
3889				archs[i].arch_flag.name);
3890		    fprintf(stderr, "same member name (%.*s) in output file "
3891			    "used for input files: ", (int)len1,
3892			    archs[i].members[j].member_name);
3893
3894		    if(archs[i].members[j].input_ar_hdr != NULL){
3895			len = archs[i].members[j].input_base_name_size;
3896			fprintf(stderr, "%s(%.*s) and: ",
3897				archs[i].members[j].input_file_name, (int)len,
3898				archs[i].members[j].input_base_name);
3899		    }
3900		    else
3901			fprintf(stderr, "%s and: ",
3902				archs[i].members[j].input_file_name);
3903
3904		    if(archs[i].members[j+1].input_ar_hdr != NULL){
3905			len = archs[i].members[j+1].input_base_name_size;
3906			fprintf(stderr, "%s(%.*s) due to use of basename, "
3907				"truncation and blank padding\n",
3908				archs[i].members[j+1].input_file_name, (int)len,
3909				archs[i].members[j+1].input_base_name);
3910		    }
3911		    else
3912			fprintf(stderr, "%s (due to use of basename, truncation"
3913				", blank padding or duplicate input files)\n",
3914				archs[i].members[j+1].input_file_name);
3915		}
3916	    }
3917
3918	    /* sort back in order of offset */
3919	    qsort(archs[i].members, archs[i].nmembers, sizeof(struct member),
3920		  (int (*)(const void *, const void *))member_offset_qsort);
3921	}
3922}
3923
3924/*
3925 * Function for qsort() for comparing member structures by ar_hdr.ar_name.
3926 */
3927static
3928int
3929member_name_qsort(
3930const struct member *member1,
3931const struct member *member2)
3932{
3933    uint32_t len, len1, len2;
3934
3935	len1 = member1->member_name_size;
3936	len2 = member2->member_name_size;
3937	len = len1 > len2 ? len1 : len2;
3938	return(strncmp(member1->member_name, member2->member_name, len));
3939}
3940
3941/*
3942 * Function for qsort() for comparing member structures by offset.
3943 */
3944static
3945int
3946member_offset_qsort(
3947const struct member *member1,
3948const struct member *member2)
3949{
3950	if(member1->offset < member2->offset)
3951	    return(-1);
3952	if(member1->offset > member2->offset)
3953	    return(1);
3954	/* member1->offset == member2->offset */
3955	    return(0);
3956}
3957
3958/*
3959 * warn_member() is like the error routines it prints the program name the
3960 * member name specified and message specified.
3961 */
3962static
3963void
3964warn_member(
3965struct arch *arch,
3966struct member *member,
3967const char *format, ...)
3968{
3969    va_list ap;
3970
3971	fprintf(stderr, "%s: ", progname);
3972	if(narchs > 1)
3973	    fprintf(stderr, "for architecture: %s ", arch->arch_flag.name);
3974
3975	if(member->input_ar_hdr != NULL){
3976	    fprintf(stderr, "file: %s(%.*s) ", member->input_file_name,
3977		    (int)member->input_base_name_size, member->input_base_name);
3978	}
3979	else
3980	    fprintf(stderr, "file: %s ", member->input_file_name);
3981
3982	va_start(ap, format);
3983	vfprintf(stderr, format, ap);
3984        fprintf(stderr, "\n");
3985	va_end(ap);
3986}
3987
3988/*
3989 * Prints the message to cmd_flags.trace_file_path, or stderr if that
3990 * isn't set.
3991 */
3992static
3993void
3994ld_trace(
3995const char *format, ...)
3996{
3997	static int trace_file = -1;
3998	char trace_buffer[MAXPATHLEN * 2];
3999	char *buffer_ptr;
4000	int length;
4001	ssize_t amount_written;
4002
4003	if(trace_file == -1){
4004		if(cmd_flags.trace_file_path != NULL){
4005			trace_file = open(cmd_flags.trace_file_path, O_WRONLY | O_APPEND | O_CREAT, 0666);
4006			if(trace_file == -1)
4007				error("Could not open or create trace file: %s\n", cmd_flags.trace_file_path);
4008		}
4009		else{
4010			trace_file = fileno(stderr);
4011		}
4012	}
4013    va_list ap;
4014
4015	va_start(ap, format);
4016	length = vsnprintf(trace_buffer, sizeof(trace_buffer), format, ap);
4017	va_end(ap);
4018	buffer_ptr = trace_buffer;
4019	while(length > 0){
4020		amount_written = write(trace_file, buffer_ptr, length);
4021		if(amount_written == -1)
4022			/* Failure to write shouldn't fail the build. */
4023			return;
4024		buffer_ptr += amount_written;
4025		length -= amount_written;
4026	}
4027}
4028