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 #include <servers/bootstrap.h>
63 * This is used internally to build the table of contents.
66 char *name
; /* symbol defined by */
67 int32_t index1
; /* library member at this index plus 1 */
70 /* used by error routines as the name of the program */
71 char *progname
= NULL
;
73 /* the bytesex of the host this program is running on */
74 static enum byte_sex host_byte_sex
= UNKNOWN_BYTE_SEX
;
77 * The time the table of contents' are set to and the time to base the
78 * modification time of the output file to be set to.
80 static time_t toc_time
= 0;
83 * The environment variable ZERO_AR_DATE is used here and other places that
84 * write archives to allow testing and comparing things for exact binary
87 static enum bool zero_ar_date
= FALSE
;
90 * The mode of the table of contents member (S_IFREG | (0666 & ~umask))
92 static u_short toc_mode
= 0;
94 /* flags set from the command line arguments */
96 char **files
; /* array of file name arguments */
98 nfiles
; /* number of file name arguments */
99 char **filelist
; /* filelist argument the file name argument came from */
101 no_files_ok
; /* ok to see no files */
102 enum bool ranlib
; /* set if this is run as ranlib not libtool */
103 enum bool s
; /* sort the table of contents */
104 enum bool a
; /* don't sort the table of contents (original form) */
105 enum bool c
; /* include commmon symbols in the table of contents */
106 enum bool t
; /* just "touch" the archives to get the date right */
107 enum bool f
; /* warn if the output archive is fat,used by ar(1) -s */
108 enum bool q
; /* only write archive if NOT fat, used by ar(1) */
109 char *output
; /* the output file specified by -o */
110 enum bool final_output_specified
; /* if -final_output is specified */
111 enum bool dynamic
; /* create a dynamic shared library, static by default */
112 char *compatibility
;/* compatibility version if specified, NULL otherwise */
113 char *current
; /* current version if specified, NULL otherwise */
114 char *install_name
; /* install name if specified, NULL otherwise */
115 char *seg1addr
; /* seg1addr if specified, NULL otherwise */
116 char *segs_read_only_addr
; /* segs_read_only_addr if specified, or NULL */
117 char *segs_read_write_addr
; /* segs_read_write_addr if specified, or NULL */
118 char *seg_addr_table
; /* seg_addr_table if specified, or NULL */
119 char *seg_addr_table_filename
;
120 /* seg_addr_table_filename if specified, or NULL */
121 char **Ldirs
; /* array of -Ldir arguments */
123 nLdirs
; /* number of -Ldir arguments */
124 char **ldflags
; /* other ld(1) flags to pass */
126 nldflags
; /* number of ld(1) flags for above */
127 enum bool verbose
; /* print exec(2) commands run */
129 arch_only_flag
; /* the -arch_only flag if specified */
130 enum bool /* set if either -prebind or -noprebind is seen */
131 prebinding_flag_specified
;
132 enum bool /* set if -prebind is seen or the LD_PREBIND */
133 prebinding
; /* environment variable is set (and -noprebind isn't)*/
134 enum bool /* set if either -all_load or -noall_load is seen */
135 all_load_flag_specified
;
136 enum bool /* set if -all_load is seen (and -noall_load isn't) */
138 enum bool /* set with -L (the default) off with -T, for -static */
139 use_long_names
; /* use 4.4bsd extended format 1 for long names */
140 enum bool L_or_T_specified
;
141 enum bool /* set if the environ var LD_TRACE_ARCHIVES is set */
143 const char * /* LD_TRACE_FILE if set and LD_TRACE_ARCHIVES is set, or NULL */
145 enum bool /* set if -search_paths_first is specified */
147 enum bool noflush
; /* don't use the output_flush routine to flush the
148 static library output file by pages */
149 uint32_t debug
; /* debug value to debug output_flush() routine */
150 enum bool /* don't warn if members have no symbols */
151 no_warning_for_no_symbols
;
153 static struct cmd_flags cmd_flags
= { 0 };
155 /* The value of the environment variable NEXT_ROOT */
156 static char *next_root
= NULL
;
158 /* the standard directories to search for -lx names */
159 char *standard_dirs
[] = {
167 * The input files are broken down in to their object files and then placed in
168 * these structures. They are sorted by architecture type and then each object
169 * has a member struct created for it in one of the arch structs. All of these
170 * structs hang off of 'archs'.
172 static struct arch
*archs
= NULL
;
173 static uint32_t narchs
= 0;
176 struct arch_flag arch_flag
; /* the identifing info of this architecture */
177 uint64_t size
; /* current working size and final size */
179 /* the table of contents (toc) stuff for this architecture in the library */
180 uint32_t toc_size
; /* total size of the toc including ar_hdr */
181 struct ar_hdr toc_ar_hdr
; /* the archive header for this member */
182 enum bool toc_long_name
; /* use the long name in the output */
183 char *toc_name
; /* name of toc member */
184 uint32_t toc_name_size
;/* size of name of toc member */
185 struct toc
*tocs
; /* internal table of contents */
186 struct ranlib
*toc_ranlibs
; /* ranlib structs for output */
187 uint32_t toc_nranlibs
;/* number of ranlib structs */
188 char *toc_strings
; /* strings of symbol names for ranlib structs */
189 uint32_t toc_strsize
; /* number of bytes for the strings above */
191 /* the members of this architecture in the library */
192 struct member
*members
; /* the members of the library for this arch */
193 uint32_t nmembers
; /* the number of the above members */
197 uint64_t offset
; /* current working offset and final offset*/
198 struct ar_hdr ar_hdr
; /* the archive header for this member */
199 char null_byte
; /* space to write '\0' for ar_hdr */
200 char *object_addr
; /* the address of the object file */
201 uint32_t object_size
; /* the size of the object file */
202 enum byte_sex object_byte_sex
; /* the byte sex of the object file */
203 struct mach_header
*mh
; /* the mach_header of 32-bit object files */
204 struct mach_header_64
*mh64
; /* the mach_header of 64-bit object files */
205 struct load_command
/* the start of the load commands */
207 struct symtab_command
*st
; /* the symbol table command */
208 struct section
**sections
; /* array of section structs for 32-bit */
209 struct section_64
**sections64
; /* array of section structs for 64-bit */
211 enum bool lto_contents
; /* TRUE if this member has lto contents */
212 uint32_t lto_toc_nsyms
; /* number of symbols for the toc */
213 uint32_t lto_toc_strsize
; /* the size of the strings for the toc */
214 char *lto_toc_strings
; /* the strings of the symbols for the toc */
215 #endif /* LTO_SUPPORT */
217 /* the name of the member in the output */
218 char *member_name
; /* the member name */
219 uint32_t member_name_size
; /* the size of the member name */
220 enum bool output_long_name
; /* use the extended format #1 for the
221 member name in the output */
223 /* info recorded from the input file this member came from */
224 char *input_file_name
; /* the input file name */
225 char *input_base_name
; /* the base name in the input file */
226 uint32_t input_base_name_size
; /* the size of the base name */
227 struct ar_hdr
*input_ar_hdr
;
228 uint64_t input_member_offset
; /* if from a thin archive */
235 static char *file_name_from_l_flag(
237 static char *search_for_file(
239 static char * search_paths_for_lname(
240 const char *lname_argument
);
241 static char * search_path_for_lname(
243 const char *lname_argument
);
244 static void add_member(
245 struct ofile
*ofile
);
246 static void free_archs(
248 static void create_library(
250 struct ofile
*ofile
);
251 static enum byte_sex
get_target_byte_sex(
253 enum byte_sex host_byte_sex
);
254 static char *put_toc_member(
257 enum byte_sex host_byte_sex
,
258 enum byte_sex target_byte_sex
);
259 static void create_dynamic_shared_library(
261 static void create_dynamic_shared_library_cleanup(
263 static void make_table_of_contents(
267 static void save_lto_member_toc_info(
268 struct member
*member
,
270 #endif /* LTO_SUPPORT */
271 static int toc_name_qsort(
272 const struct toc
*toc1
,
273 const struct toc
*toc2
);
274 static int toc_index1_qsort(
275 const struct toc
*toc1
,
276 const struct toc
*toc2
);
277 static enum bool toc_symbol(
278 struct nlist
*symbol
,
279 struct section
**sections
);
280 static enum bool toc_symbol_64(
281 struct nlist_64
*symbol64
,
282 struct section_64
**sections64
);
283 static enum bool toc(
287 enum bool attr_no_toc
);
288 static enum bool check_sort_tocs(
291 enum bool library_warnings
);
292 static void warn_duplicate_member_names(
294 static int member_name_qsort(
295 const struct member
*member1
,
296 const struct member
*member2
);
297 static int member_offset_qsort(
298 const struct member
*member1
,
299 const struct member
*member2
);
300 static void warn_member(
302 struct member
*member
,
303 const char *format
, ...) __attribute__ ((format (printf
, 3, 4)));
304 static void ld_trace(
305 const char *format
, ...) __attribute__ ((format (printf
, 1, 2)));
308 * This structure is used to describe blocks of the output file that are flushed
309 * to the disk file with output_flush. It is kept in an ordered list starting
310 * with output_blocks.
312 static struct block
{
313 uint64_t offset
; /* starting offset of this block */
314 uint64_t size
; /* size of this block */
315 uint64_t written_offset
;/* first page offset after starting offset */
316 uint64_t written_size
; /* size of written area from written_offset */
317 struct block
*next
; /* next block in the list */
320 static void output_flush(
322 uint64_t library_size
,
326 static void final_output_flush(
330 static void print_block_list(void);
332 static struct block
*get_block(void);
333 static void remove_block(
334 struct block
*block
);
335 static uint32_t trnc(
339 /* apple_version is in vers.c which is created by the libstuff/Makefile */
340 extern char apple_version
[];
348 char *p
, *endp
, *filelist
, *dirname
, *addr
;
350 struct stat stat_buf
;
351 uint32_t j
, nfiles
, maxfiles
;
354 enum bool lflags_seen
, bad_flag_seen
, Vflag
;
360 host_byte_sex
= get_host_byte_sex();
363 * The environment variable ZERO_AR_DATE is used here and other
364 * places that write archives to allow testing and comparing
365 * things for exact binary equality.
367 if(getenv("ZERO_AR_DATE") == NULL
)
368 zero_ar_date
= FALSE
;
371 if(zero_ar_date
== FALSE
)
377 oumask
= umask(numask
);
378 toc_mode
= S_IFREG
| (0666 & ~oumask
);
381 /* see if this is being run as ranlib */
382 p
= strrchr(argv
[0], '/');
387 if(strncmp(p
, "ranlib", sizeof("ranlib") - 1) == 0)
388 cmd_flags
.ranlib
= TRUE
;
390 /* The default is to used long names */
391 cmd_flags
.use_long_names
= TRUE
;
393 /* process the command line arguments and collect the files */
395 cmd_flags
.files
= allocate(sizeof(char *) * maxfiles
);
396 cmd_flags
.filelist
= allocate(sizeof(char *) * maxfiles
);
397 memset(cmd_flags
.filelist
, '\0', sizeof(char *) * maxfiles
);
398 for(i
= 1; i
< argc
; i
++){
399 if(argv
[i
][0] == '-'){
400 if(argv
[i
][1] == '\0'){
401 for(i
+= 1 ; i
< argc
; i
++)
402 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
];
405 if(strcmp(argv
[i
], "-o") == 0){
406 if(cmd_flags
.ranlib
== TRUE
){
407 error("unknown option: %s", argv
[i
]);
411 error("missing argument to: %s option", argv
[i
]);
414 if(cmd_flags
.output
!= NULL
){
415 error("more than one: %s option specified", argv
[i
]);
418 cmd_flags
.output
= argv
[i
+1];
421 else if(strcmp(argv
[i
], "-arch_only") == 0){
422 if(cmd_flags
.ranlib
== TRUE
){
423 error("unknown option: %s", argv
[i
]);
427 error("missing argument to %s option", argv
[i
]);
430 if(cmd_flags
.arch_only_flag
.name
!= NULL
){
431 error("more than one: %s option specified", argv
[i
]);
435 if(get_arch_from_flag(argv
[i
+1],
436 &cmd_flags
.arch_only_flag
) == 0){
437 error("unknown architecture specification flag: "
438 "%s %s", argv
[i
], argv
[i
+1]);
445 else if(strcmp(argv
[i
], "-dynamic") == 0){
446 if(cmd_flags
.ranlib
== TRUE
){
447 error("unknown option: %s", argv
[i
]);
450 cmd_flags
.dynamic
= TRUE
;
452 else if(strcmp(argv
[i
], "-static") == 0){
453 if(cmd_flags
.ranlib
== TRUE
){
454 error("unknown option: %s", argv
[i
]);
457 cmd_flags
.dynamic
= FALSE
;
459 else if(strcmp(argv
[i
], "-filelist") == 0){
460 if(cmd_flags
.ranlib
== TRUE
){
461 error("unknown option: %s", argv
[i
]);
465 error("missing argument to: %s option", argv
[i
]);
468 filelist
= argv
[i
+ 1];
469 dirname
= strrchr(filelist
, ',');
476 if((fd
= open(filelist
, O_RDONLY
, 0)) == -1)
477 system_fatal("can't open file list file: %s", filelist
);
478 if(fstat(fd
, &stat_buf
) == -1)
479 system_fatal("can't stat file list file: %s", filelist
);
481 * For some reason mapping files with zero size fails
482 * so it has to be handled specially.
485 if(stat_buf
.st_size
!= 0){
486 addr
= mmap(0, stat_buf
.st_size
, PROT_READ
|PROT_WRITE
,
487 MAP_FILE
|MAP_PRIVATE
, fd
, 0);
488 if((intptr_t)addr
== -1)
489 system_error("can't map file list file: %s",
493 fatal("file list file: %s is empty", filelist
);
499 for(j
= 0; j
< stat_buf
.st_size
; j
++){
503 if(addr
[stat_buf
.st_size
- 1] != '\n')
505 p
= allocate((strlen(dirname
) + 1) * nfiles
+
507 cmd_flags
.files
= reallocate(cmd_flags
.files
,
508 sizeof(char *) * (maxfiles
+ nfiles
));
509 cmd_flags
.filelist
= reallocate(cmd_flags
.filelist
,
510 sizeof(char *) * (maxfiles
+ nfiles
));
511 memset(cmd_flags
.filelist
+ maxfiles
, '\0',
512 sizeof(char *) * nfiles
);
515 cmd_flags
.files
[cmd_flags
.nfiles
] = p
;
516 cmd_flags
.filelist
[cmd_flags
.nfiles
] = filelist
;
518 if(*dirname
!= '\0'){
520 p
+= strlen(dirname
);
523 for(j
= 0; j
< stat_buf
.st_size
; j
++){
528 if(j
!= stat_buf
.st_size
- 1){
529 cmd_flags
.files
[cmd_flags
.nfiles
] = p
;
530 cmd_flags
.filelist
[cmd_flags
.nfiles
] =argv
[i
+1];
532 if(*dirname
!= '\0'){
534 p
+= strlen(dirname
);
540 if(addr
[stat_buf
.st_size
- 1] != '\n')
544 else if(strcmp(argv
[i
], "-compatibility_version") == 0){
545 if(cmd_flags
.ranlib
== TRUE
){
546 error("unknown option: %s", argv
[i
]);
550 error("missing argument to: %s option", argv
[i
]);
553 if(cmd_flags
.compatibility
!= NULL
){
554 error("more than one: %s option specified", argv
[i
]);
557 if(get_version_number(argv
[i
], argv
[i
+1], &temp
) == FALSE
){
560 cmd_flags
.compatibility
= argv
[i
+1];
563 else if(strcmp(argv
[i
], "-current_version") == 0){
564 if(cmd_flags
.ranlib
== TRUE
){
565 error("unknown option: %s", argv
[i
]);
569 error("missing argument to: %s option", argv
[i
]);
572 if(cmd_flags
.current
!= NULL
){
573 error("more than one: %s option specified", argv
[i
]);
576 if(get_version_number(argv
[i
], argv
[i
+1], &temp
) == FALSE
){
579 cmd_flags
.current
= argv
[i
+1];
582 else if(strcmp(argv
[i
], "-install_name") == 0){
583 if(cmd_flags
.ranlib
== TRUE
){
584 error("unknown option: %s", argv
[i
]);
588 error("missing argument to: %s option", argv
[i
]);
591 if(cmd_flags
.install_name
!= NULL
){
592 error("more than one: %s option specified", argv
[i
]);
595 cmd_flags
.install_name
= argv
[i
+1];
598 else if(strcmp(argv
[i
], "-seg1addr") == 0 ||
599 strcmp(argv
[i
], "-image_base") == 0){
600 if(cmd_flags
.ranlib
== TRUE
){
601 error("unknown option: %s", argv
[i
]);
605 error("missing argument to: %s option", argv
[i
]);
608 if(cmd_flags
.seg1addr
!= NULL
){
609 error("more than one: %s option specified", argv
[i
]);
612 temp
= strtoul(argv
[i
+ 1], &endp
, 16);
614 error("address for -seg1addr %s not a proper "
615 "hexadecimal number", argv
[i
+1]);
618 cmd_flags
.seg1addr
= argv
[i
+1];
621 else if(strcmp(argv
[i
], "-segs_read_only_addr") == 0){
622 if(cmd_flags
.ranlib
== TRUE
){
623 error("unknown option: %s", argv
[i
]);
627 error("missing argument to: %s option", argv
[i
]);
630 if(cmd_flags
.segs_read_only_addr
!= NULL
){
631 error("more than one: %s option specified", argv
[i
]);
634 temp
= strtoul(argv
[i
+ 1], &endp
, 16);
636 error("address for -segs_read_only_addr %s not a "
637 "proper hexadecimal number", argv
[i
+1]);
640 cmd_flags
.segs_read_only_addr
= argv
[i
+1];
643 else if(strcmp(argv
[i
], "-segs_read_write_addr") == 0){
644 if(cmd_flags
.ranlib
== TRUE
){
645 error("unknown option: %s", argv
[i
]);
649 error("missing argument to: %s option", argv
[i
]);
652 if(cmd_flags
.segs_read_write_addr
!= NULL
){
653 error("more than one: %s option specified", argv
[i
]);
656 temp
= strtoul(argv
[i
+ 1], &endp
, 16);
658 error("address for -segs_read_write_addr %s not a "
659 "proper hexadecimal number", argv
[i
+1]);
662 cmd_flags
.segs_read_write_addr
= argv
[i
+1];
665 else if(strcmp(argv
[i
], "-seg_addr_table") == 0){
666 if(cmd_flags
.ranlib
== TRUE
){
667 error("unknown option: %s", argv
[i
]);
671 error("missing argument to: %s option", argv
[i
]);
674 if(cmd_flags
.seg_addr_table
!= NULL
){
675 error("more than one: %s option specified", argv
[i
]);
678 cmd_flags
.seg_addr_table
= argv
[i
+1];
681 else if(strcmp(argv
[i
], "-seg_addr_table_filename") == 0){
682 if(cmd_flags
.ranlib
== TRUE
){
683 error("unknown option: %s", argv
[i
]);
687 error("missing argument to: %s option", argv
[i
]);
690 if(cmd_flags
.seg_addr_table_filename
!= NULL
){
691 error("more than one: %s option specified", argv
[i
]);
694 cmd_flags
.seg_addr_table_filename
= argv
[i
+1];
697 else if(strcmp(argv
[i
], "-syslibroot") == 0){
698 if(cmd_flags
.ranlib
== TRUE
){
699 error("unknown option: %s", argv
[i
]);
703 error("missing argument to: %s option", argv
[i
]);
706 if(next_root
!= NULL
&& strcmp(next_root
, argv
[i
+1]) != 0){
707 error("more than one: %s option specified", argv
[i
]);
710 next_root
= argv
[i
+1];
711 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
712 sizeof(char *) * (cmd_flags
.nldflags
+ 2));
713 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
714 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
+1];
717 else if(strcmp(argv
[i
], "-sectcreate") == 0 ||
718 strcmp(argv
[i
], "-segcreate") == 0 ||
719 strcmp(argv
[i
], "-sectorder") == 0 ||
720 strcmp(argv
[i
], "-sectalign") == 0 ||
721 strcmp(argv
[i
], "-segprot") == 0){
722 if(cmd_flags
.ranlib
== TRUE
){
723 error("unknown option: %s", argv
[i
]);
727 error("not enough arguments follow %s", argv
[i
]);
730 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
731 sizeof(char *) * (cmd_flags
.nldflags
+ 4));
732 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
733 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
+1];
734 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
+2];
735 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
+3];
736 if(strcmp(argv
[i
], "-sectcreate") == 0 ||
737 strcmp(argv
[i
], "-segcreate") == 0)
738 cmd_flags
.no_files_ok
= TRUE
;
741 else if(strcmp(argv
[i
], "-segalign") == 0 ||
742 strcmp(argv
[i
], "-undefined") == 0 ||
743 strcmp(argv
[i
], "-macosx_version_min") == 0 ||
744 strcmp(argv
[i
], "-ios_version_min") == 0 ||
745 strcmp(argv
[i
], "-ios_simulator_version_min") == 0 ||
746 strcmp(argv
[i
], "-watchos_version_min") == 0 ||
747 strcmp(argv
[i
], "-watchos_simulator_version_min") == 0 ||
748 strcmp(argv
[i
], "-tvos_version_min") == 0 ||
749 strcmp(argv
[i
], "-tvos_simulator_version_min") == 0 ||
750 strcmp(argv
[i
], "-multiply_defined") == 0 ||
751 strcmp(argv
[i
], "-multiply_defined_unused") == 0 ||
752 strcmp(argv
[i
], "-umbrella") == 0 ||
753 strcmp(argv
[i
], "-sub_umbrella") == 0 ||
754 strcmp(argv
[i
], "-sub_library") == 0 ||
755 strcmp(argv
[i
], "-allowable_client") == 0 ||
756 strcmp(argv
[i
], "-read_only_relocs") == 0 ||
757 strcmp(argv
[i
], "-init") == 0 ||
758 strcmp(argv
[i
], "-U") == 0 ||
759 strcmp(argv
[i
], "-Y") == 0 ||
760 strcmp(argv
[i
], "-dylib_file") == 0 ||
761 strcmp(argv
[i
], "-final_output") == 0 ||
762 strcmp(argv
[i
], "-headerpad") == 0 ||
763 strcmp(argv
[i
], "-weak_reference_mismatches") == 0 ||
764 strcmp(argv
[i
], "-u") == 0 ||
765 strcmp(argv
[i
], "-exported_symbols_list") == 0 ||
766 strcmp(argv
[i
], "-unexported_symbols_list") == 0 ||
767 strcmp(argv
[i
], "-executable_path") == 0){
768 if(cmd_flags
.ranlib
== TRUE
){
769 error("unknown option: %s", argv
[i
]);
773 error("not enough arguments follow %s", argv
[i
]);
776 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
777 sizeof(char *) * (cmd_flags
.nldflags
+ 2));
778 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
779 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
+1];
780 if(strcmp(argv
[i
], "-final_output") == 0)
781 cmd_flags
.final_output_specified
= TRUE
;
784 else if(strcmp(argv
[i
], "-sectorder_detail") == 0 ||
785 strcmp(argv
[i
], "-Sn") == 0 ||
786 strcmp(argv
[i
], "-Si") == 0 ||
787 strcmp(argv
[i
], "-Sp") == 0 ||
788 strcmp(argv
[i
], "-S") == 0 ||
789 strcmp(argv
[i
], "-X") == 0 ||
790 strcmp(argv
[i
], "-x") == 0 ||
791 strcmp(argv
[i
], "-whatsloaded") == 0 ||
792 strcmp(argv
[i
], "-whyload") == 0 ||
793 strcmp(argv
[i
], "-arch_errors_fatal") == 0 ||
794 strcmp(argv
[i
], "-run_init_lazily") == 0 ||
795 strcmp(argv
[i
], "-twolevel_namespace") == 0 ||
796 strcmp(argv
[i
], "-twolevel_namespace_hints") == 0 ||
797 strcmp(argv
[i
], "-flat_namespace") == 0 ||
798 strcmp(argv
[i
], "-nomultidefs") == 0 ||
799 strcmp(argv
[i
], "-headerpad_max_install_names") == 0 ||
800 strcmp(argv
[i
], "-prebind_all_twolevel_modules") == 0 ||
801 strcmp(argv
[i
], "-prebind_allow_overlap") == 0 ||
802 strcmp(argv
[i
], "-ObjC") == 0 ||
803 strcmp(argv
[i
], "-M") == 0 ||
804 strcmp(argv
[i
], "-t") == 0 ||
805 strcmp(argv
[i
], "-single_module") == 0 ||
806 strcmp(argv
[i
], "-multi_module") == 0 ||
807 strcmp(argv
[i
], "-m") == 0 ||
808 strcmp(argv
[i
], "-dead_strip") == 0 ||
809 strcmp(argv
[i
], "-no_uuid") == 0 ||
810 strcmp(argv
[i
], "-no_dead_strip_inits_and_terms") == 0){
811 if(cmd_flags
.ranlib
== TRUE
){
812 error("unknown option: %s", argv
[i
]);
815 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
816 sizeof(char *) * (cmd_flags
.nldflags
+ 1));
817 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
819 else if(strcmp(argv
[i
], "-no_arch_warnings") == 0){
820 if(cmd_flags
.ranlib
== TRUE
){
821 error("unknown option: %s", argv
[i
]);
824 /* ignore this flag */
826 else if(strcmp(argv
[i
], "-prebind") == 0){
827 if(cmd_flags
.ranlib
== TRUE
){
828 error("unknown option: %s", argv
[i
]);
831 if(cmd_flags
.prebinding_flag_specified
== TRUE
&&
832 cmd_flags
.prebinding
== FALSE
){
833 error("both -prebind and -noprebind can't be "
837 cmd_flags
.prebinding_flag_specified
= TRUE
;
838 cmd_flags
.prebinding
= TRUE
;
839 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
840 sizeof(char *) * (cmd_flags
.nldflags
+ 1));
841 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
843 else if(strcmp(argv
[i
], "-noprebind") == 0){
844 if(cmd_flags
.ranlib
== TRUE
){
845 error("unknown option: %s", argv
[i
]);
848 if(cmd_flags
.prebinding_flag_specified
== TRUE
&&
849 cmd_flags
.prebinding
== TRUE
){
850 error("both -prebind and -noprebind can't be "
854 cmd_flags
.prebinding_flag_specified
= TRUE
;
855 cmd_flags
.prebinding
= FALSE
;
856 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
857 sizeof(char *) * (cmd_flags
.nldflags
+ 1));
858 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
860 else if(strcmp(argv
[i
], "-all_load") == 0){
861 if(cmd_flags
.ranlib
== TRUE
){
862 error("unknown option: %s", argv
[i
]);
865 if(cmd_flags
.all_load_flag_specified
== TRUE
&&
866 cmd_flags
.all_load
== FALSE
){
867 error("both -all_load and -noall_load can't be "
871 cmd_flags
.all_load_flag_specified
= TRUE
;
872 cmd_flags
.all_load
= TRUE
;
874 else if(strcmp(argv
[i
], "-noall_load") == 0){
875 if(cmd_flags
.ranlib
== TRUE
){
876 error("unknown option: %s", argv
[i
]);
879 if(cmd_flags
.all_load_flag_specified
== TRUE
&&
880 cmd_flags
.all_load
== TRUE
){
881 error("both -all_load and -noall_load can't be "
885 cmd_flags
.all_load_flag_specified
= TRUE
;
886 cmd_flags
.all_load
= FALSE
;
888 else if(strncmp(argv
[i
], "-y", 2) == 0 ||
889 strncmp(argv
[i
], "-i", 2) == 0){
890 if(cmd_flags
.ranlib
== TRUE
){
891 error("unknown option: %s", argv
[i
]);
894 if(strncmp(argv
[i
], "-i", 2) == 0)
895 cmd_flags
.no_files_ok
= TRUE
;
896 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
897 sizeof(char *) * (cmd_flags
.nldflags
+ 1));
898 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
900 else if(argv
[i
][1] == 'l'){
901 if(cmd_flags
.ranlib
== TRUE
){
902 error("unknown option: %s", argv
[i
]);
905 if(argv
[i
][2] == '\0'){
906 error("-l: name missing");
909 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
];
912 else if(strncmp(argv
[i
], "-weak-l", 7) == 0){
913 if(cmd_flags
.ranlib
== TRUE
){
914 error("unknown option: %s", argv
[i
]);
917 if(argv
[i
][7] == '\0'){
918 error("-weak-l: name missing");
921 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
];
924 else if(strcmp(argv
[i
], "-framework") == 0 ||
925 strcmp(argv
[i
], "-weak_framework") == 0 ||
926 strcmp(argv
[i
], "-weak_library") == 0){
927 if(cmd_flags
.ranlib
== TRUE
){
928 error("unknown option: %s", argv
[i
]);
932 error("not enough arguments follow %s", argv
[i
]);
935 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
];
936 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
+1];
940 else if(strcmp(argv
[i
], "-T") == 0){
941 if(cmd_flags
.L_or_T_specified
== TRUE
){
942 error("both -T and -L can't be specified");
945 cmd_flags
.L_or_T_specified
= TRUE
;
946 cmd_flags
.use_long_names
= FALSE
;
948 else if(argv
[i
][1] == 'L' || argv
[i
][1] == 'F'){
949 if(argv
[i
][1] == 'L' && argv
[i
][2] == '\0'){
950 if(cmd_flags
.L_or_T_specified
== TRUE
){
951 error("both -T and -L can't be specified");
954 cmd_flags
.L_or_T_specified
= TRUE
;
955 cmd_flags
.use_long_names
= TRUE
;
958 if(cmd_flags
.ranlib
== TRUE
){
959 error("unknown option: %s", argv
[i
]);
962 cmd_flags
.Ldirs
= realloc(cmd_flags
.Ldirs
,
963 sizeof(char *) * (cmd_flags
.nLdirs
+ 1));
964 cmd_flags
.Ldirs
[cmd_flags
.nLdirs
++] = argv
[i
];
967 else if(argv
[i
][1] == 'g'){
968 if(cmd_flags
.ranlib
== TRUE
){
969 error("unknown option: %s", argv
[i
]);
972 /* We need to ignore -g[gdb,codeview,stab][number] flags */
975 else if(strcmp(argv
[i
], "-pg") == 0){
976 if(cmd_flags
.ranlib
== TRUE
){
977 error("unknown option: %s", argv
[i
]);
980 /* We need to ignore -pg */
983 else if(strcmp(argv
[i
], "-search_paths_first") == 0){
984 if(cmd_flags
.ranlib
== TRUE
){
985 error("unknown option: %s", argv
[i
]);
988 cmd_flags
.search_paths_first
= TRUE
;
989 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
990 sizeof(char *) * (cmd_flags
.nldflags
+ 1));
991 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
993 else if(strcmp(argv
[i
], "-noflush") == 0){
994 cmd_flags
.noflush
= TRUE
;
996 else if(strcmp(argv
[i
], "-no_warning_for_no_symbols") == 0){
997 cmd_flags
.no_warning_for_no_symbols
= TRUE
;
1000 else if(strcmp(argv
[i
], "-debug") == 0){
1002 error("not enough arguments follow %s", argv
[i
]);
1006 cmd_flags
.debug
|= 1 << strtoul(argv
[i
], &endp
, 10);
1007 if(*endp
!= '\0' || strtoul(argv
[i
], &endp
, 10) > 32)
1008 fatal("argument for -debug %s not a proper "
1009 "decimal number less than 32", argv
[i
]);
1013 for(j
= 1; argv
[i
][j
] != '\0'; j
++){
1025 if(cmd_flags
.ranlib
== TRUE
){
1026 error("unknown option character `%c' in: %s",
1027 argv
[i
][j
], argv
[i
]);
1030 cmd_flags
.verbose
= TRUE
;
1033 printf("Apple Inc. version %s\n", apple_version
);
1037 if(cmd_flags
.ranlib
== TRUE
){
1038 warning("touch option (`%c' in: %s) ignored "
1039 "(table of contents rebuilt anyway)",
1040 argv
[i
][j
], argv
[i
]);
1045 error("unknown option character `%c' in: %s",
1046 argv
[i
][j
], argv
[i
]);
1050 if(cmd_flags
.ranlib
== TRUE
){
1055 error("unknown option character `%c' in: %s",
1056 argv
[i
][j
], argv
[i
]);
1060 if(cmd_flags
.ranlib
== TRUE
){
1065 error("unknown option character `%c' in: %s",
1066 argv
[i
][j
], argv
[i
]);
1070 error("unknown option character `%c' in: %s",
1071 argv
[i
][j
], argv
[i
]);
1078 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
];
1081 * Test to see if the environment variable LD_TRACE_ARCHIVES is set.
1083 if((getenv("RC_TRACE_ARCHIVES") != NULL
) ||
1084 (getenv("LD_TRACE_ARCHIVES") != NULL
)) {
1085 cmd_flags
.ld_trace_archives
= TRUE
;
1086 cmd_flags
.trace_file_path
= getenv("LD_TRACE_FILE");
1090 * If either -syslibroot or the environment variable NEXT_ROOT is set
1091 * prepend it to the standard paths for library searches. This was
1092 * added to ease cross build environments.
1094 if(next_root
!= NULL
){
1095 if(getenv("NEXT_ROOT") != NULL
)
1096 warning("NEXT_ROOT environment variable ignored because "
1097 "-syslibroot specified");
1100 next_root
= getenv("NEXT_ROOT");
1102 if(next_root
!= NULL
){
1103 for(i
= 0; standard_dirs
[i
] != NULL
; i
++){
1104 p
= allocate(strlen(next_root
) +
1105 strlen(standard_dirs
[i
]) + 1);
1106 strcpy(p
, next_root
);
1107 strcat(p
, standard_dirs
[i
]);
1108 standard_dirs
[i
] = p
;
1110 for(i
= 0; i
< cmd_flags
.nLdirs
; i
++){
1111 if(cmd_flags
.Ldirs
[i
][1] != 'L')
1113 if(cmd_flags
.Ldirs
[i
][2] == '/'){
1114 p
= makestr(next_root
, cmd_flags
.Ldirs
[i
] + 2, NULL
);
1115 if(access(p
, F_OK
) != -1){
1117 p
= makestr("-L", next_root
, cmd_flags
.Ldirs
[i
] + 2,
1119 cmd_flags
.Ldirs
[i
] = p
;
1128 /* check the command line arguments for correctness */
1129 if(cmd_flags
.ranlib
== FALSE
&& cmd_flags
.dynamic
== TRUE
){
1130 if(cmd_flags
.s
== TRUE
){
1131 warning("-static not specified, -s invalid");
1133 if(cmd_flags
.a
== TRUE
){
1134 warning("-static not specified, -a invalid");
1136 if(cmd_flags
.c
== TRUE
){
1137 warning("-static not specified, -c invalid");
1139 if(cmd_flags
.L_or_T_specified
== TRUE
){
1140 if(cmd_flags
.use_long_names
== TRUE
)
1141 warning("-static not specified, -L invalid");
1143 warning("-static not specified, -T invalid");
1146 if(cmd_flags
.s
== TRUE
&& cmd_flags
.a
== TRUE
){
1147 error("only one of -s or -a can be specified");
1150 if(cmd_flags
.ranlib
== FALSE
&& cmd_flags
.output
== NULL
){
1153 error("no output file specified (specify with -o output)");
1156 if(cmd_flags
.dynamic
== FALSE
){
1157 if(cmd_flags
.compatibility
!= NULL
){
1158 warning("-dynamic not specified, -compatibility_version %s "
1159 "invalid", cmd_flags
.compatibility
);
1161 if(cmd_flags
.current
!= NULL
){
1162 warning("-dynamic not specified, -current_version %s invalid",
1165 if(cmd_flags
.install_name
!= NULL
){
1166 warning("-dynamic not specified, -install_name %s invalid",
1167 cmd_flags
.install_name
);
1169 if(cmd_flags
.seg1addr
!= NULL
){
1170 warning("-dynamic not specified, -seg1addr %s invalid",
1171 cmd_flags
.seg1addr
);
1173 if(cmd_flags
.segs_read_only_addr
!= NULL
){
1174 warning("-dynamic not specified, -segs_read_only_addr %s "
1175 "invalid", cmd_flags
.segs_read_only_addr
);
1177 if(cmd_flags
.segs_read_write_addr
!= NULL
){
1178 warning("-dynamic not specified, -segs_read_write_addr %s "
1179 "invalid", cmd_flags
.segs_read_write_addr
);
1181 if(cmd_flags
.seg_addr_table
!= NULL
){
1182 warning("-dynamic not specified, -seg_addr_table %s "
1183 "invalid", cmd_flags
.seg_addr_table
);
1185 if(cmd_flags
.seg_addr_table_filename
!= NULL
){
1186 warning("-dynamic not specified, -seg_addr_table_filename %s "
1187 "invalid", cmd_flags
.seg_addr_table_filename
);
1189 if(cmd_flags
.all_load_flag_specified
== TRUE
){
1190 if(cmd_flags
.all_load
== TRUE
)
1191 warning("-dynamic not specified, -all_load invalid");
1193 warning("-dynamic not specified, -noall_load invalid");
1195 if(cmd_flags
.nldflags
!= 0){
1196 bad_flag_seen
= FALSE
;
1197 for(j
= 0; j
< cmd_flags
.nldflags
; j
++){
1198 if(strcmp(cmd_flags
.ldflags
[j
], "-syslibroot") == 0){
1202 if(bad_flag_seen
== FALSE
){
1203 fprintf(stderr
, "%s: -dynamic not specified the "
1204 "following flags are invalid: ", progname
);
1205 bad_flag_seen
= TRUE
;
1207 fprintf(stderr
, "%s ", cmd_flags
.ldflags
[j
]);
1209 if(bad_flag_seen
== TRUE
)
1210 fprintf(stderr
, "\n");
1212 if(cmd_flags
.nLdirs
!= 0){
1213 /* Note: both -L and -F flags are in cmd_flags.Ldirs to keep the
1214 search order right. */
1215 bad_flag_seen
= FALSE
;
1216 for(j
= 0; j
< cmd_flags
.nLdirs
; j
++){
1217 if(strncmp(cmd_flags
.Ldirs
[j
], "-L", 2) == 0)
1219 if(bad_flag_seen
== FALSE
){
1220 fprintf(stderr
, "%s: -dynamic not specified the "
1221 "following flags are invalid: ", progname
);
1222 bad_flag_seen
= TRUE
;
1224 fprintf(stderr
, "%s ", cmd_flags
.Ldirs
[j
]);
1226 if(bad_flag_seen
== TRUE
)
1227 fprintf(stderr
, "\n");
1232 * The -prebind flag can also be specified with the LD_PREBIND
1233 * environment variable.
1235 if(getenv("LD_PREBIND") != NULL
){
1236 if(cmd_flags
.prebinding_flag_specified
== TRUE
&&
1237 cmd_flags
.prebinding
== FALSE
){
1238 warning("LD_PREBIND environment variable ignored because "
1239 "-noprebind specified");
1242 cmd_flags
.prebinding_flag_specified
= TRUE
;
1243 cmd_flags
.prebinding
= TRUE
;
1247 if(cmd_flags
.nfiles
== 0){
1248 if(cmd_flags
.ranlib
== TRUE
){
1249 error("no archives specified");
1253 if(cmd_flags
.dynamic
== TRUE
&& cmd_flags
.no_files_ok
== TRUE
)
1254 warning("warning no files specified");
1256 error("no files specified");
1262 /* set the defaults if not specified */
1263 if(cmd_flags
.a
== FALSE
)
1264 cmd_flags
.s
= TRUE
; /* sort table of contents by default */
1269 return(EXIT_SUCCESS
);
1271 return(EXIT_FAILURE
);
1275 * usage() prints the current usage message and exits indicating failure.
1282 if(cmd_flags
.ranlib
)
1283 fprintf(stderr
, "Usage: %s [-sactfqLT] [-] archive [...]\n",
1286 fprintf(stderr
, "Usage: %s -static [-] file [...] "
1287 "[-filelist listfile[,dirname]] [-arch_only arch] "
1288 "[-sacLT] [-no_warning_for_no_symbols]\n", progname
);
1289 fprintf(stderr
, "Usage: %s -dynamic [-] file [...] "
1290 "[-filelist listfile[,dirname]] [-arch_only arch] "
1291 "[-o output] [-install_name name] "
1292 "[-compatibility_version #] [-current_version #] "
1293 "[-seg1addr 0x#] [-segs_read_only_addr 0x#] "
1294 "[-segs_read_write_addr 0x#] [-seg_addr_table <filename>] "
1295 "[-seg_addr_table_filename <file_system_path>] "
1296 "[-all_load] [-noall_load]\n",
1303 * process() the input files into libraries based on the command flags.
1310 uint32_t i
, j
, k
, previous_errors
;
1311 struct ofile
*ofiles
;
1313 enum bool flag
, ld_trace_archive_printed
;
1316 * For libtool processing put all input files in the specified output
1317 * file. For ranlib processing all input files should be archives or
1318 * fat files with archives in them and each is processed by itself and
1319 * not combined with anything else. The format of fat object files in
1320 * a thin archive is supported here also.
1322 ofiles
= allocate(sizeof(struct ofile
) * cmd_flags
.nfiles
);
1323 for(i
= 0; i
< cmd_flags
.nfiles
; i
++){
1324 if(strncmp(cmd_flags
.files
[i
], "-l", 2) == 0 ||
1325 strncmp(cmd_flags
.files
[i
], "-weak-l", 7) == 0){
1326 file_name
= file_name_from_l_flag(cmd_flags
.files
[i
]);
1327 if(file_name
!= NULL
)
1328 if(ofile_map(file_name
, NULL
, NULL
, ofiles
+ i
, TRUE
) ==
1332 else if(strcmp(cmd_flags
.files
[i
], "-framework") == 0 ||
1333 strcmp(cmd_flags
.files
[i
], "-weak_framework") == 0 ||
1334 strcmp(cmd_flags
.files
[i
], "-weak_library") == 0){
1339 if(ofile_map(cmd_flags
.files
[i
], NULL
, NULL
, ofiles
+ i
,
1344 previous_errors
= errors
;
1346 ld_trace_archive_printed
= FALSE
;
1348 if(ofiles
[i
].file_type
== OFILE_FAT
){
1349 (void)ofile_first_arch(ofiles
+ i
);
1351 if(ofiles
[i
].arch_type
== OFILE_ARCHIVE
){
1352 if(cmd_flags
.ld_trace_archives
== TRUE
&&
1353 cmd_flags
.dynamic
== FALSE
&&
1354 ld_trace_archive_printed
== FALSE
){
1355 char resolvedname
[MAXPATHLEN
];
1356 if(realpath(ofiles
[i
].file_name
, resolvedname
) !=
1358 ld_trace("[Logging for XBS] Used static "
1359 "archive: %s\n", resolvedname
);
1361 ld_trace("[Logging for XBS] Used static "
1362 "archive: %s\n", ofiles
[i
].file_name
);
1363 ld_trace_archive_printed
= TRUE
;
1365 /* loop through archive */
1366 if((flag
= ofile_first_member(ofiles
+ i
)) == TRUE
){
1367 if(ofiles
[i
].member_ar_hdr
!= NULL
&&
1368 strncmp(ofiles
[i
].member_name
, SYMDEF
,
1369 sizeof(SYMDEF
) - 1) == 0)
1370 flag
= ofile_next_member(ofiles
+ i
);
1371 while(flag
== TRUE
){
1372 /* No fat members in a fat file */
1373 if(ofiles
[i
].mh
!= NULL
||
1374 ofiles
[i
].mh64
!= NULL
||
1376 ofiles
[i
].lto
!= NULL
||
1377 #endif /* LTO_SUPPORT */
1378 cmd_flags
.ranlib
== TRUE
)
1379 add_member(ofiles
+ i
);
1381 error("for architecture: %s file: %s(%.*s) "
1382 "is not an object file (not allowed "
1384 ofiles
[i
].arch_flag
.name
,
1386 (int)ofiles
[i
].member_name_size
,
1387 ofiles
[i
].member_name
);
1389 flag
= ofile_next_member(ofiles
+ i
);
1393 else if(ofiles
[i
].arch_type
== OFILE_Mach_O
1395 || ofiles
[i
].arch_type
== OFILE_LLVM_BITCODE
1398 if(cmd_flags
.ranlib
== TRUE
){
1399 error("for architecture: %s file: %s is not an "
1400 "archive (no processing done on this file)",
1401 ofiles
[i
].arch_flag
.name
, cmd_flags
.files
[i
]);
1402 goto ranlib_fat_error
;
1405 add_member(ofiles
+ i
);
1407 else if(ofiles
[i
].arch_type
== OFILE_UNKNOWN
){
1408 if(cmd_flags
.ranlib
== TRUE
){
1409 error("for architecture: %s file: %s is not an "
1410 "archive (no processing done on this file)",
1411 ofiles
[i
].arch_flag
.name
, cmd_flags
.files
[i
]);
1412 goto ranlib_fat_error
;
1415 error("for architecture: %s file: %s is not an "
1416 "object file (not allowed in a library)",
1417 ofiles
[i
].arch_flag
.name
, cmd_flags
.files
[i
]);
1420 }while(ofile_next_arch(ofiles
+ i
) == TRUE
);
1422 else if(ofiles
[i
].file_type
== OFILE_ARCHIVE
){
1423 if(cmd_flags
.ld_trace_archives
== TRUE
&&
1424 cmd_flags
.dynamic
== FALSE
&&
1425 ld_trace_archive_printed
== FALSE
){
1426 char resolvedname
[MAXPATHLEN
];
1427 if(realpath(ofiles
[i
].file_name
, resolvedname
) != NULL
)
1428 ld_trace("[Logging for XBS] Used static archive: "
1429 "%s\n", resolvedname
);
1431 ld_trace("[Logging for XBS] Used static archive: "
1432 "%s\n", ofiles
[i
].file_name
);
1433 ld_trace_archive_printed
= TRUE
;
1435 /* loop through archive */
1436 if((flag
= ofile_first_member(ofiles
+ i
)) == TRUE
){
1437 if(ofiles
[i
].member_ar_hdr
!= NULL
&&
1438 strncmp(ofiles
[i
].member_name
, SYMDEF
,
1439 sizeof(SYMDEF
) - 1) == 0){
1440 flag
= ofile_next_member(ofiles
+ i
);
1442 while(flag
== TRUE
){
1443 /* incorrect form: archive with fat object members */
1444 if(ofiles
[i
].member_type
== OFILE_FAT
){
1445 (void)ofile_first_arch(ofiles
+ i
);
1447 if(ofiles
[i
].mh
!= NULL
||
1448 ofiles
[i
].mh64
!= NULL
||
1449 ofiles
[i
].lto
!= NULL
||
1450 cmd_flags
.ranlib
== TRUE
){
1451 add_member(ofiles
+ i
);
1455 * Can't really get here because ofile_*()
1456 * routines will refuse to process this
1457 * type of file (but I'll leave it here).
1459 error("file: %s(%.*s) for architecture: %s "
1460 "is not an object file (not allowed in "
1461 "a library)", cmd_flags
.files
[i
],
1462 (int)ofiles
[i
].member_name_size
,
1463 ofiles
[i
].member_name
,
1464 ofiles
[i
].arch_flag
.name
);
1467 }while(ofile_next_arch(ofiles
+ i
) == TRUE
);
1469 else if(ofiles
[i
].mh
!= NULL
||
1470 ofiles
[i
].mh64
!= NULL
||
1472 ofiles
[i
].lto
!= NULL
||
1473 #endif /* LTO_SUPPORT */
1474 cmd_flags
.ranlib
== TRUE
){
1475 add_member(ofiles
+ i
);
1478 error("file: %s(%.*s) is not an object file (not "
1479 "allowed in a library)", cmd_flags
.files
[i
],
1480 (int)ofiles
[i
].member_name_size
,
1481 ofiles
[i
].member_name
);
1483 flag
= ofile_next_member(ofiles
+ i
);
1487 else if(ofiles
[i
].file_type
== OFILE_Mach_O
){
1488 if(cmd_flags
.ranlib
== TRUE
){
1489 error("file: %s is not an archive", cmd_flags
.files
[i
]);
1492 add_member(ofiles
+ i
);
1495 else if(ofiles
[i
].file_type
== OFILE_LLVM_BITCODE
){
1496 if(cmd_flags
.ranlib
== TRUE
){
1497 error("file: %s is not an archive", cmd_flags
.files
[i
]);
1500 add_member(ofiles
+ i
);
1502 #endif /* LTO_SUPPORT */
1503 else{ /* ofiles[i].file_type == OFILE_UNKNOWN */
1504 if(cmd_flags
.ranlib
== TRUE
){
1505 error("file: %s is not an archive", cmd_flags
.files
[i
]);
1509 error("file: %s is not an object file (not allowed in a "
1510 "library)", cmd_flags
.files
[i
]);
1514 if(cmd_flags
.ranlib
== TRUE
){
1516 * In the case where ranlib is being used on an archive that
1517 * contains fat object files with multiple members and non-
1518 * object members this has to be treated as an error because
1519 * it is not known which architecture(s) the non-object file
1523 for(j
= 0; j
< narchs
; j
++){
1524 for(k
= 0; k
< archs
[j
].nmembers
; k
++){
1525 if(archs
[j
].members
[k
].mh
== NULL
&&
1527 archs
[j
].members
[k
].lto_contents
== FALSE
&&
1528 #endif /* LTO_SUPPORT */
1529 archs
[j
].members
[k
].mh64
== NULL
){
1530 error("library member: %s(%.*s) is not an "
1531 "object file (not allowed in a library "
1532 "with multiple architectures)",
1534 (int)archs
[j
].members
[k
].
1535 input_base_name_size
,
1536 archs
[j
].members
[k
].input_base_name
);
1542 create_library(cmd_flags
.files
[i
], ofiles
+ i
);
1543 if(cmd_flags
.nfiles
> 1){
1546 ofile_unmap(ofiles
+ i
);
1549 errors
+= previous_errors
;
1551 if(cmd_flags
.ranlib
== FALSE
&& errors
== 0)
1552 create_library(cmd_flags
.output
, NULL
);
1555 * Clean-up of ofiles[] and archs could be done here but since this
1556 * program is now done it is faster to just exit.
1561 * file_name_from_l_flag() is passed a "-lx" or "-weak-lx" flag and returns a
1562 * name of a file for this flag. The flag "-lx" and "-weak-lx" are the same
1563 * flags as used in the link editor to refer to file names. If it can't find a
1564 * file name for the flag it prints an error and returns NULL.
1568 file_name_from_l_flag(
1571 char *file_name
, *p
, *start
;
1573 if(strncmp(l_flag
, "-weak-l", 7) == 0)
1577 p
= strrchr(start
, '.');
1578 if(p
!= NULL
&& strcmp(p
, ".o") == 0){
1580 file_name
= search_for_file(p
);
1584 if(cmd_flags
.dynamic
== TRUE
){
1585 if(cmd_flags
.search_paths_first
== TRUE
){
1586 file_name
= search_paths_for_lname(start
);
1589 p
= makestr("lib", start
, ".dylib", NULL
);
1590 file_name
= search_for_file(p
);
1592 if(file_name
== NULL
){
1593 p
= makestr("lib", start
, ".a", NULL
);
1594 file_name
= search_for_file(p
);
1600 p
= makestr("lib", start
, ".a", NULL
);
1601 file_name
= search_for_file(p
);
1605 if(file_name
== NULL
)
1606 error("can't locate file for: %s", l_flag
);
1611 * search_for_file() takes base_name and trys to find a file with that base name
1612 * is the -L search directories and in the standard directories. If it is
1613 * sucessful it returns a pointer to the file name else it returns NULL.
1623 for(i
= 0; i
< cmd_flags
.nLdirs
; i
++){
1624 if(cmd_flags
.Ldirs
[i
][1] != 'L')
1626 file_name
= makestr(cmd_flags
.Ldirs
[i
] + 2, "/", base_name
, NULL
);
1627 if(access(file_name
, R_OK
) != -1)
1631 for(i
= 0; standard_dirs
[i
] != NULL
; i
++){
1632 file_name
= makestr(standard_dirs
[i
], base_name
, NULL
);
1633 if(access(file_name
, R_OK
) != -1)
1641 * search_paths_for_lname() takes the argument to a -lx option and and trys to
1642 * find a file with the name libx.dylib or libx.a. This routine is only used
1643 * when the -search_paths_first option is specified and -dynamic is in effect.
1644 * And looks for a file name ending in .dylib then .a in each directory before
1645 * looking in the next directory. The list of the -L search directories and in
1646 * the standard directories are searched in that order. If this is sucessful
1647 * it returns a pointer to the file name else NULL.
1651 search_paths_for_lname(
1652 const char *lname_argument
)
1655 char *file_name
, *dir
;
1657 for(i
= 0; i
< cmd_flags
.nLdirs
; i
++){
1658 if(cmd_flags
.Ldirs
[i
][1] != 'L')
1660 dir
= makestr(cmd_flags
.Ldirs
[i
] + 2, "/", NULL
);
1661 file_name
= search_path_for_lname(dir
, lname_argument
);
1663 if(file_name
!= NULL
)
1666 for(i
= 0; standard_dirs
[i
] != NULL
; i
++){
1667 file_name
= search_path_for_lname(standard_dirs
[i
], lname_argument
);
1668 if(file_name
!= NULL
)
1675 * search_path_for_lname() takes the argument to a -lx option and and trys to
1676 * find a file with the name libx.dylib then libx.a in the specified directory
1677 * name. This routine is only used when the -search_paths_first option is
1678 * specified and -dynamic is in effect. If this is sucessful it returns a
1679 * pointer to the file name else NULL.
1683 search_path_for_lname(
1685 const char *lname_argument
)
1689 file_name
= makestr(dir
, "/", "lib", lname_argument
, ".dylib", NULL
);
1690 if(access(file_name
, R_OK
) != -1)
1694 file_name
= makestr(dir
, "/", "lib", lname_argument
, ".a", NULL
);
1695 if(access(file_name
, R_OK
) != -1)
1703 * add_member() add the specified ofile as a member to the library. The
1704 * specified ofile must be either an object file (libtool or ranlib) or an
1705 * archive member with an unknown file type (ranlib only).
1710 struct ofile
*ofile
)
1712 uint32_t i
, j
, size
, ar_name_size
;
1714 struct member
*member
;
1715 struct stat stat_buf
;
1716 char *p
, c
, ar_name_buf
[sizeof(ofile
->member_ar_hdr
->ar_name
) + 1];
1717 char ar_size_buf
[sizeof(ofile
->member_ar_hdr
->ar_size
) + 1];
1718 const struct arch_flag
*family_arch_flag
;
1721 * If this did not come from an archive get the stat info which is
1722 * needed to fill in the archive header for this member.
1724 if(ofile
->member_ar_hdr
== NULL
){
1725 if(stat(ofile
->file_name
, &stat_buf
) == -1){
1726 system_error("can't stat file: %s", ofile
->file_name
);
1732 * Determine the size this member will have in the library which
1733 * includes the padding as a result of rounding the size of the
1734 * member. To get all members on an 8 byte boundary (so that mapping
1735 * in object files can be used directly) the size of the member is
1736 * CHANGED to reflect this padding. In the UNIX definition of archives
1737 * the size of the member is never changed but the offset to the next
1738 * member is defined to be the offset of the previous member plus
1739 * the size of the previous member rounded to 2. So to get 8 byte
1740 * boundaries without breaking the UNIX definition of archives the
1741 * size is changed here. As with the UNIX ar(1) program the padded
1742 * bytes are set to the character '\n'.
1744 if(ofile
->mh
!= NULL
|| ofile
->mh64
!= NULL
)
1745 size
= rnd(ofile
->object_size
, 8);
1747 else if(ofile
->lto
!= NULL
){
1748 if(ofile
->file_type
== OFILE_LLVM_BITCODE
)
1749 size
= rnd(ofile
->file_size
, 8);
1750 else if(ofile
->file_type
== OFILE_FAT
||
1751 (ofile
->file_type
== OFILE_ARCHIVE
&&
1752 ofile
->member_type
== OFILE_FAT
))
1753 size
= rnd(ofile
->object_size
, 8);
1755 size
= rnd(ofile
->member_size
, 8);
1757 #endif /* LTO_SUPPORT */
1759 size
= rnd(ofile
->member_size
, 8);
1761 /* select or create an arch type to put this in */
1763 if(ofile
->mh
!= NULL
||
1764 ofile
->mh64
!= NULL
){
1765 if(ofile
->mh_cputype
== 0){
1766 if(ofile
->member_ar_hdr
!= NULL
){
1767 error("file: %s(%.*s) cputype is zero (a reserved value)",
1768 ofile
->file_name
, (int)ofile
->member_name_size
,
1769 ofile
->member_name
);
1772 error("file: %s cputype is zero (a reserved value)",
1777 * If we are building a dynamic library then don't add dynamic
1778 * shared libraries to the archs. This is so that a dependent
1779 * dynamic shared library that happens to be fat will not cause the
1780 * library to be created fat unless there are object going into
1781 * the library that are fat.
1783 if(ofile
->mh_filetype
== MH_DYLIB
||
1784 ofile
->mh_filetype
== MH_DYLIB_STUB
){
1786 * If we are building a static library we should not put a
1787 * dynamic library Mach-O file into the static library. This
1788 * can happen if a libx.a file is really a dynamic library and
1789 * someone is using -lx when creating a static library.
1791 if(cmd_flags
.dynamic
!= TRUE
){
1792 if(ofile
->member_ar_hdr
!= NULL
){
1793 warning("file: %s(%.*s) is a dynamic library, not "
1794 "added to the static library",
1795 ofile
->file_name
, (int)ofile
->member_name_size
,
1796 ofile
->member_name
);
1799 warning("file: %s is a dynamic library, not added to "
1800 "the static library", ofile
->file_name
);
1805 * If -arch_only is specified then only add this file if it matches
1806 * the architecture specified.
1808 if(cmd_flags
.arch_only_flag
.name
!= NULL
){
1809 if(cmd_flags
.arch_only_flag
.cputype
!= ofile
->mh_cputype
)
1811 if(cmd_flags
.arch_only_flag
.cputype
== CPU_TYPE_ARM
||
1812 cmd_flags
.arch_only_flag
.cputype
== CPU_TYPE_X86_64
){
1813 if(cmd_flags
.arch_only_flag
.cpusubtype
!=
1814 ofile
->mh_cpusubtype
)
1817 if(cmd_flags
.arch_only_flag
.cputype
== CPU_TYPE_ARM64
){
1818 if(cmd_flags
.arch_only_flag
.cpusubtype
==
1819 CPU_SUBTYPE_ARM64_ALL
){
1820 if(ofile
->mh_cpusubtype
!= CPU_SUBTYPE_ARM64_ALL
&&
1821 ofile
->mh_cpusubtype
!= CPU_SUBTYPE_ARM64_V8
)
1824 else if(cmd_flags
.arch_only_flag
.cpusubtype
!=
1825 ofile
->mh_cpusubtype
)
1830 for( ; i
< narchs
; i
++){
1831 if(archs
[i
].arch_flag
.cputype
== ofile
->mh_cputype
){
1832 if((archs
[i
].arch_flag
.cputype
== CPU_TYPE_ARM
||
1833 archs
[i
].arch_flag
.cputype
== CPU_TYPE_X86_64
) &&
1834 archs
[i
].arch_flag
.cpusubtype
!= ofile
->mh_cpusubtype
)
1836 if(cmd_flags
.arch_only_flag
.cputype
== CPU_TYPE_ARM64
){
1837 if(cmd_flags
.arch_only_flag
.cpusubtype
==
1838 CPU_SUBTYPE_ARM64_ALL
){
1839 if(ofile
->mh_cpusubtype
!= CPU_SUBTYPE_ARM64_ALL
&&
1840 ofile
->mh_cpusubtype
!= CPU_SUBTYPE_ARM64_V8
)
1843 else if(cmd_flags
.arch_only_flag
.cpusubtype
!=
1844 ofile
->mh_cpusubtype
)
1852 else if(ofile
->lto
!= NULL
){
1854 * If -arch_only is specified then only add this file if it matches
1855 * the architecture specified.
1857 if(cmd_flags
.arch_only_flag
.name
!= NULL
){
1858 if(cmd_flags
.arch_only_flag
.cputype
!= ofile
->lto_cputype
)
1860 if(cmd_flags
.arch_only_flag
.cputype
== CPU_TYPE_ARM
||
1861 cmd_flags
.arch_only_flag
.cputype
== CPU_TYPE_X86_64
){
1862 if(cmd_flags
.arch_only_flag
.cpusubtype
!=
1863 ofile
->lto_cpusubtype
)
1866 if(cmd_flags
.arch_only_flag
.cputype
== CPU_TYPE_ARM64
){
1867 if(cmd_flags
.arch_only_flag
.cpusubtype
==
1868 CPU_SUBTYPE_ARM64_ALL
){
1869 if(ofile
->lto_cpusubtype
!= CPU_SUBTYPE_ARM64_ALL
&&
1870 ofile
->lto_cpusubtype
!= CPU_SUBTYPE_ARM64_V8
)
1873 else if(cmd_flags
.arch_only_flag
.cpusubtype
!=
1874 ofile
->lto_cpusubtype
)
1879 for( ; i
< narchs
; i
++){
1880 if(archs
[i
].arch_flag
.cputype
== ofile
->lto_cputype
){
1881 if((archs
[i
].arch_flag
.cputype
== CPU_TYPE_ARM
||
1882 archs
[i
].arch_flag
.cputype
== CPU_TYPE_X86_64
) &&
1883 archs
[i
].arch_flag
.cpusubtype
!= ofile
->lto_cpusubtype
)
1885 if(cmd_flags
.arch_only_flag
.cputype
== CPU_TYPE_ARM64
){
1886 if(cmd_flags
.arch_only_flag
.cpusubtype
==
1887 CPU_SUBTYPE_ARM64_ALL
&&
1888 (ofile
->lto_cpusubtype
!= CPU_SUBTYPE_ARM64_ALL
&&
1889 ofile
->lto_cpusubtype
!= CPU_SUBTYPE_ARM64_V8
))
1891 else if(cmd_flags
.arch_only_flag
.cpusubtype
!=
1892 ofile
->lto_cpusubtype
)
1899 #endif /* LTO_SUPPORT */
1900 if(narchs
== 1 && archs
[0].arch_flag
.cputype
== 0){
1903 else if(i
== narchs
){
1904 archs
= reallocate(archs
, sizeof(struct arch
) * (narchs
+1));
1905 memset(archs
+ narchs
, '\0', sizeof(struct arch
));
1906 if(ofile
->mh
!= NULL
||
1907 ofile
->mh64
!= NULL
){
1908 if(ofile
->mh_cputype
== CPU_TYPE_ARM
||
1909 ofile
->mh_cputype
== CPU_TYPE_ARM64
||
1910 ofile
->mh_cputype
== CPU_TYPE_X86_64
){
1911 archs
[narchs
].arch_flag
.name
= (char *)
1912 get_arch_name_from_types(
1913 ofile
->mh_cputype
, ofile
->mh_cpusubtype
);
1914 archs
[narchs
].arch_flag
.cputype
= ofile
->mh_cputype
;
1915 archs
[narchs
].arch_flag
.cpusubtype
= ofile
->mh_cpusubtype
;
1919 get_arch_family_from_cputype(ofile
->mh_cputype
);
1920 if(family_arch_flag
!= NULL
)
1921 archs
[narchs
].arch_flag
= *family_arch_flag
;
1925 else if(ofile
->lto
!= NULL
){
1926 if(ofile
->lto_cputype
== CPU_TYPE_ARM
||
1927 ofile
->lto_cputype
== CPU_TYPE_ARM64
||
1928 ofile
->lto_cputype
== CPU_TYPE_X86_64
){
1929 archs
[narchs
].arch_flag
.name
= (char *)
1930 get_arch_name_from_types(
1931 ofile
->lto_cputype
, ofile
->lto_cpusubtype
);
1932 archs
[narchs
].arch_flag
.cputype
= ofile
->lto_cputype
;
1933 archs
[narchs
].arch_flag
.cpusubtype
= ofile
->lto_cpusubtype
;
1937 get_arch_family_from_cputype(ofile
->lto_cputype
);
1938 if(family_arch_flag
!= NULL
)
1939 archs
[narchs
].arch_flag
= *family_arch_flag
;
1942 #endif /* LTO_SUPPORT */
1944 archs
[narchs
].arch_flag
.name
= "unknown";
1950 * If the cputype of this arch is not yet known then see if this new
1951 * member can determine it.
1953 if(arch
->arch_flag
.cputype
== 0 &&
1954 (ofile
->mh
!= NULL
|| ofile
->mh64
!= NULL
)){
1955 family_arch_flag
= get_arch_family_from_cputype(ofile
->mh_cputype
);
1956 if(family_arch_flag
!= NULL
){
1957 arch
->arch_flag
= *family_arch_flag
;
1960 arch
->arch_flag
.name
=
1961 savestr("cputype 1234567890 cpusubtype 1234567890");
1962 if(arch
->arch_flag
.name
!= NULL
)
1963 sprintf(arch
->arch_flag
.name
, "cputype %u cpusubtype %u",
1964 ofile
->mh_cputype
, ofile
->mh_cpusubtype
&
1966 arch
->arch_flag
.cputype
= ofile
->mh_cputype
;
1967 arch
->arch_flag
.cpusubtype
= ofile
->mh_cpusubtype
;
1971 if(arch
->arch_flag
.cputype
== 0 &&
1972 (ofile
->lto
!= NULL
)){
1973 family_arch_flag
= get_arch_family_from_cputype(ofile
->lto_cputype
);
1974 if(family_arch_flag
!= NULL
){
1975 arch
->arch_flag
= *family_arch_flag
;
1978 arch
->arch_flag
.name
=
1979 savestr("cputype 1234567890 cpusubtype 1234567890");
1980 if(arch
->arch_flag
.name
!= NULL
)
1981 sprintf(arch
->arch_flag
.name
, "cputype %u cpusubtype %u",
1982 ofile
->lto_cputype
, ofile
->lto_cpusubtype
&
1984 arch
->arch_flag
.cputype
= ofile
->lto_cputype
;
1985 arch
->arch_flag
.cpusubtype
= ofile
->lto_cpusubtype
;
1988 #endif /* LTO_SUPPORT */
1990 /* create a member in this arch type for this member */
1991 arch
->members
= reallocate(arch
->members
, sizeof(struct member
) *
1992 (arch
->nmembers
+ 1));
1993 member
= arch
->members
+ arch
->nmembers
;
1994 memset(member
, '\0', sizeof(struct member
));
1997 /* fill in the member for this ofile */
1998 member
->input_file_name
= ofile
->file_name
;
2000 if(ofile
->member_ar_hdr
== NULL
){
2002 * We are creating an archive member in the output file from a
2003 * file (that is not archive member in an input file). First get
2004 * the base name the file_name for the member name.
2006 p
= strrchr(ofile
->file_name
, '/');
2010 p
= ofile
->file_name
;
2011 member
->input_base_name
= p
;
2012 member
->input_base_name_size
= strlen(p
);
2013 member
->member_name
= member
->input_base_name
;
2015 * If we can use long names then force using them to allow 64-bit
2016 * objects to be aligned on an 8 byte boundary. This is needed
2017 * since the struct ar_hdr is not a multiple of 8. This is normally
2018 * done if the name does not fit in the archive header or contains
2019 * a space character then we use the extened format #1. The size
2020 * of the name is rounded up so the object file after the name will
2021 * be on an 8 byte boundary (including rounding the size of the
2022 * struct ar_hdr). The name will be padded with '\0's when it is
2025 if(cmd_flags
.use_long_names
== TRUE
){
2026 member
->output_long_name
= TRUE
;
2027 member
->member_name_size
= member
->input_base_name_size
;
2028 ar_name_size
= rnd(member
->input_base_name_size
, 8) +
2029 (rnd(sizeof(struct ar_hdr
), 8) -
2030 sizeof(struct ar_hdr
));
2031 sprintf(ar_name_buf
, "%s%-*lu", AR_EFMT1
,
2032 (int)(sizeof(member
->ar_hdr
.ar_name
) -
2033 (sizeof(AR_EFMT1
) - 1)),
2034 (long unsigned int)ar_name_size
);
2035 memcpy(member
->ar_hdr
.ar_name
, ar_name_buf
,
2036 sizeof(member
->ar_hdr
.ar_name
));
2040 member
->output_long_name
= FALSE
;
2042 * Truncate the file_name if needed and place in archive header.
2045 if(strlen(p
) > sizeof(member
->ar_hdr
.ar_name
)){
2046 c
= p
[sizeof(member
->ar_hdr
.ar_name
)];
2047 p
[sizeof(member
->ar_hdr
.ar_name
)] = '\0';
2049 sprintf((char *)(&member
->ar_hdr
), "%-*s",
2050 (int)sizeof(member
->ar_hdr
.ar_name
), p
);
2052 p
[sizeof(member
->ar_hdr
.ar_name
)] = c
;
2053 member
->member_name_size
= size_ar_name(&member
->ar_hdr
);
2055 if(zero_ar_date
== TRUE
)
2056 stat_buf
.st_mtime
= 0;
2058 * Create the rest of the archive header after the name.
2060 sprintf((char *)(&member
->ar_hdr
) + sizeof(member
->ar_hdr
.ar_name
),
2061 "%-*ld%-*u%-*u%-*o%-*ld%-*s",
2062 (int)sizeof(member
->ar_hdr
.ar_date
),
2063 (long int)stat_buf
.st_mtime
,
2064 (int)sizeof(member
->ar_hdr
.ar_uid
),
2065 (unsigned short)stat_buf
.st_uid
,
2066 (int)sizeof(member
->ar_hdr
.ar_gid
),
2067 (unsigned short)stat_buf
.st_gid
,
2068 (int)sizeof(member
->ar_hdr
.ar_mode
),
2069 (unsigned int)stat_buf
.st_mode
,
2070 (int)sizeof(member
->ar_hdr
.ar_size
),
2071 (long)size
+ ar_name_size
,
2072 (int)sizeof(member
->ar_hdr
.ar_fmag
),
2077 * We are creating an archive member in the output file from an
2078 * archive member in an input file. There can be some changes to
2079 * the contents. First the size might be changed and the contents
2080 * padded with '\n's to round it to a multiple of 8
2081 * Second we may take a member using extended format #1
2082 * for it's name and truncate it then place the name in the archive
2083 * header. Or we may round the name size to a multiple of 8.
2085 member
->input_ar_hdr
= ofile
->member_ar_hdr
;
2086 member
->input_base_name
= ofile
->member_name
;
2087 member
->input_base_name_size
= ofile
->member_name_size
;
2088 member
->input_member_offset
= ofile
->member_offset
-
2089 sizeof(struct ar_hdr
);
2090 if(strncmp(ofile
->member_ar_hdr
->ar_name
, AR_EFMT1
,
2091 sizeof(AR_EFMT1
) - 1) == 0)
2092 member
->input_member_offset
-= ofile
->member_name_size
;
2094 member
->ar_hdr
= *(ofile
->member_ar_hdr
);
2095 member
->member_name
= ofile
->member_name
;
2097 if(cmd_flags
.use_long_names
== TRUE
){
2099 * We can use long names. So if the input ofile is using the
2100 * extended format #1 we need make sure the size of the name and
2101 * the size of struct ar_hdr are rounded to 8 bytes. And write
2102 * that size into the ar_name with the AR_EFMT1 string. To
2103 * avoid growing the size of names first trim the long name size
2104 * before rounding up.
2106 if(ofile
->member_name
!= ofile
->member_ar_hdr
->ar_name
){
2107 member
->output_long_name
= TRUE
;
2108 member
->member_name_size
= ofile
->member_name_size
;
2109 for(ar_name_size
= member
->member_name_size
;
2112 if(ofile
->member_name
[ar_name_size
- 1] != '\0')
2115 member
->member_name_size
= ar_name_size
;
2116 ar_name_size
= rnd(ar_name_size
, 8) +
2117 (rnd(sizeof(struct ar_hdr
), 8) -
2118 sizeof(struct ar_hdr
));
2119 sprintf(ar_name_buf
, "%s%-*lu", AR_EFMT1
,
2120 (int)(sizeof(member
->ar_hdr
.ar_name
) -
2121 (sizeof(AR_EFMT1
) - 1)),
2122 (long unsigned int)ar_name_size
);
2123 memcpy(member
->ar_hdr
.ar_name
, ar_name_buf
,
2124 sizeof(member
->ar_hdr
.ar_name
));
2128 * Since we can use long names force this to use extended
2129 * format #1. And round the name size to 8 plus the size of
2130 * struct ar_hdr rounded to 8 bytes.
2132 member
->member_name_size
= size_ar_name(&member
->ar_hdr
);
2133 ar_name_size
= rnd(ofile
->member_name_size
, 8) +
2134 (rnd(sizeof(struct ar_hdr
), 8) -
2135 sizeof(struct ar_hdr
));
2136 member
->output_long_name
= TRUE
;
2137 sprintf(ar_name_buf
, "%s%-*lu", AR_EFMT1
,
2138 (int)(sizeof(member
->ar_hdr
.ar_name
) -
2139 (sizeof(AR_EFMT1
) - 1)),
2140 (long unsigned int)ar_name_size
);
2141 memcpy(member
->ar_hdr
.ar_name
, ar_name_buf
,
2142 sizeof(member
->ar_hdr
.ar_name
));
2147 * We can't use long names. So if the input ofile is using the
2148 * extended format #1 we need to truncate the name and write it
2149 * into the ar_name field. Note the extended format is also
2150 * used it the name has a space in it so it may be shorter than
2151 * sizeof(ar_hdr.ar_name) .
2154 member
->output_long_name
= FALSE
;
2155 if(ofile
->member_name
!= ofile
->member_ar_hdr
->ar_name
){
2156 for(j
= 0; j
< sizeof(member
->ar_hdr
.ar_name
) &&
2157 j
< ofile
->member_name_size
&&
2158 ofile
->member_name
[j
] != '\0'; j
++)
2159 member
->ar_hdr
.ar_name
[j
] = ofile
->member_name
[j
];
2160 for( ; j
< sizeof(member
->ar_hdr
.ar_name
); j
++)
2161 member
->ar_hdr
.ar_name
[j
] = ' ';
2163 member
->member_name_size
= size_ar_name(&member
->ar_hdr
);
2166 * Since sprintf() writes a '\0' at the end of the string the
2167 * memcpy is needed to preserve the ARFMAG string that follows.
2169 sprintf(ar_size_buf
, "%-*ld",
2170 (int)sizeof(member
->ar_hdr
.ar_size
),
2171 (long)size
+ ar_name_size
);
2172 memcpy(member
->ar_hdr
.ar_size
, ar_size_buf
,
2173 sizeof(member
->ar_hdr
.ar_size
));
2176 member
->offset
= arch
->size
;
2177 arch
->size
+= sizeof(struct ar_hdr
) + size
+ ar_name_size
;
2179 if(ofile
->mh
!= NULL
||
2180 ofile
->mh64
!= NULL
){
2181 member
->object_addr
= ofile
->object_addr
;
2182 member
->object_size
= ofile
->object_size
;
2183 member
->object_byte_sex
= ofile
->object_byte_sex
;
2184 member
->mh
= ofile
->mh
;
2185 member
->mh64
= ofile
->mh64
;
2186 member
->load_commands
= ofile
->load_commands
;
2189 else if(ofile
->file_type
== OFILE_LLVM_BITCODE
){
2190 member
->object_addr
= ofile
->file_addr
;
2191 member
->object_size
= ofile
->file_size
;
2192 member
->lto_contents
= TRUE
;
2193 save_lto_member_toc_info(member
, ofile
->lto
);
2194 lto_free(ofile
->lto
);
2196 member
->object_byte_sex
= get_byte_sex_from_flag(&arch
->arch_flag
);
2198 else if((ofile
->file_type
== OFILE_FAT
&&
2199 ofile
->arch_type
== OFILE_LLVM_BITCODE
) ||
2200 (ofile
->file_type
== OFILE_ARCHIVE
&&
2201 ofile
->member_type
== OFILE_FAT
&&
2202 ofile
->arch_type
== OFILE_LLVM_BITCODE
)){
2203 member
->object_addr
= ofile
->object_addr
;
2204 member
->object_size
= ofile
->object_size
;
2205 member
->lto_contents
= TRUE
;
2206 save_lto_member_toc_info(member
, ofile
->lto
);
2207 lto_free(ofile
->lto
);
2209 member
->object_byte_sex
= get_byte_sex_from_flag(&arch
->arch_flag
);
2211 #endif /* LTO_SUPPORT */
2213 member
->object_addr
= ofile
->member_addr
;
2214 member
->object_size
= ofile
->member_size
;
2216 if(ofile
->lto
!= NULL
){
2217 member
->lto_contents
= TRUE
;
2218 save_lto_member_toc_info(member
, ofile
->lto
);
2219 lto_free(ofile
->lto
);
2221 member
->object_byte_sex
= get_byte_sex_from_flag(
2224 #endif /* LTO_SUPPORT */
2229 * free_archs() frees the memory allocated that is pointed to by archs.
2238 for(i
= 0 ; i
< narchs
; i
++){
2240 * Just leak memory on the arch_flag.name in some cases
2241 * (unknown archiectures only where the space is malloced and
2242 * a sprintf() is done into the memory)
2244 if(archs
[i
].tocs
!= NULL
)
2245 free(archs
[i
].tocs
);
2246 if(archs
[i
].toc_ranlibs
!= NULL
)
2247 free(archs
[i
].toc_ranlibs
);
2248 if(archs
[i
].toc_strings
!= NULL
)
2249 free(archs
[i
].toc_strings
);
2250 if(archs
[i
].members
!= NULL
)
2251 free(archs
[i
].members
);
2260 * create_library() creates a library from the data structure pointed to by
2261 * archs into the specified output file. Only when more than one architecture
2262 * is in archs will a fat file be created.
2264 * In the case of cmd_flags.ranlib == TRUE the ofile may not be NULL if it
2265 * from a thin archive. If so and the toc_* fields are set and we may update
2266 * the table of contents in place if the new one fits where the old table of
2273 struct ofile
*ofile
)
2275 uint32_t i
, j
, k
, pad
;
2276 uint64_t library_size
, offset
, *time_offsets
;
2277 enum byte_sex target_byte_sex
;
2278 char *library
, *p
, *flush_start
;
2281 struct fat_header
*fat_header
;
2282 struct fat_arch
*fat_arch
;
2284 #ifndef __OPENSTEP__
2285 struct utimbuf timep
;
2289 struct stat stat_buf
;
2290 struct ar_hdr toc_ar_hdr
;
2291 enum bool some_tocs
, same_toc
, different_offsets
;
2294 if(cmd_flags
.ranlib
== TRUE
){
2295 if(cmd_flags
.q
== FALSE
)
2296 warning("empty library: %s (no table of contents added)",
2301 if(cmd_flags
.dynamic
== FALSE
||
2302 cmd_flags
.no_files_ok
== FALSE
){
2303 if(cmd_flags
.arch_only_flag
.name
!= NULL
)
2304 error("no library created (no object files in input "
2305 "files matching -arch_only %s)",
2306 cmd_flags
.arch_only_flag
.name
);
2308 error("no library created (no object files in input "
2315 if(cmd_flags
.dynamic
== TRUE
){
2316 create_dynamic_shared_library(output
);
2320 /* if this is libtool warn about duplicate member names */
2321 if(cmd_flags
.ranlib
== FALSE
)
2322 warn_duplicate_member_names();
2325 * Calculate the total size of the library and the final size of each
2329 library_size
= sizeof(struct fat_header
) +
2330 sizeof(struct fat_arch
) * narchs
;
2332 * The ar(1) program uses the -q flag to ranlib(1) to add a table
2333 * of contents only of the output is not a fat file. This is done
2334 * by default for UNIX standards conformance when the files are
2337 if(cmd_flags
.q
== TRUE
)
2340 * The ar(1) program uses the -f to ranlib(1) when it see the 's'
2341 * option. And if we are creating a fat file issue a warning that
2342 * ar(1) will not be able to use it.
2344 if(cmd_flags
.f
== TRUE
)
2345 warning("archive library: %s will be fat and ar(1) will not "
2346 "be able to operate on it", output
);
2351 for(i
= 0; i
< narchs
; i
++){
2352 if(narchs
> 1 && (archs
[i
].arch_flag
.cputype
& CPU_ARCH_ABI64
))
2353 library_size
= rnd(library_size
, 1 << 3);
2354 make_table_of_contents(archs
+ i
, output
);
2357 if(archs
[i
].toc_nranlibs
!= 0)
2359 archs
[i
].size
+= SARMAG
+ archs
[i
].toc_size
;
2360 library_size
+= archs
[i
].size
;
2363 * The ar(1) program uses the -q flag to ranlib(1) to add a table of
2364 * contents only of the output contains some object files. This is
2365 * done for UNIX standards conformance.
2367 if(cmd_flags
.q
== TRUE
&& some_tocs
== FALSE
)
2371 * If this is ranlib(1) and we are running in UNIX standard mode and
2372 * the file is not writeable just print and error message and return.
2374 if(cmd_flags
.ranlib
== TRUE
&&
2375 get_unix_standard_mode() == TRUE
&&
2376 access(output
, W_OK
) == -1){
2377 system_error("file: %s is not writable", output
);
2382 * If this is ranlib(1) and we have a thin archive that has an existing
2383 * table of contents see if we have enough room to update it in place.
2384 * Actually we check to see that we have the exact same number of
2385 * ranlib structs and string size, as this is the most common case that
2386 * the defined global symbols have not changed when rebuilding and it
2387 * will just be the offset to archive members that will have changed.
2389 if(cmd_flags
.ranlib
== TRUE
&& narchs
== 1 &&
2390 ofile
!= NULL
&& ofile
->toc_addr
!= NULL
&&
2391 ofile
->toc_bad
== FALSE
&&
2392 archs
[0].toc_nranlibs
== ofile
->toc_nranlibs
&&
2393 archs
[0].toc_strsize
== ofile
->toc_strsize
){
2396 * If the table of contents in the input does have a long name and
2397 * the one we built does not (or vice a versa) then don't update it
2400 if(strcmp(ofile
->toc_ar_hdr
->ar_name
, AR_EFMT1
) == 0){
2401 if(archs
[0].toc_long_name
!= TRUE
)
2402 goto fail_to_update_toc_in_place
;
2405 if(archs
[0].toc_long_name
== TRUE
)
2406 goto fail_to_update_toc_in_place
;
2410 * The existing thin archive may not be laid out the same way as
2411 * libtool(1) would do it. As ar(1) does not know to pad things
2412 * so object files are on their natural alignment. So check to
2413 * see if the offsets are not the same and if the alignment is OK.
2415 different_offsets
= FALSE
;
2416 for(i
= 0; i
< archs
[0].nmembers
; i
++){
2417 if(archs
[0].members
[i
].input_member_offset
!=
2418 archs
[0].members
[i
].offset
){
2419 different_offsets
= TRUE
;
2421 * For now we will allow alignments of 4 bytes offsets even
2422 * though we would produce 8 byte alignments.
2424 if(archs
[0].members
[i
].input_member_offset
% 4 != 0){
2425 goto fail_to_update_toc_in_place
;
2431 * The time_offsets array records the offsets to the table of
2432 * contents archive header's ar_date fields. In this case we just
2433 * have one since this is a thin file (non-fat) file.
2435 time_offsets
= allocate(1 * sizeof(uint64_t));
2437 * Calculate the offset to the archive header's time field for the
2438 * table of contents.
2440 time_offsets
[0] = SARMAG
+
2441 ((char *)&toc_ar_hdr
.ar_date
- (char *)&toc_ar_hdr
);
2444 * If we had different member offsets in the input thin archive
2445 * we adjust the ranlib structs ran_off to use them.
2447 if(different_offsets
== TRUE
){
2449 for(i
= 0; i
< archs
[0].toc_nranlibs
; i
++){
2450 for(j
= 0; j
< archs
[0].nmembers
; j
++){
2451 if(archs
[0].members
[j
].offset
==
2452 archs
[0].toc_ranlibs
[i
].ran_off
){
2453 archs
[0].toc_ranlibs
[i
].ran_off
=
2454 archs
[0].members
[j
].input_member_offset
;
2462 * If the new table of contents and the new string table are the
2463 * same as the old then the archive only needs to be "touched"
2464 * and the time field of the toc needs to be updated.
2467 for(i
= 0; i
< archs
[0].toc_nranlibs
; i
++){
2468 if(archs
[0].toc_ranlibs
[i
].ran_un
.ran_strx
!=
2469 ofile
->toc_ranlibs
[i
].ran_un
.ran_strx
||
2470 archs
[0].toc_ranlibs
[i
].ran_off
!=
2471 ofile
->toc_ranlibs
[i
].ran_off
){
2476 if(same_toc
== TRUE
){
2477 for(i
= 0; i
< archs
[0].toc_strsize
; i
++){
2478 if(archs
[0].toc_strings
[i
] != ofile
->toc_strings
[i
]){
2486 library_size
= SARMAG
;
2487 if(same_toc
== FALSE
)
2488 library_size
+= archs
[0].toc_size
;
2489 if((r
= vm_allocate(mach_task_self(), (vm_address_t
*)&library
,
2490 library_size
, TRUE
)) != KERN_SUCCESS
)
2491 mach_fatal(r
, "can't vm_allocate() buffer for output file: %s "
2492 "of size %llu", output
, library_size
);
2495 /* put in the archive magic string in the buffer */
2497 memcpy(p
, ARMAG
, SARMAG
);
2500 /* put the table of contents in the buffer if needed */
2501 target_byte_sex
= get_target_byte_sex(archs
+ 0, host_byte_sex
);
2502 if(same_toc
== FALSE
)
2503 p
= put_toc_member(p
, archs
+0, host_byte_sex
, target_byte_sex
);
2505 if((fd
= open(output
, O_WRONLY
, 0)) == -1){
2506 system_error("can't open output file: %s", output
);
2509 if(write(fd
, library
, library_size
) != (int)library_size
){
2510 system_error("can't write output file: %s", output
);
2513 if(close(fd
) == -1){
2514 system_fatal("can't close output file: %s", output
);
2517 goto update_toc_ar_dates
;
2519 fail_to_update_toc_in_place
:
2522 * This buffer is vm_allocate'ed to make sure all holes are filled with
2525 if((r
= vm_allocate(mach_task_self(), (vm_address_t
*)&library
,
2526 library_size
, TRUE
)) != KERN_SUCCESS
)
2527 mach_fatal(r
, "can't vm_allocate() buffer for output file: %s of "
2528 "size %llu", output
, library_size
);
2531 * Create the output file. The unlink() is done to handle the problem
2532 * when the outputfile is not writable but the directory allows the
2533 * file to be removed (since the file may not be there the return code
2534 * of the unlink() is ignored).
2536 (void)unlink(output
);
2537 if((fd
= open(output
, O_WRONLY
| O_CREAT
| O_TRUNC
, 0666)) == -1){
2538 system_error("can't create output file: %s", output
);
2542 /* tell filesystem to NOT cache the file when reading or writing */
2543 (void)fcntl(fd
, F_NOCACHE
, 1);
2547 * If there is more than one architecture then fill in the fat file
2548 * header and the fat_arch structures in the buffer.
2551 fat_header
= (struct fat_header
*)library
;
2552 fat_header
->magic
= FAT_MAGIC
;
2553 fat_header
->nfat_arch
= narchs
;
2554 offset
= sizeof(struct fat_header
) +
2555 sizeof(struct fat_arch
) * narchs
;
2556 fat_arch
= (struct fat_arch
*)(library
+ sizeof(struct fat_header
));
2557 for(i
= 0; i
< narchs
; i
++){
2558 fat_arch
[i
].cputype
= archs
[i
].arch_flag
.cputype
;
2559 fat_arch
[i
].cpusubtype
= archs
[i
].arch_flag
.cpusubtype
;
2560 if(offset
> UINT32_MAX
)
2561 error("file too large to create as a fat file because "
2562 "offset field in struct fat_arch is only 32-bits and "
2563 "offset (%llu) to architecture %s exceeds that",
2564 offset
, archs
[i
].arch_flag
.name
);
2565 if(fat_arch
[i
].cputype
& CPU_ARCH_ABI64
)
2566 fat_arch
[i
].align
= 3;
2568 fat_arch
[i
].align
= 2;
2569 offset
= rnd(offset
, 1 << fat_arch
[i
].align
);
2570 fat_arch
[i
].offset
= offset
;
2571 if(archs
[i
].size
> UINT32_MAX
)
2572 error("file too large to create as a fat file because "
2573 "size field in struct fat_arch is only 32-bits and "
2574 "size (%llu) of architecture %s exceeds that",
2575 archs
[i
].size
, archs
[i
].arch_flag
.name
);
2576 fat_arch
[i
].size
= archs
[i
].size
;
2577 offset
+= archs
[i
].size
;
2580 (void)unlink(output
);
2583 #ifdef __LITTLE_ENDIAN__
2584 swap_fat_header(fat_header
, BIG_ENDIAN_BYTE_SEX
);
2585 swap_fat_arch(fat_arch
, narchs
, BIG_ENDIAN_BYTE_SEX
);
2586 #endif /* __LITTLE_ENDIAN__ */
2587 offset
= sizeof(struct fat_header
) +
2588 sizeof(struct fat_arch
) * narchs
;
2593 /* flush out the fat headers if any */
2594 output_flush(library
, library_size
, fd
, 0, offset
);
2597 * The time_offsets array records the offsets to the table of conternts
2598 * archive header's ar_date fields.
2600 time_offsets
= allocate(narchs
* sizeof(uint64_t));
2603 * Now put each arch in the buffer.
2605 for(i
= 0; i
< narchs
; i
++){
2607 if(narchs
> 1 && (arch
->arch_flag
.cputype
& CPU_ARCH_ABI64
)){
2608 pad
= rnd(offset
, 1 << 3) - offset
;
2609 output_flush(library
, library_size
, fd
, offset
, pad
);
2610 offset
= rnd(offset
, 1 << 3);
2612 p
= library
+ offset
;
2616 * If the input files only contains non-object files then the
2617 * byte sex of the output can't be determined which is needed for
2618 * the two binary long's of the table of contents. But since these
2619 * will be zero (the same in both byte sexes) because there are no
2620 * symbols in the table of contents if there are no object files.
2623 /* put in the archive magic string */
2624 memcpy(p
, ARMAG
, SARMAG
);
2628 * Warn for what really is a bad library that has an empty table of
2629 * contents but this is allowed in the original ranlib.
2631 if(arch
->toc_nranlibs
== 0 && cmd_flags
.q
== FALSE
){
2633 warning("warning for library: %s for architecture: %s the "
2634 "table of contents is empty (no object file members"
2635 " in the library define global symbols)", output
,
2636 arch
->arch_flag
.name
);
2638 warning("warning for library: %s the table of contents is "
2639 "empty (no object file members in the library "
2640 "define global symbols)", output
);
2644 * Pick the byte sex to write the table of contents in.
2646 target_byte_sex
= get_target_byte_sex(arch
, host_byte_sex
);
2649 * Remember the offset to the archive header's time field for this
2650 * arch's table of contents member.
2654 ((char *)&toc_ar_hdr
.ar_date
- (char *)&toc_ar_hdr
);
2657 * Put in the table of contents member in the output buffer.
2659 p
= put_toc_member(p
, arch
, host_byte_sex
, target_byte_sex
);
2661 output_flush(library
, library_size
, fd
, flush_start
- library
,
2665 * Put in the archive header and member contents for each member.
2667 for(j
= 0; j
< arch
->nmembers
; j
++){
2669 memcpy(p
, (char *)&(arch
->members
[j
].ar_hdr
),
2670 sizeof(struct ar_hdr
));
2671 p
+= sizeof(struct ar_hdr
);
2674 * If we are using extended format #1 for long names write out
2675 * the name. Note the name is padded with '\0' and the
2676 * member_name_size is the unrounded size.
2678 if(arch
->members
[j
].output_long_name
== TRUE
){
2679 strncpy(p
, arch
->members
[j
].member_name
,
2680 arch
->members
[j
].member_name_size
);
2681 p
+= rnd(arch
->members
[j
].member_name_size
, 8) +
2682 (rnd(sizeof(struct ar_hdr
), 8) -
2683 sizeof(struct ar_hdr
));
2687 * ofile_map swaps the headers to the host_byte_sex if the
2688 * object's byte sex is not the same as the host byte sex so
2689 * if this is the case swap them back before writing them out.
2691 if(arch
->members
[j
].mh
!= NULL
&&
2692 arch
->members
[j
].object_byte_sex
!= host_byte_sex
){
2693 if(swap_object_headers(arch
->members
[j
].mh
,
2694 arch
->members
[j
].load_commands
) == FALSE
)
2695 fatal("internal error: swap_object_headers() failed");
2697 else if(arch
->members
[j
].mh64
!= NULL
&&
2698 arch
->members
[j
].object_byte_sex
!= host_byte_sex
){
2699 if(swap_object_headers(arch
->members
[j
].mh64
,
2700 arch
->members
[j
].load_commands
) == FALSE
)
2701 fatal("internal error: swap_object_headers() failed");
2703 memcpy(p
, arch
->members
[j
].object_addr
,
2704 arch
->members
[j
].object_size
);
2705 #ifdef VM_SYNC_DEACTIVATE
2706 vm_msync(mach_task_self(),
2707 (vm_address_t
)arch
->members
[j
].object_addr
,
2708 (vm_size_t
)arch
->members
[j
].object_size
,
2709 VM_SYNC_DEACTIVATE
);
2710 #endif /* VM_SYNC_DEACTIVATE */
2711 p
+= arch
->members
[j
].object_size
;
2712 pad
= rnd(arch
->members
[j
].object_size
, 8) -
2713 arch
->members
[j
].object_size
;
2714 /* as with the UNIX ar(1) program pad with '\n' characters */
2715 for(k
= 0; k
< pad
; k
++)
2718 output_flush(library
, library_size
, fd
, flush_start
- library
,
2721 offset
+= arch
->size
;
2725 * Write the library to the file or flush the remaining buffer to the
2728 if(cmd_flags
.noflush
== TRUE
){
2729 if(write(fd
, library
, library_size
) != (int)library_size
){
2730 system_error("can't write output file: %s", output
);
2735 final_output_flush(library
, fd
);
2737 if(close(fd
) == -1){
2738 system_fatal("can't close output file: %s", output
);
2742 update_toc_ar_dates
:
2744 * Now that the library is created on the file system it is written
2745 * to get the time for the file on that file system.
2747 if(stat(output
, &stat_buf
) == -1){
2748 system_fatal("can't stat file output file: %s", output
);
2751 if((fd
= open(output
, O_WRONLY
, 0)) == -1){
2752 system_error("can't open output file: %s", output
);
2755 if(zero_ar_date
== TRUE
)
2756 stat_buf
.st_mtime
= 0;
2758 * With the time from the file system the library is on set the ar_date
2759 * using the modification time returned by stat. Then write this into
2760 * all the ar_date's in the file.
2762 sprintf((char *)(&toc_ar_hdr
), "%-*s%-*ld",
2763 (int)sizeof(toc_ar_hdr
.ar_name
),
2765 (int)sizeof(toc_ar_hdr
.ar_date
),
2766 (long int)stat_buf
.st_mtime
+ 5);
2767 for(i
= 0; i
< narchs
; i
++){
2768 if(lseek(fd
, time_offsets
[i
], L_SET
) == -1){
2769 system_error("can't lseek in output file: %s", output
);
2772 if(write(fd
, &toc_ar_hdr
.ar_date
, sizeof(toc_ar_hdr
.ar_date
)) !=
2773 sizeof(toc_ar_hdr
.ar_date
)){
2774 system_error("can't write to output file: %s", output
);
2778 if(close(fd
) == -1){
2779 system_fatal("can't close output file: %s", output
);
2783 * Now set the modtime of the created library back to it's stat time
2784 * when we first closed it.
2786 #ifndef __OPENSTEP__
2787 timep
.actime
= stat_buf
.st_mtime
;
2788 timep
.modtime
= stat_buf
.st_mtime
;
2789 if(utime(output
, &timep
) == -1)
2791 timep
[0] = stat_buf
.st_mtime
;
2792 timep
[1] = stat_buf
.st_mtime
;
2793 if(utime(output
, timep
) == -1)
2796 system_fatal("can't set the modifiy times in output file: %s",
2800 if((r
= vm_deallocate(mach_task_self(), (vm_address_t
)library
,
2801 library_size
)) != KERN_SUCCESS
){
2802 my_mach_error(r
, "can't vm_deallocate() buffer for output file");
2808 * get_target_byte_sex() pick the byte sex to write the table of contents in
2813 get_target_byte_sex(
2815 enum byte_sex host_byte_sex
)
2818 enum byte_sex target_byte_sex
;
2820 target_byte_sex
= UNKNOWN_BYTE_SEX
;
2822 i
< arch
->nmembers
&& target_byte_sex
== UNKNOWN_BYTE_SEX
;
2824 target_byte_sex
= arch
->members
[i
].object_byte_sex
;
2826 if(target_byte_sex
== UNKNOWN_BYTE_SEX
)
2827 target_byte_sex
= host_byte_sex
;
2828 return(target_byte_sex
);
2832 * put_toc_member() put the contents member for arch into the buffer p and
2833 * returns the pointer to the buffer after the table of contents.
2834 * The table of contents member is:
2835 * the archive header
2836 * the archive member name (if using a long name)
2837 * a uint32_t for the number of bytes of the ranlib structs
2838 * the ranlib structs
2839 * a uint32_t for the number of bytes of the strings for the
2841 * the strings for the ranlib structs
2848 enum byte_sex host_byte_sex
,
2849 enum byte_sex target_byte_sex
)
2853 memcpy(p
, (char *)&arch
->toc_ar_hdr
, sizeof(struct ar_hdr
));
2854 p
+= sizeof(struct ar_hdr
);
2856 if(arch
->toc_long_name
== TRUE
){
2857 memcpy(p
, arch
->toc_name
, arch
->toc_name_size
);
2858 p
+= arch
->toc_name_size
+
2859 (rnd(sizeof(struct ar_hdr
), 8) -
2860 sizeof(struct ar_hdr
));
2863 l
= arch
->toc_nranlibs
* sizeof(struct ranlib
);
2864 if(target_byte_sex
!= host_byte_sex
)
2866 memcpy(p
, (char *)&l
, sizeof(uint32_t));
2867 p
+= sizeof(uint32_t);
2869 if(target_byte_sex
!= host_byte_sex
)
2870 swap_ranlib(arch
->toc_ranlibs
, arch
->toc_nranlibs
,
2872 memcpy(p
, (char *)arch
->toc_ranlibs
,
2873 arch
->toc_nranlibs
* sizeof(struct ranlib
));
2874 p
+= arch
->toc_nranlibs
* sizeof(struct ranlib
);
2876 l
= arch
->toc_strsize
;
2877 if(target_byte_sex
!= host_byte_sex
)
2879 memcpy(p
, (char *)&l
, sizeof(uint32_t));
2880 p
+= sizeof(uint32_t);
2882 memcpy(p
, (char *)arch
->toc_strings
, arch
->toc_strsize
);
2883 p
+= arch
->toc_strsize
;
2889 * output_flush() takes an offset and a size of part of the output library,
2890 * known in the comments as the new area, and causes any fully flushed pages to
2891 * be written to the library file the new area in combination with previous
2892 * areas created. The data structure output_blocks has ordered blocks of areas
2893 * that have been flushed which are maintained by this routine. Any area can
2894 * only be flushed once and an error will result is the new area overlaps with a
2895 * previously flushed area.
2901 uint64_t library_size
,
2906 uint64_t write_offset
, write_size
, host_pagesize
;
2907 struct block
**p
, *block
, *before
, *after
;
2910 host_pagesize
= 0x2000;
2912 if(cmd_flags
.noflush
== TRUE
)
2915 if(offset
+ size
> library_size
)
2916 fatal("internal error: output_flush(offset = %llu, size = %llu) "
2917 "out of range for library_size = %llu", offset
, size
,
2921 if(cmd_flags
.debug
& (1 << 2))
2923 if(cmd_flags
.debug
& (1 << 1))
2924 printf("output_flush(offset = %llu, size %llu)", offset
, size
);
2929 if(cmd_flags
.debug
& (1 << 1))
2936 * Search through the ordered output blocks to find the block before the
2937 * new area and after the new area if any exist.
2941 p
= &(output_blocks
);
2944 if(offset
< block
->offset
){
2955 * Check for overlap of the new area with the block before and after the
2956 * new area if there are such blocks.
2959 if(before
->offset
+ before
->size
> offset
){
2960 warning("internal error: output_flush(offset = %llu, size = "
2961 "%llu) overlaps with flushed block(offset = %llu, "
2962 "size = %llu)", offset
, size
, before
->offset
,
2964 printf("calling abort()\n");
2969 if(offset
+ size
> after
->offset
){
2970 warning("internal error: output_flush(offset = %llu, size = "
2971 "%llu) overlaps with flushed block(offset = %llu, "
2972 "size = %llu)", offset
, size
, after
->offset
,
2974 printf("calling abort()\n");
2980 * Now see how the new area fits in with the blocks before and after it
2981 * (that is does it touch both, one or the other or neither blocks).
2982 * For each case first the offset and size to write (write_offset and
2983 * write_size) are set for the area of full pages that can now be
2984 * written from the block. Then the area written in the block
2985 * (->written_offset and ->written_size) are set to reflect the total
2986 * area in the block now written. Then offset and size the block
2987 * refers to (->offset and ->size) are set to total area of the block.
2988 * Finally the links to others blocks in the list are adjusted if a
2989 * block is added or removed.
2991 * See if there is a block before the new area and the new area
2992 * starts at the end of that block.
2994 if(before
!= NULL
&& before
->offset
+ before
->size
== offset
){
2996 * See if there is also a block after the new area and the new area
2997 * ends at the start of that block.
2999 if(after
!= NULL
&& offset
+ size
== after
->offset
){
3001 * This is the case where the new area exactly fill the area
3002 * between two existing blocks. The total area is folded into
3003 * the block before the new area and the block after the new
3004 * area is removed from the list.
3006 if(before
->offset
== 0 && before
->written_size
== 0){
3008 before
->written_offset
= 0;
3011 write_offset
=before
->written_offset
+ before
->written_size
;
3012 if(after
->written_size
== 0)
3013 write_size
= trnc(after
->offset
+ after
->size
-
3014 write_offset
, host_pagesize
);
3016 write_size
= trnc(after
->written_offset
- write_offset
,
3018 if(write_size
!= 0){
3019 before
->written_size
+= write_size
;
3021 if(after
->written_size
!= 0)
3022 before
->written_size
+= after
->written_size
;
3023 before
->size
+= size
+ after
->size
;
3025 /* remove the block after the new area */
3026 before
->next
= after
->next
;
3027 remove_block(after
);
3031 * This is the case where the new area starts at the end of the
3032 * block just before it but does not end where the block after
3033 * it (if any) starts. The new area is folded into the block
3034 * before the new area.
3036 write_offset
= before
->written_offset
+ before
->written_size
;
3037 write_size
= trnc(offset
+ size
- write_offset
, host_pagesize
);
3039 before
->written_size
+= write_size
;
3040 before
->size
+= size
;
3044 * See if the new area and the new area ends at the start of the block
3045 * after it (if any).
3047 else if(after
!= NULL
&& offset
+ size
== after
->offset
){
3049 * This is the case where the new area ends at the begining of the
3050 * block just after it but does not start where the block before it.
3051 * (if any) ends. The new area is folded into this block after the
3054 write_offset
= rnd(offset
, host_pagesize
);
3055 if(after
->written_size
== 0)
3056 write_size
= trnc(after
->offset
+ after
->size
- write_offset
,
3059 write_size
= trnc(after
->written_offset
- write_offset
,
3061 if(write_size
!= 0){
3062 after
->written_offset
= write_offset
;
3063 after
->written_size
+= write_size
;
3065 else if(write_offset
!= after
->written_offset
){
3066 after
->written_offset
= write_offset
;
3068 after
->offset
= offset
;
3069 after
->size
+= size
;
3073 * This is the case where the new area neither starts at the end of
3074 * the block just before it (if any) or ends where the block after
3075 * it (if any) starts. A new block is created and the new area is
3078 write_offset
= rnd(offset
, host_pagesize
);
3079 write_size
= trnc(offset
+ size
- write_offset
, host_pagesize
);
3080 block
= get_block();
3081 block
->offset
= offset
;
3083 block
->written_offset
= write_offset
;
3084 block
->written_size
= write_size
;
3086 * Insert this block in the ordered list in the correct place.
3089 block
->next
= before
->next
;
3090 before
->next
= block
;
3093 block
->next
= output_blocks
;
3094 output_blocks
= block
;
3099 * Now if there are full pages to write write them to the output file.
3101 if(write_size
!= 0){
3103 if((cmd_flags
.debug
& (1 << 1)) || (cmd_flags
.debug
& (1 << 0)))
3104 printf(" writing (write_offset = %llu write_size = %llu)\n",
3105 write_offset
, write_size
);
3107 lseek(fd
, write_offset
, L_SET
);
3108 if(write(fd
, library
+ write_offset
, write_size
) !=
3110 system_fatal("can't write to output file");
3111 if((r
= vm_deallocate(mach_task_self(), (vm_address_t
)(library
+
3112 write_offset
), write_size
)) != KERN_SUCCESS
)
3113 mach_fatal(r
, "can't vm_deallocate() buffer for output file");
3117 if(cmd_flags
.debug
& (1 << 1))
3118 printf(" no write\n");
3124 * final_output_flush() flushes the last part of the last page of the object
3125 * file if it does not round out to exactly a page.
3133 struct block
*block
;
3134 uint64_t write_offset
, write_size
;
3138 /* The compiler "warning: `write_offset' may be used uninitialized in */
3139 /* this function" can safely be ignored */
3141 if((cmd_flags
.debug
& (1 << 1)) || (cmd_flags
.debug
& (1 << 0))){
3142 printf("final_output_flush block_list:\n");
3148 block
= output_blocks
;
3150 if(block
->offset
!= 0)
3151 fatal("internal error: first block not at offset 0");
3152 if(block
->written_size
!= 0){
3153 if(block
->written_offset
!= 0)
3154 fatal("internal error: first block written_offset not 0");
3155 write_offset
= block
->written_size
;
3156 write_size
= block
->size
- block
->written_size
;
3159 write_offset
= block
->offset
;
3160 write_size
= block
->size
;
3162 if(block
->next
!= NULL
)
3163 fatal("internal error: more than one block in final list");
3165 if(write_size
!= 0){
3167 if((cmd_flags
.debug
& (1 << 1)) || (cmd_flags
.debug
& (1 << 1)))
3168 printf(" writing (write_offset = %llu write_size = %llu)\n",
3169 write_offset
, write_size
);
3171 lseek(fd
, write_offset
, L_SET
);
3172 if(write(fd
, library
+ write_offset
, write_size
) !=
3174 system_fatal("can't write to output file");
3175 if((r
= vm_deallocate(mach_task_self(), (vm_address_t
)(library
+
3176 write_offset
), write_size
)) != KERN_SUCCESS
)
3177 mach_fatal(r
, "can't vm_deallocate() buffer for output file");
3179 output_blocks
= NULL
;
3184 * print_block_list() prints the list of blocks. Used for debugging.
3188 print_block_list(void)
3190 struct block
**p
, *block
;
3192 p
= &(output_blocks
);
3194 printf("Empty block list\n");
3197 printf("block 0x%x\n", (unsigned int)block
);
3198 printf(" offset %llu\n", block
->offset
);
3199 printf(" size %llu\n", block
->size
);
3200 printf(" written_offset %llu\n", block
->written_offset
);
3201 printf(" written_size %llu\n", block
->written_size
);
3202 printf(" next 0x%x\n", (unsigned int)(block
->next
));
3209 * get_block() returns a pointer to a new block. This could be done by
3210 * allocating block of these placing them on a free list and and handing them
3211 * out. For the initial release of this code this number is typicly low and not
3212 * a big win so each block just allocated and free'ed.
3218 struct block
*block
;
3220 block
= allocate(sizeof(struct block
));
3225 * remove_block() throws away the block specified. See comments in get_block().
3230 struct block
*block
)
3236 * trnc() truncates the value 'v' to the power of two value 'r'. If v is
3237 * less than zero it returns zero.
3245 if(((int32_t)v
) < 0)
3247 return(v
& ~(r
- 1));
3251 * create_dynamic_shared_library() creates a dynamic shared library from the
3252 * data structure pointed to by archs into the specified output file. Only
3253 * when more than one architecture is in archs will a fat file be created.
3257 create_dynamic_shared_library(
3262 struct stat stat_buf
;
3263 enum bool use_force_cpusubtype_ALL
;
3264 const struct arch_flag
*family_arch_flag
;
3267 * If there is more than one architecture setup a signal handler to
3268 * clean up the temporary files in case we get a signal.
3271 signal(SIGINT
, create_dynamic_shared_library_cleanup
);
3274 * If -arch_only is specified with a specific cpusubtype other than the
3275 * family cpusubtype do not use -force_cpusubtype_ALL as the user wants
3276 * the output to be tagged with that cpusubtype.
3278 use_force_cpusubtype_ALL
= TRUE
;
3279 if(cmd_flags
.arch_only_flag
.name
!= NULL
){
3280 family_arch_flag
= get_arch_family_from_cputype(
3281 cmd_flags
.arch_only_flag
.cputype
);
3282 if(family_arch_flag
!= NULL
){
3283 if((family_arch_flag
->cpusubtype
& ~CPU_SUBTYPE_MASK
) !=
3284 (cmd_flags
.arch_only_flag
.cpusubtype
& ~CPU_SUBTYPE_MASK
))
3285 use_force_cpusubtype_ALL
= FALSE
;
3290 * For each architecture run ld(1) -dylib to create the dynamic shared
3293 for(i
= 0; i
< narchs
|| (i
== 0 && narchs
== 0); i
++){
3294 reset_execute_list();
3295 add_execute_list_with_prefix("ld");
3296 if(narchs
!= 0 && cmd_flags
.arch_only_flag
.name
== NULL
)
3297 add_execute_list("-arch_multiple");
3299 add_execute_list("-arch");
3300 if(use_force_cpusubtype_ALL
== TRUE
)
3301 add_execute_list(archs
[i
].arch_flag
.name
);
3303 add_execute_list(cmd_flags
.arch_only_flag
.name
);
3305 add_execute_list("-dylib");
3306 add_execute_list("-dynamic");
3307 if(cmd_flags
.all_load_flag_specified
== FALSE
||
3308 cmd_flags
.all_load
== TRUE
)
3309 add_execute_list("-all_load");
3310 if(use_force_cpusubtype_ALL
== TRUE
)
3311 add_execute_list("-force_cpusubtype_ALL");
3312 add_execute_list("-no_arch_warnings");
3313 if(cmd_flags
.seg1addr
!= NULL
){
3314 add_execute_list("-seg1addr");
3315 add_execute_list(cmd_flags
.seg1addr
);
3317 if(cmd_flags
.segs_read_only_addr
!= NULL
){
3318 add_execute_list("-segs_read_only_addr");
3319 add_execute_list(cmd_flags
.segs_read_only_addr
);
3321 if(cmd_flags
.segs_read_write_addr
!= NULL
){
3322 add_execute_list("-segs_read_write_addr");
3323 add_execute_list(cmd_flags
.segs_read_write_addr
);
3325 if(cmd_flags
.seg_addr_table
!= NULL
){
3326 add_execute_list("-seg_addr_table");
3327 add_execute_list(cmd_flags
.seg_addr_table
);
3329 if(cmd_flags
.seg_addr_table_filename
!= NULL
){
3330 add_execute_list("-seg_addr_table_filename");
3331 add_execute_list(cmd_flags
.seg_addr_table_filename
);
3333 if(cmd_flags
.compatibility
!= NULL
){
3334 add_execute_list("-dylib_compatibility_version");
3335 add_execute_list(cmd_flags
.compatibility
);
3337 if(cmd_flags
.current
!= NULL
){
3338 add_execute_list("-dylib_current_version");
3339 add_execute_list(cmd_flags
.current
);
3341 if(cmd_flags
.install_name
!= NULL
){
3342 add_execute_list("-dylib_install_name");
3343 add_execute_list(cmd_flags
.install_name
);
3347 add_execute_list("-dylib_install_name");
3348 add_execute_list(cmd_flags
.output
);
3351 for(j
= 0; j
< cmd_flags
.nldflags
; j
++)
3352 add_execute_list(cmd_flags
.ldflags
[j
]);
3353 for(j
= 0; j
< cmd_flags
.nLdirs
; j
++)
3354 add_execute_list(cmd_flags
.Ldirs
[j
]);
3356 // Support using libtool on a systems without the SDK in '/'. This
3357 // works because the shims that are included in 10.9 and forwards
3358 // automatically inject SDKROOT into the environment of the actual
3359 // tools. See <rdar://problem/14264125>.
3360 const char *sdkroot
= getenv("SDKROOT");
3362 // If the SDKROOT environment variable is set and is an absolute
3363 // path, then see if we can find dylib1.o inside it and use that if
3365 enum bool use_dashl_dylib1o
= TRUE
;
3366 if (sdkroot
&& sdkroot
[0] == '/') {
3367 // Construct the path to the object file.
3368 char *sdk_dylib1o_path
;
3369 int res
= asprintf(&sdk_dylib1o_path
, "%s/usr/lib/dylib1.o",
3371 if (res
> 0 && sdk_dylib1o_path
) {
3373 // Add the full path if it exists.
3374 if (stat(sdk_dylib1o_path
, &s
) == 0) {
3375 add_execute_list(sdk_dylib1o_path
);
3376 use_dashl_dylib1o
= FALSE
;
3378 free(sdk_dylib1o_path
);
3383 for(j
= 0; j
< cmd_flags
.nfiles
; j
++){
3384 if(cmd_flags
.filelist
[j
] == NULL
){
3385 add_execute_list(cmd_flags
.files
[j
]);
3388 if(cmd_flags
.filelist
[j
] != filelist
){
3389 add_execute_list("-filelist");
3390 add_execute_list(cmd_flags
.filelist
[j
]);
3391 filelist
= cmd_flags
.filelist
[j
];
3396 add_execute_list("-o");
3397 add_execute_list(cmd_flags
.output
);
3400 add_execute_list("-o");
3401 add_execute_list(makestr(cmd_flags
.output
, ".libtool.",
3402 archs
[i
].arch_flag
.name
, NULL
));
3403 if(cmd_flags
.final_output_specified
== FALSE
){
3404 add_execute_list("-final_output");
3405 add_execute_list(cmd_flags
.output
);
3408 if(execute_list(cmd_flags
.verbose
) == 0)
3409 fatal("internal link edit command failed");
3412 * If there is more than one architecture then run lipo to put them
3416 reset_execute_list();
3417 add_execute_list_with_prefix("lipo");
3418 add_execute_list("-create");
3419 add_execute_list("-output");
3420 add_execute_list(cmd_flags
.output
);
3421 for(i
= 0; i
< narchs
; i
++){
3422 add_execute_list(makestr(cmd_flags
.output
, ".libtool.",
3423 archs
[i
].arch_flag
.name
, NULL
));
3425 if(execute_list(cmd_flags
.verbose
) == 0)
3426 fatal("internal lipo command failed");
3427 for(i
= 0; i
< narchs
; i
++){
3428 p
= makestr(cmd_flags
.output
, ".libtool.",
3429 archs
[i
].arch_flag
.name
, NULL
);
3430 if(unlink(p
) == -1){
3431 error("can't remove temporary file: %s", p
);
3436 * If we are doing prebinding then run objcunique on the
3439 if(cmd_flags
.prebinding
== TRUE
){
3440 if(stat("/usr/bin/objcunique", &stat_buf
) != -1){
3441 reset_execute_list();
3442 add_execute_list_with_prefix("objcunique");
3443 add_execute_list(cmd_flags
.output
);
3444 add_execute_list("-prebind");
3445 for(j
= 0; j
< cmd_flags
.nLdirs
; j
++)
3446 add_execute_list(cmd_flags
.Ldirs
[j
]);
3447 if(execute_list(cmd_flags
.verbose
) == 0)
3448 fatal("internal objcunique command failed");
3454 * create_dynamic_shared_library_cleanup() is the signal handler to remove the
3455 * temporary files if more than one arch is being used.
3459 create_dynamic_shared_library_cleanup(
3464 for(i
= 0; i
< narchs
; i
++){
3465 (void)unlink(makestr(cmd_flags
.output
, ".libtool.",
3466 archs
[i
].arch_flag
.name
, NULL
));
3472 * make_table_of_contents() make the table of contents for the specified arch
3473 * and fills in the toc_* fields in the arch. Output is the name of the output
3474 * file for error messages.
3478 make_table_of_contents(
3482 uint32_t i
, j
, k
, r
, s
, nsects
, ncmds
, n_strx
;
3483 struct member
*member
;
3484 struct load_command
*lc
;
3485 struct segment_command
*sg
;
3486 struct segment_command_64
*sg64
;
3487 struct nlist
*symbols
;
3488 struct nlist_64
*symbols64
;
3490 enum bool sorted
, is_toc_symbol
;
3492 struct section
*section
;
3493 struct section_64
*section64
;
3494 uint8_t n_type
, n_sect
;
3496 char *lto_toc_string
;
3497 #endif /* LTO_SUPPORT */
3502 * First pass over the members to count how many ranlib structs are
3503 * needed and the size of the strings in the toc that are needed.
3505 for(i
= 0; i
< arch
->nmembers
; i
++){
3506 member
= arch
->members
+ i
;
3507 if(member
->mh
!= NULL
|| member
->mh64
!= NULL
){
3509 lc
= member
->load_commands
;
3510 if(member
->mh
!= NULL
)
3511 ncmds
= member
->mh
->ncmds
;
3513 ncmds
= member
->mh64
->ncmds
;
3514 for(j
= 0; j
< ncmds
; j
++){
3515 if(lc
->cmd
== LC_SYMTAB
){
3516 if(member
->st
== NULL
)
3517 member
->st
= (struct symtab_command
*)lc
;
3519 else if(lc
->cmd
== LC_SEGMENT
){
3520 sg
= (struct segment_command
*)lc
;
3521 nsects
+= sg
->nsects
;
3523 else if(lc
->cmd
== LC_SEGMENT_64
){
3524 sg64
= (struct segment_command_64
*)lc
;
3525 nsects
+= sg64
->nsects
;
3527 lc
= (struct load_command
*)((char *)lc
+ lc
->cmdsize
);
3529 if(member
->mh
!= NULL
)
3530 member
->sections
= allocate(nsects
*
3531 sizeof(struct section
*));
3533 member
->sections64
= allocate(nsects
*
3534 sizeof(struct section_64
*));
3536 lc
= member
->load_commands
;
3537 for(j
= 0; j
< ncmds
; j
++){
3538 if(lc
->cmd
== LC_SEGMENT
){
3539 sg
= (struct segment_command
*)lc
;
3540 section
= (struct section
*)
3541 ((char *)sg
+ sizeof(struct segment_command
));
3542 for(k
= 0; k
< sg
->nsects
; k
++){
3543 member
->sections
[nsects
++] = section
++;
3546 else if(lc
->cmd
== LC_SEGMENT_64
){
3547 sg64
= (struct segment_command_64
*)lc
;
3548 section64
= (struct section_64
*)
3549 ((char *)sg64
+ sizeof(struct segment_command_64
));
3550 for(k
= 0; k
< sg64
->nsects
; k
++){
3551 member
->sections64
[nsects
++] = section64
++;
3554 lc
= (struct load_command
*)((char *)lc
+ lc
->cmdsize
);
3556 if(member
->st
!= NULL
&& member
->st
->nsyms
!= 0){
3557 if(member
->mh
!= NULL
){
3558 symbols
= (struct nlist
*)(member
->object_addr
+
3559 member
->st
->symoff
);
3560 if(member
->object_byte_sex
!= get_host_byte_sex())
3561 swap_nlist(symbols
, member
->st
->nsyms
,
3562 get_host_byte_sex());
3565 symbols64
= (struct nlist_64
*)(member
->object_addr
+
3566 member
->st
->symoff
);
3567 if(member
->object_byte_sex
!= get_host_byte_sex())
3568 swap_nlist_64(symbols64
, member
->st
->nsyms
,
3569 get_host_byte_sex());
3571 strings
= member
->object_addr
+ member
->st
->stroff
;
3572 for(j
= 0; j
< member
->st
->nsyms
; j
++){
3573 if(member
->mh
!= NULL
){
3574 n_strx
= symbols
[j
].n_un
.n_strx
;
3575 n_type
= symbols
[j
].n_type
;
3576 n_sect
= symbols
[j
].n_sect
;
3579 n_strx
= symbols64
[j
].n_un
.n_strx
;
3580 n_type
= symbols64
[j
].n_type
;
3581 n_sect
= symbols64
[j
].n_sect
;
3583 if(n_strx
> member
->st
->strsize
){
3584 warn_member(arch
, member
, "malformed object "
3585 "(symbol %u n_strx field extends past the "
3586 "end of the string table)", j
);
3590 if((n_type
& N_TYPE
) == N_SECT
){
3591 if(n_sect
== NO_SECT
){
3592 warn_member(arch
, member
, "malformed object "
3593 "(symbol %u must not have NO_SECT for its "
3594 "n_sect field given its type (N_SECT))", j
);
3598 if(n_sect
> nsects
){
3599 warn_member(arch
, member
, "malformed object "
3600 "(symbol %u n_sect field greater than the "
3601 "number of sections in the file)", j
);
3606 if(member
->mh
!= NULL
)
3607 is_toc_symbol
= toc_symbol(symbols
+ j
,
3610 is_toc_symbol
= toc_symbol_64(symbols64
+ j
,
3611 member
->sections64
);
3612 if(is_toc_symbol
== TRUE
){
3613 arch
->toc_nranlibs
++;
3614 arch
->toc_strsize
+= strlen(strings
+ n_strx
) + 1;
3619 if(cmd_flags
.no_warning_for_no_symbols
== FALSE
)
3620 warn_member(arch
, member
, "has no symbols");
3624 else if(member
->lto_contents
== TRUE
){
3625 arch
->toc_nranlibs
+= member
->lto_toc_nsyms
;
3626 arch
->toc_strsize
+= member
->lto_toc_strsize
;
3628 #endif /* LTO_SUPPORT */
3630 if(cmd_flags
.ranlib
== FALSE
){
3631 warn_member(arch
, member
, "is not an object file");
3640 * Allocate the space for the ranlib structs and strings for the
3641 * table of contents.
3643 arch
->toc_ranlibs
= allocate(sizeof(struct ranlib
) *arch
->toc_nranlibs
);
3644 arch
->tocs
= allocate(sizeof(struct toc
) * arch
->toc_nranlibs
);
3645 arch
->toc_strsize
= rnd(arch
->toc_strsize
, 8);
3646 arch
->toc_strings
= allocate(arch
->toc_strsize
);
3649 * Second pass over the members to fill in the ranlib structs and
3650 * the strings for the table of contents. The ran_name field is
3651 * filled in with a pointer to a string contained in arch->toc_strings
3652 * for easy sorting and conversion to an index. The ran_off field is
3653 * filled in with the member index plus one to allow marking with it's
3654 * negative value by check_sort_tocs() and easy conversion to the
3659 for(i
= 0; i
< arch
->nmembers
; i
++){
3660 member
= arch
->members
+ i
;
3661 if(member
->mh
!= NULL
|| member
->mh64
!= NULL
){
3662 if(member
->st
!= NULL
&& member
->st
->nsyms
!= 0){
3663 if(member
->mh
!= NULL
)
3664 symbols
= (struct nlist
*)(member
->object_addr
+
3665 member
->st
->symoff
);
3667 symbols64
= (struct nlist_64
*)(member
->object_addr
+
3668 member
->st
->symoff
);
3669 strings
= member
->object_addr
+ member
->st
->stroff
;
3670 for(j
= 0; j
< member
->st
->nsyms
; j
++){
3671 if(member
->mh
!= NULL
)
3672 n_strx
= symbols
[j
].n_un
.n_strx
;
3674 n_strx
= symbols64
[j
].n_un
.n_strx
;
3675 if(n_strx
> member
->st
->strsize
)
3677 if(member
->mh
!= NULL
)
3678 is_toc_symbol
= toc_symbol(symbols
+ j
,
3681 is_toc_symbol
= toc_symbol_64(symbols64
+ j
,
3682 member
->sections64
);
3683 if(is_toc_symbol
== TRUE
){
3684 strcpy(arch
->toc_strings
+ s
,
3686 arch
->tocs
[r
].name
= arch
->toc_strings
+ s
;
3687 arch
->tocs
[r
].index1
= i
+ 1;
3689 s
+= strlen(strings
+ n_strx
) + 1;
3692 if(member
->object_byte_sex
!= get_host_byte_sex()){
3693 if(member
->mh
!= NULL
)
3694 swap_nlist(symbols
, member
->st
->nsyms
,
3695 member
->object_byte_sex
);
3697 swap_nlist_64(symbols64
, member
->st
->nsyms
,
3698 member
->object_byte_sex
);
3703 else if(member
->lto_contents
== TRUE
){
3704 lto_toc_string
= member
->lto_toc_strings
;
3705 for(j
= 0; j
< member
->lto_toc_nsyms
; j
++){
3706 strcpy(arch
->toc_strings
+ s
, lto_toc_string
);
3707 arch
->tocs
[r
].name
= arch
->toc_strings
+ s
;
3708 arch
->tocs
[r
].index1
= i
+ 1;
3710 s
+= strlen(lto_toc_string
) + 1;
3711 lto_toc_string
+= strlen(lto_toc_string
) + 1;
3714 #endif /* LTO_SUPPORT */
3718 * If the table of contents is to be sorted by symbol name then try to
3719 * sort it and leave it sorted if no duplicates.
3721 if(cmd_flags
.s
== TRUE
){
3722 qsort(arch
->tocs
, arch
->toc_nranlibs
, sizeof(struct toc
),
3723 (int (*)(const void *, const void *))toc_name_qsort
);
3724 sorted
= check_sort_tocs(arch
, output
, FALSE
);
3725 if(sorted
== FALSE
){
3726 qsort(arch
->tocs
, arch
->toc_nranlibs
, sizeof(struct toc
),
3727 (int (*)(const void *, const void *))toc_index1_qsort
);
3728 arch
->toc_name
= SYMDEF
;
3729 arch
->toc_name_size
= sizeof(SYMDEF
) - 1;
3730 if(cmd_flags
.use_long_names
== TRUE
){
3731 arch
->toc_long_name
= TRUE
;
3733 * This assumes that "__.SYMDEF\0\0\0\0\0\0\0" is 16 bytes
3735 * (rnd(sizeof(struct ar_hdr), 8) - sizeof(struct ar_hdr)
3738 ar_name
= AR_EFMT1
"20";
3739 arch
->toc_name_size
= 16;
3740 arch
->toc_name
= SYMDEF
"\0\0\0\0\0\0\0";
3743 arch
->toc_long_name
= FALSE
;
3744 ar_name
= arch
->toc_name
;
3749 * Since the SYMDEF_SORTED is "__.SYMDEF SORTED" which contains
3750 * a space, it should use extended format #1 if we can use long
3753 arch
->toc_name
= SYMDEF_SORTED
;
3754 arch
->toc_name_size
= sizeof(SYMDEF_SORTED
) - 1;
3755 if(cmd_flags
.use_long_names
== TRUE
){
3756 arch
->toc_long_name
= TRUE
;
3758 * This assumes that "__.SYMDEF SORTED" is 16 bytes and
3759 * (rnd(sizeof(struct ar_hdr), 8) - sizeof(struct ar_hdr)
3762 ar_name
= AR_EFMT1
"20";
3765 arch
->toc_long_name
= FALSE
;
3766 ar_name
= arch
->toc_name
;
3772 arch
->toc_name
= SYMDEF
;
3773 arch
->toc_name_size
= sizeof(SYMDEF
) - 1;
3774 if(cmd_flags
.use_long_names
== TRUE
){
3775 arch
->toc_long_name
= TRUE
;
3777 * This assumes that "__.SYMDEF\0\0\0\0\0\0\0" is 16 bytes and
3778 * (rnd(sizeof(struct ar_hdr), 8) - sizeof(struct ar_hdr)
3781 ar_name
= AR_EFMT1
"20";
3782 arch
->toc_name_size
= 16;
3783 arch
->toc_name
= SYMDEF
"\0\0\0\0\0\0\0";
3786 arch
->toc_long_name
= FALSE
;
3787 ar_name
= arch
->toc_name
;
3792 * Now set the ran_off and ran_un.ran_strx fields of the ranlib structs.
3793 * To do this the size of the toc member must be know because it comes
3794 * first in the library. The size of the toc member is made up of the
3795 * sizeof an archive header struct (the size of the name if a long name
3796 * is used) then the toc which is (as defined in ranlib.h):
3797 * a uint32_t for the number of bytes of the ranlib structs
3798 * the ranlib structures
3799 * a uint32_t for the number of bytes of the strings
3802 arch
->toc_size
= sizeof(struct ar_hdr
) +
3804 arch
->toc_nranlibs
* sizeof(struct ranlib
) +
3807 /* add the size of the name is a long name is used */
3808 if(arch
->toc_long_name
== TRUE
)
3809 arch
->toc_size
+= arch
->toc_name_size
+
3810 (rnd(sizeof(struct ar_hdr
), 8) -
3811 sizeof(struct ar_hdr
));
3812 for(i
= 0; i
< arch
->nmembers
; i
++)
3813 arch
->members
[i
].offset
+= SARMAG
+ arch
->toc_size
;
3814 for(i
= 0; i
< arch
->toc_nranlibs
; i
++){
3815 arch
->toc_ranlibs
[i
].ran_un
.ran_strx
=
3816 arch
->tocs
[i
].name
- arch
->toc_strings
;
3817 arch
->toc_ranlibs
[i
].ran_off
=
3818 arch
->members
[arch
->tocs
[i
].index1
- 1].offset
;
3821 sprintf((char *)(&arch
->toc_ar_hdr
), "%-*s%-*ld%-*u%-*u%-*o%-*ld",
3822 (int)sizeof(arch
->toc_ar_hdr
.ar_name
),
3824 (int)sizeof(arch
->toc_ar_hdr
.ar_date
),
3826 (int)sizeof(arch
->toc_ar_hdr
.ar_uid
),
3827 (unsigned short)getuid(),
3828 (int)sizeof(arch
->toc_ar_hdr
.ar_gid
),
3829 (unsigned short)getgid(),
3830 (int)sizeof(arch
->toc_ar_hdr
.ar_mode
),
3831 (unsigned int)toc_mode
,
3832 (int)sizeof(arch
->toc_ar_hdr
.ar_size
),
3833 (long)(arch
->toc_size
- sizeof(struct ar_hdr
)));
3835 * This has to be done by hand because sprintf puts a null
3836 * at the end of the buffer.
3838 memcpy(arch
->toc_ar_hdr
.ar_fmag
, ARFMAG
,
3839 (int)sizeof(arch
->toc_ar_hdr
.ar_fmag
));
3844 * save_lto_member_toc_info() saves away the table of contents info for a
3845 * member that has lto_content. This allows the lto module to be disposed of
3846 * after reading to keep only on in memory at a time. As these turn out to
3847 * use a lot of memory.
3851 save_lto_member_toc_info(
3852 struct member
*member
,
3858 member
->lto_toc_nsyms
= 0;
3859 nsyms
= lto_get_nsyms(mod
);
3860 for(i
= 0; i
< nsyms
; i
++){
3861 if(lto_toc_symbol(mod
, i
, cmd_flags
.c
) == TRUE
){
3862 member
->lto_toc_nsyms
++;
3863 member
->lto_toc_strsize
+= strlen(lto_symbol_name(mod
, i
)) + 1;
3866 member
->lto_toc_strings
= allocate(member
->lto_toc_strsize
);
3867 s
= member
->lto_toc_strings
;
3868 for(i
= 0; i
< nsyms
; i
++){
3869 if(lto_toc_symbol(mod
, i
, cmd_flags
.c
) == TRUE
){
3870 strcpy(s
, lto_symbol_name(mod
, i
));
3871 s
+= strlen(lto_symbol_name(mod
, i
)) + 1;
3875 #endif /* LTO_SUPPORT */
3878 * Function for qsort() for comparing toc structures by name.
3883 const struct toc
*toc1
,
3884 const struct toc
*toc2
)
3886 return(strcmp(toc1
->name
, toc2
->name
));
3890 * Function for qsort() for comparing toc structures by index1.
3895 const struct toc
*toc1
,
3896 const struct toc
*toc2
)
3898 if(toc1
->index1
< toc2
->index1
)
3900 if(toc1
->index1
> toc2
->index1
)
3902 /* toc1->index1 == toc2->index1 */
3907 * toc_symbol() returns TRUE if the symbol is to be included in the table of
3908 * contents otherwise it returns FALSE.
3913 struct nlist
*symbol
,
3914 struct section
**sections
)
3916 return(toc(symbol
->n_un
.n_strx
,
3919 (symbol
->n_type
& N_TYPE
) == N_SECT
&&
3920 sections
[symbol
->n_sect
- 1]->flags
& S_ATTR_NO_TOC
));
3926 struct nlist_64
*symbol64
,
3927 struct section_64
**sections64
)
3929 return(toc(symbol64
->n_un
.n_strx
,
3932 (symbol64
->n_type
& N_TYPE
) == N_SECT
&&
3933 sections64
[symbol64
->n_sect
-1]->flags
& S_ATTR_NO_TOC
));
3942 enum bool attr_no_toc
)
3944 /* if the name is NULL then it won't be in the table of contents */
3947 /* if symbol is not external then it won't be in the toc */
3948 if((n_type
& N_EXT
) == 0)
3950 /* if symbol is undefined then it won't be in the toc */
3951 if((n_type
& N_TYPE
) == N_UNDF
&& n_value
== 0)
3953 /* if symbol is common and the -c flag is not specified then ... */
3954 if((n_type
& N_TYPE
) == N_UNDF
&& n_value
!= 0 &&
3955 cmd_flags
.c
== FALSE
)
3957 /* if the symbols is in a section marked NO_TOC then ... */
3958 if(attr_no_toc
!= 0)
3965 * check_sort_tocs() checks the table of contents for the specified arch
3966 * which is sorted by name for more then one object defining the same symbol.
3967 * It this is the case it prints each symbol that is defined in more than one
3968 * object along with the object it is defined in. It returns TRUE if there are
3969 * no multiple definitions and FALSE otherwise.
3976 enum bool library_warnings
)
3979 enum bool multiple_defs
;
3980 struct member
*member
;
3982 if(arch
->toc_nranlibs
== 0)
3985 * Since the symbol table is sorted by name look to any two adjcent
3986 * entries with the same name. If such entries are found print them
3987 * only once (marked by changing the sign of their ran_off).
3989 multiple_defs
= FALSE
;
3990 for(i
= 0; i
< arch
->toc_nranlibs
- 1; i
++){
3991 if(strcmp(arch
->tocs
[i
].name
, arch
->tocs
[i
+1].name
) == 0){
3992 if(multiple_defs
== FALSE
){
3993 if(library_warnings
== FALSE
)
3995 fprintf(stderr
, "%s: same symbol defined in more than one "
3996 "member ", progname
);
3998 fprintf(stderr
, "for architecture: %s ",
3999 arch
->arch_flag
.name
);
4000 fprintf(stderr
, "in: %s (table of contents will not be "
4001 "sorted)\n", output
);
4002 multiple_defs
= TRUE
;
4004 if((int)(arch
->tocs
[i
].index1
) > 0){
4005 member
= arch
->members
+ arch
->tocs
[i
].index1
- 1;
4006 warn_member(arch
, member
, "defines symbol: %s",
4007 arch
->tocs
[i
].name
);
4008 arch
->tocs
[i
].index1
=
4009 -(arch
->tocs
[i
].index1
);
4011 if((int)(arch
->tocs
[i
+1].index1
) > 0){
4012 member
= arch
->members
+ arch
->tocs
[i
+1].index1
- 1;
4013 warn_member(arch
, member
, "defines symbol: %s",
4014 arch
->tocs
[i
+1].name
);
4015 arch
->tocs
[i
+1].index1
=
4016 -(arch
->tocs
[i
+1].index1
);
4021 if(multiple_defs
== FALSE
)
4024 for(i
= 0; i
< arch
->toc_nranlibs
; i
++)
4025 if(((int)arch
->tocs
[i
].index1
) < 0)
4026 arch
->tocs
[i
].index1
=
4027 -(arch
->tocs
[i
].index1
);
4033 * warn_duplicate_member_names() generates a warning if two members end up with
4034 * the same ar_name. This is only a warning because ld(1) and this program
4035 * has no problems with it. Only if ar(1) were used to extract the files
4036 * would this be a problem (even the 4.4bsd ar(1) using long names can
4037 * get hosed by base names, the 4.3bsd ar(1) can't handle full 16 character
4042 warn_duplicate_member_names(
4045 uint32_t i
, j
, len
, len1
, len2
;
4047 for(i
= 0; i
< narchs
; i
++){
4048 /* sort in order of ar_names */
4049 qsort(archs
[i
].members
, archs
[i
].nmembers
, sizeof(struct member
),
4050 (int (*)(const void *, const void *))member_name_qsort
);
4052 /* check for duplicate names */
4053 for(j
= 0; j
< archs
[i
].nmembers
- 1; j
++){
4054 len1
= archs
[i
].members
[j
].member_name_size
;
4055 len2
= archs
[i
].members
[j
+1].member_name_size
;
4056 len
= len1
> len2
? len1
: len2
;
4057 if(strncmp(archs
[i
].members
[j
].member_name
,
4058 archs
[i
].members
[j
+1].member_name
,
4060 fprintf(stderr
, "%s: warning ", progname
);
4062 fprintf(stderr
, "for architecture: %s ",
4063 archs
[i
].arch_flag
.name
);
4064 fprintf(stderr
, "same member name (%.*s) in output file "
4065 "used for input files: ", (int)len1
,
4066 archs
[i
].members
[j
].member_name
);
4068 if(archs
[i
].members
[j
].input_ar_hdr
!= NULL
){
4069 len
= archs
[i
].members
[j
].input_base_name_size
;
4070 fprintf(stderr
, "%s(%.*s) and: ",
4071 archs
[i
].members
[j
].input_file_name
, (int)len
,
4072 archs
[i
].members
[j
].input_base_name
);
4075 fprintf(stderr
, "%s and: ",
4076 archs
[i
].members
[j
].input_file_name
);
4078 if(archs
[i
].members
[j
+1].input_ar_hdr
!= NULL
){
4079 len
= archs
[i
].members
[j
+1].input_base_name_size
;
4080 fprintf(stderr
, "%s(%.*s) due to use of basename, "
4081 "truncation and blank padding\n",
4082 archs
[i
].members
[j
+1].input_file_name
, (int)len
,
4083 archs
[i
].members
[j
+1].input_base_name
);
4086 fprintf(stderr
, "%s (due to use of basename, truncation"
4087 ", blank padding or duplicate input files)\n",
4088 archs
[i
].members
[j
+1].input_file_name
);
4092 /* sort back in order of offset */
4093 qsort(archs
[i
].members
, archs
[i
].nmembers
, sizeof(struct member
),
4094 (int (*)(const void *, const void *))member_offset_qsort
);
4099 * Function for qsort() for comparing member structures by ar_hdr.ar_name.
4104 const struct member
*member1
,
4105 const struct member
*member2
)
4107 uint32_t len
, len1
, len2
;
4109 len1
= member1
->member_name_size
;
4110 len2
= member2
->member_name_size
;
4111 len
= len1
> len2
? len1
: len2
;
4112 return(strncmp(member1
->member_name
, member2
->member_name
, len
));
4116 * Function for qsort() for comparing member structures by offset.
4120 member_offset_qsort(
4121 const struct member
*member1
,
4122 const struct member
*member2
)
4124 if(member1
->offset
< member2
->offset
)
4126 if(member1
->offset
> member2
->offset
)
4128 /* member1->offset == member2->offset */
4133 * warn_member() is like the error routines it prints the program name the
4134 * member name specified and message specified.
4140 struct member
*member
,
4141 const char *format
, ...)
4145 fprintf(stderr
, "%s: ", progname
);
4147 fprintf(stderr
, "for architecture: %s ", arch
->arch_flag
.name
);
4149 if(member
->input_ar_hdr
!= NULL
){
4150 fprintf(stderr
, "file: %s(%.*s) ", member
->input_file_name
,
4151 (int)member
->input_base_name_size
, member
->input_base_name
);
4154 fprintf(stderr
, "file: %s ", member
->input_file_name
);
4156 va_start(ap
, format
);
4157 vfprintf(stderr
, format
, ap
);
4158 fprintf(stderr
, "\n");
4163 * Prints the message to cmd_flags.trace_file_path, or stderr if that
4169 const char *format
, ...)
4171 static int trace_file
= -1;
4172 char trace_buffer
[MAXPATHLEN
* 2];
4175 ssize_t amount_written
;
4177 if(trace_file
== -1){
4178 if(cmd_flags
.trace_file_path
!= NULL
){
4179 trace_file
= open(cmd_flags
.trace_file_path
, O_WRONLY
| O_APPEND
| O_CREAT
, 0666);
4180 if(trace_file
== -1)
4181 error("Could not open or create trace file: %s\n", cmd_flags
.trace_file_path
);
4184 trace_file
= fileno(stderr
);
4189 va_start(ap
, format
);
4190 length
= vsnprintf(trace_buffer
, sizeof(trace_buffer
), format
, ap
);
4192 buffer_ptr
= trace_buffer
;
4194 amount_written
= write(trace_file
, buffer_ptr
, length
);
4195 if(amount_written
== -1)
4196 /* Failure to write shouldn't fail the build. */
4198 buffer_ptr
+= amount_written
;
4199 length
-= amount_written
;