2 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
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)
28 #include <mach/mach.h>
29 #include "stuff/openstep_mach.h"
39 #include <mach-o/ranlib.h>
40 #include <sys/types.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"
52 #include "stuff/lto.h"
53 #endif /* LTO_SUPPORT */
55 #include <mach/mach_init.h>
56 #if defined(__OPENSTEP__) || defined(__GONZO_BUNSEN_BEAKER__)
57 #include <servers/netname.h>
59 #ifndef __has_extension
60 # define __has_extension(x) 0
63 #define __has_feature(x) 0
65 #include <servers/bootstrap.h>
69 * This is used internally to build the table of contents.
72 char *name
; /* symbol defined by */
73 int64_t index1
; /* library member at this index plus 1 */
76 /* used by error routines as the name of the program */
77 char *progname
= NULL
;
78 /* .. as above but without the path, if any was used in the invocation. */
81 /* the bytesex of the host this program is running on */
82 static enum byte_sex host_byte_sex
= UNKNOWN_BYTE_SEX
;
85 * The time the table of contents' are set to and the time to base the
86 * modification time of the output file to be set to.
88 static time_t toc_time
= 0;
91 * The environment variable ZERO_AR_DATE is used here and other places that
92 * write archives to allow testing and comparing things for exact binary
95 static enum bool zero_ar_date
= FALSE
;
98 * The mode of the table of contents member (S_IFREG | (0666 & ~umask))
100 static u_short toc_mode
= 0;
102 /* flags set from the command line arguments */
104 char **files
; /* array of file name arguments */
106 nfiles
; /* number of file name arguments */
107 char **filelist
; /* filelist argument the file name argument came from */
109 no_files_ok
; /* ok to see no files */
110 enum bool ranlib
; /* set if this is run as ranlib not libtool */
111 enum bool s
; /* sort the table of contents */
112 enum bool a
; /* don't sort the table of contents (original form) */
113 enum bool c
; /* include commmon symbols in the table of contents */
114 enum bool t
; /* just "touch" the archives to get the date right */
115 enum bool f
; /* warn if the output archive is fat,used by ar(1) -s */
116 enum bool q
; /* only write archive if NOT fat, used by ar(1) */
117 char *output
; /* the output file specified by -o */
118 enum bool final_output_specified
; /* if -final_output is specified */
119 enum bool dynamic
; /* create a dynamic shared library, static by default */
120 char *compatibility
;/* compatibility version if specified, NULL otherwise */
121 char *current
; /* current version if specified, NULL otherwise */
122 char *install_name
; /* install name if specified, NULL otherwise */
123 char *seg1addr
; /* seg1addr if specified, NULL otherwise */
124 char *segs_read_only_addr
; /* segs_read_only_addr if specified, or NULL */
125 char *segs_read_write_addr
; /* segs_read_write_addr if specified, or NULL */
126 char *seg_addr_table
; /* seg_addr_table if specified, or NULL */
127 char *seg_addr_table_filename
;
128 /* seg_addr_table_filename if specified, or NULL */
129 char **Ldirs
; /* array of -Ldir arguments */
131 nLdirs
; /* number of -Ldir arguments */
132 char **ldflags
; /* other ld(1) flags to pass */
134 nldflags
; /* number of ld(1) flags for above */
135 enum bool verbose
; /* print exec(2) commands run */
137 arch_only_flag
; /* the -arch_only flag if specified */
138 enum bool /* set if either -prebind or -noprebind is seen */
139 prebinding_flag_specified
;
140 enum bool /* set if -prebind is seen or the LD_PREBIND */
141 prebinding
; /* environment variable is set (and -noprebind isn't)*/
142 enum bool /* set if either -all_load or -noall_load is seen */
143 all_load_flag_specified
;
144 enum bool /* set if -all_load is seen (and -noall_load isn't) */
146 enum bool /* set with -L (the default) off with -T, for -static */
147 use_long_names
; /* use 4.4bsd extended format 1 for long names */
148 enum bool L_or_T_specified
;
149 enum bool /* set if the environ var LD_TRACE_ARCHIVES is set */
151 const char * /* LD_TRACE_FILE if set and LD_TRACE_ARCHIVES is set, or NULL */
153 enum bool /* set if -search_paths_first is specified */
155 enum bool noflush
; /* don't use the output_flush routine to flush the
156 static library output file by pages */
157 uint32_t debug
; /* debug value to debug output_flush() routine */
158 enum bool /* don't warn if members have no symbols */
159 no_warning_for_no_symbols
;
160 enum bool toc64
; /* force the use of the 64-bit toc */
161 enum bool fat64
; /* force the use of 64-bit fat files
162 when a fat is to be created */
164 static struct cmd_flags cmd_flags
= { 0 };
166 /* The value of the environment variable NEXT_ROOT */
167 static char *next_root
= NULL
;
169 /* the standard directories to search for -lx names */
170 char *standard_dirs
[] = {
178 * The input files are broken down in to their object files and then placed in
179 * these structures. They are sorted by architecture type and then each object
180 * has a member struct created for it in one of the arch structs. All of these
181 * structs hang off of 'archs'.
183 static struct arch
*archs
= NULL
;
184 static uint32_t narchs
= 0;
187 struct arch_flag arch_flag
; /* the identifing info of this architecture */
188 uint64_t size
; /* current working size and final size */
190 /* the table of contents (toc) stuff for this architecture in the library */
191 uint32_t toc_size
; /* total size of the toc including ar_hdr */
192 struct ar_hdr toc_ar_hdr
; /* the archive header for this member */
193 enum bool toc_long_name
; /* use the long name in the output */
194 char *toc_name
; /* name of toc member */
195 uint32_t toc_name_size
;/* size of name of toc member */
196 struct toc
*tocs
; /* internal table of contents */
197 enum bool using_64toc
; /* TRUE if we are using a 64-bit toc */
198 struct ranlib
*toc_ranlibs
; /* 32-bit ranlib structs for output */
199 struct ranlib_64
*toc_ranlibs64
; /* 64-bit ranlib structs for output */
200 uint64_t toc_nranlibs
;/* number of ranlib structs */
201 char *toc_strings
; /* strings of symbol names for ranlib structs */
202 uint64_t toc_strsize
; /* number of bytes for the strings above */
204 /* the members of this architecture in the library */
205 struct member
*members
; /* the members of the library for this arch */
206 uint32_t nmembers
; /* the number of the above members */
210 uint64_t offset
; /* current working offset and final offset*/
211 struct ar_hdr ar_hdr
; /* the archive header for this member */
212 char null_byte
; /* space to write '\0' for ar_hdr */
213 char *object_addr
; /* the address of the object file */
214 uint32_t object_size
; /* the size of the object file */
215 enum byte_sex object_byte_sex
; /* the byte sex of the object file */
216 struct mach_header
*mh
; /* the mach_header of 32-bit object files */
217 struct mach_header_64
*mh64
; /* the mach_header of 64-bit object files */
218 struct load_command
/* the start of the load commands */
220 struct symtab_command
*st
; /* the symbol table command */
221 struct section
**sections
; /* array of section structs for 32-bit */
222 struct section_64
**sections64
; /* array of section structs for 64-bit */
224 enum bool lto_contents
; /* TRUE if this member has lto contents */
225 uint32_t lto_toc_nsyms
; /* number of symbols for the toc */
226 uint32_t lto_toc_strsize
; /* the size of the strings for the toc */
227 char *lto_toc_strings
; /* the strings of the symbols for the toc */
228 #endif /* LTO_SUPPORT */
230 /* the name of the member in the output */
231 char *member_name
; /* the member name */
232 uint32_t member_name_size
; /* the size of the member name */
233 enum bool output_long_name
; /* use the extended format #1 for the
234 member name in the output */
236 /* info recorded from the input file this member came from */
237 char *input_file_name
; /* the input file name */
238 char *input_base_name
; /* the base name in the input file */
239 uint32_t input_base_name_size
; /* the size of the base name */
240 struct ar_hdr
*input_ar_hdr
;
241 uint64_t input_member_offset
; /* if from a thin archive */
248 static char *file_name_from_l_flag(
250 static char *search_for_file(
252 static char * search_paths_for_lname(
253 const char *lname_argument
);
254 static char * search_path_for_lname(
256 const char *lname_argument
);
257 static void add_member(
258 struct ofile
*ofile
);
259 static void free_archs(
261 static void create_library(
263 struct ofile
*ofile
);
264 static enum byte_sex
get_target_byte_sex(
266 enum byte_sex host_byte_sex
);
267 static char *put_toc_member(
270 enum byte_sex host_byte_sex
,
271 enum byte_sex target_byte_sex
);
272 static void create_dynamic_shared_library(
274 static void create_dynamic_shared_library_cleanup(
276 static void make_table_of_contents(
280 static void save_lto_member_toc_info(
281 struct member
*member
,
283 #endif /* LTO_SUPPORT */
284 static int toc_name_qsort(
285 const struct toc
*toc1
,
286 const struct toc
*toc2
);
287 static int toc_index1_qsort(
288 const struct toc
*toc1
,
289 const struct toc
*toc2
);
290 static enum bool toc_symbol(
291 struct nlist
*symbol
,
292 struct section
**sections
);
293 static enum bool toc_symbol_64(
294 struct nlist_64
*symbol64
,
295 struct section_64
**sections64
);
296 static enum bool toc(
300 enum bool attr_no_toc
);
301 static enum bool check_sort_tocs(
304 enum bool library_warnings
);
305 static void warn_duplicate_member_names(
307 static int member_name_qsort(
308 const struct member
*member1
,
309 const struct member
*member2
);
310 static int member_offset_qsort(
311 const struct member
*member1
,
312 const struct member
*member2
);
313 static void warn_member(
315 struct member
*member
,
316 const char *format
, ...) __attribute__ ((format (printf
, 3, 4)));
317 static void ld_trace(
318 const char *format
, ...) __attribute__ ((format (printf
, 1, 2)));
321 * This structure is used to describe blocks of the output file that are flushed
322 * to the disk file with output_flush. It is kept in an ordered list starting
323 * with output_blocks.
325 static struct block
{
326 uint64_t offset
; /* starting offset of this block */
327 uint64_t size
; /* size of this block */
328 uint64_t written_offset
;/* first page offset after starting offset */
329 uint64_t written_size
; /* size of written area from written_offset */
330 struct block
*next
; /* next block in the list */
333 static void output_flush(
335 uint64_t library_size
,
339 static void final_output_flush(
343 static void print_block_list(void);
345 static struct block
*get_block(void);
346 static void remove_block(
347 struct block
*block
);
348 static uint32_t trnc(
352 /* apple_version is in vers.c which is created by the libstuff/Makefile */
353 extern char apple_version
[];
355 /* likewise xtools_version, lto_suport and support_url. */
356 extern char xtools_version
[];
357 extern char package_version
[];
358 extern char support_url
[];
359 extern char lto_support
[];
361 #define RSZ (sizeof("ranlib")-1)
368 char *p
, *endp
, *filelist
, *dirname
, *addr
;
370 struct stat stat_buf
;
371 uint32_t j
, nfiles
, maxfiles
;
374 enum bool lflags_seen
, bad_flag_seen
, Vflag
;
380 host_byte_sex
= get_host_byte_sex();
383 * The environment variable ZERO_AR_DATE is used here and other
384 * places that write archives to allow testing and comparing
385 * things for exact binary equality.
387 if(getenv("ZERO_AR_DATE") == NULL
)
388 zero_ar_date
= FALSE
;
391 if(zero_ar_date
== FALSE
)
397 oumask
= umask(numask
);
398 toc_mode
= S_IFREG
| (0666 & ~oumask
);
401 /* see if this is being run as ranlib */
402 pnam
= strrchr(argv
[0], '/');
409 /* If the name by which this was invoked ends in 'ranlib' then we are in
411 if(len
>= RSZ
&& strncmp(pnam
+len
-RSZ
, "ranlib", RSZ
) == 0)
412 cmd_flags
.ranlib
= TRUE
;
414 /* The default is to used long names */
415 cmd_flags
.use_long_names
= TRUE
;
417 /* process the command line arguments and collect the files */
419 cmd_flags
.files
= allocate(sizeof(char *) * maxfiles
);
420 cmd_flags
.filelist
= allocate(sizeof(char *) * maxfiles
);
421 memset(cmd_flags
.filelist
, '\0', sizeof(char *) * maxfiles
);
422 for(i
= 1; i
< argc
; i
++){
423 if(argv
[i
][0] == '-'){
424 if(strcmp(argv
[i
], "--version") == 0){
425 /* Implement a gnu-style --version. */
426 fprintf(stdout
, "xtools-%s %s %s\nBased on Apple Inc. %s%s\n",
427 xtools_version
, pnam
, package_version
,
428 apple_version
, lto_support
);
430 } else if(strcmp(argv
[i
], "--help") == 0){
432 fprintf(stdout
, "Please report bugs to %s\n", support_url
);
435 if(argv
[i
][1] == '\0'){
436 for(i
+= 1 ; i
< argc
; i
++)
437 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
];
440 if(strcmp(argv
[i
], "-o") == 0){
441 if(cmd_flags
.ranlib
== TRUE
){
442 error("unknown option: %s", argv
[i
]);
446 error("missing argument to: %s option", argv
[i
]);
449 if(cmd_flags
.output
!= NULL
){
450 error("more than one: %s option specified", argv
[i
]);
453 cmd_flags
.output
= argv
[i
+1];
456 else if(strcmp(argv
[i
], "-arch_only") == 0){
457 if(cmd_flags
.ranlib
== TRUE
){
458 error("unknown option: %s", argv
[i
]);
462 error("missing argument to %s option", argv
[i
]);
465 if(cmd_flags
.arch_only_flag
.name
!= NULL
){
466 error("more than one: %s option specified", argv
[i
]);
470 if(get_arch_from_flag(argv
[i
+1],
471 &cmd_flags
.arch_only_flag
) == 0){
472 error("unknown architecture specification flag: "
473 "%s %s", argv
[i
], argv
[i
+1]);
480 else if(strcmp(argv
[i
], "-dynamic") == 0){
481 if(cmd_flags
.ranlib
== TRUE
){
482 error("unknown option: %s", argv
[i
]);
485 cmd_flags
.dynamic
= TRUE
;
487 else if(strcmp(argv
[i
], "-static") == 0){
488 if(cmd_flags
.ranlib
== TRUE
){
489 error("unknown option: %s", argv
[i
]);
492 cmd_flags
.dynamic
= FALSE
;
494 else if(strcmp(argv
[i
], "-filelist") == 0){
495 if(cmd_flags
.ranlib
== TRUE
){
496 error("unknown option: %s", argv
[i
]);
500 error("missing argument to: %s option", argv
[i
]);
503 filelist
= argv
[i
+ 1];
504 dirname
= strrchr(filelist
, ',');
511 if((fd
= open(filelist
, O_RDONLY
, 0)) == -1)
512 system_fatal("can't open file list file: %s", filelist
);
513 if(fstat(fd
, &stat_buf
) == -1)
514 system_fatal("can't stat file list file: %s", filelist
);
516 * For some reason mapping files with zero size fails
517 * so it has to be handled specially.
520 if(stat_buf
.st_size
!= 0){
521 addr
= mmap(0, stat_buf
.st_size
, PROT_READ
|PROT_WRITE
,
522 MAP_FILE
|MAP_PRIVATE
, fd
, 0);
523 if((intptr_t)addr
== -1)
524 system_error("can't map file list file: %s",
528 fatal("file list file: %s is empty", filelist
);
534 for(j
= 0; j
< stat_buf
.st_size
; j
++){
538 if(addr
[stat_buf
.st_size
- 1] != '\n')
540 p
= allocate((strlen(dirname
) + 1) * nfiles
+
542 cmd_flags
.files
= reallocate(cmd_flags
.files
,
543 sizeof(char *) * (maxfiles
+ nfiles
));
544 cmd_flags
.filelist
= reallocate(cmd_flags
.filelist
,
545 sizeof(char *) * (maxfiles
+ nfiles
));
546 memset(cmd_flags
.filelist
+ maxfiles
, '\0',
547 sizeof(char *) * nfiles
);
550 cmd_flags
.files
[cmd_flags
.nfiles
] = p
;
551 cmd_flags
.filelist
[cmd_flags
.nfiles
] = filelist
;
553 if(*dirname
!= '\0'){
555 p
+= strlen(dirname
);
558 for(j
= 0; j
< stat_buf
.st_size
; j
++){
563 if(j
!= stat_buf
.st_size
- 1){
564 cmd_flags
.files
[cmd_flags
.nfiles
] = p
;
565 cmd_flags
.filelist
[cmd_flags
.nfiles
] =argv
[i
+1];
567 if(*dirname
!= '\0'){
569 p
+= strlen(dirname
);
575 if(addr
[stat_buf
.st_size
- 1] != '\n')
579 else if(strcmp(argv
[i
], "-compatibility_version") == 0){
580 if(cmd_flags
.ranlib
== TRUE
){
581 error("unknown option: %s", argv
[i
]);
585 error("missing argument to: %s option", argv
[i
]);
588 if(cmd_flags
.compatibility
!= NULL
){
589 error("more than one: %s option specified", argv
[i
]);
592 if(get_version_number(argv
[i
], argv
[i
+1], &temp
) == FALSE
){
595 cmd_flags
.compatibility
= argv
[i
+1];
598 else if(strcmp(argv
[i
], "-current_version") == 0){
599 if(cmd_flags
.ranlib
== TRUE
){
600 error("unknown option: %s", argv
[i
]);
604 error("missing argument to: %s option", argv
[i
]);
607 if(cmd_flags
.current
!= NULL
){
608 error("more than one: %s option specified", argv
[i
]);
611 if(get_version_number(argv
[i
], argv
[i
+1], &temp
) == FALSE
){
614 cmd_flags
.current
= argv
[i
+1];
617 else if(strcmp(argv
[i
], "-install_name") == 0){
618 if(cmd_flags
.ranlib
== TRUE
){
619 error("unknown option: %s", argv
[i
]);
623 error("missing argument to: %s option", argv
[i
]);
626 if(cmd_flags
.install_name
!= NULL
){
627 error("more than one: %s option specified", argv
[i
]);
630 cmd_flags
.install_name
= argv
[i
+1];
633 else if(strcmp(argv
[i
], "-seg1addr") == 0 ||
634 strcmp(argv
[i
], "-image_base") == 0){
635 if(cmd_flags
.ranlib
== TRUE
){
636 error("unknown option: %s", argv
[i
]);
640 error("missing argument to: %s option", argv
[i
]);
643 if(cmd_flags
.seg1addr
!= NULL
){
644 error("more than one: %s option specified", argv
[i
]);
647 temp
= strtoul(argv
[i
+ 1], &endp
, 16);
649 error("address for -seg1addr %s not a proper "
650 "hexadecimal number", argv
[i
+1]);
653 cmd_flags
.seg1addr
= argv
[i
+1];
656 else if(strcmp(argv
[i
], "-segs_read_only_addr") == 0){
657 if(cmd_flags
.ranlib
== TRUE
){
658 error("unknown option: %s", argv
[i
]);
662 error("missing argument to: %s option", argv
[i
]);
665 if(cmd_flags
.segs_read_only_addr
!= NULL
){
666 error("more than one: %s option specified", argv
[i
]);
669 temp
= strtoul(argv
[i
+ 1], &endp
, 16);
671 error("address for -segs_read_only_addr %s not a "
672 "proper hexadecimal number", argv
[i
+1]);
675 cmd_flags
.segs_read_only_addr
= argv
[i
+1];
678 else if(strcmp(argv
[i
], "-segs_read_write_addr") == 0){
679 if(cmd_flags
.ranlib
== TRUE
){
680 error("unknown option: %s", argv
[i
]);
684 error("missing argument to: %s option", argv
[i
]);
687 if(cmd_flags
.segs_read_write_addr
!= NULL
){
688 error("more than one: %s option specified", argv
[i
]);
691 temp
= strtoul(argv
[i
+ 1], &endp
, 16);
693 error("address for -segs_read_write_addr %s not a "
694 "proper hexadecimal number", argv
[i
+1]);
697 cmd_flags
.segs_read_write_addr
= argv
[i
+1];
700 else if(strcmp(argv
[i
], "-seg_addr_table") == 0){
701 if(cmd_flags
.ranlib
== TRUE
){
702 error("unknown option: %s", argv
[i
]);
706 error("missing argument to: %s option", argv
[i
]);
709 if(cmd_flags
.seg_addr_table
!= NULL
){
710 error("more than one: %s option specified", argv
[i
]);
713 cmd_flags
.seg_addr_table
= argv
[i
+1];
716 else if(strcmp(argv
[i
], "-seg_addr_table_filename") == 0){
717 if(cmd_flags
.ranlib
== TRUE
){
718 error("unknown option: %s", argv
[i
]);
722 error("missing argument to: %s option", argv
[i
]);
725 if(cmd_flags
.seg_addr_table_filename
!= NULL
){
726 error("more than one: %s option specified", argv
[i
]);
729 cmd_flags
.seg_addr_table_filename
= argv
[i
+1];
732 else if(strcmp(argv
[i
], "-syslibroot") == 0){
733 if(cmd_flags
.ranlib
== TRUE
){
734 error("unknown option: %s", argv
[i
]);
738 error("missing argument to: %s option", argv
[i
]);
741 if(next_root
!= NULL
&& strcmp(next_root
, argv
[i
+1]) != 0){
742 error("more than one: %s option specified", argv
[i
]);
745 next_root
= argv
[i
+1];
746 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
747 sizeof(char *) * (cmd_flags
.nldflags
+ 2));
748 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
749 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
+1];
752 else if(strcmp(argv
[i
], "-sectcreate") == 0 ||
753 strcmp(argv
[i
], "-segcreate") == 0 ||
754 strcmp(argv
[i
], "-sectorder") == 0 ||
755 strcmp(argv
[i
], "-sectalign") == 0 ||
756 strcmp(argv
[i
], "-segprot") == 0){
757 if(cmd_flags
.ranlib
== TRUE
){
758 error("unknown option: %s", argv
[i
]);
762 error("not enough arguments follow %s", argv
[i
]);
765 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
766 sizeof(char *) * (cmd_flags
.nldflags
+ 4));
767 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
768 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
+1];
769 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
+2];
770 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
+3];
771 if(strcmp(argv
[i
], "-sectcreate") == 0 ||
772 strcmp(argv
[i
], "-segcreate") == 0)
773 cmd_flags
.no_files_ok
= TRUE
;
776 else if(strcmp(argv
[i
], "-segalign") == 0 ||
777 strcmp(argv
[i
], "-undefined") == 0 ||
778 strcmp(argv
[i
], "-macosx_version_min") == 0 ||
779 strcmp(argv
[i
], "-ios_version_min") == 0 ||
780 strcmp(argv
[i
], "-ios_simulator_version_min") == 0 ||
781 strcmp(argv
[i
], "-watchos_version_min") == 0 ||
782 strcmp(argv
[i
], "-watchos_simulator_version_min") == 0 ||
783 strcmp(argv
[i
], "-tvos_version_min") == 0 ||
784 strcmp(argv
[i
], "-tvos_simulator_version_min") == 0 ||
785 strcmp(argv
[i
], "-multiply_defined") == 0 ||
786 strcmp(argv
[i
], "-multiply_defined_unused") == 0 ||
787 strcmp(argv
[i
], "-umbrella") == 0 ||
788 strcmp(argv
[i
], "-sub_umbrella") == 0 ||
789 strcmp(argv
[i
], "-sub_library") == 0 ||
790 strcmp(argv
[i
], "-allowable_client") == 0 ||
791 strcmp(argv
[i
], "-read_only_relocs") == 0 ||
792 strcmp(argv
[i
], "-init") == 0 ||
793 strcmp(argv
[i
], "-U") == 0 ||
794 strcmp(argv
[i
], "-Y") == 0 ||
795 strcmp(argv
[i
], "-dylib_file") == 0 ||
796 strcmp(argv
[i
], "-final_output") == 0 ||
797 strcmp(argv
[i
], "-headerpad") == 0 ||
798 strcmp(argv
[i
], "-weak_reference_mismatches") == 0 ||
799 strcmp(argv
[i
], "-u") == 0 ||
800 strcmp(argv
[i
], "-exported_symbols_list") == 0 ||
801 strcmp(argv
[i
], "-unexported_symbols_list") == 0 ||
802 strcmp(argv
[i
], "-executable_path") == 0){
803 if(cmd_flags
.ranlib
== TRUE
){
804 error("unknown option: %s", argv
[i
]);
808 error("not enough arguments follow %s", argv
[i
]);
811 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
812 sizeof(char *) * (cmd_flags
.nldflags
+ 2));
813 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
814 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
+1];
815 if(strcmp(argv
[i
], "-final_output") == 0)
816 cmd_flags
.final_output_specified
= TRUE
;
819 else if(strcmp(argv
[i
], "-sectorder_detail") == 0 ||
820 strcmp(argv
[i
], "-Sn") == 0 ||
821 strcmp(argv
[i
], "-Si") == 0 ||
822 strcmp(argv
[i
], "-Sp") == 0 ||
823 strcmp(argv
[i
], "-S") == 0 ||
824 strcmp(argv
[i
], "-X") == 0 ||
825 strcmp(argv
[i
], "-x") == 0 ||
826 strcmp(argv
[i
], "-whatsloaded") == 0 ||
827 strcmp(argv
[i
], "-whyload") == 0 ||
828 strcmp(argv
[i
], "-arch_errors_fatal") == 0 ||
829 strcmp(argv
[i
], "-run_init_lazily") == 0 ||
830 strcmp(argv
[i
], "-twolevel_namespace") == 0 ||
831 strcmp(argv
[i
], "-twolevel_namespace_hints") == 0 ||
832 strcmp(argv
[i
], "-flat_namespace") == 0 ||
833 strcmp(argv
[i
], "-nomultidefs") == 0 ||
834 strcmp(argv
[i
], "-headerpad_max_install_names") == 0 ||
835 strcmp(argv
[i
], "-prebind_all_twolevel_modules") == 0 ||
836 strcmp(argv
[i
], "-prebind_allow_overlap") == 0 ||
837 strcmp(argv
[i
], "-ObjC") == 0 ||
838 strcmp(argv
[i
], "-M") == 0 ||
839 strcmp(argv
[i
], "-t") == 0 ||
840 strcmp(argv
[i
], "-single_module") == 0 ||
841 strcmp(argv
[i
], "-multi_module") == 0 ||
842 strcmp(argv
[i
], "-m") == 0 ||
843 strcmp(argv
[i
], "-dead_strip") == 0 ||
844 strcmp(argv
[i
], "-no_uuid") == 0 ||
845 strcmp(argv
[i
], "-no_dead_strip_inits_and_terms") == 0){
846 if(cmd_flags
.ranlib
== TRUE
){
847 error("unknown option: %s", argv
[i
]);
850 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
851 sizeof(char *) * (cmd_flags
.nldflags
+ 1));
852 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
854 else if(strcmp(argv
[i
], "-no_arch_warnings") == 0){
855 if(cmd_flags
.ranlib
== TRUE
){
856 error("unknown option: %s", argv
[i
]);
859 /* ignore this flag */
861 else if(strcmp(argv
[i
], "-prebind") == 0){
862 if(cmd_flags
.ranlib
== TRUE
){
863 error("unknown option: %s", argv
[i
]);
866 if(cmd_flags
.prebinding_flag_specified
== TRUE
&&
867 cmd_flags
.prebinding
== FALSE
){
868 error("both -prebind and -noprebind can't be "
872 cmd_flags
.prebinding_flag_specified
= TRUE
;
873 cmd_flags
.prebinding
= TRUE
;
874 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
875 sizeof(char *) * (cmd_flags
.nldflags
+ 1));
876 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
878 else if(strcmp(argv
[i
], "-noprebind") == 0){
879 if(cmd_flags
.ranlib
== TRUE
){
880 error("unknown option: %s", argv
[i
]);
883 if(cmd_flags
.prebinding_flag_specified
== TRUE
&&
884 cmd_flags
.prebinding
== TRUE
){
885 error("both -prebind and -noprebind can't be "
889 cmd_flags
.prebinding_flag_specified
= TRUE
;
890 cmd_flags
.prebinding
= FALSE
;
891 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
892 sizeof(char *) * (cmd_flags
.nldflags
+ 1));
893 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
895 else if(strcmp(argv
[i
], "-all_load") == 0){
896 if(cmd_flags
.ranlib
== TRUE
){
897 error("unknown option: %s", argv
[i
]);
900 if(cmd_flags
.all_load_flag_specified
== TRUE
&&
901 cmd_flags
.all_load
== FALSE
){
902 error("both -all_load and -noall_load can't be "
906 cmd_flags
.all_load_flag_specified
= TRUE
;
907 cmd_flags
.all_load
= TRUE
;
909 else if(strcmp(argv
[i
], "-noall_load") == 0){
910 if(cmd_flags
.ranlib
== TRUE
){
911 error("unknown option: %s", argv
[i
]);
914 if(cmd_flags
.all_load_flag_specified
== TRUE
&&
915 cmd_flags
.all_load
== TRUE
){
916 error("both -all_load and -noall_load can't be "
920 cmd_flags
.all_load_flag_specified
= TRUE
;
921 cmd_flags
.all_load
= FALSE
;
923 else if(strncmp(argv
[i
], "-y", 2) == 0 ||
924 strncmp(argv
[i
], "-i", 2) == 0){
925 if(cmd_flags
.ranlib
== TRUE
){
926 error("unknown option: %s", argv
[i
]);
929 if(strncmp(argv
[i
], "-i", 2) == 0)
930 cmd_flags
.no_files_ok
= TRUE
;
931 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
932 sizeof(char *) * (cmd_flags
.nldflags
+ 1));
933 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
935 else if(argv
[i
][1] == 'l'){
936 if(cmd_flags
.ranlib
== TRUE
){
937 error("unknown option: %s", argv
[i
]);
940 if(argv
[i
][2] == '\0'){
941 error("-l: name missing");
944 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
];
947 else if(strncmp(argv
[i
], "-weak-l", 7) == 0){
948 if(cmd_flags
.ranlib
== TRUE
){
949 error("unknown option: %s", argv
[i
]);
952 if(argv
[i
][7] == '\0'){
953 error("-weak-l: name missing");
956 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
];
959 else if(strcmp(argv
[i
], "-framework") == 0 ||
960 strcmp(argv
[i
], "-weak_framework") == 0 ||
961 strcmp(argv
[i
], "-weak_library") == 0){
962 if(cmd_flags
.ranlib
== TRUE
){
963 error("unknown option: %s", argv
[i
]);
967 error("not enough arguments follow %s", argv
[i
]);
970 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
];
971 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
+1];
975 else if(strcmp(argv
[i
], "-T") == 0){
976 if(cmd_flags
.L_or_T_specified
== TRUE
){
977 error("both -T and -L can't be specified");
980 cmd_flags
.L_or_T_specified
= TRUE
;
981 cmd_flags
.use_long_names
= FALSE
;
983 else if(argv
[i
][1] == 'L' || argv
[i
][1] == 'F'){
984 if(argv
[i
][1] == 'L' && argv
[i
][2] == '\0'){
985 if(cmd_flags
.L_or_T_specified
== TRUE
){
986 error("both -T and -L can't be specified");
989 cmd_flags
.L_or_T_specified
= TRUE
;
990 cmd_flags
.use_long_names
= TRUE
;
993 if(cmd_flags
.ranlib
== TRUE
){
994 error("unknown option: %s", argv
[i
]);
997 cmd_flags
.Ldirs
= realloc(cmd_flags
.Ldirs
,
998 sizeof(char *) * (cmd_flags
.nLdirs
+ 1));
999 cmd_flags
.Ldirs
[cmd_flags
.nLdirs
++] = argv
[i
];
1002 else if(argv
[i
][1] == 'g'){
1003 if(cmd_flags
.ranlib
== TRUE
){
1004 error("unknown option: %s", argv
[i
]);
1005 usage(EXIT_FAILURE
);
1007 /* We need to ignore -g[gdb,codeview,stab][number] flags */
1010 else if(strcmp(argv
[i
], "-pg") == 0){
1011 if(cmd_flags
.ranlib
== TRUE
){
1012 error("unknown option: %s", argv
[i
]);
1013 usage(EXIT_FAILURE
);
1015 /* We need to ignore -pg */
1018 else if(strcmp(argv
[i
], "-search_paths_first") == 0){
1019 if(cmd_flags
.ranlib
== TRUE
){
1020 error("unknown option: %s", argv
[i
]);
1021 usage(EXIT_FAILURE
);
1023 cmd_flags
.search_paths_first
= TRUE
;
1024 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
1025 sizeof(char *) * (cmd_flags
.nldflags
+ 1));
1026 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
1028 else if(strcmp(argv
[i
], "-noflush") == 0){
1029 cmd_flags
.noflush
= TRUE
;
1031 else if(strcmp(argv
[i
], "-no_warning_for_no_symbols") == 0){
1032 cmd_flags
.no_warning_for_no_symbols
= TRUE
;
1034 else if(strcmp(argv
[i
], "-toc64") == 0){
1035 cmd_flags
.toc64
= TRUE
;
1037 else if(strcmp(argv
[i
], "-fat64") == 0){
1038 cmd_flags
.fat64
= TRUE
;
1041 else if(strcmp(argv
[i
], "-debug") == 0){
1043 error("not enough arguments follow %s", argv
[i
]);
1044 usage(EXIT_FAILURE
);
1047 cmd_flags
.debug
|= 1 << strtoul(argv
[i
], &endp
, 10);
1048 if(*endp
!= '\0' || strtoul(argv
[i
], &endp
, 10) > 32)
1049 fatal("argument for -debug %s not a proper "
1050 "decimal number less than 32", argv
[i
]);
1054 for(j
= 1; argv
[i
][j
] != '\0'; j
++){
1066 if(cmd_flags
.ranlib
== TRUE
){
1067 error("unknown option character `%c' in: %s",
1068 argv
[i
][j
], argv
[i
]);
1069 usage(EXIT_FAILURE
);
1071 cmd_flags
.verbose
= TRUE
;
1074 printf("Apple Inc. version %s\n", apple_version
);
1078 if(cmd_flags
.ranlib
== TRUE
){
1079 warning("touch option (`%c' in: %s) ignored "
1080 "(table of contents rebuilt anyway)",
1081 argv
[i
][j
], argv
[i
]);
1086 error("unknown option character `%c' in: %s",
1087 argv
[i
][j
], argv
[i
]);
1088 usage(EXIT_FAILURE
);
1091 if(cmd_flags
.ranlib
== TRUE
){
1096 error("unknown option character `%c' in: %s",
1097 argv
[i
][j
], argv
[i
]);
1098 usage(EXIT_FAILURE
);
1101 if(cmd_flags
.ranlib
== TRUE
){
1106 error("unknown option character `%c' in: %s",
1107 argv
[i
][j
], argv
[i
]);
1108 usage(EXIT_FAILURE
);
1111 error("unknown option character `%c' in: %s",
1112 argv
[i
][j
], argv
[i
]);
1113 usage(EXIT_FAILURE
);
1119 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
];
1122 * Test to see if the environment variable LD_TRACE_ARCHIVES is set.
1124 if((getenv("RC_TRACE_ARCHIVES") != NULL
) ||
1125 (getenv("LD_TRACE_ARCHIVES") != NULL
)) {
1126 cmd_flags
.ld_trace_archives
= TRUE
;
1127 cmd_flags
.trace_file_path
= getenv("LD_TRACE_FILE");
1131 * If either -syslibroot or the environment variable NEXT_ROOT is set
1132 * prepend it to the standard paths for library searches. This was
1133 * added to ease cross build environments.
1135 if(next_root
!= NULL
){
1136 if(getenv("NEXT_ROOT") != NULL
)
1137 warning("NEXT_ROOT environment variable ignored because "
1138 "-syslibroot specified");
1141 next_root
= getenv("NEXT_ROOT");
1143 if(next_root
!= NULL
){
1144 for(i
= 0; standard_dirs
[i
] != NULL
; i
++){
1145 p
= allocate(strlen(next_root
) +
1146 strlen(standard_dirs
[i
]) + 1);
1147 strcpy(p
, next_root
);
1148 strcat(p
, standard_dirs
[i
]);
1149 standard_dirs
[i
] = p
;
1151 for(i
= 0; i
< cmd_flags
.nLdirs
; i
++){
1152 if(cmd_flags
.Ldirs
[i
][1] != 'L')
1154 if(cmd_flags
.Ldirs
[i
][2] == '/'){
1155 p
= makestr(next_root
, cmd_flags
.Ldirs
[i
] + 2, NULL
);
1156 if(access(p
, F_OK
) != -1){
1158 p
= makestr("-L", next_root
, cmd_flags
.Ldirs
[i
] + 2,
1160 cmd_flags
.Ldirs
[i
] = p
;
1169 /* check the command line arguments for correctness */
1170 if(cmd_flags
.ranlib
== FALSE
&& cmd_flags
.dynamic
== TRUE
){
1171 if(cmd_flags
.s
== TRUE
){
1172 warning("-static not specified, -s invalid");
1174 if(cmd_flags
.a
== TRUE
){
1175 warning("-static not specified, -a invalid");
1177 if(cmd_flags
.c
== TRUE
){
1178 warning("-static not specified, -c invalid");
1180 if(cmd_flags
.L_or_T_specified
== TRUE
){
1181 if(cmd_flags
.use_long_names
== TRUE
)
1182 warning("-static not specified, -L invalid");
1184 warning("-static not specified, -T invalid");
1187 if(cmd_flags
.s
== TRUE
&& cmd_flags
.a
== TRUE
){
1188 error("only one of -s or -a can be specified");
1189 usage(EXIT_FAILURE
);
1191 if(cmd_flags
.ranlib
== FALSE
&& cmd_flags
.output
== NULL
){
1194 error("no output file specified (specify with -o output)");
1195 usage(EXIT_FAILURE
);
1197 if(cmd_flags
.dynamic
== FALSE
){
1198 if(cmd_flags
.compatibility
!= NULL
){
1199 warning("-dynamic not specified, -compatibility_version %s "
1200 "invalid", cmd_flags
.compatibility
);
1202 if(cmd_flags
.current
!= NULL
){
1203 warning("-dynamic not specified, -current_version %s invalid",
1206 if(cmd_flags
.install_name
!= NULL
){
1207 warning("-dynamic not specified, -install_name %s invalid",
1208 cmd_flags
.install_name
);
1210 if(cmd_flags
.seg1addr
!= NULL
){
1211 warning("-dynamic not specified, -seg1addr %s invalid",
1212 cmd_flags
.seg1addr
);
1214 if(cmd_flags
.segs_read_only_addr
!= NULL
){
1215 warning("-dynamic not specified, -segs_read_only_addr %s "
1216 "invalid", cmd_flags
.segs_read_only_addr
);
1218 if(cmd_flags
.segs_read_write_addr
!= NULL
){
1219 warning("-dynamic not specified, -segs_read_write_addr %s "
1220 "invalid", cmd_flags
.segs_read_write_addr
);
1222 if(cmd_flags
.seg_addr_table
!= NULL
){
1223 warning("-dynamic not specified, -seg_addr_table %s "
1224 "invalid", cmd_flags
.seg_addr_table
);
1226 if(cmd_flags
.seg_addr_table_filename
!= NULL
){
1227 warning("-dynamic not specified, -seg_addr_table_filename %s "
1228 "invalid", cmd_flags
.seg_addr_table_filename
);
1230 if(cmd_flags
.all_load_flag_specified
== TRUE
){
1231 if(cmd_flags
.all_load
== TRUE
)
1232 warning("-dynamic not specified, -all_load invalid");
1234 warning("-dynamic not specified, -noall_load invalid");
1236 if(cmd_flags
.nldflags
!= 0){
1237 bad_flag_seen
= FALSE
;
1238 for(j
= 0; j
< cmd_flags
.nldflags
; j
++){
1239 if(strcmp(cmd_flags
.ldflags
[j
], "-syslibroot") == 0){
1243 if(bad_flag_seen
== FALSE
){
1244 fprintf(stderr
, "%s: -dynamic not specified the "
1245 "following flags are invalid: ", pnam
);
1246 bad_flag_seen
= TRUE
;
1248 fprintf(stderr
, "%s ", cmd_flags
.ldflags
[j
]);
1250 if(bad_flag_seen
== TRUE
)
1251 fprintf(stderr
, "\n");
1253 if(cmd_flags
.nLdirs
!= 0){
1254 /* Note: both -L and -F flags are in cmd_flags.Ldirs to keep the
1255 search order right. */
1256 bad_flag_seen
= FALSE
;
1257 for(j
= 0; j
< cmd_flags
.nLdirs
; j
++){
1258 if(strncmp(cmd_flags
.Ldirs
[j
], "-L", 2) == 0)
1260 if(bad_flag_seen
== FALSE
){
1261 fprintf(stderr
, "%s: -dynamic not specified the "
1262 "following flags are invalid: ", pnam
);
1263 bad_flag_seen
= TRUE
;
1265 fprintf(stderr
, "%s ", cmd_flags
.Ldirs
[j
]);
1267 if(bad_flag_seen
== TRUE
)
1268 fprintf(stderr
, "\n");
1273 * The -prebind flag can also be specified with the LD_PREBIND
1274 * environment variable.
1276 if(getenv("LD_PREBIND") != NULL
){
1277 if(cmd_flags
.prebinding_flag_specified
== TRUE
&&
1278 cmd_flags
.prebinding
== FALSE
){
1279 warning("LD_PREBIND environment variable ignored because "
1280 "-noprebind specified");
1283 cmd_flags
.prebinding_flag_specified
= TRUE
;
1284 cmd_flags
.prebinding
= TRUE
;
1288 if(cmd_flags
.nfiles
== 0){
1289 if(cmd_flags
.ranlib
== TRUE
){
1290 error("no archives specified");
1291 usage(EXIT_FAILURE
);
1294 if(cmd_flags
.dynamic
== TRUE
&& cmd_flags
.no_files_ok
== TRUE
)
1295 warning("warning no files specified");
1297 error("no files specified");
1298 usage(EXIT_FAILURE
);
1303 /* set the defaults if not specified */
1304 if(cmd_flags
.a
== FALSE
)
1305 cmd_flags
.s
= TRUE
; /* sort table of contents by default */
1310 return(EXIT_SUCCESS
);
1312 return(EXIT_FAILURE
);
1316 * usage(EXIT_FAILURE) prints the current usage message and exits indicating failure.
1319 usage(int exit_with_code
)
1321 FILE *out
= exit_with_code
? stderr
: stdout
;
1322 if(cmd_flags
.ranlib
)
1323 fprintf(out
, "Usage: %s [-sactfqLT] [-] archive [...]\n",
1326 fprintf(out
, "Usage: %s -static [-] file [...] "
1327 "[-filelist listfile[,dirname]] [-arch_only arch] "
1328 "[-sacLT] [-no_warning_for_no_symbols]\n", pnam
);
1329 fprintf(out
, "Usage: %s -dynamic [-] file [...] "
1330 "[-filelist listfile[,dirname]] [-arch_only arch] "
1331 "[-o output] [-install_name name] "
1332 "[-compatibility_version #] [-current_version #] "
1333 "[-seg1addr 0x#] [-segs_read_only_addr 0x#] "
1334 "[-segs_read_write_addr 0x#] [-seg_addr_table <filename>] "
1335 "[-seg_addr_table_filename <file_system_path>] "
1336 "[-all_load] [-noall_load]\n",
1340 exit(exit_with_code
);
1344 * process() the input files into libraries based on the command flags.
1351 uint32_t i
, j
, k
, previous_errors
;
1352 struct ofile
*ofiles
;
1354 enum bool flag
, ld_trace_archive_printed
;
1357 * For libtool processing put all input files in the specified output
1358 * file. For ranlib processing all input files should be archives or
1359 * fat files with archives in them and each is processed by itself and
1360 * not combined with anything else. The format of fat object files in
1361 * a thin archive is supported here also.
1363 ofiles
= allocate(sizeof(struct ofile
) * cmd_flags
.nfiles
);
1364 for(i
= 0; i
< cmd_flags
.nfiles
; i
++){
1365 if(strncmp(cmd_flags
.files
[i
], "-l", 2) == 0 ||
1366 strncmp(cmd_flags
.files
[i
], "-weak-l", 7) == 0){
1367 if(cmd_flags
.dynamic
== TRUE
)
1369 file_name
= file_name_from_l_flag(cmd_flags
.files
[i
]);
1370 if(file_name
!= NULL
)
1371 if(ofile_map(file_name
, NULL
, NULL
, ofiles
+ i
, TRUE
) ==
1375 else if(strcmp(cmd_flags
.files
[i
], "-framework") == 0 ||
1376 strcmp(cmd_flags
.files
[i
], "-weak_framework") == 0 ||
1377 strcmp(cmd_flags
.files
[i
], "-weak_library") == 0){
1382 if(ofile_map(cmd_flags
.files
[i
], NULL
, NULL
, ofiles
+ i
,
1387 previous_errors
= errors
;
1389 ld_trace_archive_printed
= FALSE
;
1391 if(ofiles
[i
].file_type
== OFILE_FAT
){
1392 (void)ofile_first_arch(ofiles
+ i
);
1394 if(ofiles
[i
].arch_type
== OFILE_ARCHIVE
){
1395 if(cmd_flags
.ld_trace_archives
== TRUE
&&
1396 cmd_flags
.dynamic
== FALSE
&&
1397 ld_trace_archive_printed
== FALSE
){
1398 char resolvedname
[MAXPATHLEN
];
1399 if(realpath(ofiles
[i
].file_name
, resolvedname
) !=
1401 ld_trace("[Logging for XBS] Used static "
1402 "archive: %s\n", resolvedname
);
1404 ld_trace("[Logging for XBS] Used static "
1405 "archive: %s\n", ofiles
[i
].file_name
);
1406 ld_trace_archive_printed
= TRUE
;
1408 /* loop through archive */
1409 if((flag
= ofile_first_member(ofiles
+ i
)) == TRUE
){
1410 if(ofiles
[i
].member_ar_hdr
!= NULL
&&
1411 strncmp(ofiles
[i
].member_name
, SYMDEF
,
1412 sizeof(SYMDEF
) - 1) == 0)
1413 flag
= ofile_next_member(ofiles
+ i
);
1414 while(flag
== TRUE
){
1415 /* No fat members in a fat file */
1416 if(ofiles
[i
].mh
!= NULL
||
1417 ofiles
[i
].mh64
!= NULL
||
1419 ofiles
[i
].lto
!= NULL
||
1420 #endif /* LTO_SUPPORT */
1421 cmd_flags
.ranlib
== TRUE
)
1422 add_member(ofiles
+ i
);
1424 error("for architecture: %s file: %s(%.*s) "
1425 "is not an object file (not allowed "
1427 ofiles
[i
].arch_flag
.name
,
1429 (int)ofiles
[i
].member_name_size
,
1430 ofiles
[i
].member_name
);
1432 flag
= ofile_next_member(ofiles
+ i
);
1436 else if(ofiles
[i
].arch_type
== OFILE_Mach_O
1438 || ofiles
[i
].arch_type
== OFILE_LLVM_BITCODE
1441 if(cmd_flags
.ranlib
== TRUE
){
1442 error("for architecture: %s file: %s is not an "
1443 "archive (no processing done on this file)",
1444 ofiles
[i
].arch_flag
.name
, cmd_flags
.files
[i
]);
1445 goto ranlib_fat_error
;
1448 add_member(ofiles
+ i
);
1450 else if(ofiles
[i
].arch_type
== OFILE_UNKNOWN
){
1451 if(cmd_flags
.ranlib
== TRUE
){
1452 error("for architecture: %s file: %s is not an "
1453 "archive (no processing done on this file)",
1454 ofiles
[i
].arch_flag
.name
, cmd_flags
.files
[i
]);
1455 goto ranlib_fat_error
;
1458 error("for architecture: %s file: %s is not an "
1459 "object file (not allowed in a library)",
1460 ofiles
[i
].arch_flag
.name
, cmd_flags
.files
[i
]);
1463 }while(ofile_next_arch(ofiles
+ i
) == TRUE
);
1465 else if(ofiles
[i
].file_type
== OFILE_ARCHIVE
){
1466 if(cmd_flags
.ld_trace_archives
== TRUE
&&
1467 cmd_flags
.dynamic
== FALSE
&&
1468 ld_trace_archive_printed
== FALSE
){
1469 char resolvedname
[MAXPATHLEN
];
1470 if(realpath(ofiles
[i
].file_name
, resolvedname
) != NULL
)
1471 ld_trace("[Logging for XBS] Used static archive: "
1472 "%s\n", resolvedname
);
1474 ld_trace("[Logging for XBS] Used static archive: "
1475 "%s\n", ofiles
[i
].file_name
);
1476 ld_trace_archive_printed
= TRUE
;
1478 /* loop through archive */
1479 if((flag
= ofile_first_member(ofiles
+ i
)) == TRUE
){
1480 if(ofiles
[i
].member_ar_hdr
!= NULL
&&
1481 strncmp(ofiles
[i
].member_name
, SYMDEF
,
1482 sizeof(SYMDEF
) - 1) == 0){
1483 flag
= ofile_next_member(ofiles
+ i
);
1485 while(flag
== TRUE
){
1486 /* incorrect form: archive with fat object members */
1487 if(ofiles
[i
].member_type
== OFILE_FAT
){
1488 (void)ofile_first_arch(ofiles
+ i
);
1490 if(ofiles
[i
].mh
!= NULL
||
1491 ofiles
[i
].mh64
!= NULL
||
1493 ofiles
[i
].lto
!= NULL
||
1495 cmd_flags
.ranlib
== TRUE
){
1496 add_member(ofiles
+ i
);
1500 * Can't really get here because ofile_*()
1501 * routines will refuse to process this
1502 * type of file (but I'll leave it here).
1504 error("file: %s(%.*s) for architecture: %s "
1505 "is not an object file (not allowed in "
1506 "a library)", cmd_flags
.files
[i
],
1507 (int)ofiles
[i
].member_name_size
,
1508 ofiles
[i
].member_name
,
1509 ofiles
[i
].arch_flag
.name
);
1512 }while(ofile_next_arch(ofiles
+ i
) == TRUE
);
1514 else if(ofiles
[i
].mh
!= NULL
||
1515 ofiles
[i
].mh64
!= NULL
||
1517 ofiles
[i
].lto
!= NULL
||
1518 #endif /* LTO_SUPPORT */
1519 cmd_flags
.ranlib
== TRUE
){
1520 add_member(ofiles
+ i
);
1523 error("file: %s(%.*s) is not an object file (not "
1524 "allowed in a library)", cmd_flags
.files
[i
],
1525 (int)ofiles
[i
].member_name_size
,
1526 ofiles
[i
].member_name
);
1528 flag
= ofile_next_member(ofiles
+ i
);
1532 else if(ofiles
[i
].file_type
== OFILE_Mach_O
){
1533 if(cmd_flags
.ranlib
== TRUE
){
1534 error("file: %s is not an archive", cmd_flags
.files
[i
]);
1537 add_member(ofiles
+ i
);
1540 else if(ofiles
[i
].file_type
== OFILE_LLVM_BITCODE
){
1541 if(cmd_flags
.ranlib
== TRUE
){
1542 error("file: %s is not an archive", cmd_flags
.files
[i
]);
1545 add_member(ofiles
+ i
);
1547 #endif /* LTO_SUPPORT */
1548 else{ /* ofiles[i].file_type == OFILE_UNKNOWN */
1549 if(cmd_flags
.ranlib
== TRUE
){
1550 error("file: %s is not an archive", cmd_flags
.files
[i
]);
1554 error("file: %s is not an object file (not allowed in a "
1555 "library)", cmd_flags
.files
[i
]);
1559 if(cmd_flags
.ranlib
== TRUE
){
1561 * In the case where ranlib is being used on an archive that
1562 * contains fat object files with multiple members and non-
1563 * object members this has to be treated as an error because
1564 * it is not known which architecture(s) the non-object file
1568 for(j
= 0; j
< narchs
; j
++){
1569 for(k
= 0; k
< archs
[j
].nmembers
; k
++){
1570 if(archs
[j
].members
[k
].mh
== NULL
&&
1572 archs
[j
].members
[k
].lto_contents
== FALSE
&&
1573 #endif /* LTO_SUPPORT */
1574 archs
[j
].members
[k
].mh64
== NULL
){
1575 error("library member: %s(%.*s) is not an "
1576 "object file (not allowed in a library "
1577 "with multiple architectures)",
1579 (int)archs
[j
].members
[k
].
1580 input_base_name_size
,
1581 archs
[j
].members
[k
].input_base_name
);
1587 create_library(cmd_flags
.files
[i
], ofiles
+ i
);
1588 if(cmd_flags
.nfiles
> 1){
1591 ofile_unmap(ofiles
+ i
);
1594 errors
+= previous_errors
;
1596 if(cmd_flags
.ranlib
== FALSE
&& errors
== 0)
1597 create_library(cmd_flags
.output
, NULL
);
1600 * Clean-up of ofiles[] and archs could be done here but since this
1601 * program is now done it is faster to just exit.
1606 * file_name_from_l_flag() is passed a "-lx" or "-weak-lx" flag and returns a
1607 * name of a file for this flag. The flag "-lx" and "-weak-lx" are the same
1608 * flags as used in the link editor to refer to file names. If it can't find a
1609 * file name for the flag it prints an error and returns NULL.
1613 file_name_from_l_flag(
1616 char *file_name
, *p
, *start
;
1618 if(strncmp(l_flag
, "-weak-l", 7) == 0)
1622 p
= strrchr(start
, '.');
1623 if(p
!= NULL
&& strcmp(p
, ".o") == 0){
1625 file_name
= search_for_file(p
);
1629 if(cmd_flags
.dynamic
== TRUE
){
1630 if(cmd_flags
.search_paths_first
== TRUE
){
1631 file_name
= search_paths_for_lname(start
);
1634 p
= makestr("lib", start
, ".dylib", NULL
);
1635 file_name
= search_for_file(p
);
1637 if(file_name
== NULL
){
1638 p
= makestr("lib", start
, ".a", NULL
);
1639 file_name
= search_for_file(p
);
1645 p
= makestr("lib", start
, ".a", NULL
);
1646 file_name
= search_for_file(p
);
1650 if(file_name
== NULL
)
1651 error("can't locate file for: %s", l_flag
);
1656 * search_for_file() takes base_name and trys to find a file with that base name
1657 * is the -L search directories and in the standard directories. If it is
1658 * sucessful it returns a pointer to the file name else it returns NULL.
1668 for(i
= 0; i
< cmd_flags
.nLdirs
; i
++){
1669 if(cmd_flags
.Ldirs
[i
][1] != 'L')
1671 file_name
= makestr(cmd_flags
.Ldirs
[i
] + 2, "/", base_name
, NULL
);
1672 if(access(file_name
, R_OK
) != -1)
1676 for(i
= 0; standard_dirs
[i
] != NULL
; i
++){
1677 file_name
= makestr(standard_dirs
[i
], base_name
, NULL
);
1678 if(access(file_name
, R_OK
) != -1)
1686 * search_paths_for_lname() takes the argument to a -lx option and and trys to
1687 * find a file with the name libx.dylib or libx.a. This routine is only used
1688 * when the -search_paths_first option is specified and -dynamic is in effect.
1689 * And looks for a file name ending in .dylib then .a in each directory before
1690 * looking in the next directory. The list of the -L search directories and in
1691 * the standard directories are searched in that order. If this is sucessful
1692 * it returns a pointer to the file name else NULL.
1696 search_paths_for_lname(
1697 const char *lname_argument
)
1700 char *file_name
, *dir
;
1702 for(i
= 0; i
< cmd_flags
.nLdirs
; i
++){
1703 if(cmd_flags
.Ldirs
[i
][1] != 'L')
1705 dir
= makestr(cmd_flags
.Ldirs
[i
] + 2, "/", NULL
);
1706 file_name
= search_path_for_lname(dir
, lname_argument
);
1708 if(file_name
!= NULL
)
1711 for(i
= 0; standard_dirs
[i
] != NULL
; i
++){
1712 file_name
= search_path_for_lname(standard_dirs
[i
], lname_argument
);
1713 if(file_name
!= NULL
)
1720 * search_path_for_lname() takes the argument to a -lx option and and trys to
1721 * find a file with the name libx.dylib then libx.a in the specified directory
1722 * name. This routine is only used when the -search_paths_first option is
1723 * specified and -dynamic is in effect. If this is sucessful it returns a
1724 * pointer to the file name else NULL.
1728 search_path_for_lname(
1730 const char *lname_argument
)
1734 file_name
= makestr(dir
, "/", "lib", lname_argument
, ".dylib", NULL
);
1735 if(access(file_name
, R_OK
) != -1)
1739 file_name
= makestr(dir
, "/", "lib", lname_argument
, ".a", NULL
);
1740 if(access(file_name
, R_OK
) != -1)
1748 * add_member() add the specified ofile as a member to the library. The
1749 * specified ofile must be either an object file (libtool or ranlib) or an
1750 * archive member with an unknown file type (ranlib only).
1755 struct ofile
*ofile
)
1757 uint32_t i
, j
, size
, ar_name_size
;
1759 struct member
*member
;
1760 struct stat stat_buf
;
1761 char *p
, c
, ar_name_buf
[sizeof(ofile
->member_ar_hdr
->ar_name
) + 1];
1762 char ar_size_buf
[sizeof(ofile
->member_ar_hdr
->ar_size
) + 1];
1763 const struct arch_flag
*family_arch_flag
;
1766 * If this did not come from an archive get the stat info which is
1767 * needed to fill in the archive header for this member.
1769 if(ofile
->member_ar_hdr
== NULL
){
1770 if(stat(ofile
->file_name
, &stat_buf
) == -1){
1771 system_error("can't stat file: %s", ofile
->file_name
);
1777 * Determine the size this member will have in the library which
1778 * includes the padding as a result of rounding the size of the
1779 * member. To get all members on an 8 byte boundary (so that mapping
1780 * in object files can be used directly) the size of the member is
1781 * CHANGED to reflect this padding. In the UNIX definition of archives
1782 * the size of the member is never changed but the offset to the next
1783 * member is defined to be the offset of the previous member plus
1784 * the size of the previous member rounded to 2. So to get 8 byte
1785 * boundaries without breaking the UNIX definition of archives the
1786 * size is changed here. As with the UNIX ar(1) program the padded
1787 * bytes are set to the character '\n'.
1789 if(ofile
->mh
!= NULL
|| ofile
->mh64
!= NULL
)
1790 size
= rnd(ofile
->object_size
, 8);
1792 else if(ofile
->lto
!= NULL
){
1793 if(ofile
->file_type
== OFILE_LLVM_BITCODE
)
1794 size
= rnd(ofile
->file_size
, 8);
1795 else if(ofile
->file_type
== OFILE_FAT
||
1796 (ofile
->file_type
== OFILE_ARCHIVE
&&
1797 ofile
->member_type
== OFILE_FAT
))
1798 size
= rnd(ofile
->object_size
, 8);
1800 size
= rnd(ofile
->member_size
, 8);
1802 #endif /* LTO_SUPPORT */
1804 size
= rnd(ofile
->member_size
, 8);
1806 /* select or create an arch type to put this in */
1808 if(ofile
->mh
!= NULL
||
1809 ofile
->mh64
!= NULL
){
1810 if(ofile
->mh_cputype
== 0){
1811 if(ofile
->member_ar_hdr
!= NULL
){
1812 error("file: %s(%.*s) cputype is zero (a reserved value)",
1813 ofile
->file_name
, (int)ofile
->member_name_size
,
1814 ofile
->member_name
);
1817 error("file: %s cputype is zero (a reserved value)",
1822 * If we are building a dynamic library then don't add dynamic
1823 * shared libraries to the archs. This is so that a dependent
1824 * dynamic shared library that happens to be fat will not cause the
1825 * library to be created fat unless there are object going into
1826 * the library that are fat.
1828 if(ofile
->mh_filetype
== MH_DYLIB
||
1829 ofile
->mh_filetype
== MH_DYLIB_STUB
){
1831 * If we are building a static library we should not put a
1832 * dynamic library Mach-O file into the static library. This
1833 * can happen if a libx.a file is really a dynamic library and
1834 * someone is using -lx when creating a static library.
1836 if(cmd_flags
.dynamic
!= TRUE
){
1837 if(ofile
->member_ar_hdr
!= NULL
){
1838 warning("file: %s(%.*s) is a dynamic library, not "
1839 "added to the static library",
1840 ofile
->file_name
, (int)ofile
->member_name_size
,
1841 ofile
->member_name
);
1844 warning("file: %s is a dynamic library, not added to "
1845 "the static library", ofile
->file_name
);
1850 * If -arch_only is specified then only add this file if it matches
1851 * the architecture specified.
1853 if(cmd_flags
.arch_only_flag
.name
!= NULL
){
1854 if(cmd_flags
.arch_only_flag
.cputype
!= ofile
->mh_cputype
)
1856 if(cmd_flags
.arch_only_flag
.cputype
== CPU_TYPE_ARM
||
1857 cmd_flags
.arch_only_flag
.cputype
== CPU_TYPE_X86_64
){
1858 if(cmd_flags
.arch_only_flag
.cpusubtype
!=
1859 ofile
->mh_cpusubtype
)
1862 if(cmd_flags
.arch_only_flag
.cputype
== CPU_TYPE_ARM64
){
1863 if(cmd_flags
.arch_only_flag
.cpusubtype
==
1864 CPU_SUBTYPE_ARM64_ALL
){
1865 if(ofile
->mh_cpusubtype
!= CPU_SUBTYPE_ARM64_ALL
&&
1866 ofile
->mh_cpusubtype
!= CPU_SUBTYPE_ARM64_V8
)
1869 else if(cmd_flags
.arch_only_flag
.cpusubtype
!=
1870 ofile
->mh_cpusubtype
)
1875 for( ; i
< narchs
; i
++){
1876 if(archs
[i
].arch_flag
.cputype
== ofile
->mh_cputype
){
1877 if((archs
[i
].arch_flag
.cputype
== CPU_TYPE_ARM
||
1878 archs
[i
].arch_flag
.cputype
== CPU_TYPE_X86_64
) &&
1879 archs
[i
].arch_flag
.cpusubtype
!= ofile
->mh_cpusubtype
)
1881 if(cmd_flags
.arch_only_flag
.cputype
== CPU_TYPE_ARM64
){
1882 if(cmd_flags
.arch_only_flag
.cpusubtype
==
1883 CPU_SUBTYPE_ARM64_ALL
){
1884 if(ofile
->mh_cpusubtype
!= CPU_SUBTYPE_ARM64_ALL
&&
1885 ofile
->mh_cpusubtype
!= CPU_SUBTYPE_ARM64_V8
)
1888 else if(cmd_flags
.arch_only_flag
.cpusubtype
!=
1889 ofile
->mh_cpusubtype
)
1897 else if(ofile
->lto
!= NULL
){
1899 * If -arch_only is specified then only add this file if it matches
1900 * the architecture specified.
1902 if(cmd_flags
.arch_only_flag
.name
!= NULL
){
1903 if(cmd_flags
.arch_only_flag
.cputype
!= ofile
->lto_cputype
)
1905 if(cmd_flags
.arch_only_flag
.cputype
== CPU_TYPE_ARM
||
1906 cmd_flags
.arch_only_flag
.cputype
== CPU_TYPE_X86_64
){
1907 if(cmd_flags
.arch_only_flag
.cpusubtype
!=
1908 ofile
->lto_cpusubtype
)
1911 if(cmd_flags
.arch_only_flag
.cputype
== CPU_TYPE_ARM64
){
1912 if(cmd_flags
.arch_only_flag
.cpusubtype
==
1913 CPU_SUBTYPE_ARM64_ALL
){
1914 if(ofile
->lto_cpusubtype
!= CPU_SUBTYPE_ARM64_ALL
&&
1915 ofile
->lto_cpusubtype
!= CPU_SUBTYPE_ARM64_V8
)
1918 else if(cmd_flags
.arch_only_flag
.cpusubtype
!=
1919 ofile
->lto_cpusubtype
)
1924 for( ; i
< narchs
; i
++){
1925 if(archs
[i
].arch_flag
.cputype
== ofile
->lto_cputype
){
1926 if((archs
[i
].arch_flag
.cputype
== CPU_TYPE_ARM
||
1927 archs
[i
].arch_flag
.cputype
== CPU_TYPE_X86_64
) &&
1928 archs
[i
].arch_flag
.cpusubtype
!= ofile
->lto_cpusubtype
)
1930 if(cmd_flags
.arch_only_flag
.cputype
== CPU_TYPE_ARM64
){
1931 if(cmd_flags
.arch_only_flag
.cpusubtype
==
1932 CPU_SUBTYPE_ARM64_ALL
&&
1933 (ofile
->lto_cpusubtype
!= CPU_SUBTYPE_ARM64_ALL
&&
1934 ofile
->lto_cpusubtype
!= CPU_SUBTYPE_ARM64_V8
))
1936 else if(cmd_flags
.arch_only_flag
.cpusubtype
!=
1937 ofile
->lto_cpusubtype
)
1944 #endif /* LTO_SUPPORT */
1945 if(narchs
== 1 && archs
[0].arch_flag
.cputype
== 0){
1948 else if(i
== narchs
){
1949 archs
= reallocate(archs
, sizeof(struct arch
) * (narchs
+1));
1950 memset(archs
+ narchs
, '\0', sizeof(struct arch
));
1951 if(ofile
->mh
!= NULL
||
1952 ofile
->mh64
!= NULL
){
1953 if(ofile
->mh_cputype
== CPU_TYPE_ARM
||
1954 ofile
->mh_cputype
== CPU_TYPE_ARM64
||
1955 ofile
->mh_cputype
== CPU_TYPE_X86_64
){
1956 archs
[narchs
].arch_flag
.name
= (char *)
1957 get_arch_name_from_types(
1958 ofile
->mh_cputype
, ofile
->mh_cpusubtype
);
1959 archs
[narchs
].arch_flag
.cputype
= ofile
->mh_cputype
;
1960 archs
[narchs
].arch_flag
.cpusubtype
= ofile
->mh_cpusubtype
;
1964 get_arch_family_from_cputype(ofile
->mh_cputype
);
1965 if(family_arch_flag
!= NULL
)
1966 archs
[narchs
].arch_flag
= *family_arch_flag
;
1970 else if(ofile
->lto
!= NULL
){
1971 if(ofile
->lto_cputype
== CPU_TYPE_ARM
||
1972 ofile
->lto_cputype
== CPU_TYPE_ARM64
||
1973 ofile
->lto_cputype
== CPU_TYPE_X86_64
){
1974 archs
[narchs
].arch_flag
.name
= (char *)
1975 get_arch_name_from_types(
1976 ofile
->lto_cputype
, ofile
->lto_cpusubtype
);
1977 archs
[narchs
].arch_flag
.cputype
= ofile
->lto_cputype
;
1978 archs
[narchs
].arch_flag
.cpusubtype
= ofile
->lto_cpusubtype
;
1982 get_arch_family_from_cputype(ofile
->lto_cputype
);
1983 if(family_arch_flag
!= NULL
)
1984 archs
[narchs
].arch_flag
= *family_arch_flag
;
1987 #endif /* LTO_SUPPORT */
1989 archs
[narchs
].arch_flag
.name
= "unknown";
1995 * If the cputype of this arch is not yet known then see if this new
1996 * member can determine it.
1998 if(arch
->arch_flag
.cputype
== 0 &&
1999 (ofile
->mh
!= NULL
|| ofile
->mh64
!= NULL
)){
2000 family_arch_flag
= get_arch_family_from_cputype(ofile
->mh_cputype
);
2001 if(family_arch_flag
!= NULL
){
2002 arch
->arch_flag
= *family_arch_flag
;
2005 arch
->arch_flag
.name
=
2006 savestr("cputype 1234567890 cpusubtype 1234567890");
2007 if(arch
->arch_flag
.name
!= NULL
)
2008 sprintf(arch
->arch_flag
.name
, "cputype %u cpusubtype %u",
2009 ofile
->mh_cputype
, ofile
->mh_cpusubtype
&
2011 arch
->arch_flag
.cputype
= ofile
->mh_cputype
;
2012 arch
->arch_flag
.cpusubtype
= ofile
->mh_cpusubtype
;
2016 if(arch
->arch_flag
.cputype
== 0 &&
2017 (ofile
->lto
!= NULL
)){
2018 family_arch_flag
= get_arch_family_from_cputype(ofile
->lto_cputype
);
2019 if(family_arch_flag
!= NULL
){
2020 arch
->arch_flag
= *family_arch_flag
;
2023 arch
->arch_flag
.name
=
2024 savestr("cputype 1234567890 cpusubtype 1234567890");
2025 if(arch
->arch_flag
.name
!= NULL
)
2026 sprintf(arch
->arch_flag
.name
, "cputype %u cpusubtype %u",
2027 ofile
->lto_cputype
, ofile
->lto_cpusubtype
&
2029 arch
->arch_flag
.cputype
= ofile
->lto_cputype
;
2030 arch
->arch_flag
.cpusubtype
= ofile
->lto_cpusubtype
;
2033 #endif /* LTO_SUPPORT */
2035 /* create a member in this arch type for this member */
2036 arch
->members
= reallocate(arch
->members
, sizeof(struct member
) *
2037 (arch
->nmembers
+ 1));
2038 member
= arch
->members
+ arch
->nmembers
;
2039 memset(member
, '\0', sizeof(struct member
));
2042 /* fill in the member for this ofile */
2043 member
->input_file_name
= ofile
->file_name
;
2045 if(ofile
->member_ar_hdr
== NULL
){
2047 * We are creating an archive member in the output file from a
2048 * file (that is not archive member in an input file). First get
2049 * the base name the file_name for the member name.
2051 p
= strrchr(ofile
->file_name
, '/');
2055 p
= ofile
->file_name
;
2056 member
->input_base_name
= p
;
2057 member
->input_base_name_size
= strlen(p
);
2058 member
->member_name
= member
->input_base_name
;
2060 * If we can use long names then force using them to allow 64-bit
2061 * objects to be aligned on an 8 byte boundary. This is needed
2062 * since the struct ar_hdr is not a multiple of 8. This is normally
2063 * done if the name does not fit in the archive header or contains
2064 * a space character then we use the extened format #1. The size
2065 * of the name is rounded up so the object file after the name will
2066 * be on an 8 byte boundary (including rounding the size of the
2067 * struct ar_hdr). The name will be padded with '\0's when it is
2070 if(cmd_flags
.use_long_names
== TRUE
){
2071 member
->output_long_name
= TRUE
;
2072 member
->member_name_size
= member
->input_base_name_size
;
2073 ar_name_size
= rnd(member
->input_base_name_size
, 8) +
2074 (rnd(sizeof(struct ar_hdr
), 8) -
2075 sizeof(struct ar_hdr
));
2076 sprintf(ar_name_buf
, "%s%-*lu", AR_EFMT1
,
2077 (int)(sizeof(member
->ar_hdr
.ar_name
) -
2078 (sizeof(AR_EFMT1
) - 1)),
2079 (long unsigned int)ar_name_size
);
2080 memcpy(member
->ar_hdr
.ar_name
, ar_name_buf
,
2081 sizeof(member
->ar_hdr
.ar_name
));
2085 member
->output_long_name
= FALSE
;
2087 * Truncate the file_name if needed and place in archive header.
2090 if(strlen(p
) > sizeof(member
->ar_hdr
.ar_name
)){
2091 c
= p
[sizeof(member
->ar_hdr
.ar_name
)];
2092 p
[sizeof(member
->ar_hdr
.ar_name
)] = '\0';
2094 sprintf((char *)(&member
->ar_hdr
), "%-*s",
2095 (int)sizeof(member
->ar_hdr
.ar_name
), p
);
2097 p
[sizeof(member
->ar_hdr
.ar_name
)] = c
;
2098 member
->member_name_size
= size_ar_name(&member
->ar_hdr
);
2100 if(zero_ar_date
== TRUE
)
2101 stat_buf
.st_mtime
= 0;
2103 * Create the rest of the archive header after the name.
2105 sprintf((char *)(&member
->ar_hdr
) + sizeof(member
->ar_hdr
.ar_name
),
2106 "%-*ld%-*u%-*u%-*o%-*ld%-*s",
2107 (int)sizeof(member
->ar_hdr
.ar_date
),
2108 (long int)stat_buf
.st_mtime
,
2109 (int)sizeof(member
->ar_hdr
.ar_uid
),
2110 (unsigned short)stat_buf
.st_uid
,
2111 (int)sizeof(member
->ar_hdr
.ar_gid
),
2112 (unsigned short)stat_buf
.st_gid
,
2113 (int)sizeof(member
->ar_hdr
.ar_mode
),
2114 (unsigned int)stat_buf
.st_mode
,
2115 (int)sizeof(member
->ar_hdr
.ar_size
),
2116 (long)size
+ ar_name_size
,
2117 (int)sizeof(member
->ar_hdr
.ar_fmag
),
2122 * We are creating an archive member in the output file from an
2123 * archive member in an input file. There can be some changes to
2124 * the contents. First the size might be changed and the contents
2125 * padded with '\n's to round it to a multiple of 8
2126 * Second we may take a member using extended format #1
2127 * for it's name and truncate it then place the name in the archive
2128 * header. Or we may round the name size to a multiple of 8.
2130 member
->input_ar_hdr
= ofile
->member_ar_hdr
;
2131 member
->input_base_name
= ofile
->member_name
;
2132 member
->input_base_name_size
= ofile
->member_name_size
;
2133 member
->input_member_offset
= ofile
->member_offset
-
2134 sizeof(struct ar_hdr
);
2135 if(strncmp(ofile
->member_ar_hdr
->ar_name
, AR_EFMT1
,
2136 sizeof(AR_EFMT1
) - 1) == 0)
2137 member
->input_member_offset
-= ofile
->member_name_size
;
2139 member
->ar_hdr
= *(ofile
->member_ar_hdr
);
2140 member
->member_name
= ofile
->member_name
;
2142 if(cmd_flags
.use_long_names
== TRUE
){
2144 * We can use long names. So if the input ofile is using the
2145 * extended format #1 we need make sure the size of the name and
2146 * the size of struct ar_hdr are rounded to 8 bytes. And write
2147 * that size into the ar_name with the AR_EFMT1 string. To
2148 * avoid growing the size of names first trim the long name size
2149 * before rounding up.
2151 if(ofile
->member_name
!= ofile
->member_ar_hdr
->ar_name
){
2152 member
->output_long_name
= TRUE
;
2153 member
->member_name_size
= ofile
->member_name_size
;
2154 for(ar_name_size
= member
->member_name_size
;
2157 if(ofile
->member_name
[ar_name_size
- 1] != '\0')
2160 member
->member_name_size
= ar_name_size
;
2161 ar_name_size
= rnd(ar_name_size
, 8) +
2162 (rnd(sizeof(struct ar_hdr
), 8) -
2163 sizeof(struct ar_hdr
));
2164 sprintf(ar_name_buf
, "%s%-*lu", AR_EFMT1
,
2165 (int)(sizeof(member
->ar_hdr
.ar_name
) -
2166 (sizeof(AR_EFMT1
) - 1)),
2167 (long unsigned int)ar_name_size
);
2168 memcpy(member
->ar_hdr
.ar_name
, ar_name_buf
,
2169 sizeof(member
->ar_hdr
.ar_name
));
2173 * Since we can use long names force this to use extended
2174 * format #1. And round the name size to 8 plus the size of
2175 * struct ar_hdr rounded to 8 bytes.
2177 member
->member_name_size
= size_ar_name(&member
->ar_hdr
);
2178 ar_name_size
= rnd(ofile
->member_name_size
, 8) +
2179 (rnd(sizeof(struct ar_hdr
), 8) -
2180 sizeof(struct ar_hdr
));
2181 member
->output_long_name
= TRUE
;
2182 sprintf(ar_name_buf
, "%s%-*lu", AR_EFMT1
,
2183 (int)(sizeof(member
->ar_hdr
.ar_name
) -
2184 (sizeof(AR_EFMT1
) - 1)),
2185 (long unsigned int)ar_name_size
);
2186 memcpy(member
->ar_hdr
.ar_name
, ar_name_buf
,
2187 sizeof(member
->ar_hdr
.ar_name
));
2192 * We can't use long names. So if the input ofile is using the
2193 * extended format #1 we need to truncate the name and write it
2194 * into the ar_name field. Note the extended format is also
2195 * used it the name has a space in it so it may be shorter than
2196 * sizeof(ar_hdr.ar_name) .
2199 member
->output_long_name
= FALSE
;
2200 if(ofile
->member_name
!= ofile
->member_ar_hdr
->ar_name
){
2201 for(j
= 0; j
< sizeof(member
->ar_hdr
.ar_name
) &&
2202 j
< ofile
->member_name_size
&&
2203 ofile
->member_name
[j
] != '\0'; j
++)
2204 member
->ar_hdr
.ar_name
[j
] = ofile
->member_name
[j
];
2205 for( ; j
< sizeof(member
->ar_hdr
.ar_name
); j
++)
2206 member
->ar_hdr
.ar_name
[j
] = ' ';
2208 member
->member_name_size
= size_ar_name(&member
->ar_hdr
);
2211 * Since sprintf() writes a '\0' at the end of the string the
2212 * memcpy is needed to preserve the ARFMAG string that follows.
2214 sprintf(ar_size_buf
, "%-*ld",
2215 (int)sizeof(member
->ar_hdr
.ar_size
),
2216 (long)size
+ ar_name_size
);
2217 memcpy(member
->ar_hdr
.ar_size
, ar_size_buf
,
2218 sizeof(member
->ar_hdr
.ar_size
));
2221 member
->offset
= arch
->size
;
2222 arch
->size
+= sizeof(struct ar_hdr
) + size
+ ar_name_size
;
2224 if(ofile
->mh
!= NULL
||
2225 ofile
->mh64
!= NULL
){
2226 member
->object_addr
= ofile
->object_addr
;
2227 member
->object_size
= ofile
->object_size
;
2228 member
->object_byte_sex
= ofile
->object_byte_sex
;
2229 member
->mh
= ofile
->mh
;
2230 member
->mh64
= ofile
->mh64
;
2231 member
->load_commands
= ofile
->load_commands
;
2234 else if(ofile
->file_type
== OFILE_LLVM_BITCODE
){
2235 member
->object_addr
= ofile
->file_addr
;
2236 member
->object_size
= ofile
->file_size
;
2237 member
->lto_contents
= TRUE
;
2238 save_lto_member_toc_info(member
, ofile
->lto
);
2239 lto_free(ofile
->lto
);
2241 member
->object_byte_sex
= get_byte_sex_from_flag(&arch
->arch_flag
);
2243 else if((ofile
->file_type
== OFILE_FAT
&&
2244 ofile
->arch_type
== OFILE_LLVM_BITCODE
) ||
2245 (ofile
->file_type
== OFILE_ARCHIVE
&&
2246 ofile
->member_type
== OFILE_FAT
&&
2247 ofile
->arch_type
== OFILE_LLVM_BITCODE
)){
2248 member
->object_addr
= ofile
->object_addr
;
2249 member
->object_size
= ofile
->object_size
;
2250 member
->lto_contents
= TRUE
;
2251 save_lto_member_toc_info(member
, ofile
->lto
);
2252 lto_free(ofile
->lto
);
2254 member
->object_byte_sex
= get_byte_sex_from_flag(&arch
->arch_flag
);
2256 #endif /* LTO_SUPPORT */
2258 member
->object_addr
= ofile
->member_addr
;
2259 member
->object_size
= ofile
->member_size
;
2261 if(ofile
->lto
!= NULL
){
2262 member
->lto_contents
= TRUE
;
2263 save_lto_member_toc_info(member
, ofile
->lto
);
2264 lto_free(ofile
->lto
);
2266 member
->object_byte_sex
= get_byte_sex_from_flag(
2269 #endif /* LTO_SUPPORT */
2274 * free_archs() frees the memory allocated that is pointed to by archs.
2283 for(i
= 0 ; i
< narchs
; i
++){
2285 * Just leak memory on the arch_flag.name in some cases
2286 * (unknown archiectures only where the space is malloced and
2287 * a sprintf() is done into the memory)
2289 if(archs
[i
].tocs
!= NULL
)
2290 free(archs
[i
].tocs
);
2291 if(archs
[i
].toc_ranlibs
!= NULL
)
2292 free(archs
[i
].toc_ranlibs
);
2293 if(archs
[i
].toc_ranlibs64
!= NULL
)
2294 free(archs
[i
].toc_ranlibs64
);
2295 if(archs
[i
].toc_strings
!= NULL
)
2296 free(archs
[i
].toc_strings
);
2297 if(archs
[i
].members
!= NULL
)
2298 free(archs
[i
].members
);
2307 * create_library() creates a library from the data structure pointed to by
2308 * archs into the specified output file. Only when more than one architecture
2309 * is in archs will a fat file be created.
2311 * In the case of cmd_flags.ranlib == TRUE the ofile may not be NULL if it
2312 * from a thin archive. If so and the toc_* fields are set and we may update
2313 * the table of contents in place if the new one fits where the old table of
2320 struct ofile
*ofile
)
2322 uint32_t i
, j
, k
, pad
;
2323 uint64_t library_size
, offset
, *time_offsets
;
2324 enum byte_sex target_byte_sex
;
2325 char *library
, *p
, *flush_start
;
2328 struct fat_header
*fat_header
;
2329 struct fat_arch
*fat_arch
;
2330 struct fat_arch_64
*fat_arch64
;
2332 #ifndef __OPENSTEP__
2333 struct utimbuf timep
;
2337 struct stat stat_buf
;
2338 struct ar_hdr toc_ar_hdr
;
2339 enum bool some_tocs
, same_toc
, different_offsets
;
2342 if(cmd_flags
.ranlib
== TRUE
){
2343 if(cmd_flags
.q
== FALSE
)
2344 warning("empty library: %s (no table of contents added)",
2349 if(cmd_flags
.dynamic
== FALSE
||
2350 cmd_flags
.no_files_ok
== FALSE
){
2351 if(cmd_flags
.arch_only_flag
.name
!= NULL
)
2352 error("no library created (no object files in input "
2353 "files matching -arch_only %s)",
2354 cmd_flags
.arch_only_flag
.name
);
2356 error("no library created (no object files in input "
2363 if(cmd_flags
.dynamic
== TRUE
){
2364 create_dynamic_shared_library(output
);
2368 /* if this is libtool warn about duplicate member names */
2369 if(cmd_flags
.ranlib
== FALSE
)
2370 warn_duplicate_member_names();
2373 * Calculate the total size of the library and the final size of each
2377 library_size
= sizeof(struct fat_header
);
2378 if(cmd_flags
.fat64
== TRUE
)
2379 library_size
+= sizeof(struct fat_arch_64
) * narchs
;
2381 library_size
+= sizeof(struct fat_arch
) * narchs
;
2383 * The ar(1) program uses the -q flag to ranlib(1) to add a table
2384 * of contents only of the output is not a fat file. This is done
2385 * by default for UNIX standards conformance when the files are
2388 if(cmd_flags
.q
== TRUE
)
2391 * The ar(1) program uses the -f to ranlib(1) when it see the 's'
2392 * option. And if we are creating a fat file issue a warning that
2393 * ar(1) will not be able to use it.
2395 if(cmd_flags
.f
== TRUE
)
2396 warning("archive library: %s will be fat and ar(1) will not "
2397 "be able to operate on it", output
);
2402 for(i
= 0; i
< narchs
; i
++){
2403 if(narchs
> 1 && (archs
[i
].arch_flag
.cputype
& CPU_ARCH_ABI64
))
2404 library_size
= rnd(library_size
, 1 << 3);
2405 make_table_of_contents(archs
+ i
, output
);
2408 if(archs
[i
].toc_nranlibs
!= 0)
2410 archs
[i
].size
+= SARMAG
+ archs
[i
].toc_size
;
2411 library_size
+= archs
[i
].size
;
2414 * The ar(1) program uses the -q flag to ranlib(1) to add a table of
2415 * contents only of the output contains some object files. This is
2416 * done for UNIX standards conformance.
2418 if(cmd_flags
.q
== TRUE
&& some_tocs
== FALSE
)
2422 * If this is ranlib(1) and we are running in UNIX standard mode and
2423 * the file is not writeable just print and error message and return.
2425 if(cmd_flags
.ranlib
== TRUE
&&
2426 get_unix_standard_mode() == TRUE
&&
2427 access(output
, W_OK
) == -1){
2428 system_error("file: %s is not writable", output
);
2433 * If this is ranlib(1) and we have a thin archive that has an existing
2434 * table of contents see if we have enough room to update it in place.
2435 * Actually we check to see that we have the exact same number of
2436 * ranlib structs and string size, as this is the most common case that
2437 * the defined global symbols have not changed when rebuilding and it
2438 * will just be the offset to archive members that will have changed.
2440 if(cmd_flags
.ranlib
== TRUE
&& narchs
== 1 &&
2441 ofile
!= NULL
&& ofile
->toc_addr
!= NULL
&&
2442 ofile
->toc_bad
== FALSE
&&
2443 archs
[0].using_64toc
!= ofile
->toc_is_32bit
&&
2444 archs
[0].toc_nranlibs
== ofile
->toc_nranlibs
&&
2445 archs
[0].toc_strsize
== ofile
->toc_strsize
){
2448 * If the table of contents in the input does have a long name and
2449 * the one we built does not (or vice a versa) then don't update it
2452 if(strncmp(ofile
->toc_ar_hdr
->ar_name
, AR_EFMT1
,
2453 sizeof(AR_EFMT1
) - 1) == 0){
2454 if(archs
[0].toc_long_name
!= TRUE
)
2455 goto fail_to_update_toc_in_place
;
2458 if(archs
[0].toc_long_name
== TRUE
)
2459 goto fail_to_update_toc_in_place
;
2463 * The existing thin archive may not be laid out the same way as
2464 * libtool(1) would do it. As ar(1) does not know to pad things
2465 * so object files are on their natural alignment. So check to
2466 * see if the offsets are not the same and if the alignment is OK.
2468 different_offsets
= FALSE
;
2469 for(i
= 0; i
< archs
[0].nmembers
; i
++){
2470 if(archs
[0].members
[i
].input_member_offset
!=
2471 archs
[0].members
[i
].offset
){
2472 different_offsets
= TRUE
;
2474 * For now we will allow alignments of 4 bytes offsets even
2475 * though we would produce 8 byte alignments.
2477 if(archs
[0].members
[i
].input_member_offset
% 4 != 0){
2478 goto fail_to_update_toc_in_place
;
2484 * The time_offsets array records the offsets to the table of
2485 * contents archive header's ar_date fields. In this case we just
2486 * have one since this is a thin file (non-fat) file.
2488 time_offsets
= allocate(1 * sizeof(uint64_t));
2490 * Calculate the offset to the archive header's time field for the
2491 * table of contents.
2493 time_offsets
[0] = SARMAG
+
2494 ((char *)&toc_ar_hdr
.ar_date
- (char *)&toc_ar_hdr
);
2497 * If we had different member offsets in the input thin archive
2498 * we adjust the ranlib structs ran_off to use them.
2500 if(different_offsets
== TRUE
){
2502 if(archs
[0].using_64toc
== FALSE
){
2503 for(i
= 0; i
< archs
[0].toc_nranlibs
; i
++){
2504 for(j
= 0; j
< archs
[0].nmembers
; j
++){
2505 if(archs
[0].members
[j
].offset
==
2506 archs
[0].toc_ranlibs
[i
].ran_off
){
2507 archs
[0].toc_ranlibs
[i
].ran_off
=
2508 archs
[0].members
[j
].input_member_offset
;
2515 for(i
= 0; i
< archs
[0].toc_nranlibs
; i
++){
2516 for(j
= 0; j
< archs
[0].nmembers
; j
++){
2517 if(archs
[0].members
[j
].offset
==
2518 archs
[0].toc_ranlibs64
[i
].ran_off
){
2519 archs
[0].toc_ranlibs64
[i
].ran_off
=
2520 archs
[0].members
[j
].input_member_offset
;
2529 * If the new table of contents and the new string table are the
2530 * same as the old then the archive only needs to be "touched"
2531 * and the time field of the toc needs to be updated.
2534 for(i
= 0; i
< archs
[0].toc_nranlibs
; i
++){
2535 if(archs
[0].using_64toc
== FALSE
){
2536 if(archs
[0].toc_ranlibs
[i
].ran_un
.ran_strx
!=
2537 ofile
->toc_ranlibs
[i
].ran_un
.ran_strx
||
2538 archs
[0].toc_ranlibs
[i
].ran_off
!=
2539 ofile
->toc_ranlibs
[i
].ran_off
){
2545 if(archs
[0].toc_ranlibs64
[i
].ran_un
.ran_strx
!=
2546 ofile
->toc_ranlibs64
[i
].ran_un
.ran_strx
||
2547 archs
[0].toc_ranlibs64
[i
].ran_off
!=
2548 ofile
->toc_ranlibs64
[i
].ran_off
){
2554 if(same_toc
== TRUE
){
2555 for(i
= 0; i
< archs
[0].toc_strsize
; i
++){
2556 if(archs
[0].toc_strings
[i
] != ofile
->toc_strings
[i
]){
2564 library_size
= SARMAG
;
2565 if(same_toc
== FALSE
)
2566 library_size
+= archs
[0].toc_size
;
2567 if((r
= vm_allocate(mach_task_self(), (vm_address_t
*)&library
,
2568 library_size
, TRUE
)) != KERN_SUCCESS
)
2569 mach_fatal(r
, "can't vm_allocate() buffer for output file: %s "
2570 "of size %llu", output
, library_size
);
2573 /* put in the archive magic string in the buffer */
2575 memcpy(p
, ARMAG
, SARMAG
);
2578 /* put the table of contents in the buffer if needed */
2579 target_byte_sex
= get_target_byte_sex(archs
+ 0, host_byte_sex
);
2580 if(same_toc
== FALSE
)
2581 p
= put_toc_member(p
, archs
+0, host_byte_sex
, target_byte_sex
);
2583 if((fd
= open(output
, O_WRONLY
, 0)) == -1){
2584 system_error("can't open output file: %s", output
);
2587 if(write(fd
, library
, library_size
) != (int)library_size
){
2588 system_error("can't write output file: %s", output
);
2591 if(close(fd
) == -1){
2592 system_fatal("can't close output file: %s", output
);
2595 goto update_toc_ar_dates
;
2597 fail_to_update_toc_in_place
:
2600 * This buffer is vm_allocate'ed to make sure all holes are filled with
2603 if((r
= vm_allocate(mach_task_self(), (vm_address_t
*)&library
,
2604 library_size
, TRUE
)) != KERN_SUCCESS
)
2605 mach_fatal(r
, "can't vm_allocate() buffer for output file: %s of "
2606 "size %llu", output
, library_size
);
2609 * Create the output file. The unlink() is done to handle the problem
2610 * when the outputfile is not writable but the directory allows the
2611 * file to be removed (since the file may not be there the return code
2612 * of the unlink() is ignored).
2614 (void)unlink(output
);
2615 if((fd
= open(output
, O_WRONLY
| O_CREAT
| O_TRUNC
, 0666)) == -1){
2616 system_error("can't create output file: %s", output
);
2620 /* tell filesystem to NOT cache the file when reading or writing */
2621 (void)fcntl(fd
, F_NOCACHE
, 1);
2625 * If there is more than one architecture then fill in the fat file
2626 * header and the fat_arch or fat_arch64 structures in the buffer.
2629 fat_header
= (struct fat_header
*)library
;
2630 if(cmd_flags
.fat64
== TRUE
)
2631 fat_header
->magic
= FAT_MAGIC_64
;
2633 fat_header
->magic
= FAT_MAGIC
;
2634 fat_header
->nfat_arch
= narchs
;
2635 offset
= sizeof(struct fat_header
);
2636 if(cmd_flags
.fat64
== TRUE
){
2637 offset
+= sizeof(struct fat_arch_64
) * narchs
;
2638 fat_arch64
= (struct fat_arch_64
*)
2639 (library
+ sizeof(struct fat_header
));
2643 offset
+= sizeof(struct fat_arch
) * narchs
;
2644 fat_arch
= (struct fat_arch
*)
2645 (library
+ sizeof(struct fat_header
));
2648 for(i
= 0; i
< narchs
; i
++){
2649 if(cmd_flags
.fat64
== TRUE
){
2650 fat_arch64
[i
].cputype
= archs
[i
].arch_flag
.cputype
;
2651 fat_arch64
[i
].cpusubtype
= archs
[i
].arch_flag
.cpusubtype
;
2654 fat_arch
[i
].cputype
= archs
[i
].arch_flag
.cputype
;
2655 fat_arch
[i
].cpusubtype
= archs
[i
].arch_flag
.cpusubtype
;
2657 if(cmd_flags
.fat64
== FALSE
&& offset
> UINT32_MAX
)
2658 error("file too large to create as a fat file because "
2659 "offset field in struct fat_arch is only 32-bits and "
2660 "offset (%llu) to architecture %s exceeds that",
2661 offset
, archs
[i
].arch_flag
.name
);
2662 if(archs
[i
].arch_flag
.cputype
& CPU_ARCH_ABI64
){
2663 if(cmd_flags
.fat64
== TRUE
)
2664 fat_arch64
[i
].align
= 3;
2666 fat_arch
[i
].align
= 3;
2669 if(cmd_flags
.fat64
== TRUE
)
2670 fat_arch64
[i
].align
= 2;
2672 fat_arch
[i
].align
= 2;
2674 if(cmd_flags
.fat64
== TRUE
)
2675 offset
= rnd(offset
, 1 << fat_arch64
[i
].align
);
2677 offset
= rnd(offset
, 1 << fat_arch
[i
].align
);
2678 if(cmd_flags
.fat64
== TRUE
)
2679 fat_arch64
[i
].offset
= offset
;
2681 fat_arch
[i
].offset
= offset
;
2682 if(cmd_flags
.fat64
== FALSE
&& archs
[i
].size
> UINT32_MAX
)
2683 error("file too large to create as a fat file because "
2684 "size field in struct fat_arch is only 32-bits and "
2685 "size (%llu) of architecture %s exceeds that",
2686 archs
[i
].size
, archs
[i
].arch_flag
.name
);
2687 if(cmd_flags
.fat64
== TRUE
)
2688 fat_arch64
[i
].size
= archs
[i
].size
;
2690 fat_arch
[i
].size
= archs
[i
].size
;
2691 offset
+= archs
[i
].size
;
2694 (void)unlink(output
);
2697 #ifdef __LITTLE_ENDIAN__
2698 swap_fat_header(fat_header
, BIG_ENDIAN_BYTE_SEX
);
2699 if(cmd_flags
.fat64
== TRUE
)
2700 swap_fat_arch_64(fat_arch64
, narchs
, BIG_ENDIAN_BYTE_SEX
);
2702 swap_fat_arch(fat_arch
, narchs
, BIG_ENDIAN_BYTE_SEX
);
2703 #endif /* __LITTLE_ENDIAN__ */
2704 offset
= sizeof(struct fat_header
);
2705 if(cmd_flags
.fat64
== TRUE
)
2706 offset
+= sizeof(struct fat_arch_64
) * narchs
;
2708 offset
+= sizeof(struct fat_arch
) * narchs
;
2713 /* flush out the fat headers if any */
2714 output_flush(library
, library_size
, fd
, 0, offset
);
2717 * The time_offsets array records the offsets to the table of conternts
2718 * archive header's ar_date fields.
2720 time_offsets
= allocate(narchs
* sizeof(uint64_t));
2723 * Now put each arch in the buffer.
2725 for(i
= 0; i
< narchs
; i
++){
2727 if(narchs
> 1 && (arch
->arch_flag
.cputype
& CPU_ARCH_ABI64
)){
2728 pad
= rnd(offset
, 1 << 3) - offset
;
2729 output_flush(library
, library_size
, fd
, offset
, pad
);
2730 offset
= rnd(offset
, 1 << 3);
2732 p
= library
+ offset
;
2736 * If the input files only contains non-object files then the
2737 * byte sex of the output can't be determined which is needed for
2738 * the two binary long's of the table of contents. But since these
2739 * will be zero (the same in both byte sexes) because there are no
2740 * symbols in the table of contents if there are no object files.
2743 /* put in the archive magic string */
2744 memcpy(p
, ARMAG
, SARMAG
);
2748 * Warn for what really is a bad library that has an empty table of
2749 * contents but this is allowed in the original ranlib.
2751 if(arch
->toc_nranlibs
== 0 && cmd_flags
.q
== FALSE
){
2753 warning("warning for library: %s for architecture: %s the "
2754 "table of contents is empty (no object file members"
2755 " in the library define global symbols)", output
,
2756 arch
->arch_flag
.name
);
2758 warning("warning for library: %s the table of contents is "
2759 "empty (no object file members in the library "
2760 "define global symbols)", output
);
2764 * Pick the byte sex to write the table of contents in.
2766 target_byte_sex
= get_target_byte_sex(arch
, host_byte_sex
);
2769 * Remember the offset to the archive header's time field for this
2770 * arch's table of contents member.
2774 ((char *)&toc_ar_hdr
.ar_date
- (char *)&toc_ar_hdr
);
2777 * Put in the table of contents member in the output buffer.
2779 p
= put_toc_member(p
, arch
, host_byte_sex
, target_byte_sex
);
2781 output_flush(library
, library_size
, fd
, flush_start
- library
,
2785 * Put in the archive header and member contents for each member.
2787 for(j
= 0; j
< arch
->nmembers
; j
++){
2789 memcpy(p
, (char *)&(arch
->members
[j
].ar_hdr
),
2790 sizeof(struct ar_hdr
));
2791 p
+= sizeof(struct ar_hdr
);
2794 * If we are using extended format #1 for long names write out
2795 * the name. Note the name is padded with '\0' and the
2796 * member_name_size is the unrounded size.
2798 if(arch
->members
[j
].output_long_name
== TRUE
){
2799 strncpy(p
, arch
->members
[j
].member_name
,
2800 arch
->members
[j
].member_name_size
);
2801 p
+= rnd(arch
->members
[j
].member_name_size
, 8) +
2802 (rnd(sizeof(struct ar_hdr
), 8) -
2803 sizeof(struct ar_hdr
));
2807 * ofile_map swaps the headers to the host_byte_sex if the
2808 * object's byte sex is not the same as the host byte sex so
2809 * if this is the case swap them back before writing them out.
2811 if(arch
->members
[j
].mh
!= NULL
&&
2812 arch
->members
[j
].object_byte_sex
!= host_byte_sex
){
2813 if(swap_object_headers(arch
->members
[j
].mh
,
2814 arch
->members
[j
].load_commands
) == FALSE
)
2815 fatal("internal error: swap_object_headers() failed");
2817 else if(arch
->members
[j
].mh64
!= NULL
&&
2818 arch
->members
[j
].object_byte_sex
!= host_byte_sex
){
2819 if(swap_object_headers(arch
->members
[j
].mh64
,
2820 arch
->members
[j
].load_commands
) == FALSE
)
2821 fatal("internal error: swap_object_headers() failed");
2823 memcpy(p
, arch
->members
[j
].object_addr
,
2824 arch
->members
[j
].object_size
);
2825 #ifdef VM_SYNC_DEACTIVATE
2826 vm_msync(mach_task_self(),
2827 (vm_address_t
)arch
->members
[j
].object_addr
,
2828 (vm_size_t
)arch
->members
[j
].object_size
,
2829 VM_SYNC_DEACTIVATE
);
2830 #endif /* VM_SYNC_DEACTIVATE */
2831 p
+= arch
->members
[j
].object_size
;
2832 pad
= rnd(arch
->members
[j
].object_size
, 8) -
2833 arch
->members
[j
].object_size
;
2834 /* as with the UNIX ar(1) program pad with '\n' characters */
2835 for(k
= 0; k
< pad
; k
++)
2838 output_flush(library
, library_size
, fd
, flush_start
- library
,
2841 offset
+= arch
->size
;
2845 * Write the library to the file or flush the remaining buffer to the
2848 if(cmd_flags
.noflush
== TRUE
){
2849 if(write(fd
, library
, library_size
) != (int)library_size
){
2850 system_error("can't write output file: %s", output
);
2855 final_output_flush(library
, fd
);
2857 if(close(fd
) == -1){
2858 system_fatal("can't close output file: %s", output
);
2862 update_toc_ar_dates
:
2864 * Now that the library is created on the file system it is written
2865 * to get the time for the file on that file system.
2867 if(stat(output
, &stat_buf
) == -1){
2868 system_fatal("can't stat file output file: %s", output
);
2871 if((fd
= open(output
, O_WRONLY
, 0)) == -1){
2872 system_error("can't open output file: %s", output
);
2875 if(zero_ar_date
== TRUE
)
2876 stat_buf
.st_mtime
= 0;
2878 * With the time from the file system the library is on set the ar_date
2879 * using the modification time returned by stat. Then write this into
2880 * all the ar_date's in the file.
2882 sprintf((char *)(&toc_ar_hdr
), "%-*s%-*ld",
2883 (int)sizeof(toc_ar_hdr
.ar_name
),
2885 (int)sizeof(toc_ar_hdr
.ar_date
),
2886 (long int)stat_buf
.st_mtime
+ 5);
2887 for(i
= 0; i
< narchs
; i
++){
2888 if(lseek(fd
, time_offsets
[i
], L_SET
) == -1){
2889 system_error("can't lseek in output file: %s", output
);
2892 if(write(fd
, &toc_ar_hdr
.ar_date
, sizeof(toc_ar_hdr
.ar_date
)) !=
2893 sizeof(toc_ar_hdr
.ar_date
)){
2894 system_error("can't write to output file: %s", output
);
2898 if(close(fd
) == -1){
2899 system_fatal("can't close output file: %s", output
);
2903 * Now set the modtime of the created library back to it's stat time
2904 * when we first closed it.
2906 #ifndef __OPENSTEP__
2907 timep
.actime
= stat_buf
.st_mtime
;
2908 timep
.modtime
= stat_buf
.st_mtime
;
2909 if(utime(output
, &timep
) == -1)
2911 timep
[0] = stat_buf
.st_mtime
;
2912 timep
[1] = stat_buf
.st_mtime
;
2913 if(utime(output
, timep
) == -1)
2916 system_fatal("can't set the modifiy times in output file: %s",
2920 if((r
= vm_deallocate(mach_task_self(), (vm_address_t
)library
,
2921 library_size
)) != KERN_SUCCESS
){
2922 my_mach_error(r
, "can't vm_deallocate() buffer for output file");
2928 * get_target_byte_sex() pick the byte sex to write the table of contents in
2933 get_target_byte_sex(
2935 enum byte_sex host_byte_sex
)
2938 enum byte_sex target_byte_sex
;
2940 target_byte_sex
= UNKNOWN_BYTE_SEX
;
2942 i
< arch
->nmembers
&& target_byte_sex
== UNKNOWN_BYTE_SEX
;
2944 target_byte_sex
= arch
->members
[i
].object_byte_sex
;
2946 if(target_byte_sex
== UNKNOWN_BYTE_SEX
)
2947 target_byte_sex
= host_byte_sex
;
2948 return(target_byte_sex
);
2952 * put_toc_member() put the contents member for arch into the buffer p and
2953 * returns the pointer to the buffer after the table of contents.
2954 * The table of contents member uses either a 32-bit toc or a 64-bit toc.
2955 * Both forms start with:
2956 * the archive header
2957 * the archive member name (if using a long name)
2958 * then for a 32-bit toc the rest is this:
2959 * a uint32_t for the number of bytes of the ranlib structs
2960 * the ranlib structs
2961 * a uint32_t for the number of bytes of the strings for the ranlibs
2962 * the strings for the ranlib structs
2963 * and for a 64-bit toc the rest is this:
2964 * a uint64_t for the number of bytes of the ranlib structs
2965 * the ranlib_64 structs
2966 * a uint64_t for the number of bytes of the strings for the ranlibs
2967 * the strings for the ranlib structs
2974 enum byte_sex host_byte_sex
,
2975 enum byte_sex target_byte_sex
)
2980 memcpy(p
, (char *)&arch
->toc_ar_hdr
, sizeof(struct ar_hdr
));
2981 p
+= sizeof(struct ar_hdr
);
2983 if(arch
->toc_long_name
== TRUE
){
2984 memcpy(p
, arch
->toc_name
, arch
->toc_name_size
);
2985 p
+= arch
->toc_name_size
+
2986 (rnd(sizeof(struct ar_hdr
), 8) -
2987 sizeof(struct ar_hdr
));
2990 if(arch
->using_64toc
== FALSE
){
2991 l
= arch
->toc_nranlibs
* sizeof(struct ranlib
);
2992 if(target_byte_sex
!= host_byte_sex
)
2994 memcpy(p
, (char *)&l
, sizeof(uint32_t));
2995 p
+= sizeof(uint32_t);
2997 if(target_byte_sex
!= host_byte_sex
)
2998 swap_ranlib(arch
->toc_ranlibs
, arch
->toc_nranlibs
,
3000 memcpy(p
, (char *)arch
->toc_ranlibs
,
3001 arch
->toc_nranlibs
* sizeof(struct ranlib
));
3002 p
+= arch
->toc_nranlibs
* sizeof(struct ranlib
);
3004 l
= arch
->toc_strsize
;
3005 if(target_byte_sex
!= host_byte_sex
)
3007 memcpy(p
, (char *)&l
, sizeof(uint32_t));
3008 p
+= sizeof(uint32_t);
3010 memcpy(p
, (char *)arch
->toc_strings
, arch
->toc_strsize
);
3011 p
+= arch
->toc_strsize
;
3014 l64
= arch
->toc_nranlibs
* sizeof(struct ranlib_64
);
3015 if(target_byte_sex
!= host_byte_sex
)
3016 l64
= SWAP_LONG_LONG(l64
);
3017 memcpy(p
, (char *)&l64
, sizeof(uint64_t));
3018 p
+= sizeof(uint64_t);
3020 if(target_byte_sex
!= host_byte_sex
)
3021 swap_ranlib_64(arch
->toc_ranlibs64
, arch
->toc_nranlibs
,
3023 memcpy(p
, (char *)arch
->toc_ranlibs64
,
3024 arch
->toc_nranlibs
* sizeof(struct ranlib_64
));
3025 p
+= arch
->toc_nranlibs
* sizeof(struct ranlib_64
);
3027 l64
= arch
->toc_strsize
;
3028 if(target_byte_sex
!= host_byte_sex
)
3029 l64
= SWAP_LONG_LONG(l64
);
3030 memcpy(p
, (char *)&l64
, sizeof(uint64_t));
3031 p
+= sizeof(uint64_t);
3033 memcpy(p
, (char *)arch
->toc_strings
, arch
->toc_strsize
);
3034 p
+= arch
->toc_strsize
;
3041 * output_flush() takes an offset and a size of part of the output library,
3042 * known in the comments as the new area, and causes any fully flushed pages to
3043 * be written to the library file the new area in combination with previous
3044 * areas created. The data structure output_blocks has ordered blocks of areas
3045 * that have been flushed which are maintained by this routine. Any area can
3046 * only be flushed once and an error will result is the new area overlaps with a
3047 * previously flushed area.
3053 uint64_t library_size
,
3058 uint64_t write_offset
, write_size
, host_pagesize
;
3059 struct block
**p
, *block
, *before
, *after
;
3062 host_pagesize
= 0x2000;
3064 if(cmd_flags
.noflush
== TRUE
)
3067 if(offset
+ size
> library_size
)
3068 fatal("internal error: output_flush(offset = %llu, size = %llu) "
3069 "out of range for library_size = %llu", offset
, size
,
3073 if(cmd_flags
.debug
& (1 << 2))
3075 if(cmd_flags
.debug
& (1 << 1))
3076 printf("output_flush(offset = %llu, size %llu)", offset
, size
);
3081 if(cmd_flags
.debug
& (1 << 1))
3088 * Search through the ordered output blocks to find the block before the
3089 * new area and after the new area if any exist.
3093 p
= &(output_blocks
);
3096 if(offset
< block
->offset
){
3107 * Check for overlap of the new area with the block before and after the
3108 * new area if there are such blocks.
3111 if(before
->offset
+ before
->size
> offset
){
3112 warning("internal error: output_flush(offset = %llu, size = "
3113 "%llu) overlaps with flushed block(offset = %llu, "
3114 "size = %llu)", offset
, size
, before
->offset
,
3116 printf("calling abort()\n");
3121 if(offset
+ size
> after
->offset
){
3122 warning("internal error: output_flush(offset = %llu, size = "
3123 "%llu) overlaps with flushed block(offset = %llu, "
3124 "size = %llu)", offset
, size
, after
->offset
,
3126 printf("calling abort()\n");
3132 * Now see how the new area fits in with the blocks before and after it
3133 * (that is does it touch both, one or the other or neither blocks).
3134 * For each case first the offset and size to write (write_offset and
3135 * write_size) are set for the area of full pages that can now be
3136 * written from the block. Then the area written in the block
3137 * (->written_offset and ->written_size) are set to reflect the total
3138 * area in the block now written. Then offset and size the block
3139 * refers to (->offset and ->size) are set to total area of the block.
3140 * Finally the links to others blocks in the list are adjusted if a
3141 * block is added or removed.
3143 * See if there is a block before the new area and the new area
3144 * starts at the end of that block.
3146 if(before
!= NULL
&& before
->offset
+ before
->size
== offset
){
3148 * See if there is also a block after the new area and the new area
3149 * ends at the start of that block.
3151 if(after
!= NULL
&& offset
+ size
== after
->offset
){
3153 * This is the case where the new area exactly fill the area
3154 * between two existing blocks. The total area is folded into
3155 * the block before the new area and the block after the new
3156 * area is removed from the list.
3158 if(before
->offset
== 0 && before
->written_size
== 0){
3160 before
->written_offset
= 0;
3163 write_offset
=before
->written_offset
+ before
->written_size
;
3164 if(after
->written_size
== 0)
3165 write_size
= trnc(after
->offset
+ after
->size
-
3166 write_offset
, host_pagesize
);
3168 write_size
= trnc(after
->written_offset
- write_offset
,
3170 if(write_size
!= 0){
3171 before
->written_size
+= write_size
;
3173 if(after
->written_size
!= 0)
3174 before
->written_size
+= after
->written_size
;
3175 before
->size
+= size
+ after
->size
;
3177 /* remove the block after the new area */
3178 before
->next
= after
->next
;
3179 remove_block(after
);
3183 * This is the case where the new area starts at the end of the
3184 * block just before it but does not end where the block after
3185 * it (if any) starts. The new area is folded into the block
3186 * before the new area.
3188 write_offset
= before
->written_offset
+ before
->written_size
;
3189 write_size
= trnc(offset
+ size
- write_offset
, host_pagesize
);
3191 before
->written_size
+= write_size
;
3192 before
->size
+= size
;
3196 * See if the new area and the new area ends at the start of the block
3197 * after it (if any).
3199 else if(after
!= NULL
&& offset
+ size
== after
->offset
){
3201 * This is the case where the new area ends at the begining of the
3202 * block just after it but does not start where the block before it.
3203 * (if any) ends. The new area is folded into this block after the
3206 write_offset
= rnd(offset
, host_pagesize
);
3207 if(after
->written_size
== 0)
3208 write_size
= trnc(after
->offset
+ after
->size
- write_offset
,
3211 write_size
= trnc(after
->written_offset
- write_offset
,
3213 if(write_size
!= 0){
3214 after
->written_offset
= write_offset
;
3215 after
->written_size
+= write_size
;
3217 else if(write_offset
!= after
->written_offset
){
3218 after
->written_offset
= write_offset
;
3220 after
->offset
= offset
;
3221 after
->size
+= size
;
3225 * This is the case where the new area neither starts at the end of
3226 * the block just before it (if any) or ends where the block after
3227 * it (if any) starts. A new block is created and the new area is
3230 write_offset
= rnd(offset
, host_pagesize
);
3231 write_size
= trnc(offset
+ size
- write_offset
, host_pagesize
);
3232 block
= get_block();
3233 block
->offset
= offset
;
3235 block
->written_offset
= write_offset
;
3236 block
->written_size
= write_size
;
3238 * Insert this block in the ordered list in the correct place.
3241 block
->next
= before
->next
;
3242 before
->next
= block
;
3245 block
->next
= output_blocks
;
3246 output_blocks
= block
;
3251 * Now if there are full pages to write write them to the output file.
3253 if(write_size
!= 0){
3255 if((cmd_flags
.debug
& (1 << 1)) || (cmd_flags
.debug
& (1 << 0)))
3256 printf(" writing (write_offset = %llu write_size = %llu)\n",
3257 write_offset
, write_size
);
3259 lseek(fd
, write_offset
, L_SET
);
3260 if(write(fd
, library
+ write_offset
, write_size
) !=
3262 system_fatal("can't write to output file");
3263 if((r
= vm_deallocate(mach_task_self(), (vm_address_t
)(library
+
3264 write_offset
), write_size
)) != KERN_SUCCESS
)
3265 mach_fatal(r
, "can't vm_deallocate() buffer for output file");
3269 if(cmd_flags
.debug
& (1 << 1))
3270 printf(" no write\n");
3276 * final_output_flush() flushes the last part of the last page of the object
3277 * file if it does not round out to exactly a page.
3285 struct block
*block
;
3286 uint64_t write_offset
, write_size
;
3290 /* The compiler "warning: `write_offset' may be used uninitialized in */
3291 /* this function" can safely be ignored */
3293 if((cmd_flags
.debug
& (1 << 1)) || (cmd_flags
.debug
& (1 << 0))){
3294 printf("final_output_flush block_list:\n");
3300 block
= output_blocks
;
3302 if(block
->offset
!= 0)
3303 fatal("internal error: first block not at offset 0");
3304 if(block
->written_size
!= 0){
3305 if(block
->written_offset
!= 0)
3306 fatal("internal error: first block written_offset not 0");
3307 write_offset
= block
->written_size
;
3308 write_size
= block
->size
- block
->written_size
;
3311 write_offset
= block
->offset
;
3312 write_size
= block
->size
;
3314 if(block
->next
!= NULL
)
3315 fatal("internal error: more than one block in final list");
3317 if(write_size
!= 0){
3319 if((cmd_flags
.debug
& (1 << 1)) || (cmd_flags
.debug
& (1 << 1)))
3320 printf(" writing (write_offset = %llu write_size = %llu)\n",
3321 write_offset
, write_size
);
3323 lseek(fd
, write_offset
, L_SET
);
3324 if(write(fd
, library
+ write_offset
, write_size
) !=
3326 system_fatal("can't write to output file");
3327 if((r
= vm_deallocate(mach_task_self(), (vm_address_t
)(library
+
3328 write_offset
), write_size
)) != KERN_SUCCESS
)
3329 mach_fatal(r
, "can't vm_deallocate() buffer for output file");
3331 output_blocks
= NULL
;
3336 * print_block_list() prints the list of blocks. Used for debugging.
3340 print_block_list(void)
3342 struct block
**p
, *block
;
3344 p
= &(output_blocks
);
3346 printf("Empty block list\n");
3349 printf("block 0x%x\n", (unsigned long)block
);
3350 printf(" offset %llu\n", block
->offset
);
3351 printf(" size %llu\n", block
->size
);
3352 printf(" written_offset %llu\n", block
->written_offset
);
3353 printf(" written_size %llu\n", block
->written_size
);
3354 printf(" next 0x%x\n", (unsigned long)(block
->next
));
3361 * get_block() returns a pointer to a new block. This could be done by
3362 * allocating block of these placing them on a free list and and handing them
3363 * out. For the initial release of this code this number is typicly low and not
3364 * a big win so each block just allocated and free'ed.
3370 struct block
*block
;
3372 block
= allocate(sizeof(struct block
));
3377 * remove_block() throws away the block specified. See comments in get_block().
3382 struct block
*block
)
3388 * trnc() truncates the value 'v' to the power of two value 'r'. If v is
3389 * less than zero it returns zero.
3397 if(((int32_t)v
) < 0)
3399 return(v
& ~(r
- 1));
3403 * create_dynamic_shared_library() creates a dynamic shared library from the
3404 * data structure pointed to by archs into the specified output file. Only
3405 * when more than one architecture is in archs will a fat file be created.
3409 create_dynamic_shared_library(
3414 struct stat stat_buf
;
3415 enum bool use_force_cpusubtype_ALL
;
3416 const struct arch_flag
*family_arch_flag
;
3419 * If there is more than one architecture setup a signal handler to
3420 * clean up the temporary files in case we get a signal.
3423 signal(SIGINT
, create_dynamic_shared_library_cleanup
);
3426 * If -arch_only is specified with a specific cpusubtype other than the
3427 * family cpusubtype do not use -force_cpusubtype_ALL as the user wants
3428 * the output to be tagged with that cpusubtype.
3430 use_force_cpusubtype_ALL
= TRUE
;
3431 if(cmd_flags
.arch_only_flag
.name
!= NULL
){
3432 family_arch_flag
= get_arch_family_from_cputype(
3433 cmd_flags
.arch_only_flag
.cputype
);
3434 if(family_arch_flag
!= NULL
){
3435 if((family_arch_flag
->cpusubtype
& ~CPU_SUBTYPE_MASK
) !=
3436 (cmd_flags
.arch_only_flag
.cpusubtype
& ~CPU_SUBTYPE_MASK
))
3437 use_force_cpusubtype_ALL
= FALSE
;
3442 * For each architecture run ld(1) -dylib to create the dynamic shared
3445 for(i
= 0; i
< narchs
|| (i
== 0 && narchs
== 0); i
++){
3446 reset_execute_list();
3447 add_execute_list_with_prefix("ld");
3448 if(narchs
!= 0 && cmd_flags
.arch_only_flag
.name
== NULL
)
3449 add_execute_list("-arch_multiple");
3451 add_execute_list("-arch");
3452 if(use_force_cpusubtype_ALL
== TRUE
)
3453 add_execute_list(archs
[i
].arch_flag
.name
);
3455 add_execute_list(cmd_flags
.arch_only_flag
.name
);
3457 add_execute_list("-dylib");
3458 add_execute_list("-dynamic");
3459 if(cmd_flags
.all_load_flag_specified
== FALSE
||
3460 cmd_flags
.all_load
== TRUE
)
3461 add_execute_list("-all_load");
3462 if(use_force_cpusubtype_ALL
== TRUE
)
3463 add_execute_list("-force_cpusubtype_ALL");
3464 add_execute_list("-no_arch_warnings");
3465 if(cmd_flags
.seg1addr
!= NULL
){
3466 add_execute_list("-seg1addr");
3467 add_execute_list(cmd_flags
.seg1addr
);
3469 if(cmd_flags
.segs_read_only_addr
!= NULL
){
3470 add_execute_list("-segs_read_only_addr");
3471 add_execute_list(cmd_flags
.segs_read_only_addr
);
3473 if(cmd_flags
.segs_read_write_addr
!= NULL
){
3474 add_execute_list("-segs_read_write_addr");
3475 add_execute_list(cmd_flags
.segs_read_write_addr
);
3477 if(cmd_flags
.seg_addr_table
!= NULL
){
3478 add_execute_list("-seg_addr_table");
3479 add_execute_list(cmd_flags
.seg_addr_table
);
3481 if(cmd_flags
.seg_addr_table_filename
!= NULL
){
3482 add_execute_list("-seg_addr_table_filename");
3483 add_execute_list(cmd_flags
.seg_addr_table_filename
);
3485 if(cmd_flags
.compatibility
!= NULL
){
3486 add_execute_list("-dylib_compatibility_version");
3487 add_execute_list(cmd_flags
.compatibility
);
3489 if(cmd_flags
.current
!= NULL
){
3490 add_execute_list("-dylib_current_version");
3491 add_execute_list(cmd_flags
.current
);
3493 if(cmd_flags
.install_name
!= NULL
){
3494 add_execute_list("-dylib_install_name");
3495 add_execute_list(cmd_flags
.install_name
);
3499 add_execute_list("-dylib_install_name");
3500 add_execute_list(cmd_flags
.output
);
3503 for(j
= 0; j
< cmd_flags
.nldflags
; j
++)
3504 add_execute_list(cmd_flags
.ldflags
[j
]);
3505 for(j
= 0; j
< cmd_flags
.nLdirs
; j
++)
3506 add_execute_list(cmd_flags
.Ldirs
[j
]);
3508 // Support using libtool on a systems without the SDK in '/'. This
3509 // works because the shims that are included in 10.9 and forwards
3510 // automatically inject SDKROOT into the environment of the actual
3511 // tools. See <rdar://problem/14264125>.
3512 const char *sdkroot
= getenv("SDKROOT");
3514 // If the SDKROOT environment variable is set and is an absolute
3515 // path, then see if we can find dylib1.o inside it and use that if
3517 enum bool use_dashl_dylib1o
= TRUE
;
3518 if (sdkroot
&& sdkroot
[0] == '/') {
3519 // Construct the path to the object file.
3520 char *sdk_dylib1o_path
;
3521 int res
= asprintf(&sdk_dylib1o_path
, "%s/usr/lib/dylib1.o",
3523 if (res
> 0 && sdk_dylib1o_path
) {
3525 // Add the full path if it exists.
3526 if (stat(sdk_dylib1o_path
, &s
) == 0) {
3527 add_execute_list(sdk_dylib1o_path
);
3528 use_dashl_dylib1o
= FALSE
;
3530 free(sdk_dylib1o_path
);
3535 for(j
= 0; j
< cmd_flags
.nfiles
; j
++){
3536 if(cmd_flags
.filelist
[j
] == NULL
){
3537 add_execute_list(cmd_flags
.files
[j
]);
3540 if(cmd_flags
.filelist
[j
] != filelist
){
3541 add_execute_list("-filelist");
3542 add_execute_list(cmd_flags
.filelist
[j
]);
3543 filelist
= cmd_flags
.filelist
[j
];
3548 add_execute_list("-o");
3549 add_execute_list(cmd_flags
.output
);
3552 add_execute_list("-o");
3553 add_execute_list(makestr(cmd_flags
.output
, ".libtool.",
3554 archs
[i
].arch_flag
.name
, NULL
));
3555 if(cmd_flags
.final_output_specified
== FALSE
){
3556 add_execute_list("-final_output");
3557 add_execute_list(cmd_flags
.output
);
3560 if(execute_list(cmd_flags
.verbose
) == 0)
3561 fatal("internal link edit command failed");
3564 * If there is more than one architecture then run lipo to put them
3568 reset_execute_list();
3569 add_execute_list_with_prefix("lipo");
3570 add_execute_list("-create");
3571 add_execute_list("-output");
3572 add_execute_list(cmd_flags
.output
);
3573 for(i
= 0; i
< narchs
; i
++){
3574 add_execute_list(makestr(cmd_flags
.output
, ".libtool.",
3575 archs
[i
].arch_flag
.name
, NULL
));
3577 if(execute_list(cmd_flags
.verbose
) == 0)
3578 fatal("internal lipo command failed");
3579 for(i
= 0; i
< narchs
; i
++){
3580 p
= makestr(cmd_flags
.output
, ".libtool.",
3581 archs
[i
].arch_flag
.name
, NULL
);
3582 if(unlink(p
) == -1){
3583 error("can't remove temporary file: %s", p
);
3588 * If we are doing prebinding then run objcunique on the
3591 if(cmd_flags
.prebinding
== TRUE
){
3592 if(stat("/usr/bin/objcunique", &stat_buf
) != -1){
3593 reset_execute_list();
3594 add_execute_list_with_prefix("objcunique");
3595 add_execute_list(cmd_flags
.output
);
3596 add_execute_list("-prebind");
3597 for(j
= 0; j
< cmd_flags
.nLdirs
; j
++)
3598 add_execute_list(cmd_flags
.Ldirs
[j
]);
3599 if(execute_list(cmd_flags
.verbose
) == 0)
3600 fatal("internal objcunique command failed");
3606 * create_dynamic_shared_library_cleanup() is the signal handler to remove the
3607 * temporary files if more than one arch is being used.
3611 create_dynamic_shared_library_cleanup(
3616 for(i
= 0; i
< narchs
; i
++){
3617 (void)unlink(makestr(cmd_flags
.output
, ".libtool.",
3618 archs
[i
].arch_flag
.name
, NULL
));
3624 * make_table_of_contents() make the table of contents for the specified arch
3625 * and fills in the toc_* fields in the arch. Output is the name of the output
3626 * file for error messages.
3630 make_table_of_contents(
3634 uint32_t i
, j
, k
, r
, s
, nsects
, ncmds
, n_strx
;
3635 struct member
*member
;
3636 struct load_command
*lc
;
3637 struct segment_command
*sg
;
3638 struct segment_command_64
*sg64
;
3639 struct nlist
*symbols
;
3640 struct nlist_64
*symbols64
;
3642 enum bool sorted
, is_toc_symbol
;
3644 struct section
*section
;
3645 struct section_64
*section64
;
3646 uint8_t n_type
, n_sect
;
3648 char *lto_toc_string
;
3649 #endif /* LTO_SUPPORT */
3654 * First pass over the members to count how many ranlib structs are
3655 * needed and the size of the strings in the toc that are needed.
3657 for(i
= 0; i
< arch
->nmembers
; i
++){
3658 member
= arch
->members
+ i
;
3659 if(member
->mh
!= NULL
|| member
->mh64
!= NULL
){
3661 lc
= member
->load_commands
;
3662 if(member
->mh
!= NULL
)
3663 ncmds
= member
->mh
->ncmds
;
3665 ncmds
= member
->mh64
->ncmds
;
3666 for(j
= 0; j
< ncmds
; j
++){
3667 if(lc
->cmd
== LC_SYMTAB
){
3668 if(member
->st
== NULL
)
3669 member
->st
= (struct symtab_command
*)lc
;
3671 else if(lc
->cmd
== LC_SEGMENT
){
3672 sg
= (struct segment_command
*)lc
;
3673 nsects
+= sg
->nsects
;
3675 else if(lc
->cmd
== LC_SEGMENT_64
){
3676 sg64
= (struct segment_command_64
*)lc
;
3677 nsects
+= sg64
->nsects
;
3679 lc
= (struct load_command
*)((char *)lc
+ lc
->cmdsize
);
3681 if(member
->mh
!= NULL
)
3682 member
->sections
= allocate(nsects
*
3683 sizeof(struct section
*));
3685 member
->sections64
= allocate(nsects
*
3686 sizeof(struct section_64
*));
3688 lc
= member
->load_commands
;
3689 for(j
= 0; j
< ncmds
; j
++){
3690 if(lc
->cmd
== LC_SEGMENT
){
3691 sg
= (struct segment_command
*)lc
;
3692 section
= (struct section
*)
3693 ((char *)sg
+ sizeof(struct segment_command
));
3694 for(k
= 0; k
< sg
->nsects
; k
++){
3695 member
->sections
[nsects
++] = section
++;
3698 else if(lc
->cmd
== LC_SEGMENT_64
){
3699 sg64
= (struct segment_command_64
*)lc
;
3700 section64
= (struct section_64
*)
3701 ((char *)sg64
+ sizeof(struct segment_command_64
));
3702 for(k
= 0; k
< sg64
->nsects
; k
++){
3703 member
->sections64
[nsects
++] = section64
++;
3706 lc
= (struct load_command
*)((char *)lc
+ lc
->cmdsize
);
3708 if(member
->st
!= NULL
&& member
->st
->nsyms
!= 0){
3709 if(member
->mh
!= NULL
){
3710 symbols
= (struct nlist
*)(member
->object_addr
+
3711 member
->st
->symoff
);
3712 if(member
->object_byte_sex
!= get_host_byte_sex())
3713 swap_nlist(symbols
, member
->st
->nsyms
,
3714 get_host_byte_sex());
3717 symbols64
= (struct nlist_64
*)(member
->object_addr
+
3718 member
->st
->symoff
);
3719 if(member
->object_byte_sex
!= get_host_byte_sex())
3720 swap_nlist_64(symbols64
, member
->st
->nsyms
,
3721 get_host_byte_sex());
3723 strings
= member
->object_addr
+ member
->st
->stroff
;
3724 for(j
= 0; j
< member
->st
->nsyms
; j
++){
3725 if(member
->mh
!= NULL
){
3726 n_strx
= symbols
[j
].n_un
.n_strx
;
3727 n_type
= symbols
[j
].n_type
;
3728 n_sect
= symbols
[j
].n_sect
;
3731 n_strx
= symbols64
[j
].n_un
.n_strx
;
3732 n_type
= symbols64
[j
].n_type
;
3733 n_sect
= symbols64
[j
].n_sect
;
3735 if(n_strx
> member
->st
->strsize
){
3736 warn_member(arch
, member
, "malformed object "
3737 "(symbol %u n_strx field extends past the "
3738 "end of the string table)", j
);
3742 if((n_type
& N_TYPE
) == N_SECT
){
3743 if(n_sect
== NO_SECT
){
3744 warn_member(arch
, member
, "malformed object "
3745 "(symbol %u must not have NO_SECT for its "
3746 "n_sect field given its type (N_SECT))", j
);
3750 if(n_sect
> nsects
){
3751 warn_member(arch
, member
, "malformed object "
3752 "(symbol %u n_sect field greater than the "
3753 "number of sections in the file)", j
);
3758 if(member
->mh
!= NULL
)
3759 is_toc_symbol
= toc_symbol(symbols
+ j
,
3762 is_toc_symbol
= toc_symbol_64(symbols64
+ j
,
3763 member
->sections64
);
3764 if(is_toc_symbol
== TRUE
){
3765 arch
->toc_nranlibs
++;
3766 arch
->toc_strsize
+= strlen(strings
+ n_strx
) + 1;
3771 if(cmd_flags
.no_warning_for_no_symbols
== FALSE
)
3772 warn_member(arch
, member
, "has no symbols");
3776 else if(member
->lto_contents
== TRUE
){
3777 arch
->toc_nranlibs
+= member
->lto_toc_nsyms
;
3778 arch
->toc_strsize
+= member
->lto_toc_strsize
;
3780 #endif /* LTO_SUPPORT */
3782 if(cmd_flags
.ranlib
== FALSE
){
3783 warn_member(arch
, member
, "is not an object file");
3792 * Allocate the space for the ranlib structs and strings for the
3793 * table of contents.
3795 arch
->toc_ranlibs
= allocate(sizeof(struct ranlib
) *arch
->toc_nranlibs
);
3796 arch
->tocs
= allocate(sizeof(struct toc
) * arch
->toc_nranlibs
);
3797 arch
->toc_strsize
= rnd(arch
->toc_strsize
, 8);
3798 arch
->toc_strings
= allocate(arch
->toc_strsize
);
3799 if(arch
->toc_strsize
>= 8)
3800 memset(arch
->toc_strings
+ arch
->toc_strsize
- 7, '\0', 7);
3803 * Second pass over the members to fill in the toc structs and
3804 * the strings for the table of contents. The toc name field is
3805 * filled in with a pointer to a string contained in arch->toc_strings
3806 * for easy sorting and conversion to an index. The toc index1 field is
3807 * filled in with the member index plus one to allow marking with it's
3808 * negative value by check_sort_tocs() and easy conversion to the
3813 for(i
= 0; i
< arch
->nmembers
; i
++){
3814 member
= arch
->members
+ i
;
3815 if(member
->mh
!= NULL
|| member
->mh64
!= NULL
){
3816 if(member
->st
!= NULL
&& member
->st
->nsyms
!= 0){
3817 if(member
->mh
!= NULL
)
3818 symbols
= (struct nlist
*)(member
->object_addr
+
3819 member
->st
->symoff
);
3821 symbols64
= (struct nlist_64
*)(member
->object_addr
+
3822 member
->st
->symoff
);
3823 strings
= member
->object_addr
+ member
->st
->stroff
;
3824 for(j
= 0; j
< member
->st
->nsyms
; j
++){
3825 if(member
->mh
!= NULL
)
3826 n_strx
= symbols
[j
].n_un
.n_strx
;
3828 n_strx
= symbols64
[j
].n_un
.n_strx
;
3829 if(n_strx
> member
->st
->strsize
)
3831 if(member
->mh
!= NULL
)
3832 is_toc_symbol
= toc_symbol(symbols
+ j
,
3835 is_toc_symbol
= toc_symbol_64(symbols64
+ j
,
3836 member
->sections64
);
3837 if(is_toc_symbol
== TRUE
){
3838 strcpy(arch
->toc_strings
+ s
,
3840 arch
->tocs
[r
].name
= arch
->toc_strings
+ s
;
3841 arch
->tocs
[r
].index1
= i
+ 1;
3843 s
+= strlen(strings
+ n_strx
) + 1;
3846 if(member
->object_byte_sex
!= get_host_byte_sex()){
3847 if(member
->mh
!= NULL
)
3848 swap_nlist(symbols
, member
->st
->nsyms
,
3849 member
->object_byte_sex
);
3851 swap_nlist_64(symbols64
, member
->st
->nsyms
,
3852 member
->object_byte_sex
);
3857 else if(member
->lto_contents
== TRUE
){
3858 lto_toc_string
= member
->lto_toc_strings
;
3859 for(j
= 0; j
< member
->lto_toc_nsyms
; j
++){
3860 strcpy(arch
->toc_strings
+ s
, lto_toc_string
);
3861 arch
->tocs
[r
].name
= arch
->toc_strings
+ s
;
3862 arch
->tocs
[r
].index1
= i
+ 1;
3864 s
+= strlen(lto_toc_string
) + 1;
3865 lto_toc_string
+= strlen(lto_toc_string
) + 1;
3868 #endif /* LTO_SUPPORT */
3872 * If the table of contents is to be sorted by symbol name then try to
3873 * sort it and leave it sorted if no duplicates.
3875 if(cmd_flags
.s
== TRUE
){
3876 qsort(arch
->tocs
, arch
->toc_nranlibs
, sizeof(struct toc
),
3877 (int (*)(const void *, const void *))toc_name_qsort
);
3878 sorted
= check_sort_tocs(arch
, output
, FALSE
);
3879 if(sorted
== FALSE
){
3880 qsort(arch
->tocs
, arch
->toc_nranlibs
, sizeof(struct toc
),
3881 (int (*)(const void *, const void *))toc_index1_qsort
);
3882 arch
->toc_name
= SYMDEF
;
3883 arch
->toc_name_size
= sizeof(SYMDEF
) - 1;
3884 if(cmd_flags
.use_long_names
== TRUE
){
3885 arch
->toc_long_name
= TRUE
;
3887 * This assumes that "__.SYMDEF\0\0\0\0\0\0\0" is 16 bytes
3889 * (rnd(sizeof(struct ar_hdr), 8) - sizeof(struct ar_hdr)
3892 ar_name
= AR_EFMT1
"20";
3893 arch
->toc_name_size
= 16;
3894 arch
->toc_name
= SYMDEF
"\0\0\0\0\0\0\0";
3897 arch
->toc_long_name
= FALSE
;
3898 ar_name
= arch
->toc_name
;
3903 * Since the SYMDEF_SORTED is "__.SYMDEF SORTED" which contains
3904 * a space, it should use extended format #1 if we can use long
3907 arch
->toc_name
= SYMDEF_SORTED
;
3908 arch
->toc_name_size
= sizeof(SYMDEF_SORTED
) - 1;
3909 if(cmd_flags
.use_long_names
== TRUE
){
3910 arch
->toc_long_name
= TRUE
;
3912 * This assumes that "__.SYMDEF SORTED" is 16 bytes and
3913 * (rnd(sizeof(struct ar_hdr), 8) - sizeof(struct ar_hdr)
3916 ar_name
= AR_EFMT1
"20";
3919 arch
->toc_long_name
= FALSE
;
3920 ar_name
= arch
->toc_name
;
3926 arch
->toc_name
= SYMDEF
;
3927 arch
->toc_name_size
= sizeof(SYMDEF
) - 1;
3928 if(cmd_flags
.use_long_names
== TRUE
){
3929 arch
->toc_long_name
= TRUE
;
3931 * This assumes that "__.SYMDEF\0\0\0\0\0\0\0" is 16 bytes and
3932 * (rnd(sizeof(struct ar_hdr), 8) - sizeof(struct ar_hdr)
3935 ar_name
= AR_EFMT1
"20";
3936 arch
->toc_name_size
= 16;
3937 arch
->toc_name
= SYMDEF
"\0\0\0\0\0\0\0";
3940 arch
->toc_long_name
= FALSE
;
3941 ar_name
= arch
->toc_name
;
3946 * Now set the ran_off and ran_un.ran_strx fields of the ranlib structs.
3947 * To do this the size of the toc member must be know because it comes
3948 * first in the library. The size of the toc member is made up of the
3949 * sizeof an archive header struct (the size of the name if a long name
3950 * is used) then the toc which is (as defined in ranlib.h):
3951 * a uint32_t for the number of bytes of the ranlib structs
3952 * the ranlib structures
3953 * a uint32_t for the number of bytes of the strings
3956 arch
->toc_size
= sizeof(struct ar_hdr
) +
3958 arch
->toc_nranlibs
* sizeof(struct ranlib
) +
3961 /* add the size of the name is a long name is used */
3962 if(arch
->toc_long_name
== TRUE
)
3963 arch
->toc_size
+= arch
->toc_name_size
+
3964 (rnd(sizeof(struct ar_hdr
), 8) -
3965 sizeof(struct ar_hdr
));
3968 * Now with the size of the 32-bit toc known we can now see if it will
3969 * work or if we have offsets to members that are more than 32-bits and
3970 * we need to switch to the 64-bit toc, or switch to that if we are
3971 * forcing a 64-bit toc via the command line option.
3973 if(cmd_flags
.toc64
== TRUE
)
3974 arch
->using_64toc
= TRUE
;
3976 arch
->using_64toc
= FALSE
;
3977 for(i
= 0; i
< arch
->nmembers
; i
++){
3978 if(arch
->members
[i
].offset
+ SARMAG
+ arch
->toc_size
>
3980 arch
->using_64toc
= TRUE
;
3985 if(arch
->using_64toc
){
3986 if(cmd_flags
.use_long_names
== FALSE
&&
3987 cmd_flags
.L_or_T_specified
== TRUE
)
3988 fatal("archive requires a 64-bit toc that must be aligned so "
3989 "-T can't be specified");
3990 arch
->toc_long_name
= TRUE
;
3991 if(sorted
== FALSE
){
3993 * This assumes that "__.SYMDEF_64\0\0\0\0" is 16 bytes
3995 * (rnd(sizeof(struct ar_hdr), 8) - sizeof(struct ar_hdr)
3998 ar_name
= AR_EFMT1
"20";
3999 arch
->toc_name_size
= 16;
4000 arch
->toc_name
= SYMDEF_64
"\0\0\0\0";
4003 arch
->toc_name
= SYMDEF_64_SORTED
;
4004 arch
->toc_name_size
= sizeof(SYMDEF_64_SORTED
) - 1;
4006 * This assumes that "__.SYMDEF_64 SORTED\0\0\0\0\0" is 24 bytes
4008 * (rnd(sizeof(struct ar_hdr), 8) - sizeof(struct ar_hdr)
4011 ar_name
= AR_EFMT1
"28";
4012 arch
->toc_name_size
= 24;
4013 arch
->toc_name
= SYMDEF_64_SORTED
"\0\0\0\0\0";
4016 * Free the space for the 32-bit ranlib structs and allocate space
4017 * for the 64-bit ranlib structs.
4019 free(arch
->toc_ranlibs
);
4020 arch
->toc_ranlibs
= NULL
;
4021 arch
->toc_ranlibs64
= allocate(sizeof(struct ranlib_64
) *
4022 arch
->toc_nranlibs
);
4024 * Now the size of the toc member when it is a 64-bit toc can be
4025 * set. It is made up of the sizeof an archive header struct (the
4026 * size of the name which is always a long name to get 8-byte
4027 * alignment then the toc which is (as defined in ranlib.h):
4028 * a uint64_t for the number of bytes of the ranlib_64 structs
4029 * the ranlib_64 structures
4030 * a uint64_t for the number of bytes of the strings
4033 arch
->toc_size
= sizeof(struct ar_hdr
) +
4035 arch
->toc_nranlibs
* sizeof(struct ranlib_64
) +
4038 /* add the size of the name as a long name is always used */
4039 arch
->toc_size
+= arch
->toc_name_size
+
4040 (rnd(sizeof(struct ar_hdr
), 8) -
4041 sizeof(struct ar_hdr
));
4044 for(i
= 0; i
< arch
->nmembers
; i
++)
4045 arch
->members
[i
].offset
+= SARMAG
+ arch
->toc_size
;
4047 for(i
= 0; i
< arch
->toc_nranlibs
; i
++){
4048 if(arch
->using_64toc
){
4049 arch
->toc_ranlibs64
[i
].ran_un
.ran_strx
=
4050 arch
->tocs
[i
].name
- arch
->toc_strings
;
4051 arch
->toc_ranlibs64
[i
].ran_off
=
4052 arch
->members
[arch
->tocs
[i
].index1
- 1].offset
;
4055 arch
->toc_ranlibs
[i
].ran_un
.ran_strx
=
4056 arch
->tocs
[i
].name
- arch
->toc_strings
;
4057 arch
->toc_ranlibs
[i
].ran_off
=
4058 arch
->members
[arch
->tocs
[i
].index1
- 1].offset
;
4062 sprintf((char *)(&arch
->toc_ar_hdr
), "%-*s%-*ld%-*u%-*u%-*o%-*ld",
4063 (int)sizeof(arch
->toc_ar_hdr
.ar_name
),
4065 (int)sizeof(arch
->toc_ar_hdr
.ar_date
),
4067 (int)sizeof(arch
->toc_ar_hdr
.ar_uid
),
4068 (unsigned short)getuid(),
4069 (int)sizeof(arch
->toc_ar_hdr
.ar_gid
),
4070 (unsigned short)getgid(),
4071 (int)sizeof(arch
->toc_ar_hdr
.ar_mode
),
4072 (unsigned int)toc_mode
,
4073 (int)sizeof(arch
->toc_ar_hdr
.ar_size
),
4074 (long)(arch
->toc_size
- sizeof(struct ar_hdr
)));
4076 * This has to be done by hand because sprintf puts a null
4077 * at the end of the buffer.
4079 memcpy(arch
->toc_ar_hdr
.ar_fmag
, ARFMAG
,
4080 (int)sizeof(arch
->toc_ar_hdr
.ar_fmag
));
4085 * save_lto_member_toc_info() saves away the table of contents info for a
4086 * member that has lto_content. This allows the lto module to be disposed of
4087 * after reading to keep only on in memory at a time. As these turn out to
4088 * use a lot of memory.
4092 save_lto_member_toc_info(
4093 struct member
*member
,
4099 member
->lto_toc_nsyms
= 0;
4100 nsyms
= lto_get_nsyms(mod
);
4101 for(i
= 0; i
< nsyms
; i
++){
4102 if(lto_toc_symbol(mod
, i
, cmd_flags
.c
) == TRUE
){
4103 member
->lto_toc_nsyms
++;
4104 member
->lto_toc_strsize
+= strlen(lto_symbol_name(mod
, i
)) + 1;
4107 member
->lto_toc_strings
= allocate(member
->lto_toc_strsize
);
4108 s
= member
->lto_toc_strings
;
4109 for(i
= 0; i
< nsyms
; i
++){
4110 if(lto_toc_symbol(mod
, i
, cmd_flags
.c
) == TRUE
){
4111 strcpy(s
, lto_symbol_name(mod
, i
));
4112 s
+= strlen(lto_symbol_name(mod
, i
)) + 1;
4116 #endif /* LTO_SUPPORT */
4119 * Function for qsort() for comparing toc structures by name.
4124 const struct toc
*toc1
,
4125 const struct toc
*toc2
)
4127 return(strcmp(toc1
->name
, toc2
->name
));
4131 * Function for qsort() for comparing toc structures by index1.
4136 const struct toc
*toc1
,
4137 const struct toc
*toc2
)
4139 if(toc1
->index1
< toc2
->index1
)
4141 if(toc1
->index1
> toc2
->index1
)
4143 /* toc1->index1 == toc2->index1 */
4148 * toc_symbol() returns TRUE if the symbol is to be included in the table of
4149 * contents otherwise it returns FALSE.
4154 struct nlist
*symbol
,
4155 struct section
**sections
)
4157 return(toc(symbol
->n_un
.n_strx
,
4160 (symbol
->n_type
& N_TYPE
) == N_SECT
&&
4161 sections
[symbol
->n_sect
- 1]->flags
& S_ATTR_NO_TOC
));
4167 struct nlist_64
*symbol64
,
4168 struct section_64
**sections64
)
4170 return(toc(symbol64
->n_un
.n_strx
,
4173 (symbol64
->n_type
& N_TYPE
) == N_SECT
&&
4174 sections64
[symbol64
->n_sect
-1]->flags
& S_ATTR_NO_TOC
));
4183 enum bool attr_no_toc
)
4185 /* if the name is NULL then it won't be in the table of contents */
4188 /* if symbol is not external then it won't be in the toc */
4189 if((n_type
& N_EXT
) == 0)
4191 /* if symbol is undefined then it won't be in the toc */
4192 if((n_type
& N_TYPE
) == N_UNDF
&& n_value
== 0)
4194 /* if symbol is common and the -c flag is not specified then ... */
4195 if((n_type
& N_TYPE
) == N_UNDF
&& n_value
!= 0 &&
4196 cmd_flags
.c
== FALSE
)
4198 /* if the symbols is in a section marked NO_TOC then ... */
4199 if(attr_no_toc
!= 0)
4206 * check_sort_tocs() checks the table of contents for the specified arch
4207 * which is sorted by name for more then one object defining the same symbol.
4208 * It this is the case it prints each symbol that is defined in more than one
4209 * object along with the object it is defined in. It returns TRUE if there are
4210 * no multiple definitions and FALSE otherwise.
4217 enum bool library_warnings
)
4220 enum bool multiple_defs
;
4221 struct member
*member
;
4223 if(arch
->toc_nranlibs
== 0)
4226 * Since the symbol table is sorted by name look to any two adjcent
4227 * entries with the same name. If such entries are found print them
4228 * only once (marked by changing the sign of their ran_off).
4230 multiple_defs
= FALSE
;
4231 for(i
= 0; i
< arch
->toc_nranlibs
- 1; i
++){
4232 if(strcmp(arch
->tocs
[i
].name
, arch
->tocs
[i
+1].name
) == 0){
4233 if(multiple_defs
== FALSE
){
4234 if(library_warnings
== FALSE
)
4236 fprintf(stderr
, "%s: same symbol defined in more than one "
4239 fprintf(stderr
, "for architecture: %s ",
4240 arch
->arch_flag
.name
);
4241 fprintf(stderr
, "in: %s (table of contents will not be "
4242 "sorted)\n", output
);
4243 multiple_defs
= TRUE
;
4245 if((int)(arch
->tocs
[i
].index1
) > 0){
4246 member
= arch
->members
+ arch
->tocs
[i
].index1
- 1;
4247 warn_member(arch
, member
, "defines symbol: %s",
4248 arch
->tocs
[i
].name
);
4249 arch
->tocs
[i
].index1
=
4250 -(arch
->tocs
[i
].index1
);
4252 if((int)(arch
->tocs
[i
+1].index1
) > 0){
4253 member
= arch
->members
+ arch
->tocs
[i
+1].index1
- 1;
4254 warn_member(arch
, member
, "defines symbol: %s",
4255 arch
->tocs
[i
+1].name
);
4256 arch
->tocs
[i
+1].index1
=
4257 -(arch
->tocs
[i
+1].index1
);
4262 if(multiple_defs
== FALSE
)
4265 for(i
= 0; i
< arch
->toc_nranlibs
; i
++)
4266 if(((int)arch
->tocs
[i
].index1
) < 0)
4267 arch
->tocs
[i
].index1
=
4268 -(arch
->tocs
[i
].index1
);
4274 * warn_duplicate_member_names() generates a warning if two members end up with
4275 * the same ar_name. This is only a warning because ld(1) and this program
4276 * has no problems with it. Only if ar(1) were used to extract the files
4277 * would this be a problem (even the 4.4bsd ar(1) using long names can
4278 * get hosed by base names, the 4.3bsd ar(1) can't handle full 16 character
4283 warn_duplicate_member_names(
4286 uint32_t i
, j
, len
, len1
, len2
;
4288 for(i
= 0; i
< narchs
; i
++){
4289 /* sort in order of ar_names */
4290 qsort(archs
[i
].members
, archs
[i
].nmembers
, sizeof(struct member
),
4291 (int (*)(const void *, const void *))member_name_qsort
);
4293 /* check for duplicate names */
4294 for(j
= 0; j
< archs
[i
].nmembers
- 1; j
++){
4295 len1
= archs
[i
].members
[j
].member_name_size
;
4296 len2
= archs
[i
].members
[j
+1].member_name_size
;
4297 len
= len1
> len2
? len1
: len2
;
4298 if(strncmp(archs
[i
].members
[j
].member_name
,
4299 archs
[i
].members
[j
+1].member_name
,
4301 fprintf(stderr
, "%s: warning ", pnam
);
4303 fprintf(stderr
, "for architecture: %s ",
4304 archs
[i
].arch_flag
.name
);
4305 fprintf(stderr
, "same member name (%.*s) in output file "
4306 "used for input files: ", (int)len1
,
4307 archs
[i
].members
[j
].member_name
);
4309 if(archs
[i
].members
[j
].input_ar_hdr
!= NULL
){
4310 len
= archs
[i
].members
[j
].input_base_name_size
;
4311 fprintf(stderr
, "%s(%.*s) and: ",
4312 archs
[i
].members
[j
].input_file_name
, (int)len
,
4313 archs
[i
].members
[j
].input_base_name
);
4316 fprintf(stderr
, "%s and: ",
4317 archs
[i
].members
[j
].input_file_name
);
4319 if(archs
[i
].members
[j
+1].input_ar_hdr
!= NULL
){
4320 len
= archs
[i
].members
[j
+1].input_base_name_size
;
4321 fprintf(stderr
, "%s(%.*s) due to use of basename, "
4322 "truncation and blank padding\n",
4323 archs
[i
].members
[j
+1].input_file_name
, (int)len
,
4324 archs
[i
].members
[j
+1].input_base_name
);
4327 fprintf(stderr
, "%s (due to use of basename, truncation"
4328 ", blank padding or duplicate input files)\n",
4329 archs
[i
].members
[j
+1].input_file_name
);
4333 /* sort back in order of offset */
4334 qsort(archs
[i
].members
, archs
[i
].nmembers
, sizeof(struct member
),
4335 (int (*)(const void *, const void *))member_offset_qsort
);
4340 * Function for qsort() for comparing member structures by ar_hdr.ar_name.
4345 const struct member
*member1
,
4346 const struct member
*member2
)
4348 uint32_t len
, len1
, len2
;
4350 len1
= member1
->member_name_size
;
4351 len2
= member2
->member_name_size
;
4352 len
= len1
> len2
? len1
: len2
;
4353 return(strncmp(member1
->member_name
, member2
->member_name
, len
));
4357 * Function for qsort() for comparing member structures by offset.
4361 member_offset_qsort(
4362 const struct member
*member1
,
4363 const struct member
*member2
)
4365 if(member1
->offset
< member2
->offset
)
4367 if(member1
->offset
> member2
->offset
)
4369 /* member1->offset == member2->offset */
4374 * warn_member() is like the error routines it prints the program name the
4375 * member name specified and message specified.
4381 struct member
*member
,
4382 const char *format
, ...)
4386 fprintf(stderr
, "%s: ", pnam
);
4388 fprintf(stderr
, "for architecture: %s ", arch
->arch_flag
.name
);
4390 if(member
->input_ar_hdr
!= NULL
){
4391 fprintf(stderr
, "file: %s(%.*s) ", member
->input_file_name
,
4392 (int)member
->input_base_name_size
, member
->input_base_name
);
4395 fprintf(stderr
, "file: %s ", member
->input_file_name
);
4397 va_start(ap
, format
);
4398 vfprintf(stderr
, format
, ap
);
4399 fprintf(stderr
, "\n");
4404 * Prints the message to cmd_flags.trace_file_path, or stderr if that
4410 const char *format
, ...)
4412 static int trace_file
= -1;
4413 char trace_buffer
[MAXPATHLEN
* 2];
4416 ssize_t amount_written
;
4418 if(trace_file
== -1){
4419 if(cmd_flags
.trace_file_path
!= NULL
){
4420 trace_file
= open(cmd_flags
.trace_file_path
, O_WRONLY
| O_APPEND
| O_CREAT
, 0666);
4421 if(trace_file
== -1)
4422 error("Could not open or create trace file: %s\n", cmd_flags
.trace_file_path
);
4425 trace_file
= fileno(stderr
);
4430 va_start(ap
, format
);
4431 length
= vsnprintf(trace_buffer
, sizeof(trace_buffer
), format
, ap
);
4433 buffer_ptr
= trace_buffer
;
4435 amount_written
= write(trace_file
, buffer_ptr
, length
);
4436 if(amount_written
== -1)
4437 /* Failure to write shouldn't fail the build. */
4439 buffer_ptr
+= amount_written
;
4440 length
-= amount_written
;