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 */
151 static struct cmd_flags cmd_flags
= { 0 };
153 /* The value of the environment variable NEXT_ROOT */
154 static char *next_root
= NULL
;
156 /* the standard directories to search for -lx names */
157 char *standard_dirs
[] = {
165 * The input files are broken down in to their object files and then placed in
166 * these structures. They are sorted by architecture type and then each object
167 * has a member struct created for it in one of the arch structs. All of these
168 * structs hang off of 'archs'.
170 static struct arch
*archs
= NULL
;
171 static uint32_t narchs
= 0;
174 struct arch_flag arch_flag
; /* the identifing info of this architecture */
175 uint64_t size
; /* current working size and final size */
177 /* the table of contents (toc) stuff for this architecture in the library */
178 uint32_t toc_size
; /* total size of the toc including ar_hdr */
179 struct ar_hdr toc_ar_hdr
; /* the archive header for this member */
180 enum bool toc_long_name
; /* use the long name in the output */
181 char *toc_name
; /* name of toc member */
182 uint32_t toc_name_size
;/* size of name of toc member */
183 struct toc
*tocs
; /* internal table of contents */
184 struct ranlib
*toc_ranlibs
; /* ranlib structs for output */
185 uint32_t toc_nranlibs
;/* number of ranlib structs */
186 char *toc_strings
; /* strings of symbol names for ranlib structs */
187 uint32_t toc_strsize
; /* number of bytes for the strings above */
189 /* the members of this architecture in the library */
190 struct member
*members
; /* the members of the library for this arch */
191 uint32_t nmembers
; /* the number of the above members */
195 uint32_t offset
; /* current working offset and final offset*/
196 struct ar_hdr ar_hdr
; /* the archive header for this member */
197 char null_byte
; /* space to write '\0' for ar_hdr */
198 char *object_addr
; /* the address of the object file */
199 uint32_t object_size
; /* the size of the object file */
200 enum byte_sex object_byte_sex
; /* the byte sex of the object file */
201 struct mach_header
*mh
; /* the mach_header of 32-bit object files */
202 struct mach_header_64
*mh64
; /* the mach_header of 64-bit object files */
203 struct load_command
/* the start of the load commands */
205 struct symtab_command
*st
; /* the symbol table command */
206 struct section
**sections
; /* array of section structs for 32-bit */
207 struct section_64
**sections64
; /* array of section structs for 64-bit */
209 void *lto
; /* lto module */
210 #endif /* LTO_SUPPORT */
212 /* the name of the member in the output */
213 char *member_name
; /* the member name */
214 uint32_t member_name_size
; /* the size of the member name */
215 enum bool output_long_name
; /* use the extended format #1 for the
216 member name in the output */
218 /* info recorded from the input file this member came from */
219 char *input_file_name
; /* the input file name */
220 char *input_base_name
; /* the base name in the input file */
221 uint32_t input_base_name_size
; /* the size of the base name */
222 struct ar_hdr
*input_ar_hdr
;
223 uint32_t input_member_offset
; /* if from a thin archive */
230 static char *file_name_from_l_flag(
232 static char *search_for_file(
234 static char * search_paths_for_lname(
235 const char *lname_argument
);
236 static char * search_path_for_lname(
238 const char *lname_argument
);
239 static void add_member(
240 struct ofile
*ofile
);
241 static void free_archs(
243 static void create_library(
245 struct ofile
*ofile
);
246 static enum byte_sex
get_target_byte_sex(
248 enum byte_sex host_byte_sex
);
249 static char *put_toc_member(
252 enum byte_sex host_byte_sex
,
253 enum byte_sex target_byte_sex
);
254 static void create_dynamic_shared_library(
256 static void create_dynamic_shared_library_cleanup(
258 static void make_table_of_contents(
261 static int toc_name_qsort(
262 const struct toc
*toc1
,
263 const struct toc
*toc2
);
264 static int toc_index1_qsort(
265 const struct toc
*toc1
,
266 const struct toc
*toc2
);
267 static enum bool toc_symbol(
268 struct nlist
*symbol
,
269 struct section
**sections
);
270 static enum bool toc_symbol_64(
271 struct nlist_64
*symbol64
,
272 struct section_64
**sections64
);
273 static enum bool toc(
277 enum bool attr_no_toc
);
278 static enum bool check_sort_tocs(
281 enum bool library_warnings
);
282 static void warn_duplicate_member_names(
284 static int member_name_qsort(
285 const struct member
*member1
,
286 const struct member
*member2
);
287 static int member_offset_qsort(
288 const struct member
*member1
,
289 const struct member
*member2
);
290 static void warn_member(
292 struct member
*member
,
293 const char *format
, ...) __attribute__ ((format (printf
, 3, 4)));
294 static void ld_trace(
295 const char *format
, ...) __attribute__ ((format (printf
, 1, 2)));
298 * This structure is used to describe blocks of the output file that are flushed
299 * to the disk file with output_flush. It is kept in an ordered list starting
300 * with output_blocks.
302 static struct block
{
303 uint64_t offset
; /* starting offset of this block */
304 uint64_t size
; /* size of this block */
305 uint64_t written_offset
;/* first page offset after starting offset */
306 uint64_t written_size
; /* size of written area from written_offset */
307 struct block
*next
; /* next block in the list */
310 static void output_flush(
312 uint64_t library_size
,
316 static void final_output_flush(
320 static void print_block_list(void);
322 static struct block
*get_block(void);
323 static void remove_block(
324 struct block
*block
);
325 static uint32_t trnc(
329 /* apple_version is in vers.c which is created by the libstuff/Makefile */
330 extern char apple_version
[];
338 char *p
, *endp
, *filelist
, *dirname
, *addr
;
340 struct stat stat_buf
;
341 uint32_t j
, nfiles
, maxfiles
;
344 enum bool lflags_seen
, bad_flag_seen
, Vflag
;
350 host_byte_sex
= get_host_byte_sex();
353 * The environment variable ZERO_AR_DATE is used here and other
354 * places that write archives to allow testing and comparing
355 * things for exact binary equality.
357 if(getenv("ZERO_AR_DATE") == NULL
)
358 zero_ar_date
= FALSE
;
361 if(zero_ar_date
== FALSE
)
367 oumask
= umask(numask
);
368 toc_mode
= S_IFREG
| (0666 & ~oumask
);
371 /* see if this is being run as ranlib */
372 p
= strrchr(argv
[0], '/');
377 if(strncmp(p
, "ranlib", sizeof("ranlib") - 1) == 0)
378 cmd_flags
.ranlib
= TRUE
;
380 /* The default is to used long names */
381 cmd_flags
.use_long_names
= TRUE
;
383 /* process the command line arguments and collect the files */
385 cmd_flags
.files
= allocate(sizeof(char *) * maxfiles
);
386 cmd_flags
.filelist
= allocate(sizeof(char *) * maxfiles
);
387 memset(cmd_flags
.filelist
, '\0', sizeof(char *) * maxfiles
);
388 for(i
= 1; i
< argc
; i
++){
389 if(argv
[i
][0] == '-'){
390 if(argv
[i
][1] == '\0'){
391 for(i
+= 1 ; i
< argc
; i
++)
392 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
];
395 if(strcmp(argv
[i
], "-o") == 0){
396 if(cmd_flags
.ranlib
== TRUE
){
397 error("unknown option: %s", argv
[i
]);
401 error("missing argument to: %s option", argv
[i
]);
404 if(cmd_flags
.output
!= NULL
){
405 error("more than one: %s option specified", argv
[i
]);
408 cmd_flags
.output
= argv
[i
+1];
411 else if(strcmp(argv
[i
], "-arch_only") == 0){
412 if(cmd_flags
.ranlib
== TRUE
){
413 error("unknown option: %s", argv
[i
]);
417 error("missing argument to %s option", argv
[i
]);
420 if(cmd_flags
.arch_only_flag
.name
!= NULL
){
421 error("more than one: %s option specified", argv
[i
]);
425 if(get_arch_from_flag(argv
[i
+1],
426 &cmd_flags
.arch_only_flag
) == 0){
427 error("unknown architecture specification flag: "
428 "%s %s", argv
[i
], argv
[i
+1]);
435 else if(strcmp(argv
[i
], "-dynamic") == 0){
436 if(cmd_flags
.ranlib
== TRUE
){
437 error("unknown option: %s", argv
[i
]);
440 cmd_flags
.dynamic
= TRUE
;
442 else if(strcmp(argv
[i
], "-static") == 0){
443 if(cmd_flags
.ranlib
== TRUE
){
444 error("unknown option: %s", argv
[i
]);
447 cmd_flags
.dynamic
= FALSE
;
449 else if(strcmp(argv
[i
], "-filelist") == 0){
450 if(cmd_flags
.ranlib
== TRUE
){
451 error("unknown option: %s", argv
[i
]);
455 error("missing argument to: %s option", argv
[i
]);
458 filelist
= argv
[i
+ 1];
459 dirname
= strrchr(filelist
, ',');
466 if((fd
= open(filelist
, O_RDONLY
, 0)) == -1)
467 system_fatal("can't open file list file: %s", filelist
);
468 if(fstat(fd
, &stat_buf
) == -1)
469 system_fatal("can't stat file list file: %s", filelist
);
471 * For some reason mapping files with zero size fails
472 * so it has to be handled specially.
475 if(stat_buf
.st_size
!= 0){
476 addr
= mmap(0, stat_buf
.st_size
, PROT_READ
|PROT_WRITE
,
477 MAP_FILE
|MAP_PRIVATE
, fd
, 0);
478 if((intptr_t)addr
== -1)
479 system_error("can't map file list file: %s",
483 fatal("file list file: %s is empty", filelist
);
489 for(j
= 0; j
< stat_buf
.st_size
; j
++){
493 if(addr
[stat_buf
.st_size
- 1] != '\n')
495 p
= allocate((strlen(dirname
) + 1) * nfiles
+
497 cmd_flags
.files
= reallocate(cmd_flags
.files
,
498 sizeof(char *) * (maxfiles
+ nfiles
));
499 cmd_flags
.filelist
= reallocate(cmd_flags
.filelist
,
500 sizeof(char *) * (maxfiles
+ nfiles
));
501 memset(cmd_flags
.filelist
+ maxfiles
, '\0',
502 sizeof(char *) * nfiles
);
505 cmd_flags
.files
[cmd_flags
.nfiles
] = p
;
506 cmd_flags
.filelist
[cmd_flags
.nfiles
] = filelist
;
508 if(*dirname
!= '\0'){
510 p
+= strlen(dirname
);
513 for(j
= 0; j
< stat_buf
.st_size
; j
++){
518 if(j
!= stat_buf
.st_size
- 1){
519 cmd_flags
.files
[cmd_flags
.nfiles
] = p
;
520 cmd_flags
.filelist
[cmd_flags
.nfiles
] =argv
[i
+1];
522 if(*dirname
!= '\0'){
524 p
+= strlen(dirname
);
530 if(addr
[stat_buf
.st_size
- 1] != '\n')
534 else if(strcmp(argv
[i
], "-compatibility_version") == 0){
535 if(cmd_flags
.ranlib
== TRUE
){
536 error("unknown option: %s", argv
[i
]);
540 error("missing argument to: %s option", argv
[i
]);
543 if(cmd_flags
.compatibility
!= NULL
){
544 error("more than one: %s option specified", argv
[i
]);
547 if(get_version_number(argv
[i
], argv
[i
+1], &temp
) == FALSE
){
550 cmd_flags
.compatibility
= argv
[i
+1];
553 else if(strcmp(argv
[i
], "-current_version") == 0){
554 if(cmd_flags
.ranlib
== TRUE
){
555 error("unknown option: %s", argv
[i
]);
559 error("missing argument to: %s option", argv
[i
]);
562 if(cmd_flags
.current
!= NULL
){
563 error("more than one: %s option specified", argv
[i
]);
566 if(get_version_number(argv
[i
], argv
[i
+1], &temp
) == FALSE
){
569 cmd_flags
.current
= argv
[i
+1];
572 else if(strcmp(argv
[i
], "-install_name") == 0){
573 if(cmd_flags
.ranlib
== TRUE
){
574 error("unknown option: %s", argv
[i
]);
578 error("missing argument to: %s option", argv
[i
]);
581 if(cmd_flags
.install_name
!= NULL
){
582 error("more than one: %s option specified", argv
[i
]);
585 cmd_flags
.install_name
= argv
[i
+1];
588 else if(strcmp(argv
[i
], "-seg1addr") == 0 ||
589 strcmp(argv
[i
], "-image_base") == 0){
590 if(cmd_flags
.ranlib
== TRUE
){
591 error("unknown option: %s", argv
[i
]);
595 error("missing argument to: %s option", argv
[i
]);
598 if(cmd_flags
.seg1addr
!= NULL
){
599 error("more than one: %s option specified", argv
[i
]);
602 temp
= strtoul(argv
[i
+ 1], &endp
, 16);
604 error("address for -seg1addr %s not a proper "
605 "hexadecimal number", argv
[i
+1]);
608 cmd_flags
.seg1addr
= argv
[i
+1];
611 else if(strcmp(argv
[i
], "-segs_read_only_addr") == 0){
612 if(cmd_flags
.ranlib
== TRUE
){
613 error("unknown option: %s", argv
[i
]);
617 error("missing argument to: %s option", argv
[i
]);
620 if(cmd_flags
.segs_read_only_addr
!= NULL
){
621 error("more than one: %s option specified", argv
[i
]);
624 temp
= strtoul(argv
[i
+ 1], &endp
, 16);
626 error("address for -segs_read_only_addr %s not a "
627 "proper hexadecimal number", argv
[i
+1]);
630 cmd_flags
.segs_read_only_addr
= argv
[i
+1];
633 else if(strcmp(argv
[i
], "-segs_read_write_addr") == 0){
634 if(cmd_flags
.ranlib
== TRUE
){
635 error("unknown option: %s", argv
[i
]);
639 error("missing argument to: %s option", argv
[i
]);
642 if(cmd_flags
.segs_read_write_addr
!= NULL
){
643 error("more than one: %s option specified", argv
[i
]);
646 temp
= strtoul(argv
[i
+ 1], &endp
, 16);
648 error("address for -segs_read_write_addr %s not a "
649 "proper hexadecimal number", argv
[i
+1]);
652 cmd_flags
.segs_read_write_addr
= argv
[i
+1];
655 else if(strcmp(argv
[i
], "-seg_addr_table") == 0){
656 if(cmd_flags
.ranlib
== TRUE
){
657 error("unknown option: %s", argv
[i
]);
661 error("missing argument to: %s option", argv
[i
]);
664 if(cmd_flags
.seg_addr_table
!= NULL
){
665 error("more than one: %s option specified", argv
[i
]);
668 cmd_flags
.seg_addr_table
= argv
[i
+1];
671 else if(strcmp(argv
[i
], "-seg_addr_table_filename") == 0){
672 if(cmd_flags
.ranlib
== TRUE
){
673 error("unknown option: %s", argv
[i
]);
677 error("missing argument to: %s option", argv
[i
]);
680 if(cmd_flags
.seg_addr_table_filename
!= NULL
){
681 error("more than one: %s option specified", argv
[i
]);
684 cmd_flags
.seg_addr_table_filename
= argv
[i
+1];
687 else if(strcmp(argv
[i
], "-syslibroot") == 0){
688 if(cmd_flags
.ranlib
== TRUE
){
689 error("unknown option: %s", argv
[i
]);
693 error("missing argument to: %s option", argv
[i
]);
696 if(next_root
!= NULL
&& strcmp(next_root
, argv
[i
+1]) != 0){
697 error("more than one: %s option specified", argv
[i
]);
700 next_root
= argv
[i
+1];
701 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
702 sizeof(char *) * (cmd_flags
.nldflags
+ 2));
703 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
704 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
+1];
707 else if(strcmp(argv
[i
], "-sectcreate") == 0 ||
708 strcmp(argv
[i
], "-segcreate") == 0 ||
709 strcmp(argv
[i
], "-sectorder") == 0 ||
710 strcmp(argv
[i
], "-sectalign") == 0 ||
711 strcmp(argv
[i
], "-segprot") == 0){
712 if(cmd_flags
.ranlib
== TRUE
){
713 error("unknown option: %s", argv
[i
]);
717 error("not enough arguments follow %s", argv
[i
]);
720 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
721 sizeof(char *) * (cmd_flags
.nldflags
+ 4));
722 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
723 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
+1];
724 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
+2];
725 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
+3];
726 if(strcmp(argv
[i
], "-sectcreate") == 0 ||
727 strcmp(argv
[i
], "-segcreate") == 0)
728 cmd_flags
.no_files_ok
= TRUE
;
731 else if(strcmp(argv
[i
], "-segalign") == 0 ||
732 strcmp(argv
[i
], "-undefined") == 0 ||
733 strcmp(argv
[i
], "-macosx_version_min") == 0 ||
734 strcmp(argv
[i
], "-multiply_defined") == 0 ||
735 strcmp(argv
[i
], "-multiply_defined_unused") == 0 ||
736 strcmp(argv
[i
], "-umbrella") == 0 ||
737 strcmp(argv
[i
], "-sub_umbrella") == 0 ||
738 strcmp(argv
[i
], "-sub_library") == 0 ||
739 strcmp(argv
[i
], "-allowable_client") == 0 ||
740 strcmp(argv
[i
], "-read_only_relocs") == 0 ||
741 strcmp(argv
[i
], "-init") == 0 ||
742 strcmp(argv
[i
], "-U") == 0 ||
743 strcmp(argv
[i
], "-Y") == 0 ||
744 strcmp(argv
[i
], "-dylib_file") == 0 ||
745 strcmp(argv
[i
], "-final_output") == 0 ||
746 strcmp(argv
[i
], "-headerpad") == 0 ||
747 strcmp(argv
[i
], "-weak_reference_mismatches") == 0 ||
748 strcmp(argv
[i
], "-u") == 0 ||
749 strcmp(argv
[i
], "-exported_symbols_list") == 0 ||
750 strcmp(argv
[i
], "-unexported_symbols_list") == 0 ||
751 strcmp(argv
[i
], "-executable_path") == 0){
752 if(cmd_flags
.ranlib
== TRUE
){
753 error("unknown option: %s", argv
[i
]);
757 error("not enough arguments follow %s", argv
[i
]);
760 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
761 sizeof(char *) * (cmd_flags
.nldflags
+ 2));
762 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
763 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
+1];
764 if(strcmp(argv
[i
], "-final_output") == 0)
765 cmd_flags
.final_output_specified
= TRUE
;
768 else if(strcmp(argv
[i
], "-sectorder_detail") == 0 ||
769 strcmp(argv
[i
], "-Sn") == 0 ||
770 strcmp(argv
[i
], "-Si") == 0 ||
771 strcmp(argv
[i
], "-Sp") == 0 ||
772 strcmp(argv
[i
], "-S") == 0 ||
773 strcmp(argv
[i
], "-X") == 0 ||
774 strcmp(argv
[i
], "-x") == 0 ||
775 strcmp(argv
[i
], "-whatsloaded") == 0 ||
776 strcmp(argv
[i
], "-whyload") == 0 ||
777 strcmp(argv
[i
], "-arch_errors_fatal") == 0 ||
778 strcmp(argv
[i
], "-run_init_lazily") == 0 ||
779 strcmp(argv
[i
], "-twolevel_namespace") == 0 ||
780 strcmp(argv
[i
], "-twolevel_namespace_hints") == 0 ||
781 strcmp(argv
[i
], "-flat_namespace") == 0 ||
782 strcmp(argv
[i
], "-nomultidefs") == 0 ||
783 strcmp(argv
[i
], "-headerpad_max_install_names") == 0 ||
784 strcmp(argv
[i
], "-prebind_all_twolevel_modules") == 0 ||
785 strcmp(argv
[i
], "-prebind_allow_overlap") == 0 ||
786 strcmp(argv
[i
], "-ObjC") == 0 ||
787 strcmp(argv
[i
], "-M") == 0 ||
788 strcmp(argv
[i
], "-t") == 0 ||
789 strcmp(argv
[i
], "-single_module") == 0 ||
790 strcmp(argv
[i
], "-multi_module") == 0 ||
791 strcmp(argv
[i
], "-m") == 0 ||
792 strcmp(argv
[i
], "-dead_strip") == 0 ||
793 strcmp(argv
[i
], "-no_uuid") == 0 ||
794 strcmp(argv
[i
], "-no_dead_strip_inits_and_terms") == 0){
795 if(cmd_flags
.ranlib
== TRUE
){
796 error("unknown option: %s", argv
[i
]);
799 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
800 sizeof(char *) * (cmd_flags
.nldflags
+ 1));
801 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
803 else if(strcmp(argv
[i
], "-no_arch_warnings") == 0){
804 if(cmd_flags
.ranlib
== TRUE
){
805 error("unknown option: %s", argv
[i
]);
808 /* ignore this flag */
810 else if(strcmp(argv
[i
], "-prebind") == 0){
811 if(cmd_flags
.ranlib
== TRUE
){
812 error("unknown option: %s", argv
[i
]);
815 if(cmd_flags
.prebinding_flag_specified
== TRUE
&&
816 cmd_flags
.prebinding
== FALSE
){
817 error("both -prebind and -noprebind can't be "
821 cmd_flags
.prebinding_flag_specified
= TRUE
;
822 cmd_flags
.prebinding
= TRUE
;
823 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
824 sizeof(char *) * (cmd_flags
.nldflags
+ 1));
825 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
827 else if(strcmp(argv
[i
], "-noprebind") == 0){
828 if(cmd_flags
.ranlib
== TRUE
){
829 error("unknown option: %s", argv
[i
]);
832 if(cmd_flags
.prebinding_flag_specified
== TRUE
&&
833 cmd_flags
.prebinding
== TRUE
){
834 error("both -prebind and -noprebind can't be "
838 cmd_flags
.prebinding_flag_specified
= TRUE
;
839 cmd_flags
.prebinding
= FALSE
;
840 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
841 sizeof(char *) * (cmd_flags
.nldflags
+ 1));
842 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
844 else if(strcmp(argv
[i
], "-all_load") == 0){
845 if(cmd_flags
.ranlib
== TRUE
){
846 error("unknown option: %s", argv
[i
]);
849 if(cmd_flags
.all_load_flag_specified
== TRUE
&&
850 cmd_flags
.all_load
== FALSE
){
851 error("both -all_load and -noall_load can't be "
855 cmd_flags
.all_load_flag_specified
= TRUE
;
856 cmd_flags
.all_load
= TRUE
;
858 else if(strcmp(argv
[i
], "-noall_load") == 0){
859 if(cmd_flags
.ranlib
== TRUE
){
860 error("unknown option: %s", argv
[i
]);
863 if(cmd_flags
.all_load_flag_specified
== TRUE
&&
864 cmd_flags
.all_load
== TRUE
){
865 error("both -all_load and -noall_load can't be "
869 cmd_flags
.all_load_flag_specified
= TRUE
;
870 cmd_flags
.all_load
= FALSE
;
872 else if(strncmp(argv
[i
], "-y", 2) == 0 ||
873 strncmp(argv
[i
], "-i", 2) == 0){
874 if(cmd_flags
.ranlib
== TRUE
){
875 error("unknown option: %s", argv
[i
]);
878 if(strncmp(argv
[i
], "-i", 2) == 0)
879 cmd_flags
.no_files_ok
= TRUE
;
880 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
881 sizeof(char *) * (cmd_flags
.nldflags
+ 1));
882 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
884 else if(argv
[i
][1] == 'l'){
885 if(cmd_flags
.ranlib
== TRUE
){
886 error("unknown option: %s", argv
[i
]);
889 if(argv
[i
][2] == '\0'){
890 error("-l: name missing");
893 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
];
896 else if(strncmp(argv
[i
], "-weak-l", 7) == 0){
897 if(cmd_flags
.ranlib
== TRUE
){
898 error("unknown option: %s", argv
[i
]);
901 if(argv
[i
][7] == '\0'){
902 error("-weak-l: name missing");
905 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
];
908 else if(strcmp(argv
[i
], "-framework") == 0 ||
909 strcmp(argv
[i
], "-weak_framework") == 0 ||
910 strcmp(argv
[i
], "-weak_library") == 0){
911 if(cmd_flags
.ranlib
== TRUE
){
912 error("unknown option: %s", argv
[i
]);
916 error("not enough arguments follow %s", argv
[i
]);
919 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
];
920 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
+1];
924 else if(strcmp(argv
[i
], "-T") == 0){
925 if(cmd_flags
.L_or_T_specified
== TRUE
){
926 error("both -T and -L can't be specified");
929 cmd_flags
.L_or_T_specified
= TRUE
;
930 cmd_flags
.use_long_names
= FALSE
;
932 else if(argv
[i
][1] == 'L' || argv
[i
][1] == 'F'){
933 if(argv
[i
][1] == 'L' && argv
[i
][2] == '\0'){
934 if(cmd_flags
.L_or_T_specified
== TRUE
){
935 error("both -T and -L can't be specified");
938 cmd_flags
.L_or_T_specified
= TRUE
;
939 cmd_flags
.use_long_names
= TRUE
;
942 if(cmd_flags
.ranlib
== TRUE
){
943 error("unknown option: %s", argv
[i
]);
946 cmd_flags
.Ldirs
= realloc(cmd_flags
.Ldirs
,
947 sizeof(char *) * (cmd_flags
.nLdirs
+ 1));
948 cmd_flags
.Ldirs
[cmd_flags
.nLdirs
++] = argv
[i
];
951 else if(argv
[i
][1] == 'g'){
952 if(cmd_flags
.ranlib
== TRUE
){
953 error("unknown option: %s", argv
[i
]);
956 /* We need to ignore -g[gdb,codeview,stab][number] flags */
959 else if(strcmp(argv
[i
], "-pg") == 0){
960 if(cmd_flags
.ranlib
== TRUE
){
961 error("unknown option: %s", argv
[i
]);
964 /* We need to ignore -pg */
967 else if(strcmp(argv
[i
], "-search_paths_first") == 0){
968 if(cmd_flags
.ranlib
== TRUE
){
969 error("unknown option: %s", argv
[i
]);
972 cmd_flags
.search_paths_first
= TRUE
;
973 cmd_flags
.ldflags
= reallocate(cmd_flags
.ldflags
,
974 sizeof(char *) * (cmd_flags
.nldflags
+ 1));
975 cmd_flags
.ldflags
[cmd_flags
.nldflags
++] = argv
[i
];
977 else if(strcmp(argv
[i
], "-noflush") == 0){
978 cmd_flags
.noflush
= TRUE
;
981 else if(strcmp(argv
[i
], "-debug") == 0){
983 error("not enough arguments follow %s", argv
[i
]);
987 cmd_flags
.debug
|= 1 << strtoul(argv
[i
], &endp
, 10);
988 if(*endp
!= '\0' || strtoul(argv
[i
], &endp
, 10) > 32)
989 fatal("argument for -debug %s not a proper "
990 "decimal number less than 32", argv
[i
]);
994 for(j
= 1; argv
[i
][j
] != '\0'; j
++){
1006 if(cmd_flags
.ranlib
== TRUE
){
1007 error("unknown option character `%c' in: %s",
1008 argv
[i
][j
], argv
[i
]);
1011 cmd_flags
.verbose
= TRUE
;
1014 printf("Apple Inc. version %s\n", apple_version
);
1018 if(cmd_flags
.ranlib
== TRUE
){
1019 warning("touch option (`%c' in: %s) ignored "
1020 "(table of contents rebuilt anyway)",
1021 argv
[i
][j
], argv
[i
]);
1026 error("unknown option character `%c' in: %s",
1027 argv
[i
][j
], argv
[i
]);
1031 if(cmd_flags
.ranlib
== TRUE
){
1036 error("unknown option character `%c' in: %s",
1037 argv
[i
][j
], argv
[i
]);
1041 if(cmd_flags
.ranlib
== TRUE
){
1046 error("unknown option character `%c' in: %s",
1047 argv
[i
][j
], argv
[i
]);
1051 error("unknown option character `%c' in: %s",
1052 argv
[i
][j
], argv
[i
]);
1059 cmd_flags
.files
[cmd_flags
.nfiles
++] = argv
[i
];
1062 * Test to see if the environment variable LD_TRACE_ARCHIVES is set.
1064 if((getenv("RC_TRACE_ARCHIVES") != NULL
) ||
1065 (getenv("LD_TRACE_ARCHIVES") != NULL
)) {
1066 cmd_flags
.ld_trace_archives
= TRUE
;
1067 cmd_flags
.trace_file_path
= getenv("LD_TRACE_FILE");
1071 * If either -syslibroot or the environment variable NEXT_ROOT is set
1072 * prepend it to the standard paths for library searches. This was
1073 * added to ease cross build environments.
1075 if(next_root
!= NULL
){
1076 if(getenv("NEXT_ROOT") != NULL
)
1077 warning("NEXT_ROOT environment variable ignored because "
1078 "-syslibroot specified");
1081 next_root
= getenv("NEXT_ROOT");
1083 if(next_root
!= NULL
){
1084 for(i
= 0; standard_dirs
[i
] != NULL
; i
++){
1085 p
= allocate(strlen(next_root
) +
1086 strlen(standard_dirs
[i
]) + 1);
1087 strcpy(p
, next_root
);
1088 strcat(p
, standard_dirs
[i
]);
1089 standard_dirs
[i
] = p
;
1091 for(i
= 0; i
< cmd_flags
.nLdirs
; i
++){
1092 if(cmd_flags
.Ldirs
[i
][1] != 'L')
1094 if(cmd_flags
.Ldirs
[i
][2] == '/'){
1095 p
= makestr(next_root
, cmd_flags
.Ldirs
[i
] + 2, NULL
);
1096 if(access(p
, F_OK
) != -1){
1098 p
= makestr("-L", next_root
, cmd_flags
.Ldirs
[i
] + 2,
1100 cmd_flags
.Ldirs
[i
] = p
;
1109 /* check the command line arguments for correctness */
1110 if(cmd_flags
.ranlib
== FALSE
&& cmd_flags
.dynamic
== TRUE
){
1111 if(cmd_flags
.s
== TRUE
){
1112 warning("-static not specified, -s invalid");
1114 if(cmd_flags
.a
== TRUE
){
1115 warning("-static not specified, -a invalid");
1117 if(cmd_flags
.c
== TRUE
){
1118 warning("-static not specified, -c invalid");
1120 if(cmd_flags
.L_or_T_specified
== TRUE
){
1121 if(cmd_flags
.use_long_names
== TRUE
)
1122 warning("-static not specified, -L invalid");
1124 warning("-static not specified, -T invalid");
1127 if(cmd_flags
.s
== TRUE
&& cmd_flags
.a
== TRUE
){
1128 error("only one of -s or -a can be specified");
1131 if(cmd_flags
.ranlib
== FALSE
&& cmd_flags
.output
== NULL
){
1134 error("no output file specified (specify with -o output)");
1137 if(cmd_flags
.dynamic
== FALSE
){
1138 if(cmd_flags
.compatibility
!= NULL
){
1139 warning("-dynamic not specified, -compatibility_version %s "
1140 "invalid", cmd_flags
.compatibility
);
1142 if(cmd_flags
.current
!= NULL
){
1143 warning("-dynamic not specified, -current_version %s invalid",
1146 if(cmd_flags
.install_name
!= NULL
){
1147 warning("-dynamic not specified, -install_name %s invalid",
1148 cmd_flags
.install_name
);
1150 if(cmd_flags
.seg1addr
!= NULL
){
1151 warning("-dynamic not specified, -seg1addr %s invalid",
1152 cmd_flags
.seg1addr
);
1154 if(cmd_flags
.segs_read_only_addr
!= NULL
){
1155 warning("-dynamic not specified, -segs_read_only_addr %s "
1156 "invalid", cmd_flags
.segs_read_only_addr
);
1158 if(cmd_flags
.segs_read_write_addr
!= NULL
){
1159 warning("-dynamic not specified, -segs_read_write_addr %s "
1160 "invalid", cmd_flags
.segs_read_write_addr
);
1162 if(cmd_flags
.seg_addr_table
!= NULL
){
1163 warning("-dynamic not specified, -seg_addr_table %s "
1164 "invalid", cmd_flags
.seg_addr_table
);
1166 if(cmd_flags
.seg_addr_table_filename
!= NULL
){
1167 warning("-dynamic not specified, -seg_addr_table_filename %s "
1168 "invalid", cmd_flags
.seg_addr_table_filename
);
1170 if(cmd_flags
.all_load_flag_specified
== TRUE
){
1171 if(cmd_flags
.all_load
== TRUE
)
1172 warning("-dynamic not specified, -all_load invalid");
1174 warning("-dynamic not specified, -noall_load invalid");
1176 if(cmd_flags
.nldflags
!= 0){
1177 bad_flag_seen
= FALSE
;
1178 for(j
= 0; j
< cmd_flags
.nldflags
; j
++){
1179 if(strcmp(cmd_flags
.ldflags
[j
], "-syslibroot") == 0){
1183 if(bad_flag_seen
== FALSE
){
1184 fprintf(stderr
, "%s: -dynamic not specified the "
1185 "following flags are invalid: ", progname
);
1186 bad_flag_seen
= TRUE
;
1188 fprintf(stderr
, "%s ", cmd_flags
.ldflags
[j
]);
1190 if(bad_flag_seen
== TRUE
)
1191 fprintf(stderr
, "\n");
1193 if(cmd_flags
.nLdirs
!= 0){
1194 /* Note: both -L and -F flags are in cmd_flags.Ldirs to keep the
1195 search order right. */
1196 bad_flag_seen
= FALSE
;
1197 for(j
= 0; j
< cmd_flags
.nLdirs
; j
++){
1198 if(strncmp(cmd_flags
.Ldirs
[j
], "-L", 2) == 0)
1200 if(bad_flag_seen
== FALSE
){
1201 fprintf(stderr
, "%s: -dynamic not specified the "
1202 "following flags are invalid: ", progname
);
1203 bad_flag_seen
= TRUE
;
1205 fprintf(stderr
, "%s ", cmd_flags
.Ldirs
[j
]);
1207 if(bad_flag_seen
== TRUE
)
1208 fprintf(stderr
, "\n");
1213 * The -prebind flag can also be specified with the LD_PREBIND
1214 * environment variable.
1216 if(getenv("LD_PREBIND") != NULL
){
1217 if(cmd_flags
.prebinding_flag_specified
== TRUE
&&
1218 cmd_flags
.prebinding
== FALSE
){
1219 warning("LD_PREBIND environment variable ignored because "
1220 "-noprebind specified");
1223 cmd_flags
.prebinding_flag_specified
= TRUE
;
1224 cmd_flags
.prebinding
= TRUE
;
1228 if(cmd_flags
.nfiles
== 0){
1229 if(cmd_flags
.ranlib
== TRUE
){
1230 error("no archives specified");
1234 if(cmd_flags
.dynamic
== TRUE
&& cmd_flags
.no_files_ok
== TRUE
)
1235 warning("warning no files specified");
1237 error("no files specified");
1243 /* set the defaults if not specified */
1244 if(cmd_flags
.a
== FALSE
)
1245 cmd_flags
.s
= TRUE
; /* sort table of contents by default */
1250 return(EXIT_SUCCESS
);
1252 return(EXIT_FAILURE
);
1256 * usage() prints the current usage message and exits indicating failure.
1263 if(cmd_flags
.ranlib
)
1264 fprintf(stderr
, "Usage: %s [-sactfqLT] [-] archive [...]\n",
1267 fprintf(stderr
, "Usage: %s -static [-] file [...] "
1268 "[-filelist listfile[,dirname]] [-arch_only arch] "
1269 "[-sacLT]\n", progname
);
1270 fprintf(stderr
, "Usage: %s -dynamic [-] file [...] "
1271 "[-filelist listfile[,dirname]] [-arch_only arch] "
1272 "[-o output] [-install_name name] "
1273 "[-compatibility_version #] [-current_version #] "
1274 "[-seg1addr 0x#] [-segs_read_only_addr 0x#] "
1275 "[-segs_read_write_addr 0x#] [-seg_addr_table <filename>] "
1276 "[-seg_addr_table_filename <file_system_path>] "
1277 "[-all_load] [-noall_load]\n",
1284 * process() the input files into libraries based on the command flags.
1291 uint32_t i
, j
, k
, previous_errors
;
1292 struct ofile
*ofiles
;
1294 enum bool flag
, ld_trace_archive_printed
;
1297 * For libtool processing put all input files in the specified output
1298 * file. For ranlib processing all input files should be archives or
1299 * fat files with archives in them and each is processed by itself and
1300 * not combined with anything else. The format of fat object files in
1301 * a thin archive is supported here also.
1303 ofiles
= allocate(sizeof(struct ofile
) * cmd_flags
.nfiles
);
1304 for(i
= 0; i
< cmd_flags
.nfiles
; i
++){
1305 if(strncmp(cmd_flags
.files
[i
], "-l", 2) == 0 ||
1306 strncmp(cmd_flags
.files
[i
], "-weak-l", 7) == 0){
1307 file_name
= file_name_from_l_flag(cmd_flags
.files
[i
]);
1308 if(file_name
!= NULL
)
1309 if(ofile_map(file_name
, NULL
, NULL
, ofiles
+ i
, TRUE
) ==
1313 else if(strcmp(cmd_flags
.files
[i
], "-framework") == 0 ||
1314 strcmp(cmd_flags
.files
[i
], "-weak_framework") == 0 ||
1315 strcmp(cmd_flags
.files
[i
], "-weak_library") == 0){
1320 if(ofile_map(cmd_flags
.files
[i
], NULL
, NULL
, ofiles
+ i
,
1325 previous_errors
= errors
;
1327 ld_trace_archive_printed
= FALSE
;
1329 if(ofiles
[i
].file_type
== OFILE_FAT
){
1330 (void)ofile_first_arch(ofiles
+ i
);
1332 if(ofiles
[i
].arch_type
== OFILE_ARCHIVE
){
1333 if(cmd_flags
.ld_trace_archives
== TRUE
&&
1334 cmd_flags
.dynamic
== FALSE
&&
1335 ld_trace_archive_printed
== FALSE
){
1336 char resolvedname
[MAXPATHLEN
];
1337 if(realpath(ofiles
[i
].file_name
, resolvedname
) !=
1339 ld_trace("[Logging for XBS] Used static "
1340 "archive: %s\n", resolvedname
);
1342 ld_trace("[Logging for XBS] Used static "
1343 "archive: %s\n", ofiles
[i
].file_name
);
1344 ld_trace_archive_printed
= TRUE
;
1346 /* loop through archive */
1347 if((flag
= ofile_first_member(ofiles
+ i
)) == TRUE
){
1348 if(ofiles
[i
].member_ar_hdr
!= NULL
&&
1349 strncmp(ofiles
[i
].member_name
, SYMDEF
,
1350 sizeof(SYMDEF
) - 1) == 0)
1351 flag
= ofile_next_member(ofiles
+ i
);
1352 while(flag
== TRUE
){
1353 /* No fat members in a fat file */
1354 if(ofiles
[i
].mh
!= NULL
||
1355 ofiles
[i
].mh64
!= NULL
||
1356 ofiles
[i
].lto
!= NULL
||
1357 cmd_flags
.ranlib
== TRUE
)
1358 add_member(ofiles
+ i
);
1360 error("for architecture: %s file: %s(%.*s) "
1361 "is not an object file (not allowed "
1363 ofiles
[i
].arch_flag
.name
,
1365 (int)ofiles
[i
].member_name_size
,
1366 ofiles
[i
].member_name
);
1368 flag
= ofile_next_member(ofiles
+ i
);
1372 else if(ofiles
[i
].arch_type
== OFILE_Mach_O
||
1373 ofiles
[i
].arch_type
== OFILE_LLVM_BITCODE
){
1374 if(cmd_flags
.ranlib
== TRUE
){
1375 error("for architecture: %s file: %s is not an "
1376 "archive (no processing done on this file)",
1377 ofiles
[i
].arch_flag
.name
, cmd_flags
.files
[i
]);
1378 goto ranlib_fat_error
;
1381 add_member(ofiles
+ i
);
1383 else if(ofiles
[i
].arch_type
== OFILE_UNKNOWN
){
1384 if(cmd_flags
.ranlib
== TRUE
){
1385 error("for architecture: %s file: %s is not an "
1386 "archive (no processing done on this file)",
1387 ofiles
[i
].arch_flag
.name
, cmd_flags
.files
[i
]);
1388 goto ranlib_fat_error
;
1391 error("for architecture: %s file: %s is not an "
1392 "object file (not allowed in a library)",
1393 ofiles
[i
].arch_flag
.name
, cmd_flags
.files
[i
]);
1396 }while(ofile_next_arch(ofiles
+ i
) == TRUE
);
1398 else if(ofiles
[i
].file_type
== OFILE_ARCHIVE
){
1399 if(cmd_flags
.ld_trace_archives
== TRUE
&&
1400 cmd_flags
.dynamic
== FALSE
&&
1401 ld_trace_archive_printed
== FALSE
){
1402 char resolvedname
[MAXPATHLEN
];
1403 if(realpath(ofiles
[i
].file_name
, resolvedname
) != NULL
)
1404 ld_trace("[Logging for XBS] Used static archive: "
1405 "%s\n", resolvedname
);
1407 ld_trace("[Logging for XBS] Used static archive: "
1408 "%s\n", ofiles
[i
].file_name
);
1409 ld_trace_archive_printed
= TRUE
;
1411 /* loop through archive */
1412 if((flag
= ofile_first_member(ofiles
+ i
)) == TRUE
){
1413 if(ofiles
[i
].member_ar_hdr
!= NULL
&&
1414 strncmp(ofiles
[i
].member_name
, SYMDEF
,
1415 sizeof(SYMDEF
) - 1) == 0){
1416 flag
= ofile_next_member(ofiles
+ i
);
1418 while(flag
== TRUE
){
1419 /* incorrect form: archive with fat object members */
1420 if(ofiles
[i
].member_type
== OFILE_FAT
){
1421 (void)ofile_first_arch(ofiles
+ i
);
1423 if(ofiles
[i
].mh
!= NULL
||
1424 ofiles
[i
].mh64
!= NULL
||
1425 ofiles
[i
].lto
!= NULL
||
1426 cmd_flags
.ranlib
== TRUE
){
1427 add_member(ofiles
+ i
);
1431 * Can't really get here because ofile_*()
1432 * routines will refuse to process this
1433 * type of file (but I'll leave it here).
1435 error("file: %s(%.*s) for architecture: %s "
1436 "is not an object file (not allowed in "
1437 "a library)", cmd_flags
.files
[i
],
1438 (int)ofiles
[i
].member_name_size
,
1439 ofiles
[i
].member_name
,
1440 ofiles
[i
].arch_flag
.name
);
1443 }while(ofile_next_arch(ofiles
+ i
) == TRUE
);
1445 else if(ofiles
[i
].mh
!= NULL
||
1446 ofiles
[i
].mh64
!= NULL
||
1448 ofiles
[i
].lto
!= NULL
||
1449 #endif /* LTO_SUPPORT */
1450 cmd_flags
.ranlib
== TRUE
){
1451 add_member(ofiles
+ i
);
1454 error("file: %s(%.*s) is not an object file (not "
1455 "allowed in a library)", cmd_flags
.files
[i
],
1456 (int)ofiles
[i
].member_name_size
,
1457 ofiles
[i
].member_name
);
1459 flag
= ofile_next_member(ofiles
+ i
);
1463 else if(ofiles
[i
].file_type
== OFILE_Mach_O
){
1464 if(cmd_flags
.ranlib
== TRUE
){
1465 error("file: %s is not an archive", cmd_flags
.files
[i
]);
1468 add_member(ofiles
+ i
);
1471 else if(ofiles
[i
].file_type
== OFILE_LLVM_BITCODE
){
1472 if(cmd_flags
.ranlib
== TRUE
){
1473 error("file: %s is not an archive", cmd_flags
.files
[i
]);
1476 add_member(ofiles
+ i
);
1478 #endif /* LTO_SUPPORT */
1479 else{ /* ofiles[i].file_type == OFILE_UNKNOWN */
1480 if(cmd_flags
.ranlib
== TRUE
){
1481 error("file: %s is not an archive", cmd_flags
.files
[i
]);
1485 error("file: %s is not an object file (not allowed in a "
1486 "library)", cmd_flags
.files
[i
]);
1490 if(cmd_flags
.ranlib
== TRUE
){
1492 * In the case where ranlib is being used on an archive that
1493 * contains fat object files with multiple members and non-
1494 * object members this has to be treated as an error because
1495 * it is not known which architecture(s) the non-object file
1499 for(j
= 0; j
< narchs
; j
++){
1500 for(k
= 0; k
< archs
[j
].nmembers
; k
++){
1501 if(archs
[j
].members
[k
].mh
== NULL
&&
1503 archs
[j
].members
[k
].lto
== NULL
&&
1504 #endif /* LTO_SUPPORT */
1505 archs
[j
].members
[k
].mh64
== NULL
){
1506 error("library member: %s(%.*s) is not an "
1507 "object file (not allowed in a library "
1508 "with multiple architectures)",
1510 (int)archs
[j
].members
[k
].
1511 input_base_name_size
,
1512 archs
[j
].members
[k
].input_base_name
);
1518 create_library(cmd_flags
.files
[i
], ofiles
+ i
);
1519 if(cmd_flags
.nfiles
> 1){
1522 ofile_unmap(ofiles
+ i
);
1525 errors
+= previous_errors
;
1527 if(cmd_flags
.ranlib
== FALSE
&& errors
== 0)
1528 create_library(cmd_flags
.output
, NULL
);
1531 * Clean-up of ofiles[] and archs could be done here but since this
1532 * program is now done it is faster to just exit.
1537 * file_name_from_l_flag() is passed a "-lx" or "-weak-lx" flag and returns a
1538 * name of a file for this flag. The flag "-lx" and "-weak-lx" are the same
1539 * flags as used in the link editor to refer to file names. If it can't find a
1540 * file name for the flag it prints an error and returns NULL.
1544 file_name_from_l_flag(
1547 char *file_name
, *p
, *start
;
1549 if(strncmp(l_flag
, "-weak-l", 7) == 0)
1553 p
= strrchr(start
, '.');
1554 if(p
!= NULL
&& strcmp(p
, ".o") == 0){
1556 file_name
= search_for_file(p
);
1560 if(cmd_flags
.dynamic
== TRUE
){
1561 if(cmd_flags
.search_paths_first
== TRUE
){
1562 file_name
= search_paths_for_lname(start
);
1565 p
= makestr("lib", start
, ".dylib", NULL
);
1566 file_name
= search_for_file(p
);
1568 if(file_name
== NULL
){
1569 p
= makestr("lib", start
, ".a", NULL
);
1570 file_name
= search_for_file(p
);
1576 p
= makestr("lib", start
, ".a", NULL
);
1577 file_name
= search_for_file(p
);
1581 if(file_name
== NULL
)
1582 error("can't locate file for: %s", l_flag
);
1587 * search_for_file() takes base_name and trys to find a file with that base name
1588 * is the -L search directories and in the standard directories. If it is
1589 * sucessful it returns a pointer to the file name else it returns NULL.
1599 for(i
= 0; i
< cmd_flags
.nLdirs
; i
++){
1600 if(cmd_flags
.Ldirs
[i
][1] != 'L')
1602 file_name
= makestr(cmd_flags
.Ldirs
[i
] + 2, "/", base_name
, NULL
);
1603 if(access(file_name
, R_OK
) != -1)
1607 for(i
= 0; standard_dirs
[i
] != NULL
; i
++){
1608 file_name
= makestr(standard_dirs
[i
], base_name
, NULL
);
1609 if(access(file_name
, R_OK
) != -1)
1617 * search_paths_for_lname() takes the argument to a -lx option and and trys to
1618 * find a file with the name libx.dylib or libx.a. This routine is only used
1619 * when the -search_paths_first option is specified and -dynamic is in effect.
1620 * And looks for a file name ending in .dylib then .a in each directory before
1621 * looking in the next directory. The list of the -L search directories and in
1622 * the standard directories are searched in that order. If this is sucessful
1623 * it returns a pointer to the file name else NULL.
1627 search_paths_for_lname(
1628 const char *lname_argument
)
1631 char *file_name
, *dir
;
1633 for(i
= 0; i
< cmd_flags
.nLdirs
; i
++){
1634 if(cmd_flags
.Ldirs
[i
][1] != 'L')
1636 dir
= makestr(cmd_flags
.Ldirs
[i
] + 2, "/", NULL
);
1637 file_name
= search_path_for_lname(dir
, lname_argument
);
1639 if(file_name
!= NULL
)
1642 for(i
= 0; standard_dirs
[i
] != NULL
; i
++){
1643 file_name
= search_path_for_lname(standard_dirs
[i
], lname_argument
);
1644 if(file_name
!= NULL
)
1651 * search_path_for_lname() takes the argument to a -lx option and and trys to
1652 * find a file with the name libx.dylib then libx.a in the specified directory
1653 * name. This routine is only used when the -search_paths_first option is
1654 * specified and -dynamic is in effect. If this is sucessful it returns a
1655 * pointer to the file name else NULL.
1659 search_path_for_lname(
1661 const char *lname_argument
)
1665 file_name
= makestr(dir
, "/", "lib", lname_argument
, ".dylib", NULL
);
1666 if(access(file_name
, R_OK
) != -1)
1670 file_name
= makestr(dir
, "/", "lib", lname_argument
, ".a", NULL
);
1671 if(access(file_name
, R_OK
) != -1)
1679 * add_member() add the specified ofile as a member to the library. The
1680 * specified ofile must be either an object file (libtool or ranlib) or an
1681 * archive member with an unknown file type (ranlib only).
1686 struct ofile
*ofile
)
1688 uint32_t i
, j
, size
, ar_name_size
;
1690 struct member
*member
;
1691 struct stat stat_buf
;
1692 char *p
, c
, ar_name_buf
[sizeof(ofile
->member_ar_hdr
->ar_name
) + 1];
1693 char ar_size_buf
[sizeof(ofile
->member_ar_hdr
->ar_size
) + 1];
1694 const struct arch_flag
*family_arch_flag
;
1697 * If this did not come from an archive get the stat info which is
1698 * needed to fill in the archive header for this member.
1700 if(ofile
->member_ar_hdr
== NULL
){
1701 if(stat(ofile
->file_name
, &stat_buf
) == -1){
1702 system_error("can't stat file: %s", ofile
->file_name
);
1708 * Determine the size this member will have in the library which
1709 * includes the padding as a result of rounding the size of the
1710 * member. To get all members on an 8 byte boundary (so that mapping
1711 * in object files can be used directly) the size of the member is
1712 * CHANGED to reflect this padding. In the UNIX definition of archives
1713 * the size of the member is never changed but the offset to the next
1714 * member is defined to be the offset of the previous member plus
1715 * the size of the previous member rounded to 2. So to get 8 byte
1716 * boundaries without breaking the UNIX definition of archives the
1717 * size is changed here. As with the UNIX ar(1) program the padded
1718 * bytes are set to the character '\n'.
1720 if(ofile
->mh
!= NULL
|| ofile
->mh64
!= NULL
)
1721 size
= rnd(ofile
->object_size
, 8);
1723 else if(ofile
->lto
!= NULL
&& ofile
->file_type
== OFILE_LLVM_BITCODE
)
1724 size
= rnd(ofile
->file_size
, 8);
1725 #endif /* LTO_SUPPORT */
1727 size
= rnd(ofile
->member_size
, 8);
1729 /* select or create an arch type to put this in */
1731 if(ofile
->mh
!= NULL
||
1732 ofile
->mh64
!= NULL
){
1733 if(ofile
->mh_cputype
== 0){
1734 if(ofile
->member_ar_hdr
!= NULL
){
1735 error("file: %s(%.*s) cputype is zero (a reserved value)",
1736 ofile
->file_name
, (int)ofile
->member_name_size
,
1737 ofile
->member_name
);
1740 error("file: %s cputype is zero (a reserved value)",
1745 * If we are building a dynamic library then don't add dynamic
1746 * shared libraries to the archs. This is so that a dependent
1747 * dynamic shared library that happens to be fat will not cause the
1748 * library to be created fat unless there are object going into
1749 * the library that are fat.
1751 if(ofile
->mh_filetype
== MH_DYLIB
||
1752 ofile
->mh_filetype
== MH_DYLIB_STUB
){
1754 * If we are building a static library we should not put a
1755 * dynamic library Mach-O file into the static library. This
1756 * can happen if a libx.a file is really a dynamic library and
1757 * someone is using -lx when creating a static library.
1759 if(cmd_flags
.dynamic
!= TRUE
){
1760 if(ofile
->member_ar_hdr
!= NULL
){
1761 warning("file: %s(%.*s) is a dynamic library, not "
1762 "added to the static library",
1763 ofile
->file_name
, (int)ofile
->member_name_size
,
1764 ofile
->member_name
);
1767 warning("file: %s is a dynamic library, not added to "
1768 "the static library", ofile
->file_name
);
1773 * If -arch_only is specified then only add this file if it matches
1774 * the architecture specified.
1776 if(cmd_flags
.arch_only_flag
.name
!= NULL
){
1777 if(cmd_flags
.arch_only_flag
.cputype
!= ofile
->mh_cputype
)
1779 if(cmd_flags
.arch_only_flag
.cputype
== CPU_TYPE_ARM
){
1780 if(cmd_flags
.arch_only_flag
.cpusubtype
!=
1781 ofile
->mh_cpusubtype
)
1786 for( ; i
< narchs
; i
++){
1787 if(archs
[i
].arch_flag
.cputype
== ofile
->mh_cputype
){
1788 if(archs
[i
].arch_flag
.cputype
== CPU_TYPE_ARM
&&
1789 archs
[i
].arch_flag
.cpusubtype
!= ofile
->mh_cpusubtype
)
1796 else if(ofile
->lto
!= NULL
){
1798 * If -arch_only is specified then only add this file if it matches
1799 * the architecture specified.
1801 if(cmd_flags
.arch_only_flag
.name
!= NULL
&&
1802 cmd_flags
.arch_only_flag
.cputype
!= ofile
->lto_cputype
)
1805 for( ; i
< narchs
; i
++){
1806 if(archs
[i
].arch_flag
.cputype
== ofile
->lto_cputype
){
1807 if(archs
[i
].arch_flag
.cputype
== CPU_TYPE_ARM
&&
1808 archs
[i
].arch_flag
.cpusubtype
!= ofile
->lto_cpusubtype
)
1814 #endif /* LTO_SUPPORT */
1815 if(narchs
== 1 && archs
[0].arch_flag
.cputype
== 0){
1818 else if(i
== narchs
){
1819 archs
= reallocate(archs
, sizeof(struct arch
) * (narchs
+1));
1820 memset(archs
+ narchs
, '\0', sizeof(struct arch
));
1821 if(ofile
->mh
!= NULL
||
1822 ofile
->mh64
!= NULL
){
1823 if(ofile
->mh_cputype
== CPU_TYPE_ARM
){
1824 archs
[narchs
].arch_flag
.name
= (char *)
1825 get_arch_name_from_types(
1826 ofile
->mh_cputype
, ofile
->mh_cpusubtype
);
1827 archs
[narchs
].arch_flag
.cputype
= ofile
->mh_cputype
;
1828 archs
[narchs
].arch_flag
.cpusubtype
= ofile
->mh_cpusubtype
;
1832 get_arch_family_from_cputype(ofile
->mh_cputype
);
1833 if(family_arch_flag
!= NULL
)
1834 archs
[narchs
].arch_flag
= *family_arch_flag
;
1838 else if(ofile
->lto
!= NULL
){
1839 if(ofile
->lto_cputype
== CPU_TYPE_ARM
){
1840 archs
[narchs
].arch_flag
.name
= (char *)
1841 get_arch_name_from_types(
1842 ofile
->lto_cputype
, ofile
->lto_cpusubtype
);
1843 archs
[narchs
].arch_flag
.cputype
= ofile
->lto_cputype
;
1844 archs
[narchs
].arch_flag
.cpusubtype
= ofile
->lto_cpusubtype
;
1848 get_arch_family_from_cputype(ofile
->lto_cputype
);
1849 if(family_arch_flag
!= NULL
)
1850 archs
[narchs
].arch_flag
= *family_arch_flag
;
1853 #endif /* LTO_SUPPORT */
1855 archs
[narchs
].arch_flag
.name
= "unknown";
1861 * If the cputype of this arch is not yet known then see if this new
1862 * member can determine it.
1864 if(arch
->arch_flag
.cputype
== 0 &&
1865 (ofile
->mh
!= NULL
|| ofile
->mh64
!= NULL
)){
1866 family_arch_flag
= get_arch_family_from_cputype(ofile
->mh_cputype
);
1867 if(family_arch_flag
!= NULL
){
1868 arch
->arch_flag
= *family_arch_flag
;
1871 arch
->arch_flag
.name
=
1872 savestr("cputype 1234567890 cpusubtype 1234567890");
1873 if(arch
->arch_flag
.name
!= NULL
)
1874 sprintf(arch
->arch_flag
.name
, "cputype %u cpusubtype %u",
1875 ofile
->mh_cputype
, ofile
->mh_cpusubtype
&
1877 arch
->arch_flag
.cputype
= ofile
->mh_cputype
;
1878 arch
->arch_flag
.cpusubtype
= ofile
->mh_cpusubtype
;
1882 if(arch
->arch_flag
.cputype
== 0 &&
1883 (ofile
->lto
!= NULL
)){
1884 family_arch_flag
= get_arch_family_from_cputype(ofile
->lto_cputype
);
1885 if(family_arch_flag
!= NULL
){
1886 arch
->arch_flag
= *family_arch_flag
;
1889 arch
->arch_flag
.name
=
1890 savestr("cputype 1234567890 cpusubtype 1234567890");
1891 if(arch
->arch_flag
.name
!= NULL
)
1892 sprintf(arch
->arch_flag
.name
, "cputype %u cpusubtype %u",
1893 ofile
->lto_cputype
, ofile
->lto_cpusubtype
&
1895 arch
->arch_flag
.cputype
= ofile
->lto_cputype
;
1896 arch
->arch_flag
.cpusubtype
= ofile
->lto_cpusubtype
;
1899 #endif /* LTO_SUPPORT */
1901 /* create a member in this arch type for this member */
1902 arch
->members
= reallocate(arch
->members
, sizeof(struct member
) *
1903 (arch
->nmembers
+ 1));
1904 member
= arch
->members
+ arch
->nmembers
;
1905 memset(member
, '\0', sizeof(struct member
));
1908 /* fill in the member for this ofile */
1909 member
->input_file_name
= ofile
->file_name
;
1911 if(ofile
->member_ar_hdr
== NULL
){
1913 * We are creating an archive member in the output file from a
1914 * file (that is not archive member in an input file). First get
1915 * the base name the file_name for the member name.
1917 p
= strrchr(ofile
->file_name
, '/');
1921 p
= ofile
->file_name
;
1922 member
->input_base_name
= p
;
1923 member
->input_base_name_size
= strlen(p
);
1924 member
->member_name
= member
->input_base_name
;
1926 * If we can use long names then force using them to allow 64-bit
1927 * objects to be aligned on an 8 byte boundary. This is needed
1928 * since the struct ar_hdr is not a multiple of 8. This is normally
1929 * done if the name does not fit in the archive header or contains
1930 * a space character then we use the extened format #1. The size
1931 * of the name is rounded up so the object file after the name will
1932 * be on an 8 byte boundary (including rounding the size of the
1933 * struct ar_hdr). The name will be padded with '\0's when it is
1936 if(cmd_flags
.use_long_names
== TRUE
){
1937 member
->output_long_name
= TRUE
;
1938 member
->member_name_size
= member
->input_base_name_size
;
1939 ar_name_size
= rnd(member
->input_base_name_size
, 8) +
1940 (rnd(sizeof(struct ar_hdr
), 8) -
1941 sizeof(struct ar_hdr
));
1942 sprintf(ar_name_buf
, "%s%-*lu", AR_EFMT1
,
1943 (int)(sizeof(member
->ar_hdr
.ar_name
) -
1944 (sizeof(AR_EFMT1
) - 1)),
1945 (long unsigned int)ar_name_size
);
1946 memcpy(member
->ar_hdr
.ar_name
, ar_name_buf
,
1947 sizeof(member
->ar_hdr
.ar_name
));
1951 member
->output_long_name
= FALSE
;
1953 * Truncate the file_name if needed and place in archive header.
1956 if(strlen(p
) > sizeof(member
->ar_hdr
.ar_name
)){
1957 c
= p
[sizeof(member
->ar_hdr
.ar_name
)];
1958 p
[sizeof(member
->ar_hdr
.ar_name
)] = '\0';
1960 sprintf((char *)(&member
->ar_hdr
), "%-*s",
1961 (int)sizeof(member
->ar_hdr
.ar_name
), p
);
1963 p
[sizeof(member
->ar_hdr
.ar_name
)] = c
;
1964 member
->member_name_size
= size_ar_name(&member
->ar_hdr
);
1966 if(zero_ar_date
== TRUE
)
1967 stat_buf
.st_mtime
= 0;
1969 * Create the rest of the archive header after the name.
1971 sprintf((char *)(&member
->ar_hdr
) + sizeof(member
->ar_hdr
.ar_name
),
1972 "%-*ld%-*u%-*u%-*o%-*ld%-*s",
1973 (int)sizeof(member
->ar_hdr
.ar_date
),
1974 (long int)stat_buf
.st_mtime
,
1975 (int)sizeof(member
->ar_hdr
.ar_uid
),
1976 (unsigned short)stat_buf
.st_uid
,
1977 (int)sizeof(member
->ar_hdr
.ar_gid
),
1978 (unsigned short)stat_buf
.st_gid
,
1979 (int)sizeof(member
->ar_hdr
.ar_mode
),
1980 (unsigned int)stat_buf
.st_mode
,
1981 (int)sizeof(member
->ar_hdr
.ar_size
),
1982 (long)size
+ ar_name_size
,
1983 (int)sizeof(member
->ar_hdr
.ar_fmag
),
1988 * We are creating an archive member in the output file from an
1989 * archive member in an input file. There can be some changes to
1990 * the contents. First the size might be changed and the contents
1991 * padded with '\n's to round it to a multiple of 8
1992 * Second we may take a member using extended format #1
1993 * for it's name and truncate it then place the name in the archive
1994 * header. Or we may round the name size to a multiple of 8.
1996 member
->input_ar_hdr
= ofile
->member_ar_hdr
;
1997 member
->input_base_name
= ofile
->member_name
;
1998 member
->input_base_name_size
= ofile
->member_name_size
;
1999 member
->input_member_offset
= ofile
->member_offset
-
2000 sizeof(struct ar_hdr
);
2001 if(strncmp(ofile
->member_ar_hdr
->ar_name
, AR_EFMT1
,
2002 sizeof(AR_EFMT1
) - 1) == 0)
2003 member
->input_member_offset
-= ofile
->member_name_size
;
2005 member
->ar_hdr
= *(ofile
->member_ar_hdr
);
2006 member
->member_name
= ofile
->member_name
;
2008 if(cmd_flags
.use_long_names
== TRUE
){
2010 * We can use long names. So if the input ofile is using the
2011 * extended format #1 we need make sure the size of the name and
2012 * the size of struct ar_hdr are rounded to 8 bytes. And write
2013 * that size into the ar_name with the AR_EFMT1 string. To
2014 * avoid growing the size of names first trim the long name size
2015 * before rounding up.
2017 if(ofile
->member_name
!= ofile
->member_ar_hdr
->ar_name
){
2018 member
->output_long_name
= TRUE
;
2019 member
->member_name_size
= ofile
->member_name_size
;
2020 for(ar_name_size
= member
->member_name_size
;
2023 if(ofile
->member_name
[ar_name_size
- 1] != '\0')
2026 member
->member_name_size
= ar_name_size
;
2027 ar_name_size
= rnd(ar_name_size
, 8) +
2028 (rnd(sizeof(struct ar_hdr
), 8) -
2029 sizeof(struct ar_hdr
));
2030 sprintf(ar_name_buf
, "%s%-*lu", AR_EFMT1
,
2031 (int)(sizeof(member
->ar_hdr
.ar_name
) -
2032 (sizeof(AR_EFMT1
) - 1)),
2033 (long unsigned int)ar_name_size
);
2034 memcpy(member
->ar_hdr
.ar_name
, ar_name_buf
,
2035 sizeof(member
->ar_hdr
.ar_name
));
2039 * Since we can use long names force this to use extended
2040 * format #1. And round the name size to 8 plus the size of
2041 * struct ar_hdr rounded to 8 bytes.
2043 member
->member_name_size
= size_ar_name(&member
->ar_hdr
);
2044 ar_name_size
= rnd(ofile
->member_name_size
, 8) +
2045 (rnd(sizeof(struct ar_hdr
), 8) -
2046 sizeof(struct ar_hdr
));
2047 member
->output_long_name
= TRUE
;
2048 sprintf(ar_name_buf
, "%s%-*lu", AR_EFMT1
,
2049 (int)(sizeof(member
->ar_hdr
.ar_name
) -
2050 (sizeof(AR_EFMT1
) - 1)),
2051 (long unsigned int)ar_name_size
);
2052 memcpy(member
->ar_hdr
.ar_name
, ar_name_buf
,
2053 sizeof(member
->ar_hdr
.ar_name
));
2058 * We can't use long names. So if the input ofile is using the
2059 * extended format #1 we need to truncate the name and write it
2060 * into the ar_name field. Note the extended format is also
2061 * used it the name has a space in it so it may be shorter than
2062 * sizeof(ar_hdr.ar_name) .
2065 member
->output_long_name
= FALSE
;
2066 if(ofile
->member_name
!= ofile
->member_ar_hdr
->ar_name
){
2067 for(j
= 0; j
< sizeof(member
->ar_hdr
.ar_name
) &&
2068 j
< ofile
->member_name_size
&&
2069 ofile
->member_name
[j
] != '\0'; j
++)
2070 member
->ar_hdr
.ar_name
[j
] = ofile
->member_name
[j
];
2071 for( ; j
< sizeof(member
->ar_hdr
.ar_name
); j
++)
2072 member
->ar_hdr
.ar_name
[j
] = ' ';
2074 member
->member_name_size
= size_ar_name(&member
->ar_hdr
);
2077 * Since sprintf() writes a '\0' at the end of the string the
2078 * memcpy is needed to preserve the ARFMAG string that follows.
2080 sprintf(ar_size_buf
, "%-*ld",
2081 (int)sizeof(member
->ar_hdr
.ar_size
),
2082 (long)size
+ ar_name_size
);
2083 memcpy(member
->ar_hdr
.ar_size
, ar_size_buf
,
2084 sizeof(member
->ar_hdr
.ar_size
));
2087 member
->offset
= arch
->size
;
2088 arch
->size
+= sizeof(struct ar_hdr
) + size
+ ar_name_size
;
2090 if(ofile
->mh
!= NULL
||
2091 ofile
->mh64
!= NULL
){
2092 member
->object_addr
= ofile
->object_addr
;
2093 member
->object_size
= ofile
->object_size
;
2094 member
->object_byte_sex
= ofile
->object_byte_sex
;
2095 member
->mh
= ofile
->mh
;
2096 member
->mh64
= ofile
->mh64
;
2097 member
->load_commands
= ofile
->load_commands
;
2100 else if(ofile
->file_type
== OFILE_LLVM_BITCODE
){
2101 member
->object_addr
= ofile
->file_addr
;
2102 member
->object_size
= ofile
->file_size
;
2103 member
->lto
= ofile
->lto
;
2104 member
->object_byte_sex
= get_byte_sex_from_flag(&arch
->arch_flag
);
2106 #endif /* LTO_SUPPORT */
2108 member
->object_addr
= ofile
->member_addr
;
2109 member
->object_size
= ofile
->member_size
;
2111 if(ofile
->lto
!= NULL
){
2112 member
->lto
= ofile
->lto
;
2113 member
->object_byte_sex
= get_byte_sex_from_flag(
2116 #endif /* LTO_SUPPORT */
2121 * free_archs() frees the memory allocated that is pointed to by archs.
2130 for(i
= 0 ; i
< narchs
; i
++){
2132 * Just leak memory on the arch_flag.name in some cases
2133 * (unknown archiectures only where the space is malloced and
2134 * a sprintf() is done into the memory)
2136 if(archs
[i
].tocs
!= NULL
)
2137 free(archs
[i
].tocs
);
2138 if(archs
[i
].toc_ranlibs
!= NULL
)
2139 free(archs
[i
].toc_ranlibs
);
2140 if(archs
[i
].toc_strings
!= NULL
)
2141 free(archs
[i
].toc_strings
);
2142 if(archs
[i
].members
!= NULL
)
2143 free(archs
[i
].members
);
2152 * create_library() creates a library from the data structure pointed to by
2153 * archs into the specified output file. Only when more than one architecture
2154 * is in archs will a fat file be created.
2156 * In the case of cmd_flags.ranlib == TRUE the ofile may not be NULL if it
2157 * from a thin archive. If so and the toc_* fields are set and we may update
2158 * the table of contents in place if the new one fits where the old table of
2165 struct ofile
*ofile
)
2167 uint32_t i
, j
, k
, pad
, *time_offsets
;
2168 uint64_t library_size
, offset
;
2169 enum byte_sex target_byte_sex
;
2170 char *library
, *p
, *flush_start
;
2173 struct fat_header
*fat_header
;
2174 struct fat_arch
*fat_arch
;
2176 #ifndef __OPENSTEP__
2177 struct utimbuf timep
;
2181 struct stat stat_buf
;
2182 struct ar_hdr toc_ar_hdr
;
2183 enum bool some_tocs
, same_toc
, different_offsets
;
2186 if(cmd_flags
.ranlib
== TRUE
){
2187 if(cmd_flags
.q
== FALSE
)
2188 warning("empty library: %s (no table of contents added)",
2193 if(cmd_flags
.dynamic
== FALSE
||
2194 cmd_flags
.no_files_ok
== FALSE
){
2195 if(cmd_flags
.arch_only_flag
.name
!= NULL
)
2196 error("no library created (no object files in input "
2197 "files matching -arch_only %s)",
2198 cmd_flags
.arch_only_flag
.name
);
2200 error("no library created (no object files in input "
2207 if(cmd_flags
.dynamic
== TRUE
){
2208 create_dynamic_shared_library(output
);
2212 /* if this is libtool warn about duplicate member names */
2213 if(cmd_flags
.ranlib
== FALSE
)
2214 warn_duplicate_member_names();
2217 * Calculate the total size of the library and the final size of each
2221 library_size
= sizeof(struct fat_header
) +
2222 sizeof(struct fat_arch
) * narchs
;
2224 * The ar(1) program uses the -q flag to ranlib(1) to add a table
2225 * of contents only of the output is not a fat file. This is done
2226 * by default for UNIX standards conformance when the files are
2229 if(cmd_flags
.q
== TRUE
)
2232 * The ar(1) program uses the -f to ranlib(1) when it see the 's'
2233 * option. And if we are creating a fat file issue a warning that
2234 * ar(1) will not be able to use it.
2236 if(cmd_flags
.f
== TRUE
)
2237 warning("archive library: %s will be fat and ar(1) will not "
2238 "be able to operate on it", output
);
2243 for(i
= 0; i
< narchs
; i
++){
2244 make_table_of_contents(archs
+ i
, output
);
2247 if(archs
[i
].toc_nranlibs
!= 0)
2249 archs
[i
].size
+= SARMAG
+ archs
[i
].toc_size
;
2250 library_size
+= archs
[i
].size
;
2253 * The ar(1) program uses the -q flag to ranlib(1) to add a table of
2254 * contents only of the output contains some object files. This is
2255 * done for UNIX standards conformance.
2257 if(cmd_flags
.q
== TRUE
&& some_tocs
== FALSE
)
2261 * If this is ranlib(1) and we are running in UNIX standard mode and
2262 * the file is not writeable just print and error message and return.
2264 if(cmd_flags
.ranlib
== TRUE
&&
2265 get_unix_standard_mode() == TRUE
&&
2266 access(output
, W_OK
) == -1){
2267 system_error("file: %s is not writable", output
);
2272 * If this is ranlib(1) and we have a thin archive that has an existing
2273 * table of contents see if we have enough room to update it in place.
2274 * Actually we check to see that we have the exact same number of
2275 * ranlib structs and string size, as this is the most common case that
2276 * the defined global symbols have not changed when rebuilding and it
2277 * will just be the offset to archive members that will have changed.
2279 if(cmd_flags
.ranlib
== TRUE
&& narchs
== 1 &&
2280 ofile
!= NULL
&& ofile
->toc_addr
!= NULL
&&
2281 ofile
->toc_bad
== FALSE
&&
2282 archs
[0].toc_nranlibs
== ofile
->toc_nranlibs
&&
2283 archs
[0].toc_strsize
== ofile
->toc_strsize
){
2286 * If the table of contents in the input does have a long name and
2287 * the one we built does not (or vice a versa) then don't update it
2290 if(strcmp(ofile
->toc_ar_hdr
->ar_name
, AR_EFMT1
) == 0){
2291 if(archs
[0].toc_long_name
!= TRUE
)
2292 goto fail_to_update_toc_in_place
;
2295 if(archs
[0].toc_long_name
== TRUE
)
2296 goto fail_to_update_toc_in_place
;
2300 * The existing thin archive may not be laid out the same way as
2301 * libtool(1) would do it. As ar(1) does not know to pad things
2302 * so object files are on their natural alignment. So check to
2303 * see if the offsets are not the same and if the alignment is OK.
2305 different_offsets
= FALSE
;
2306 for(i
= 0; i
< archs
[0].nmembers
; i
++){
2307 if(archs
[0].members
[i
].input_member_offset
!=
2308 archs
[0].members
[i
].offset
){
2309 different_offsets
= TRUE
;
2311 * For now we will allow alignments of 4 bytes offsets even
2312 * though we would produce 8 byte alignments.
2314 if(archs
[0].members
[i
].input_member_offset
% 4 != 0){
2315 goto fail_to_update_toc_in_place
;
2321 * The time_offsets array records the offsets to the table of
2322 * contents archive header's ar_date fields. In this case we just
2323 * have one since this is a thin file (non-fat) file.
2325 time_offsets
= allocate(1 * sizeof(uint32_t));
2327 * Calculate the offset to the archive header's time field for the
2328 * table of contents.
2330 time_offsets
[0] = SARMAG
+
2331 ((char *)&toc_ar_hdr
.ar_date
- (char *)&toc_ar_hdr
);
2334 * If we had different member offsets in the input thin archive
2335 * we adjust the ranlib structs ran_off to use them.
2337 if(different_offsets
== TRUE
){
2339 for(i
= 0; i
< archs
[0].toc_nranlibs
; i
++){
2340 for(j
= 0; j
< archs
[0].nmembers
; j
++){
2341 if(archs
[0].members
[j
].offset
==
2342 archs
[0].toc_ranlibs
[i
].ran_off
){
2343 archs
[0].toc_ranlibs
[i
].ran_off
=
2344 archs
[0].members
[j
].input_member_offset
;
2352 * If the new table of contents and the new string table are the
2353 * same as the old then the archive only needs to be "touched"
2354 * and the time field of the toc needs to be updated.
2357 for(i
= 0; i
< archs
[0].toc_nranlibs
; i
++){
2358 if(archs
[0].toc_ranlibs
[i
].ran_un
.ran_strx
!=
2359 ofile
->toc_ranlibs
[i
].ran_un
.ran_strx
||
2360 archs
[0].toc_ranlibs
[i
].ran_off
!=
2361 ofile
->toc_ranlibs
[i
].ran_off
){
2366 if(same_toc
== TRUE
){
2367 for(i
= 0; i
< archs
[0].toc_strsize
; i
++){
2368 if(archs
[0].toc_strings
[i
] != ofile
->toc_strings
[i
]){
2376 library_size
= SARMAG
;
2377 if(same_toc
== FALSE
)
2378 library_size
+= archs
[0].toc_size
;
2379 if((r
= vm_allocate(mach_task_self(), (vm_address_t
*)&library
,
2380 library_size
, TRUE
)) != KERN_SUCCESS
)
2381 mach_fatal(r
, "can't vm_allocate() buffer for output file: %s "
2382 "of size %llu", output
, library_size
);
2385 /* put in the archive magic string in the buffer */
2387 memcpy(p
, ARMAG
, SARMAG
);
2390 /* put the table of contents in the buffer if needed */
2391 target_byte_sex
= get_target_byte_sex(archs
+ 0, host_byte_sex
);
2392 if(same_toc
== FALSE
)
2393 p
= put_toc_member(p
, archs
+0, host_byte_sex
, target_byte_sex
);
2395 if((fd
= open(output
, O_WRONLY
, 0)) == -1){
2396 system_error("can't open output file: %s", output
);
2399 if(write(fd
, library
, library_size
) != (int)library_size
){
2400 system_error("can't write output file: %s", output
);
2403 if(close(fd
) == -1){
2404 system_fatal("can't close output file: %s", output
);
2407 goto update_toc_ar_dates
;
2409 fail_to_update_toc_in_place
:
2412 * This buffer is vm_allocate'ed to make sure all holes are filled with
2415 if((r
= vm_allocate(mach_task_self(), (vm_address_t
*)&library
,
2416 library_size
, TRUE
)) != KERN_SUCCESS
)
2417 mach_fatal(r
, "can't vm_allocate() buffer for output file: %s of "
2418 "size %llu", output
, library_size
);
2421 * Create the output file. The unlink() is done to handle the problem
2422 * when the outputfile is not writable but the directory allows the
2423 * file to be removed (since the file may not be there the return code
2424 * of the unlink() is ignored).
2426 (void)unlink(output
);
2427 if((fd
= open(output
, O_WRONLY
| O_CREAT
| O_TRUNC
, 0666)) == -1){
2428 system_error("can't create output file: %s", output
);
2432 /* tell filesystem to NOT cache the file when reading or writing */
2433 (void)fcntl(fd
, F_NOCACHE
, 1);
2437 * If there is more than one architecture then fill in the fat file
2438 * header and the fat_arch structures in the buffer.
2441 fat_header
= (struct fat_header
*)library
;
2442 fat_header
->magic
= FAT_MAGIC
;
2443 fat_header
->nfat_arch
= narchs
;
2444 offset
= sizeof(struct fat_header
) +
2445 sizeof(struct fat_arch
) * narchs
;
2446 fat_arch
= (struct fat_arch
*)(library
+ sizeof(struct fat_header
));
2447 for(i
= 0; i
< narchs
; i
++){
2448 fat_arch
[i
].cputype
= archs
[i
].arch_flag
.cputype
;
2449 fat_arch
[i
].cpusubtype
= archs
[i
].arch_flag
.cpusubtype
;
2450 if(offset
> UINT32_MAX
)
2451 error("file too large to create as a fat file because "
2452 "offset field in struct fat_arch is only 32-bits and "
2453 "offset (%llu) to architecture %s exceeds that",
2454 offset
, archs
[i
].arch_flag
.name
);
2455 fat_arch
[i
].offset
= offset
;
2456 if(archs
[i
].size
> UINT32_MAX
)
2457 error("file too large to create as a fat file because "
2458 "size field in struct fat_arch is only 32-bits and "
2459 "size (%llu) of architecture %s exceeds that",
2460 archs
[i
].size
, archs
[i
].arch_flag
.name
);
2461 fat_arch
[i
].size
= archs
[i
].size
;
2462 fat_arch
[i
].align
= 2;
2463 offset
+= archs
[i
].size
;
2466 (void)unlink(output
);
2469 #ifdef __LITTLE_ENDIAN__
2470 swap_fat_header(fat_header
, BIG_ENDIAN_BYTE_SEX
);
2471 swap_fat_arch(fat_arch
, narchs
, BIG_ENDIAN_BYTE_SEX
);
2472 #endif /* __LITTLE_ENDIAN__ */
2473 offset
= sizeof(struct fat_header
) +
2474 sizeof(struct fat_arch
) * narchs
;
2479 /* flush out the fat headers if any */
2480 output_flush(library
, library_size
, fd
, 0, offset
);
2483 * The time_offsets array records the offsets to the table of conternts
2484 * archive header's ar_date fields.
2486 time_offsets
= allocate(narchs
* sizeof(uint32_t));
2489 * Now put each arch in the buffer.
2491 for(i
= 0; i
< narchs
; i
++){
2492 p
= library
+ offset
;
2497 * If the input files only contains non-object files then the
2498 * byte sex of the output can't be determined which is needed for
2499 * the two binary long's of the table of contents. But since these
2500 * will be zero (the same in both byte sexes) because there are no
2501 * symbols in the table of contents if there are no object files.
2504 /* put in the archive magic string */
2505 memcpy(p
, ARMAG
, SARMAG
);
2509 * Warn for what really is a bad library that has an empty table of
2510 * contents but this is allowed in the original ranlib.
2512 if(arch
->toc_nranlibs
== 0 && cmd_flags
.q
== FALSE
){
2514 warning("warning for library: %s for architecture: %s the "
2515 "table of contents is empty (no object file members"
2516 " in the library define global symbols)", output
,
2517 arch
->arch_flag
.name
);
2519 warning("warning for library: %s the table of contents is "
2520 "empty (no object file members in the library "
2521 "define global symbols)", output
);
2525 * Pick the byte sex to write the table of contents in.
2527 target_byte_sex
= get_target_byte_sex(arch
, host_byte_sex
);
2530 * Remember the offset to the archive header's time field for this
2531 * arch's table of contents member.
2535 ((char *)&toc_ar_hdr
.ar_date
- (char *)&toc_ar_hdr
);
2538 * Put in the table of contents member in the output buffer.
2540 p
= put_toc_member(p
, arch
, host_byte_sex
, target_byte_sex
);
2542 output_flush(library
, library_size
, fd
, flush_start
- library
,
2546 * Put in the archive header and member contents for each member.
2548 for(j
= 0; j
< arch
->nmembers
; j
++){
2550 memcpy(p
, (char *)&(arch
->members
[j
].ar_hdr
),
2551 sizeof(struct ar_hdr
));
2552 p
+= sizeof(struct ar_hdr
);
2555 * If we are using extended format #1 for long names write out
2556 * the name. Note the name is padded with '\0' and the
2557 * member_name_size is the unrounded size.
2559 if(arch
->members
[j
].output_long_name
== TRUE
){
2560 strncpy(p
, arch
->members
[j
].member_name
,
2561 arch
->members
[j
].member_name_size
);
2562 p
+= rnd(arch
->members
[j
].member_name_size
, 8) +
2563 (rnd(sizeof(struct ar_hdr
), 8) -
2564 sizeof(struct ar_hdr
));
2568 * ofile_map swaps the headers to the host_byte_sex if the
2569 * object's byte sex is not the same as the host byte sex so
2570 * if this is the case swap them back before writing them out.
2572 if(arch
->members
[j
].mh
!= NULL
&&
2573 arch
->members
[j
].object_byte_sex
!= host_byte_sex
){
2574 if(swap_object_headers(arch
->members
[j
].mh
,
2575 arch
->members
[j
].load_commands
) == FALSE
)
2576 fatal("internal error: swap_object_headers() failed");
2578 else if(arch
->members
[j
].mh64
!= NULL
&&
2579 arch
->members
[j
].object_byte_sex
!= host_byte_sex
){
2580 if(swap_object_headers(arch
->members
[j
].mh64
,
2581 arch
->members
[j
].load_commands
) == FALSE
)
2582 fatal("internal error: swap_object_headers() failed");
2584 memcpy(p
, arch
->members
[j
].object_addr
,
2585 arch
->members
[j
].object_size
);
2586 #ifdef VM_SYNC_DEACTIVATE
2587 vm_msync(mach_task_self(),
2588 (vm_address_t
)arch
->members
[j
].object_addr
,
2589 (vm_size_t
)arch
->members
[j
].object_size
,
2590 VM_SYNC_DEACTIVATE
);
2591 #endif /* VM_SYNC_DEACTIVATE */
2592 p
+= arch
->members
[j
].object_size
;
2593 pad
= rnd(arch
->members
[j
].object_size
, 8) -
2594 arch
->members
[j
].object_size
;
2595 /* as with the UNIX ar(1) program pad with '\n' characters */
2596 for(k
= 0; k
< pad
; k
++)
2599 output_flush(library
, library_size
, fd
, flush_start
- library
,
2602 offset
+= arch
->size
;
2606 * Write the library to the file or flush the remaining buffer to the
2609 if(cmd_flags
.noflush
== TRUE
){
2610 if(write(fd
, library
, library_size
) != (int)library_size
){
2611 system_error("can't write output file: %s", output
);
2616 final_output_flush(library
, fd
);
2618 if(close(fd
) == -1){
2619 system_fatal("can't close output file: %s", output
);
2623 update_toc_ar_dates
:
2625 * Now that the library is created on the file system it is written
2626 * to get the time for the file on that file system.
2628 if(stat(output
, &stat_buf
) == -1){
2629 system_fatal("can't stat file output file: %s", output
);
2632 if((fd
= open(output
, O_WRONLY
, 0)) == -1){
2633 system_error("can't open output file: %s", output
);
2636 if(zero_ar_date
== TRUE
)
2637 stat_buf
.st_mtime
= 0;
2639 * With the time from the file system the library is on set the ar_date
2640 * using the modification time returned by stat. Then write this into
2641 * all the ar_date's in the file.
2643 sprintf((char *)(&toc_ar_hdr
), "%-*s%-*ld",
2644 (int)sizeof(toc_ar_hdr
.ar_name
),
2646 (int)sizeof(toc_ar_hdr
.ar_date
),
2647 (long int)stat_buf
.st_mtime
+ 5);
2648 for(i
= 0; i
< narchs
; i
++){
2649 if(lseek(fd
, time_offsets
[i
], L_SET
) == -1){
2650 system_error("can't lseek in output file: %s", output
);
2653 if(write(fd
, &toc_ar_hdr
.ar_date
, sizeof(toc_ar_hdr
.ar_date
)) !=
2654 sizeof(toc_ar_hdr
.ar_date
)){
2655 system_error("can't write to output file: %s", output
);
2659 if(close(fd
) == -1){
2660 system_fatal("can't close output file: %s", output
);
2664 * Now set the modtime of the created library back to it's stat time
2665 * when we first closed it.
2667 #ifndef __OPENSTEP__
2668 timep
.actime
= stat_buf
.st_mtime
;
2669 timep
.modtime
= stat_buf
.st_mtime
;
2670 if(utime(output
, &timep
) == -1)
2672 timep
[0] = stat_buf
.st_mtime
;
2673 timep
[1] = stat_buf
.st_mtime
;
2674 if(utime(output
, timep
) == -1)
2677 system_fatal("can't set the modifiy times in output file: %s",
2681 if((r
= vm_deallocate(mach_task_self(), (vm_address_t
)library
,
2682 library_size
)) != KERN_SUCCESS
){
2683 my_mach_error(r
, "can't vm_deallocate() buffer for output file");
2689 * get_target_byte_sex() pick the byte sex to write the table of contents in
2694 get_target_byte_sex(
2696 enum byte_sex host_byte_sex
)
2699 enum byte_sex target_byte_sex
;
2701 target_byte_sex
= UNKNOWN_BYTE_SEX
;
2703 i
< arch
->nmembers
&& target_byte_sex
== UNKNOWN_BYTE_SEX
;
2705 target_byte_sex
= arch
->members
[i
].object_byte_sex
;
2707 if(target_byte_sex
== UNKNOWN_BYTE_SEX
)
2708 target_byte_sex
= host_byte_sex
;
2709 return(target_byte_sex
);
2713 * put_toc_member() put the contents member for arch into the buffer p and
2714 * returns the pointer to the buffer after the table of contents.
2715 * The table of contents member is:
2716 * the archive header
2717 * the archive member name (if using a long name)
2718 * a uint32_t for the number of bytes of the ranlib structs
2719 * the ranlib structs
2720 * a uint32_t for the number of bytes of the strings for the
2722 * the strings for the ranlib structs
2729 enum byte_sex host_byte_sex
,
2730 enum byte_sex target_byte_sex
)
2734 memcpy(p
, (char *)&arch
->toc_ar_hdr
, sizeof(struct ar_hdr
));
2735 p
+= sizeof(struct ar_hdr
);
2737 if(arch
->toc_long_name
== TRUE
){
2738 memcpy(p
, arch
->toc_name
, arch
->toc_name_size
);
2739 p
+= arch
->toc_name_size
+
2740 (rnd(sizeof(struct ar_hdr
), 8) -
2741 sizeof(struct ar_hdr
));
2744 l
= arch
->toc_nranlibs
* sizeof(struct ranlib
);
2745 if(target_byte_sex
!= host_byte_sex
)
2747 memcpy(p
, (char *)&l
, sizeof(uint32_t));
2748 p
+= sizeof(uint32_t);
2750 if(target_byte_sex
!= host_byte_sex
)
2751 swap_ranlib(arch
->toc_ranlibs
, arch
->toc_nranlibs
,
2753 memcpy(p
, (char *)arch
->toc_ranlibs
,
2754 arch
->toc_nranlibs
* sizeof(struct ranlib
));
2755 p
+= arch
->toc_nranlibs
* sizeof(struct ranlib
);
2757 l
= arch
->toc_strsize
;
2758 if(target_byte_sex
!= host_byte_sex
)
2760 memcpy(p
, (char *)&l
, sizeof(uint32_t));
2761 p
+= sizeof(uint32_t);
2763 memcpy(p
, (char *)arch
->toc_strings
, arch
->toc_strsize
);
2764 p
+= arch
->toc_strsize
;
2770 * output_flush() takes an offset and a size of part of the output library,
2771 * known in the comments as the new area, and causes any fully flushed pages to
2772 * be written to the library file the new area in combination with previous
2773 * areas created. The data structure output_blocks has ordered blocks of areas
2774 * that have been flushed which are maintained by this routine. Any area can
2775 * only be flushed once and an error will result is the new area overlaps with a
2776 * previously flushed area.
2782 uint64_t library_size
,
2787 uint64_t write_offset
, write_size
, host_pagesize
;
2788 struct block
**p
, *block
, *before
, *after
;
2791 host_pagesize
= 0x2000;
2793 if(cmd_flags
.noflush
== TRUE
)
2796 if(offset
+ size
> library_size
)
2797 fatal("internal error: output_flush(offset = %llu, size = %llu) "
2798 "out of range for library_size = %llu", offset
, size
,
2802 if(cmd_flags
.debug
& (1 << 2))
2804 if(cmd_flags
.debug
& (1 << 1))
2805 printf("output_flush(offset = %llu, size %llu)", offset
, size
);
2810 if(cmd_flags
.debug
& (1 << 1))
2817 * Search through the ordered output blocks to find the block before the
2818 * new area and after the new area if any exist.
2822 p
= &(output_blocks
);
2825 if(offset
< block
->offset
){
2836 * Check for overlap of the new area with the block before and after the
2837 * new area if there are such blocks.
2840 if(before
->offset
+ before
->size
> offset
){
2841 warning("internal error: output_flush(offset = %llu, size = "
2842 "%llu) overlaps with flushed block(offset = %llu, "
2843 "size = %llu)", offset
, size
, before
->offset
,
2845 printf("calling abort()\n");
2850 if(offset
+ size
> after
->offset
){
2851 warning("internal error: output_flush(offset = %llu, size = "
2852 "%llu) overlaps with flushed block(offset = %llu, "
2853 "size = %llu)", offset
, size
, after
->offset
,
2855 printf("calling abort()\n");
2861 * Now see how the new area fits in with the blocks before and after it
2862 * (that is does it touch both, one or the other or neither blocks).
2863 * For each case first the offset and size to write (write_offset and
2864 * write_size) are set for the area of full pages that can now be
2865 * written from the block. Then the area written in the block
2866 * (->written_offset and ->written_size) are set to reflect the total
2867 * area in the block now written. Then offset and size the block
2868 * refers to (->offset and ->size) are set to total area of the block.
2869 * Finally the links to others blocks in the list are adjusted if a
2870 * block is added or removed.
2872 * See if there is a block before the new area and the new area
2873 * starts at the end of that block.
2875 if(before
!= NULL
&& before
->offset
+ before
->size
== offset
){
2877 * See if there is also a block after the new area and the new area
2878 * ends at the start of that block.
2880 if(after
!= NULL
&& offset
+ size
== after
->offset
){
2882 * This is the case where the new area exactly fill the area
2883 * between two existing blocks. The total area is folded into
2884 * the block before the new area and the block after the new
2885 * area is removed from the list.
2887 if(before
->offset
== 0 && before
->written_size
== 0){
2889 before
->written_offset
= 0;
2892 write_offset
=before
->written_offset
+ before
->written_size
;
2893 if(after
->written_size
== 0)
2894 write_size
= trnc(after
->offset
+ after
->size
-
2895 write_offset
, host_pagesize
);
2897 write_size
= trnc(after
->written_offset
- write_offset
,
2899 if(write_size
!= 0){
2900 before
->written_size
+= write_size
;
2902 if(after
->written_size
!= 0)
2903 before
->written_size
+= after
->written_size
;
2904 before
->size
+= size
+ after
->size
;
2906 /* remove the block after the new area */
2907 before
->next
= after
->next
;
2908 remove_block(after
);
2912 * This is the case where the new area starts at the end of the
2913 * block just before it but does not end where the block after
2914 * it (if any) starts. The new area is folded into the block
2915 * before the new area.
2917 write_offset
= before
->written_offset
+ before
->written_size
;
2918 write_size
= trnc(offset
+ size
- write_offset
, host_pagesize
);
2920 before
->written_size
+= write_size
;
2921 before
->size
+= size
;
2925 * See if the new area and the new area ends at the start of the block
2926 * after it (if any).
2928 else if(after
!= NULL
&& offset
+ size
== after
->offset
){
2930 * This is the case where the new area ends at the begining of the
2931 * block just after it but does not start where the block before it.
2932 * (if any) ends. The new area is folded into this block after the
2935 write_offset
= rnd(offset
, host_pagesize
);
2936 if(after
->written_size
== 0)
2937 write_size
= trnc(after
->offset
+ after
->size
- write_offset
,
2940 write_size
= trnc(after
->written_offset
- write_offset
,
2942 if(write_size
!= 0){
2943 after
->written_offset
= write_offset
;
2944 after
->written_size
+= write_size
;
2946 else if(write_offset
!= after
->written_offset
){
2947 after
->written_offset
= write_offset
;
2949 after
->offset
= offset
;
2950 after
->size
+= size
;
2954 * This is the case where the new area neither starts at the end of
2955 * the block just before it (if any) or ends where the block after
2956 * it (if any) starts. A new block is created and the new area is
2959 write_offset
= rnd(offset
, host_pagesize
);
2960 write_size
= trnc(offset
+ size
- write_offset
, host_pagesize
);
2961 block
= get_block();
2962 block
->offset
= offset
;
2964 block
->written_offset
= write_offset
;
2965 block
->written_size
= write_size
;
2967 * Insert this block in the ordered list in the correct place.
2970 block
->next
= before
->next
;
2971 before
->next
= block
;
2974 block
->next
= output_blocks
;
2975 output_blocks
= block
;
2980 * Now if there are full pages to write write them to the output file.
2982 if(write_size
!= 0){
2984 if((cmd_flags
.debug
& (1 << 1)) || (cmd_flags
.debug
& (1 << 0)))
2985 printf(" writing (write_offset = %llu write_size = %llu)\n",
2986 write_offset
, write_size
);
2988 lseek(fd
, write_offset
, L_SET
);
2989 if(write(fd
, library
+ write_offset
, write_size
) !=
2991 system_fatal("can't write to output file");
2992 if((r
= vm_deallocate(mach_task_self(), (vm_address_t
)(library
+
2993 write_offset
), write_size
)) != KERN_SUCCESS
)
2994 mach_fatal(r
, "can't vm_deallocate() buffer for output file");
2998 if(cmd_flags
.debug
& (1 << 1))
2999 printf(" no write\n");
3005 * final_output_flush() flushes the last part of the last page of the object
3006 * file if it does not round out to exactly a page.
3014 struct block
*block
;
3015 uint64_t write_offset
, write_size
;
3019 /* The compiler "warning: `write_offset' may be used uninitialized in */
3020 /* this function" can safely be ignored */
3022 if((cmd_flags
.debug
& (1 << 1)) || (cmd_flags
.debug
& (1 << 0))){
3023 printf("final_output_flush block_list:\n");
3029 block
= output_blocks
;
3031 if(block
->offset
!= 0)
3032 fatal("internal error: first block not at offset 0");
3033 if(block
->written_size
!= 0){
3034 if(block
->written_offset
!= 0)
3035 fatal("internal error: first block written_offset not 0");
3036 write_offset
= block
->written_size
;
3037 write_size
= block
->size
- block
->written_size
;
3040 write_offset
= block
->offset
;
3041 write_size
= block
->size
;
3043 if(block
->next
!= NULL
)
3044 fatal("internal error: more than one block in final list");
3046 if(write_size
!= 0){
3048 if((cmd_flags
.debug
& (1 << 1)) || (cmd_flags
.debug
& (1 << 1)))
3049 printf(" writing (write_offset = %llu write_size = %llu)\n",
3050 write_offset
, write_size
);
3052 lseek(fd
, write_offset
, L_SET
);
3053 if(write(fd
, library
+ write_offset
, write_size
) !=
3055 system_fatal("can't write to output file");
3056 if((r
= vm_deallocate(mach_task_self(), (vm_address_t
)(library
+
3057 write_offset
), write_size
)) != KERN_SUCCESS
)
3058 mach_fatal(r
, "can't vm_deallocate() buffer for output file");
3060 output_blocks
= NULL
;
3065 * print_block_list() prints the list of blocks. Used for debugging.
3069 print_block_list(void)
3071 struct block
**p
, *block
;
3073 p
= &(output_blocks
);
3075 printf("Empty block list\n");
3078 printf("block 0x%x\n", (unsigned int)block
);
3079 printf(" offset %llu\n", block
->offset
);
3080 printf(" size %llu\n", block
->size
);
3081 printf(" written_offset %llu\n", block
->written_offset
);
3082 printf(" written_size %llu\n", block
->written_size
);
3083 printf(" next 0x%x\n", (unsigned int)(block
->next
));
3090 * get_block() returns a pointer to a new block. This could be done by
3091 * allocating block of these placing them on a free list and and handing them
3092 * out. For the initial release of this code this number is typicly low and not
3093 * a big win so each block just allocated and free'ed.
3099 struct block
*block
;
3101 block
= allocate(sizeof(struct block
));
3106 * remove_block() throws away the block specified. See comments in get_block().
3111 struct block
*block
)
3117 * trnc() truncates the value 'v' to the power of two value 'r'. If v is
3118 * less than zero it returns zero.
3126 if(((int32_t)v
) < 0)
3128 return(v
& ~(r
- 1));
3132 * create_dynamic_shared_library() creates a dynamic shared library from the
3133 * data structure pointed to by archs into the specified output file. Only
3134 * when more than one architecture is in archs will a fat file be created.
3138 create_dynamic_shared_library(
3143 struct stat stat_buf
;
3144 enum bool use_force_cpusubtype_ALL
;
3145 const struct arch_flag
*family_arch_flag
;
3148 * If there is more than one architecture setup a signal handler to
3149 * clean up the temporary files in case we get a signal.
3152 signal(SIGINT
, create_dynamic_shared_library_cleanup
);
3155 * If -arch_only is specified with a specific cpusubtype other than the
3156 * family cpusubtype do not use -force_cpusubtype_ALL as the user wants
3157 * the output to be tagged with that cpusubtype.
3159 use_force_cpusubtype_ALL
= TRUE
;
3160 if(cmd_flags
.arch_only_flag
.name
!= NULL
){
3161 family_arch_flag
= get_arch_family_from_cputype(
3162 cmd_flags
.arch_only_flag
.cputype
);
3163 if(family_arch_flag
!= NULL
){
3164 if((family_arch_flag
->cpusubtype
& ~CPU_SUBTYPE_MASK
) !=
3165 (cmd_flags
.arch_only_flag
.cpusubtype
& ~CPU_SUBTYPE_MASK
))
3166 use_force_cpusubtype_ALL
= FALSE
;
3171 * For each architecture run ld(1) -dylib to create the dynamic shared
3174 for(i
= 0; i
< narchs
|| (i
== 0 && narchs
== 0); i
++){
3175 reset_execute_list();
3176 add_execute_list_with_prefix("ld");
3177 if(narchs
!= 0 && cmd_flags
.arch_only_flag
.name
== NULL
)
3178 add_execute_list("-arch_multiple");
3180 add_execute_list("-arch");
3181 if(use_force_cpusubtype_ALL
== TRUE
)
3182 add_execute_list(archs
[i
].arch_flag
.name
);
3184 add_execute_list(cmd_flags
.arch_only_flag
.name
);
3186 add_execute_list("-dylib");
3187 add_execute_list("-dynamic");
3188 if(cmd_flags
.all_load_flag_specified
== FALSE
||
3189 cmd_flags
.all_load
== TRUE
)
3190 add_execute_list("-all_load");
3191 if(use_force_cpusubtype_ALL
== TRUE
)
3192 add_execute_list("-force_cpusubtype_ALL");
3193 add_execute_list("-no_arch_warnings");
3194 if(cmd_flags
.seg1addr
!= NULL
){
3195 add_execute_list("-seg1addr");
3196 add_execute_list(cmd_flags
.seg1addr
);
3198 if(cmd_flags
.segs_read_only_addr
!= NULL
){
3199 add_execute_list("-segs_read_only_addr");
3200 add_execute_list(cmd_flags
.segs_read_only_addr
);
3202 if(cmd_flags
.segs_read_write_addr
!= NULL
){
3203 add_execute_list("-segs_read_write_addr");
3204 add_execute_list(cmd_flags
.segs_read_write_addr
);
3206 if(cmd_flags
.seg_addr_table
!= NULL
){
3207 add_execute_list("-seg_addr_table");
3208 add_execute_list(cmd_flags
.seg_addr_table
);
3210 if(cmd_flags
.seg_addr_table_filename
!= NULL
){
3211 add_execute_list("-seg_addr_table_filename");
3212 add_execute_list(cmd_flags
.seg_addr_table_filename
);
3214 if(cmd_flags
.compatibility
!= NULL
){
3215 add_execute_list("-dylib_compatibility_version");
3216 add_execute_list(cmd_flags
.compatibility
);
3218 if(cmd_flags
.current
!= NULL
){
3219 add_execute_list("-dylib_current_version");
3220 add_execute_list(cmd_flags
.current
);
3222 if(cmd_flags
.install_name
!= NULL
){
3223 add_execute_list("-dylib_install_name");
3224 add_execute_list(cmd_flags
.install_name
);
3228 add_execute_list("-dylib_install_name");
3229 add_execute_list(cmd_flags
.output
);
3232 for(j
= 0; j
< cmd_flags
.nldflags
; j
++)
3233 add_execute_list(cmd_flags
.ldflags
[j
]);
3234 for(j
= 0; j
< cmd_flags
.nLdirs
; j
++)
3235 add_execute_list(cmd_flags
.Ldirs
[j
]);
3236 add_execute_list("-ldylib1.o");
3238 for(j
= 0; j
< cmd_flags
.nfiles
; j
++){
3239 if(cmd_flags
.filelist
[j
] == NULL
){
3240 add_execute_list(cmd_flags
.files
[j
]);
3243 if(cmd_flags
.filelist
[j
] != filelist
){
3244 add_execute_list("-filelist");
3245 add_execute_list(cmd_flags
.filelist
[j
]);
3246 filelist
= cmd_flags
.filelist
[j
];
3251 add_execute_list("-o");
3252 add_execute_list(cmd_flags
.output
);
3255 add_execute_list("-o");
3256 add_execute_list(makestr(cmd_flags
.output
, ".libtool.",
3257 archs
[i
].arch_flag
.name
, NULL
));
3258 if(cmd_flags
.final_output_specified
== FALSE
){
3259 add_execute_list("-final_output");
3260 add_execute_list(cmd_flags
.output
);
3263 if(execute_list(cmd_flags
.verbose
) == 0)
3264 fatal("internal link edit command failed");
3267 * If there is more than one architecture then run lipo to put them
3271 reset_execute_list();
3272 add_execute_list_with_prefix("lipo");
3273 add_execute_list("-create");
3274 add_execute_list("-output");
3275 add_execute_list(cmd_flags
.output
);
3276 for(i
= 0; i
< narchs
; i
++){
3277 add_execute_list(makestr(cmd_flags
.output
, ".libtool.",
3278 archs
[i
].arch_flag
.name
, NULL
));
3280 if(execute_list(cmd_flags
.verbose
) == 0)
3281 fatal("internal lipo command failed");
3282 for(i
= 0; i
< narchs
; i
++){
3283 p
= makestr(cmd_flags
.output
, ".libtool.",
3284 archs
[i
].arch_flag
.name
, NULL
);
3285 if(unlink(p
) == -1){
3286 error("can't remove temporary file: %s", p
);
3291 * If we are doing prebinding then run objcunique on the
3294 if(cmd_flags
.prebinding
== TRUE
){
3295 if(stat("/usr/bin/objcunique", &stat_buf
) != -1){
3296 reset_execute_list();
3297 add_execute_list_with_prefix("objcunique");
3298 add_execute_list(cmd_flags
.output
);
3299 add_execute_list("-prebind");
3300 for(j
= 0; j
< cmd_flags
.nLdirs
; j
++)
3301 add_execute_list(cmd_flags
.Ldirs
[j
]);
3302 if(execute_list(cmd_flags
.verbose
) == 0)
3303 fatal("internal objcunique command failed");
3309 * create_dynamic_shared_library_cleanup() is the signal handler to remove the
3310 * temporary files if more than one arch is being used.
3314 create_dynamic_shared_library_cleanup(
3319 for(i
= 0; i
< narchs
; i
++){
3320 (void)unlink(makestr(cmd_flags
.output
, ".libtool.",
3321 archs
[i
].arch_flag
.name
, NULL
));
3327 * make_table_of_contents() make the table of contents for the specified arch
3328 * and fills in the toc_* fields in the arch. Output is the name of the output
3329 * file for error messages.
3333 make_table_of_contents(
3337 uint32_t i
, j
, k
, r
, s
, nsects
, ncmds
, n_strx
;
3338 struct member
*member
;
3339 struct load_command
*lc
;
3340 struct segment_command
*sg
;
3341 struct segment_command_64
*sg64
;
3342 struct nlist
*symbols
;
3343 struct nlist_64
*symbols64
;
3345 enum bool sorted
, is_toc_symbol
;
3347 struct section
*section
;
3348 struct section_64
*section64
;
3349 uint8_t n_type
, n_sect
;
3352 #endif /* LTO_SUPPORT */
3357 * First pass over the members to count how many ranlib structs are
3358 * needed and the size of the strings in the toc that are needed.
3360 for(i
= 0; i
< arch
->nmembers
; i
++){
3361 member
= arch
->members
+ i
;
3362 if(member
->mh
!= NULL
|| member
->mh64
!= NULL
){
3364 lc
= member
->load_commands
;
3365 if(member
->mh
!= NULL
)
3366 ncmds
= member
->mh
->ncmds
;
3368 ncmds
= member
->mh64
->ncmds
;
3369 for(j
= 0; j
< ncmds
; j
++){
3370 if(lc
->cmd
== LC_SYMTAB
){
3371 if(member
->st
== NULL
)
3372 member
->st
= (struct symtab_command
*)lc
;
3374 else if(lc
->cmd
== LC_SEGMENT
){
3375 sg
= (struct segment_command
*)lc
;
3376 nsects
+= sg
->nsects
;
3378 else if(lc
->cmd
== LC_SEGMENT_64
){
3379 sg64
= (struct segment_command_64
*)lc
;
3380 nsects
+= sg64
->nsects
;
3382 lc
= (struct load_command
*)((char *)lc
+ lc
->cmdsize
);
3384 if(member
->mh
!= NULL
)
3385 member
->sections
= allocate(nsects
*
3386 sizeof(struct section
*));
3388 member
->sections64
= allocate(nsects
*
3389 sizeof(struct section_64
*));
3391 lc
= member
->load_commands
;
3392 for(j
= 0; j
< ncmds
; j
++){
3393 if(lc
->cmd
== LC_SEGMENT
){
3394 sg
= (struct segment_command
*)lc
;
3395 section
= (struct section
*)
3396 ((char *)sg
+ sizeof(struct segment_command
));
3397 for(k
= 0; k
< sg
->nsects
; k
++){
3398 member
->sections
[nsects
++] = section
++;
3401 else if(lc
->cmd
== LC_SEGMENT_64
){
3402 sg64
= (struct segment_command_64
*)lc
;
3403 section64
= (struct section_64
*)
3404 ((char *)sg64
+ sizeof(struct segment_command_64
));
3405 for(k
= 0; k
< sg64
->nsects
; k
++){
3406 member
->sections64
[nsects
++] = section64
++;
3409 lc
= (struct load_command
*)((char *)lc
+ lc
->cmdsize
);
3411 if(member
->st
!= NULL
&& member
->st
->nsyms
!= 0){
3412 if(member
->mh
!= NULL
){
3413 symbols
= (struct nlist
*)(member
->object_addr
+
3414 member
->st
->symoff
);
3415 if(member
->object_byte_sex
!= get_host_byte_sex())
3416 swap_nlist(symbols
, member
->st
->nsyms
,
3417 get_host_byte_sex());
3420 symbols64
= (struct nlist_64
*)(member
->object_addr
+
3421 member
->st
->symoff
);
3422 if(member
->object_byte_sex
!= get_host_byte_sex())
3423 swap_nlist_64(symbols64
, member
->st
->nsyms
,
3424 get_host_byte_sex());
3426 strings
= member
->object_addr
+ member
->st
->stroff
;
3427 for(j
= 0; j
< member
->st
->nsyms
; j
++){
3428 if(member
->mh
!= NULL
){
3429 n_strx
= symbols
[j
].n_un
.n_strx
;
3430 n_type
= symbols
[j
].n_type
;
3431 n_sect
= symbols
[j
].n_sect
;
3434 n_strx
= symbols64
[j
].n_un
.n_strx
;
3435 n_type
= symbols64
[j
].n_type
;
3436 n_sect
= symbols64
[j
].n_sect
;
3438 if(n_strx
> member
->st
->strsize
){
3439 warn_member(arch
, member
, "malformed object "
3440 "(symbol %u n_strx field extends past the "
3441 "end of the string table)", j
);
3445 if((n_type
& N_TYPE
) == N_SECT
){
3446 if(n_sect
== NO_SECT
){
3447 warn_member(arch
, member
, "malformed object "
3448 "(symbol %u must not have NO_SECT for its "
3449 "n_sect field given its type (N_SECT))", j
);
3453 if(n_sect
> nsects
){
3454 warn_member(arch
, member
, "malformed object "
3455 "(symbol %u n_sect field greater than the "
3456 "number of sections in the file)", j
);
3461 if(member
->mh
!= NULL
)
3462 is_toc_symbol
= toc_symbol(symbols
+ j
,
3465 is_toc_symbol
= toc_symbol_64(symbols64
+ j
,
3466 member
->sections64
);
3467 if(is_toc_symbol
== TRUE
){
3468 arch
->toc_nranlibs
++;
3469 arch
->toc_strsize
+= strlen(strings
+ n_strx
) + 1;
3474 warn_member(arch
, member
, "has no symbols");
3477 else if(member
->lto
!= NULL
){
3478 nsyms
= lto_get_nsyms(member
->lto
);
3479 for(j
= 0; j
< nsyms
; j
++){
3480 if(lto_toc_symbol(member
->lto
, j
, cmd_flags
.c
) == TRUE
){
3481 arch
->toc_nranlibs
++;
3482 arch
->toc_strsize
+=
3483 strlen(lto_symbol_name(member
->lto
, j
)) + 1;
3487 #endif /* LTO_SUPPORT */
3489 if(cmd_flags
.ranlib
== FALSE
){
3490 warn_member(arch
, member
, "is not an object file");
3499 * Allocate the space for the ranlib structs and strings for the
3500 * table of contents.
3502 arch
->toc_ranlibs
= allocate(sizeof(struct ranlib
) *arch
->toc_nranlibs
);
3503 arch
->tocs
= allocate(sizeof(struct toc
) * arch
->toc_nranlibs
);
3504 arch
->toc_strsize
= rnd(arch
->toc_strsize
, 8);
3505 arch
->toc_strings
= allocate(arch
->toc_strsize
);
3508 * Second pass over the members to fill in the ranlib structs and
3509 * the strings for the table of contents. The ran_name field is
3510 * filled in with a pointer to a string contained in arch->toc_strings
3511 * for easy sorting and conversion to an index. The ran_off field is
3512 * filled in with the member index plus one to allow marking with it's
3513 * negative value by check_sort_tocs() and easy conversion to the
3518 for(i
= 0; i
< arch
->nmembers
; i
++){
3519 member
= arch
->members
+ i
;
3520 if(member
->mh
!= NULL
|| member
->mh64
!= NULL
){
3521 if(member
->st
!= NULL
&& member
->st
->nsyms
!= 0){
3522 if(member
->mh
!= NULL
)
3523 symbols
= (struct nlist
*)(member
->object_addr
+
3524 member
->st
->symoff
);
3526 symbols64
= (struct nlist_64
*)(member
->object_addr
+
3527 member
->st
->symoff
);
3528 strings
= member
->object_addr
+ member
->st
->stroff
;
3529 for(j
= 0; j
< member
->st
->nsyms
; j
++){
3530 if(member
->mh
!= NULL
)
3531 n_strx
= symbols
[j
].n_un
.n_strx
;
3533 n_strx
= symbols64
[j
].n_un
.n_strx
;
3534 if(n_strx
> member
->st
->strsize
)
3536 if(member
->mh
!= NULL
)
3537 is_toc_symbol
= toc_symbol(symbols
+ j
,
3540 is_toc_symbol
= toc_symbol_64(symbols64
+ j
,
3541 member
->sections64
);
3542 if(is_toc_symbol
== TRUE
){
3543 strcpy(arch
->toc_strings
+ s
,
3545 arch
->tocs
[r
].name
= arch
->toc_strings
+ s
;
3546 arch
->tocs
[r
].index1
= i
+ 1;
3548 s
+= strlen(strings
+ n_strx
) + 1;
3551 if(member
->object_byte_sex
!= get_host_byte_sex()){
3552 if(member
->mh
!= NULL
)
3553 swap_nlist(symbols
, member
->st
->nsyms
,
3554 member
->object_byte_sex
);
3556 swap_nlist_64(symbols64
, member
->st
->nsyms
,
3557 member
->object_byte_sex
);
3562 else if(member
->lto
!= NULL
){
3563 nsyms
= lto_get_nsyms(member
->lto
);
3564 for(j
= 0; j
< nsyms
; j
++){
3565 if(lto_toc_symbol(member
->lto
, j
, cmd_flags
.c
) == TRUE
){
3566 strcpy(arch
->toc_strings
+ s
,
3567 lto_symbol_name(member
->lto
, j
));
3568 arch
->tocs
[r
].name
= arch
->toc_strings
+ s
;
3569 arch
->tocs
[r
].index1
= i
+ 1;
3571 s
+= strlen(lto_symbol_name(member
->lto
, j
)) + 1;
3575 #endif /* LTO_SUPPORT */
3579 * If the table of contents is to be sorted by symbol name then try to
3580 * sort it and leave it sorted if no duplicates.
3582 if(cmd_flags
.s
== TRUE
){
3583 qsort(arch
->tocs
, arch
->toc_nranlibs
, sizeof(struct toc
),
3584 (int (*)(const void *, const void *))toc_name_qsort
);
3585 sorted
= check_sort_tocs(arch
, output
, FALSE
);
3586 if(sorted
== FALSE
){
3587 qsort(arch
->tocs
, arch
->toc_nranlibs
, sizeof(struct toc
),
3588 (int (*)(const void *, const void *))toc_index1_qsort
);
3589 arch
->toc_name
= SYMDEF
;
3590 arch
->toc_name_size
= sizeof(SYMDEF
) - 1;
3591 if(cmd_flags
.use_long_names
== TRUE
){
3592 arch
->toc_long_name
= TRUE
;
3594 * This assumes that "__.SYMDEF\0\0\0\0\0\0\0" is 16 bytes
3596 * (rnd(sizeof(struct ar_hdr), 8) - sizeof(struct ar_hdr)
3599 ar_name
= AR_EFMT1
"20";
3600 arch
->toc_name_size
= 16;
3601 arch
->toc_name
= SYMDEF
"\0\0\0\0\0\0\0";
3604 arch
->toc_long_name
= FALSE
;
3605 ar_name
= arch
->toc_name
;
3610 * Since the SYMDEF_SORTED is "__.SYMDEF SORTED" which contains
3611 * a space, it should use extended format #1 if we can use long
3614 arch
->toc_name
= SYMDEF_SORTED
;
3615 arch
->toc_name_size
= sizeof(SYMDEF_SORTED
) - 1;
3616 if(cmd_flags
.use_long_names
== TRUE
){
3617 arch
->toc_long_name
= TRUE
;
3619 * This assumes that "__.SYMDEF SORTED" is 16 bytes and
3620 * (rnd(sizeof(struct ar_hdr), 8) - sizeof(struct ar_hdr)
3623 ar_name
= AR_EFMT1
"20";
3626 arch
->toc_long_name
= FALSE
;
3627 ar_name
= arch
->toc_name
;
3633 arch
->toc_name
= SYMDEF
;
3634 arch
->toc_name_size
= sizeof(SYMDEF
) - 1;
3635 if(cmd_flags
.use_long_names
== TRUE
){
3636 arch
->toc_long_name
= TRUE
;
3638 * This assumes that "__.SYMDEF\0\0\0\0\0\0\0" is 16 bytes and
3639 * (rnd(sizeof(struct ar_hdr), 8) - sizeof(struct ar_hdr)
3642 ar_name
= AR_EFMT1
"20";
3643 arch
->toc_name_size
= 16;
3644 arch
->toc_name
= SYMDEF
"\0\0\0\0\0\0\0";
3647 arch
->toc_long_name
= FALSE
;
3648 ar_name
= arch
->toc_name
;
3653 * Now set the ran_off and ran_un.ran_strx fields of the ranlib structs.
3654 * To do this the size of the toc member must be know because it comes
3655 * first in the library. The size of the toc member is made up of the
3656 * sizeof an archive header struct (the size of the name if a long name
3657 * is used) then the toc which is (as defined in ranlib.h):
3658 * a uint32_t for the number of bytes of the ranlib structs
3659 * the ranlib structures
3660 * a uint32_t for the number of bytes of the strings
3663 arch
->toc_size
= sizeof(struct ar_hdr
) +
3665 arch
->toc_nranlibs
* sizeof(struct ranlib
) +
3668 /* add the size of the name is a long name is used */
3669 if(arch
->toc_long_name
== TRUE
)
3670 arch
->toc_size
+= arch
->toc_name_size
+
3671 (rnd(sizeof(struct ar_hdr
), 8) -
3672 sizeof(struct ar_hdr
));
3673 for(i
= 0; i
< arch
->nmembers
; i
++)
3674 arch
->members
[i
].offset
+= SARMAG
+ arch
->toc_size
;
3675 for(i
= 0; i
< arch
->toc_nranlibs
; i
++){
3676 arch
->toc_ranlibs
[i
].ran_un
.ran_strx
=
3677 arch
->tocs
[i
].name
- arch
->toc_strings
;
3678 arch
->toc_ranlibs
[i
].ran_off
=
3679 arch
->members
[arch
->tocs
[i
].index1
- 1].offset
;
3682 sprintf((char *)(&arch
->toc_ar_hdr
), "%-*s%-*ld%-*u%-*u%-*o%-*ld",
3683 (int)sizeof(arch
->toc_ar_hdr
.ar_name
),
3685 (int)sizeof(arch
->toc_ar_hdr
.ar_date
),
3687 (int)sizeof(arch
->toc_ar_hdr
.ar_uid
),
3688 (unsigned short)getuid(),
3689 (int)sizeof(arch
->toc_ar_hdr
.ar_gid
),
3690 (unsigned short)getgid(),
3691 (int)sizeof(arch
->toc_ar_hdr
.ar_mode
),
3692 (unsigned int)toc_mode
,
3693 (int)sizeof(arch
->toc_ar_hdr
.ar_size
),
3694 (long)(arch
->toc_size
- sizeof(struct ar_hdr
)));
3696 * This has to be done by hand because sprintf puts a null
3697 * at the end of the buffer.
3699 memcpy(arch
->toc_ar_hdr
.ar_fmag
, ARFMAG
,
3700 (int)sizeof(arch
->toc_ar_hdr
.ar_fmag
));
3704 * Function for qsort() for comparing toc structures by name.
3709 const struct toc
*toc1
,
3710 const struct toc
*toc2
)
3712 return(strcmp(toc1
->name
, toc2
->name
));
3716 * Function for qsort() for comparing toc structures by index1.
3721 const struct toc
*toc1
,
3722 const struct toc
*toc2
)
3724 if(toc1
->index1
< toc2
->index1
)
3726 if(toc1
->index1
> toc2
->index1
)
3728 /* toc1->index1 == toc2->index1 */
3733 * toc_symbol() returns TRUE if the symbol is to be included in the table of
3734 * contents otherwise it returns FALSE.
3739 struct nlist
*symbol
,
3740 struct section
**sections
)
3742 return(toc(symbol
->n_un
.n_strx
,
3745 (symbol
->n_type
& N_TYPE
) == N_SECT
&&
3746 sections
[symbol
->n_sect
- 1]->flags
& S_ATTR_NO_TOC
));
3752 struct nlist_64
*symbol64
,
3753 struct section_64
**sections64
)
3755 return(toc(symbol64
->n_un
.n_strx
,
3758 (symbol64
->n_type
& N_TYPE
) == N_SECT
&&
3759 sections64
[symbol64
->n_sect
-1]->flags
& S_ATTR_NO_TOC
));
3768 enum bool attr_no_toc
)
3770 /* if the name is NULL then it won't be in the table of contents */
3773 /* if symbol is not external then it won't be in the toc */
3774 if((n_type
& N_EXT
) == 0)
3776 /* if symbol is undefined then it won't be in the toc */
3777 if((n_type
& N_TYPE
) == N_UNDF
&& n_value
== 0)
3779 /* if symbol is common and the -c flag is not specified then ... */
3780 if((n_type
& N_TYPE
) == N_UNDF
&& n_value
!= 0 &&
3781 cmd_flags
.c
== FALSE
)
3783 /* if the symbols is in a section marked NO_TOC then ... */
3784 if(attr_no_toc
!= 0)
3791 * check_sort_tocs() checks the table of contents for the specified arch
3792 * which is sorted by name for more then one object defining the same symbol.
3793 * It this is the case it prints each symbol that is defined in more than one
3794 * object along with the object it is defined in. It returns TRUE if there are
3795 * no multiple definitions and FALSE otherwise.
3802 enum bool library_warnings
)
3805 enum bool multiple_defs
;
3806 struct member
*member
;
3808 if(arch
->toc_nranlibs
== 0)
3811 * Since the symbol table is sorted by name look to any two adjcent
3812 * entries with the same name. If such entries are found print them
3813 * only once (marked by changing the sign of their ran_off).
3815 multiple_defs
= FALSE
;
3816 for(i
= 0; i
< arch
->toc_nranlibs
- 1; i
++){
3817 if(strcmp(arch
->tocs
[i
].name
, arch
->tocs
[i
+1].name
) == 0){
3818 if(multiple_defs
== FALSE
){
3819 if(library_warnings
== FALSE
)
3821 fprintf(stderr
, "%s: same symbol defined in more than one "
3822 "member ", progname
);
3824 fprintf(stderr
, "for architecture: %s ",
3825 arch
->arch_flag
.name
);
3826 fprintf(stderr
, "in: %s (table of contents will not be "
3827 "sorted)\n", output
);
3828 multiple_defs
= TRUE
;
3830 if((int)(arch
->tocs
[i
].index1
) > 0){
3831 member
= arch
->members
+ arch
->tocs
[i
].index1
- 1;
3832 warn_member(arch
, member
, "defines symbol: %s",
3833 arch
->tocs
[i
].name
);
3834 arch
->tocs
[i
].index1
=
3835 -(arch
->tocs
[i
].index1
);
3837 if((int)(arch
->tocs
[i
+1].index1
) > 0){
3838 member
= arch
->members
+ arch
->tocs
[i
+1].index1
- 1;
3839 warn_member(arch
, member
, "defines symbol: %s",
3840 arch
->tocs
[i
+1].name
);
3841 arch
->tocs
[i
+1].index1
=
3842 -(arch
->tocs
[i
+1].index1
);
3847 if(multiple_defs
== FALSE
)
3850 for(i
= 0; i
< arch
->toc_nranlibs
; i
++)
3851 if(((int)arch
->tocs
[i
].index1
) < 0)
3852 arch
->tocs
[i
].index1
=
3853 -(arch
->tocs
[i
].index1
);
3859 * warn_duplicate_member_names() generates a warning if two members end up with
3860 * the same ar_name. This is only a warning because ld(1) and this program
3861 * has no problems with it. Only if ar(1) were used to extract the files
3862 * would this be a problem (even the 4.4bsd ar(1) using long names can
3863 * get hosed by base names, the 4.3bsd ar(1) can't handle full 16 character
3868 warn_duplicate_member_names(
3871 uint32_t i
, j
, len
, len1
, len2
;
3873 for(i
= 0; i
< narchs
; i
++){
3874 /* sort in order of ar_names */
3875 qsort(archs
[i
].members
, archs
[i
].nmembers
, sizeof(struct member
),
3876 (int (*)(const void *, const void *))member_name_qsort
);
3878 /* check for duplicate names */
3879 for(j
= 0; j
< archs
[i
].nmembers
- 1; j
++){
3880 len1
= archs
[i
].members
[j
].member_name_size
;
3881 len2
= archs
[i
].members
[j
+1].member_name_size
;
3882 len
= len1
> len2
? len1
: len2
;
3883 if(strncmp(archs
[i
].members
[j
].member_name
,
3884 archs
[i
].members
[j
+1].member_name
,
3886 fprintf(stderr
, "%s: warning ", progname
);
3888 fprintf(stderr
, "for architecture: %s ",
3889 archs
[i
].arch_flag
.name
);
3890 fprintf(stderr
, "same member name (%.*s) in output file "
3891 "used for input files: ", (int)len1
,
3892 archs
[i
].members
[j
].member_name
);
3894 if(archs
[i
].members
[j
].input_ar_hdr
!= NULL
){
3895 len
= archs
[i
].members
[j
].input_base_name_size
;
3896 fprintf(stderr
, "%s(%.*s) and: ",
3897 archs
[i
].members
[j
].input_file_name
, (int)len
,
3898 archs
[i
].members
[j
].input_base_name
);
3901 fprintf(stderr
, "%s and: ",
3902 archs
[i
].members
[j
].input_file_name
);
3904 if(archs
[i
].members
[j
+1].input_ar_hdr
!= NULL
){
3905 len
= archs
[i
].members
[j
+1].input_base_name_size
;
3906 fprintf(stderr
, "%s(%.*s) due to use of basename, "
3907 "truncation and blank padding\n",
3908 archs
[i
].members
[j
+1].input_file_name
, (int)len
,
3909 archs
[i
].members
[j
+1].input_base_name
);
3912 fprintf(stderr
, "%s (due to use of basename, truncation"
3913 ", blank padding or duplicate input files)\n",
3914 archs
[i
].members
[j
+1].input_file_name
);
3918 /* sort back in order of offset */
3919 qsort(archs
[i
].members
, archs
[i
].nmembers
, sizeof(struct member
),
3920 (int (*)(const void *, const void *))member_offset_qsort
);
3925 * Function for qsort() for comparing member structures by ar_hdr.ar_name.
3930 const struct member
*member1
,
3931 const struct member
*member2
)
3933 uint32_t len
, len1
, len2
;
3935 len1
= member1
->member_name_size
;
3936 len2
= member2
->member_name_size
;
3937 len
= len1
> len2
? len1
: len2
;
3938 return(strncmp(member1
->member_name
, member2
->member_name
, len
));
3942 * Function for qsort() for comparing member structures by offset.
3946 member_offset_qsort(
3947 const struct member
*member1
,
3948 const struct member
*member2
)
3950 if(member1
->offset
< member2
->offset
)
3952 if(member1
->offset
> member2
->offset
)
3954 /* member1->offset == member2->offset */
3959 * warn_member() is like the error routines it prints the program name the
3960 * member name specified and message specified.
3966 struct member
*member
,
3967 const char *format
, ...)
3971 fprintf(stderr
, "%s: ", progname
);
3973 fprintf(stderr
, "for architecture: %s ", arch
->arch_flag
.name
);
3975 if(member
->input_ar_hdr
!= NULL
){
3976 fprintf(stderr
, "file: %s(%.*s) ", member
->input_file_name
,
3977 (int)member
->input_base_name_size
, member
->input_base_name
);
3980 fprintf(stderr
, "file: %s ", member
->input_file_name
);
3982 va_start(ap
, format
);
3983 vfprintf(stderr
, format
, ap
);
3984 fprintf(stderr
, "\n");
3989 * Prints the message to cmd_flags.trace_file_path, or stderr if that
3995 const char *format
, ...)
3997 static int trace_file
= -1;
3998 char trace_buffer
[MAXPATHLEN
* 2];
4001 ssize_t amount_written
;
4003 if(trace_file
== -1){
4004 if(cmd_flags
.trace_file_path
!= NULL
){
4005 trace_file
= open(cmd_flags
.trace_file_path
, O_WRONLY
| O_APPEND
| O_CREAT
, 0666);
4006 if(trace_file
== -1)
4007 error("Could not open or create trace file: %s\n", cmd_flags
.trace_file_path
);
4010 trace_file
= fileno(stderr
);
4015 va_start(ap
, format
);
4016 length
= vsnprintf(trace_buffer
, sizeof(trace_buffer
), format
, ap
);
4018 buffer_ptr
= trace_buffer
;
4020 amount_written
= write(trace_file
, buffer_ptr
, length
);
4021 if(amount_written
== -1)
4022 /* Failure to write shouldn't fail the build. */
4024 buffer_ptr
+= amount_written
;
4025 length
-= amount_written
;