836
[darwin-xtools.git] / cctools / misc / libtool.c
blob70b85b648a30c4a0ef260b02c88e47acb820587b
1 /*
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
11 * file.
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)
26 * program.
28 #include <mach/mach.h>
29 #include "stuff/openstep_mach.h"
30 #include <libc.h>
31 #ifndef __OPENSTEP__
32 #include <utime.h>
33 #endif
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <signal.h>
38 #include <ar.h>
39 #include <mach-o/ranlib.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <sys/mman.h>
43 #include "stuff/bool.h"
44 #include "stuff/ofile.h"
45 #include "stuff/rnd.h"
46 #include "stuff/errors.h"
47 #include "stuff/allocate.h"
48 #include "stuff/execute.h"
49 #include "stuff/version_number.h"
50 #include "stuff/unix_standard_mode.h"
51 #ifdef LTO_SUPPORT
52 #include "stuff/lto.h"
53 #endif /* LTO_SUPPORT */
55 #include <mach/mach_init.h>
56 #if defined(__OPENSTEP__) || defined(__GONZO_BUNSEN_BEAKER__)
57 #include <servers/netname.h>
58 #else
59 #include <servers/bootstrap.h>
60 #endif
63 * This is used internally to build the table of contents.
65 struct toc {
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
85 * equality.
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 */
95 struct cmd_flags {
96 char **files; /* array of file name arguments */
97 uint32_t
98 nfiles; /* number of file name arguments */
99 char **filelist; /* filelist argument the file name argument came from */
100 enum bool
101 no_files_ok; /* ok to see no files */
102 enum bool ranlib; /* set if this is run as ranlib not libtool */
103 enum bool s; /* sort the table of contents */
104 enum bool a; /* don't sort the table of contents (original form) */
105 enum bool c; /* include commmon symbols in the table of contents */
106 enum bool t; /* just "touch" the archives to get the date right */
107 enum bool f; /* warn if the output archive is fat,used by ar(1) -s */
108 enum bool q; /* only write archive if NOT fat, used by ar(1) */
109 char *output; /* the output file specified by -o */
110 enum bool final_output_specified; /* if -final_output is specified */
111 enum bool dynamic; /* create a dynamic shared library, static by default */
112 char *compatibility;/* compatibility version if specified, NULL otherwise */
113 char *current; /* current version if specified, NULL otherwise */
114 char *install_name; /* install name if specified, NULL otherwise */
115 char *seg1addr; /* seg1addr if specified, NULL otherwise */
116 char *segs_read_only_addr; /* segs_read_only_addr if specified, or NULL */
117 char *segs_read_write_addr; /* segs_read_write_addr if specified, or NULL */
118 char *seg_addr_table; /* seg_addr_table if specified, or NULL */
119 char *seg_addr_table_filename;
120 /* seg_addr_table_filename if specified, or NULL */
121 char **Ldirs; /* array of -Ldir arguments */
122 uint32_t
123 nLdirs; /* number of -Ldir arguments */
124 char **ldflags; /* other ld(1) flags to pass */
125 uint32_t
126 nldflags; /* number of ld(1) flags for above */
127 enum bool verbose; /* print exec(2) commands run */
128 struct arch_flag
129 arch_only_flag; /* the -arch_only flag if specified */
130 enum bool /* set if either -prebind or -noprebind is seen */
131 prebinding_flag_specified;
132 enum bool /* set if -prebind is seen or the LD_PREBIND */
133 prebinding; /* environment variable is set (and -noprebind isn't)*/
134 enum bool /* set if either -all_load or -noall_load is seen */
135 all_load_flag_specified;
136 enum bool /* set if -all_load is seen (and -noall_load isn't) */
137 all_load;
138 enum bool /* set with -L (the default) off with -T, for -static */
139 use_long_names; /* use 4.4bsd extended format 1 for long names */
140 enum bool L_or_T_specified;
141 enum bool /* set if the environ var LD_TRACE_ARCHIVES is set */
142 ld_trace_archives;
143 const char * /* LD_TRACE_FILE if set and LD_TRACE_ARCHIVES is set, or NULL */
144 trace_file_path;
145 enum bool /* set if -search_paths_first is specified */
146 search_paths_first;
147 enum bool noflush; /* don't use the output_flush routine to flush the
148 static library output file by pages */
149 uint32_t debug; /* debug value to debug output_flush() routine */
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[] = {
158 "/lib/",
159 "/usr/lib/",
160 "/usr/local/lib/",
161 NULL
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;
173 struct arch {
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 */
194 struct member {
195 uint32_t offset; /* current working offset and final offset*/
196 struct ar_hdr ar_hdr; /* the archive header for this member */
197 char null_byte; /* space to write '\0' for ar_hdr */
198 char *object_addr; /* the address of the object file */
199 uint32_t object_size; /* the size of the object file */
200 enum byte_sex object_byte_sex; /* the byte sex of the object file */
201 struct mach_header *mh; /* the mach_header of 32-bit object files */
202 struct mach_header_64 *mh64; /* the mach_header of 64-bit object files */
203 struct load_command /* the start of the load commands */
204 *load_commands;
205 struct symtab_command *st; /* the symbol table command */
206 struct section **sections; /* array of section structs for 32-bit */
207 struct section_64 **sections64; /* array of section structs for 64-bit */
208 #ifdef LTO_SUPPORT
209 void *lto; /* lto module */
210 #endif /* LTO_SUPPORT */
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 */
226 static void usage(
227 void);
228 static void process(
229 void);
230 static char *file_name_from_l_flag(
231 char *l_flag);
232 static char *search_for_file(
233 char *base_name);
234 static char * search_paths_for_lname(
235 const char *lname_argument);
236 static char * search_path_for_lname(
237 const char *dir,
238 const char *lname_argument);
239 static void add_member(
240 struct ofile *ofile);
241 static void free_archs(
242 void);
243 static void create_library(
244 char *output,
245 struct ofile *ofile);
246 static enum byte_sex get_target_byte_sex(
247 struct arch *arch,
248 enum byte_sex host_byte_sex);
249 static char *put_toc_member(
250 char *p,
251 struct arch *arch,
252 enum byte_sex host_byte_sex,
253 enum byte_sex target_byte_sex);
254 static void create_dynamic_shared_library(
255 char *output);
256 static void create_dynamic_shared_library_cleanup(
257 int sig);
258 static void make_table_of_contents(
259 struct arch *arch,
260 char *output);
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(
274 uint32_t n_strx,
275 uint8_t n_type,
276 uint64_t n_value,
277 enum bool attr_no_toc);
278 static enum bool check_sort_tocs(
279 struct arch *arch,
280 char *output,
281 enum bool library_warnings);
282 static void warn_duplicate_member_names(
283 void);
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(
291 struct arch *arch,
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 */
308 } *output_blocks;
310 static void output_flush(
311 char *library,
312 uint64_t library_size,
313 int fd,
314 uint64_t offset,
315 uint64_t size);
316 static void final_output_flush(
317 char *library,
318 int fd);
319 #ifdef DEBUG
320 static void print_block_list(void);
321 #endif /* DEBUG */
322 static struct block *get_block(void);
323 static void remove_block(
324 struct block *block);
325 static uint32_t trnc(
326 uint32_t v,
327 uint32_t r);
329 /* apple_version is in vers.c which is created by the libstuff/Makefile */
330 extern char apple_version[];
333 main(
334 int argc,
335 char **argv,
336 char **envp)
338 char *p, *endp, *filelist, *dirname, *addr;
339 int fd, i;
340 struct stat stat_buf;
341 uint32_t j, nfiles, maxfiles;
342 uint32_t temp;
343 int oumask, numask;
344 enum bool lflags_seen, bad_flag_seen, Vflag;
346 lflags_seen = FALSE;
347 Vflag = FALSE;
348 progname = argv[0];
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;
359 else
360 zero_ar_date = TRUE;
361 if(zero_ar_date == FALSE)
362 toc_time = time(0);
363 else
364 toc_time = 0;
366 numask = 0;
367 oumask = umask(numask);
368 toc_mode = S_IFREG | (0666 & ~oumask);
369 (void)umask(oumask);
371 /* see if this is being run as ranlib */
372 p = strrchr(argv[0], '/');
373 if(p != NULL)
374 p++;
375 else
376 p = argv[0];
377 if(strncmp(p, "ranlib", sizeof("ranlib") - 1) == 0)
378 cmd_flags.ranlib = TRUE;
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 */
384 maxfiles = argc;
385 cmd_flags.files = allocate(sizeof(char *) * maxfiles);
386 cmd_flags.filelist = allocate(sizeof(char *) * maxfiles);
387 memset(cmd_flags.filelist, '\0', sizeof(char *) * maxfiles);
388 for(i = 1; i < argc; i++){
389 if(argv[i][0] == '-'){
390 if(argv[i][1] == '\0'){
391 for(i += 1 ; i < argc; i++)
392 cmd_flags.files[cmd_flags.nfiles++] = argv[i];
393 break;
395 if(strcmp(argv[i], "-o") == 0){
396 if(cmd_flags.ranlib == TRUE){
397 error("unknown option: %s", argv[i]);
398 usage();
400 if(i + 1 == argc){
401 error("missing argument to: %s option", argv[i]);
402 usage();
404 if(cmd_flags.output != NULL){
405 error("more than one: %s option specified", argv[i]);
406 usage();
408 cmd_flags.output = argv[i+1];
409 i++;
411 else if(strcmp(argv[i], "-arch_only") == 0){
412 if(cmd_flags.ranlib == TRUE){
413 error("unknown option: %s", argv[i]);
414 usage();
416 if(i + 1 == argc){
417 error("missing argument to %s option", argv[i]);
418 usage();
420 if(cmd_flags.arch_only_flag.name != NULL){
421 error("more than one: %s option specified", argv[i]);
422 usage();
424 else{
425 if(get_arch_from_flag(argv[i+1],
426 &cmd_flags.arch_only_flag) == 0){
427 error("unknown architecture specification flag: "
428 "%s %s", argv[i], argv[i+1]);
429 arch_usage();
430 usage();
433 i++;
435 else if(strcmp(argv[i], "-dynamic") == 0){
436 if(cmd_flags.ranlib == TRUE){
437 error("unknown option: %s", argv[i]);
438 usage();
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]);
445 usage();
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]);
452 usage();
454 if(i + 1 == argc){
455 error("missing argument to: %s option", argv[i]);
456 usage();
458 filelist = argv[i + 1];
459 dirname = strrchr(filelist, ',');
460 if(dirname != NULL){
461 *dirname = '\0';
462 dirname++;
464 else
465 dirname = "";
466 if((fd = open(filelist, O_RDONLY, 0)) == -1)
467 system_fatal("can't open file list file: %s", filelist);
468 if(fstat(fd, &stat_buf) == -1)
469 system_fatal("can't stat file list file: %s", filelist);
471 * For some reason mapping files with zero size fails
472 * so it has to be handled specially.
474 addr = NULL;
475 if(stat_buf.st_size != 0){
476 addr = mmap(0, stat_buf.st_size, PROT_READ|PROT_WRITE,
477 MAP_FILE|MAP_PRIVATE, fd, 0);
478 if((intptr_t)addr == -1)
479 system_error("can't map file list file: %s",
480 filelist);
482 else{
483 fatal("file list file: %s is empty", filelist);
485 if(*dirname != '\0')
486 dirname[-1] = ',';
487 close(fd);
488 nfiles = 0;
489 for(j = 0; j < stat_buf.st_size; j++){
490 if(addr[j] == '\n')
491 nfiles++;
493 if(addr[stat_buf.st_size - 1] != '\n')
494 nfiles++;
495 p = allocate((strlen(dirname) + 1) * nfiles +
496 stat_buf.st_size);
497 cmd_flags.files = reallocate(cmd_flags.files,
498 sizeof(char *) * (maxfiles + nfiles));
499 cmd_flags.filelist = reallocate(cmd_flags.filelist,
500 sizeof(char *) * (maxfiles + nfiles));
501 memset(cmd_flags.filelist + maxfiles, '\0',
502 sizeof(char *) * nfiles);
503 maxfiles += nfiles;
505 cmd_flags.files[cmd_flags.nfiles] = p;
506 cmd_flags.filelist[cmd_flags.nfiles] = filelist;
507 cmd_flags.nfiles++;
508 if(*dirname != '\0'){
509 strcpy(p, dirname);
510 p += strlen(dirname);
511 *p++ = '/';
513 for(j = 0; j < stat_buf.st_size; j++){
514 if(addr[j] != '\n')
515 *p++ = addr[j];
516 else{
517 *p++ = '\0';
518 if(j != stat_buf.st_size - 1){
519 cmd_flags.files[cmd_flags.nfiles] = p;
520 cmd_flags.filelist[cmd_flags.nfiles] =argv[i+1];
521 cmd_flags.nfiles++;
522 if(*dirname != '\0'){
523 strcpy(p, dirname);
524 p += strlen(dirname);
525 *p++ = '/';
530 if(addr[stat_buf.st_size - 1] != '\n')
531 *p = '\0';
532 i++;
534 else if(strcmp(argv[i], "-compatibility_version") == 0){
535 if(cmd_flags.ranlib == TRUE){
536 error("unknown option: %s", argv[i]);
537 usage();
539 if(i + 1 == argc){
540 error("missing argument to: %s option", argv[i]);
541 usage();
543 if(cmd_flags.compatibility != NULL){
544 error("more than one: %s option specified", argv[i]);
545 usage();
547 if(get_version_number(argv[i], argv[i+1], &temp) == FALSE){
548 usage();
550 cmd_flags.compatibility = argv[i+1];
551 i++;
553 else if(strcmp(argv[i], "-current_version") == 0){
554 if(cmd_flags.ranlib == TRUE){
555 error("unknown option: %s", argv[i]);
556 usage();
558 if(i + 1 == argc){
559 error("missing argument to: %s option", argv[i]);
560 usage();
562 if(cmd_flags.current != NULL){
563 error("more than one: %s option specified", argv[i]);
564 usage();
566 if(get_version_number(argv[i], argv[i+1], &temp) == FALSE){
567 usage();
569 cmd_flags.current = argv[i+1];
570 i++;
572 else if(strcmp(argv[i], "-install_name") == 0){
573 if(cmd_flags.ranlib == TRUE){
574 error("unknown option: %s", argv[i]);
575 usage();
577 if(i + 1 == argc){
578 error("missing argument to: %s option", argv[i]);
579 usage();
581 if(cmd_flags.install_name != NULL){
582 error("more than one: %s option specified", argv[i]);
583 usage();
585 cmd_flags.install_name = argv[i+1];
586 i++;
588 else if(strcmp(argv[i], "-seg1addr") == 0 ||
589 strcmp(argv[i], "-image_base") == 0){
590 if(cmd_flags.ranlib == TRUE){
591 error("unknown option: %s", argv[i]);
592 usage();
594 if(i + 1 == argc){
595 error("missing argument to: %s option", argv[i]);
596 usage();
598 if(cmd_flags.seg1addr != NULL){
599 error("more than one: %s option specified", argv[i]);
600 usage();
602 temp = strtoul(argv[i + 1], &endp, 16);
603 if(*endp != '\0'){
604 error("address for -seg1addr %s not a proper "
605 "hexadecimal number", argv[i+1]);
606 usage();
608 cmd_flags.seg1addr = argv[i+1];
609 i++;
611 else if(strcmp(argv[i], "-segs_read_only_addr") == 0){
612 if(cmd_flags.ranlib == TRUE){
613 error("unknown option: %s", argv[i]);
614 usage();
616 if(i + 1 == argc){
617 error("missing argument to: %s option", argv[i]);
618 usage();
620 if(cmd_flags.segs_read_only_addr != NULL){
621 error("more than one: %s option specified", argv[i]);
622 usage();
624 temp = strtoul(argv[i + 1], &endp, 16);
625 if(*endp != '\0'){
626 error("address for -segs_read_only_addr %s not a "
627 "proper hexadecimal number", argv[i+1]);
628 usage();
630 cmd_flags.segs_read_only_addr = argv[i+1];
631 i++;
633 else if(strcmp(argv[i], "-segs_read_write_addr") == 0){
634 if(cmd_flags.ranlib == TRUE){
635 error("unknown option: %s", argv[i]);
636 usage();
638 if(i + 1 == argc){
639 error("missing argument to: %s option", argv[i]);
640 usage();
642 if(cmd_flags.segs_read_write_addr != NULL){
643 error("more than one: %s option specified", argv[i]);
644 usage();
646 temp = strtoul(argv[i + 1], &endp, 16);
647 if(*endp != '\0'){
648 error("address for -segs_read_write_addr %s not a "
649 "proper hexadecimal number", argv[i+1]);
650 usage();
652 cmd_flags.segs_read_write_addr = argv[i+1];
653 i++;
655 else if(strcmp(argv[i], "-seg_addr_table") == 0){
656 if(cmd_flags.ranlib == TRUE){
657 error("unknown option: %s", argv[i]);
658 usage();
660 if(i + 1 == argc){
661 error("missing argument to: %s option", argv[i]);
662 usage();
664 if(cmd_flags.seg_addr_table != NULL){
665 error("more than one: %s option specified", argv[i]);
666 usage();
668 cmd_flags.seg_addr_table = argv[i+1];
669 i++;
671 else if(strcmp(argv[i], "-seg_addr_table_filename") == 0){
672 if(cmd_flags.ranlib == TRUE){
673 error("unknown option: %s", argv[i]);
674 usage();
676 if(i + 1 == argc){
677 error("missing argument to: %s option", argv[i]);
678 usage();
680 if(cmd_flags.seg_addr_table_filename != NULL){
681 error("more than one: %s option specified", argv[i]);
682 usage();
684 cmd_flags.seg_addr_table_filename = argv[i+1];
685 i++;
687 else if(strcmp(argv[i], "-syslibroot") == 0){
688 if(cmd_flags.ranlib == TRUE){
689 error("unknown option: %s", argv[i]);
690 usage();
692 if(i + 1 == argc){
693 error("missing argument to: %s option", argv[i]);
694 usage();
696 if(next_root != NULL && strcmp(next_root, argv[i+1]) != 0){
697 error("more than one: %s option specified", argv[i]);
698 usage();
700 next_root = argv[i+1];
701 cmd_flags.ldflags = reallocate(cmd_flags.ldflags,
702 sizeof(char *) * (cmd_flags.nldflags + 2));
703 cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i];
704 cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i+1];
705 i++;
707 else if(strcmp(argv[i], "-sectcreate") == 0 ||
708 strcmp(argv[i], "-segcreate") == 0 ||
709 strcmp(argv[i], "-sectorder") == 0 ||
710 strcmp(argv[i], "-sectalign") == 0 ||
711 strcmp(argv[i], "-segprot") == 0){
712 if(cmd_flags.ranlib == TRUE){
713 error("unknown option: %s", argv[i]);
714 usage();
716 if(i + 3 >= argc){
717 error("not enough arguments follow %s", argv[i]);
718 usage();
720 cmd_flags.ldflags = reallocate(cmd_flags.ldflags,
721 sizeof(char *) * (cmd_flags.nldflags + 4));
722 cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i];
723 cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i+1];
724 cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i+2];
725 cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i+3];
726 if(strcmp(argv[i], "-sectcreate") == 0 ||
727 strcmp(argv[i], "-segcreate") == 0)
728 cmd_flags.no_files_ok = TRUE;
729 i += 3;
731 else if(strcmp(argv[i], "-segalign") == 0 ||
732 strcmp(argv[i], "-undefined") == 0 ||
733 strcmp(argv[i], "-macosx_version_min") == 0 ||
734 strcmp(argv[i], "-multiply_defined") == 0 ||
735 strcmp(argv[i], "-multiply_defined_unused") == 0 ||
736 strcmp(argv[i], "-umbrella") == 0 ||
737 strcmp(argv[i], "-sub_umbrella") == 0 ||
738 strcmp(argv[i], "-sub_library") == 0 ||
739 strcmp(argv[i], "-allowable_client") == 0 ||
740 strcmp(argv[i], "-read_only_relocs") == 0 ||
741 strcmp(argv[i], "-init") == 0 ||
742 strcmp(argv[i], "-U") == 0 ||
743 strcmp(argv[i], "-Y") == 0 ||
744 strcmp(argv[i], "-dylib_file") == 0 ||
745 strcmp(argv[i], "-final_output") == 0 ||
746 strcmp(argv[i], "-headerpad") == 0 ||
747 strcmp(argv[i], "-weak_reference_mismatches") == 0 ||
748 strcmp(argv[i], "-u") == 0 ||
749 strcmp(argv[i], "-exported_symbols_list") == 0 ||
750 strcmp(argv[i], "-unexported_symbols_list") == 0 ||
751 strcmp(argv[i], "-executable_path") == 0){
752 if(cmd_flags.ranlib == TRUE){
753 error("unknown option: %s", argv[i]);
754 usage();
756 if(i + 1 >= argc){
757 error("not enough arguments follow %s", argv[i]);
758 usage();
760 cmd_flags.ldflags = reallocate(cmd_flags.ldflags,
761 sizeof(char *) * (cmd_flags.nldflags + 2));
762 cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i];
763 cmd_flags.ldflags[cmd_flags.nldflags++] = argv[i+1];
764 if(strcmp(argv[i], "-final_output") == 0)
765 cmd_flags.final_output_specified = TRUE;
766 i += 1;
768 else if(strcmp(argv[i], "-sectorder_detail") == 0 ||
769 strcmp(argv[i], "-Sn") == 0 ||
770 strcmp(argv[i], "-Si") == 0 ||
771 strcmp(argv[i], "-Sp") == 0 ||
772 strcmp(argv[i], "-S") == 0 ||
773 strcmp(argv[i], "-X") == 0 ||
774 strcmp(argv[i], "-x") == 0 ||
775 strcmp(argv[i], "-whatsloaded") == 0 ||
776 strcmp(argv[i], "-whyload") == 0 ||
777 strcmp(argv[i], "-arch_errors_fatal") == 0 ||
778 strcmp(argv[i], "-run_init_lazily") == 0 ||
779 strcmp(argv[i], "-twolevel_namespace") == 0 ||
780 strcmp(argv[i], "-twolevel_namespace_hints") == 0 ||
781 strcmp(argv[i], "-flat_namespace") == 0 ||
782 strcmp(argv[i], "-nomultidefs") == 0 ||
783 strcmp(argv[i], "-headerpad_max_install_names") == 0 ||
784 strcmp(argv[i], "-prebind_all_twolevel_modules") == 0 ||
785 strcmp(argv[i], "-prebind_allow_overlap") == 0 ||
786 strcmp(argv[i], "-ObjC") == 0 ||
787 strcmp(argv[i], "-M") == 0 ||
788 strcmp(argv[i], "-t") == 0 ||
789 strcmp(argv[i], "-single_module") == 0 ||
790 strcmp(argv[i], "-multi_module") == 0 ||
791 strcmp(argv[i], "-m") == 0 ||
792 strcmp(argv[i], "-dead_strip") == 0 ||
793 strcmp(argv[i], "-no_uuid") == 0 ||
794 strcmp(argv[i], "-no_dead_strip_inits_and_terms") == 0){
795 if(cmd_flags.ranlib == TRUE){
796 error("unknown option: %s", argv[i]);
797 usage();
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]);
806 usage();
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]);
813 usage();
815 if(cmd_flags.prebinding_flag_specified == TRUE &&
816 cmd_flags.prebinding == FALSE){
817 error("both -prebind and -noprebind can't be "
818 "specified");
819 usage();
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]);
830 usage();
832 if(cmd_flags.prebinding_flag_specified == TRUE &&
833 cmd_flags.prebinding == TRUE){
834 error("both -prebind and -noprebind can't be "
835 "specified");
836 usage();
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]);
847 usage();
849 if(cmd_flags.all_load_flag_specified == TRUE &&
850 cmd_flags.all_load == FALSE){
851 error("both -all_load and -noall_load can't be "
852 "specified");
853 usage();
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]);
861 usage();
863 if(cmd_flags.all_load_flag_specified == TRUE &&
864 cmd_flags.all_load == TRUE){
865 error("both -all_load and -noall_load can't be "
866 "specified");
867 usage();
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]);
876 usage();
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]);
887 usage();
889 if(argv[i][2] == '\0'){
890 error("-l: name missing");
891 usage();
893 cmd_flags.files[cmd_flags.nfiles++] = argv[i];
894 lflags_seen = TRUE;
896 else if(strncmp(argv[i], "-weak-l", 7) == 0){
897 if(cmd_flags.ranlib == TRUE){
898 error("unknown option: %s", argv[i]);
899 usage();
901 if(argv[i][7] == '\0'){
902 error("-weak-l: name missing");
903 usage();
905 cmd_flags.files[cmd_flags.nfiles++] = argv[i];
906 lflags_seen = TRUE;
908 else if(strcmp(argv[i], "-framework") == 0 ||
909 strcmp(argv[i], "-weak_framework") == 0 ||
910 strcmp(argv[i], "-weak_library") == 0){
911 if(cmd_flags.ranlib == TRUE){
912 error("unknown option: %s", argv[i]);
913 usage();
915 if(i + 1 >= argc){
916 error("not enough arguments follow %s", argv[i]);
917 usage();
919 cmd_flags.files[cmd_flags.nfiles++] = argv[i];
920 cmd_flags.files[cmd_flags.nfiles++] = argv[i+1];
921 lflags_seen = TRUE;
922 i += 1;
924 else if(strcmp(argv[i], "-T") == 0){
925 if(cmd_flags.L_or_T_specified == TRUE){
926 error("both -T and -L can't be specified");
927 usage();
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");
936 usage();
938 cmd_flags.L_or_T_specified = TRUE;
939 cmd_flags.use_long_names = TRUE;
941 else{
942 if(cmd_flags.ranlib == TRUE){
943 error("unknown option: %s", argv[i]);
944 usage();
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]);
954 usage();
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]);
962 usage();
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]);
970 usage();
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;
980 #ifdef DEBUG
981 else if(strcmp(argv[i], "-debug") == 0){
982 if(i + 1 >= argc){
983 error("not enough arguments follow %s", argv[i]);
984 usage();
986 i++;
987 cmd_flags.debug |= 1 << strtoul(argv[i], &endp, 10);
988 if(*endp != '\0' || strtoul(argv[i], &endp, 10) > 32)
989 fatal("argument for -debug %s not a proper "
990 "decimal number less than 32", argv[i]);
992 #endif /* DEBUG */
993 else{
994 for(j = 1; argv[i][j] != '\0'; j++){
995 switch(argv[i][j]){
996 case 's':
997 cmd_flags.s = TRUE;
998 break;
999 case 'a':
1000 cmd_flags.a = TRUE;
1001 break;
1002 case 'c':
1003 cmd_flags.c = TRUE;
1004 break;
1005 case 'v':
1006 if(cmd_flags.ranlib == TRUE){
1007 error("unknown option character `%c' in: %s",
1008 argv[i][j], argv[i]);
1009 usage();
1011 cmd_flags.verbose= TRUE;
1012 break;
1013 case 'V':
1014 printf("Apple Inc. version %s\n", apple_version);
1015 Vflag = TRUE;
1016 break;
1017 case 't':
1018 if(cmd_flags.ranlib == TRUE){
1019 warning("touch option (`%c' in: %s) ignored "
1020 "(table of contents rebuilt anyway)",
1021 argv[i][j], argv[i]);
1022 cmd_flags.t = TRUE;
1023 break;
1025 else {
1026 error("unknown option character `%c' in: %s",
1027 argv[i][j], argv[i]);
1028 usage();
1030 case 'f':
1031 if(cmd_flags.ranlib == TRUE){
1032 cmd_flags.f = TRUE;
1033 break;
1035 else {
1036 error("unknown option character `%c' in: %s",
1037 argv[i][j], argv[i]);
1038 usage();
1040 case 'q':
1041 if(cmd_flags.ranlib == TRUE){
1042 cmd_flags.q = TRUE;
1043 break;
1045 else {
1046 error("unknown option character `%c' in: %s",
1047 argv[i][j], argv[i]);
1048 usage();
1050 default:
1051 error("unknown option character `%c' in: %s",
1052 argv[i][j], argv[i]);
1053 usage();
1058 else
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");
1080 else{
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')
1093 continue;
1094 if(cmd_flags.Ldirs[i][2] == '/'){
1095 p = makestr(next_root, cmd_flags.Ldirs[i] + 2, NULL);
1096 if(access(p, F_OK) != -1){
1097 free(p);
1098 p = makestr("-L", next_root, cmd_flags.Ldirs[i] + 2,
1099 NULL);
1100 cmd_flags.Ldirs[i] = p;
1102 else{
1103 free(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");
1123 else
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");
1129 usage();
1131 if(cmd_flags.ranlib == FALSE && cmd_flags.output == NULL){
1132 if(Vflag == TRUE)
1133 exit(EXIT_SUCCESS);
1134 error("no output file specified (specify with -o output)");
1135 usage();
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",
1144 cmd_flags.current);
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");
1173 else
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){
1180 j++;
1181 continue;
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)
1199 continue;
1200 if(bad_flag_seen == FALSE){
1201 fprintf(stderr, "%s: -dynamic not specified the "
1202 "following flags are invalid: ", progname);
1203 bad_flag_seen = TRUE;
1205 fprintf(stderr, "%s ", cmd_flags.Ldirs[j]);
1207 if(bad_flag_seen == TRUE)
1208 fprintf(stderr, "\n");
1211 else{
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");
1222 else{
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");
1231 usage();
1233 else{
1234 if(cmd_flags.dynamic == TRUE && cmd_flags.no_files_ok == TRUE)
1235 warning("warning no files specified");
1236 else{
1237 error("no files specified");
1238 usage();
1243 /* set the defaults if not specified */
1244 if(cmd_flags.a == FALSE)
1245 cmd_flags.s = TRUE; /* sort table of contents by default */
1247 process();
1249 if(errors == 0)
1250 return(EXIT_SUCCESS);
1251 else
1252 return(EXIT_FAILURE);
1256 * usage() prints the current usage message and exits indicating failure.
1258 static
1259 void
1260 usage(
1261 void)
1263 if(cmd_flags.ranlib)
1264 fprintf(stderr, "Usage: %s [-sactfqLT] [-] archive [...]\n",
1265 progname);
1266 else{
1267 fprintf(stderr, "Usage: %s -static [-] file [...] "
1268 "[-filelist listfile[,dirname]] [-arch_only arch] "
1269 "[-sacLT]\n", progname);
1270 fprintf(stderr, "Usage: %s -dynamic [-] file [...] "
1271 "[-filelist listfile[,dirname]] [-arch_only arch] "
1272 "[-o output] [-install_name name] "
1273 "[-compatibility_version #] [-current_version #] "
1274 "[-seg1addr 0x#] [-segs_read_only_addr 0x#] "
1275 "[-segs_read_write_addr 0x#] [-seg_addr_table <filename>] "
1276 "[-seg_addr_table_filename <file_system_path>] "
1277 "[-all_load] [-noall_load]\n",
1278 progname);
1280 exit(EXIT_FAILURE);
1284 * process() the input files into libraries based on the command flags.
1286 static
1287 void
1288 process(
1289 void)
1291 uint32_t i, j, k, previous_errors;
1292 struct ofile *ofiles;
1293 char *file_name;
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) ==
1310 FALSE)
1311 continue;
1313 else if(strcmp(cmd_flags.files[i], "-framework") == 0 ||
1314 strcmp(cmd_flags.files[i], "-weak_framework") == 0 ||
1315 strcmp(cmd_flags.files[i], "-weak_library") == 0){
1316 i++;
1317 continue;
1319 else{
1320 if(ofile_map(cmd_flags.files[i], NULL, NULL, ofiles + i,
1321 TRUE) == FALSE)
1322 continue;
1325 previous_errors = errors;
1326 errors = 0;
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) !=
1338 NULL)
1339 ld_trace("[Logging for XBS] Used static "
1340 "archive: %s\n", resolvedname);
1341 else
1342 ld_trace("[Logging for XBS] Used static "
1343 "archive: %s\n", ofiles[i].file_name);
1344 ld_trace_archive_printed = TRUE;
1346 /* loop through archive */
1347 if((flag = ofile_first_member(ofiles + i)) == TRUE){
1348 if(ofiles[i].member_ar_hdr != NULL &&
1349 strncmp(ofiles[i].member_name, SYMDEF,
1350 sizeof(SYMDEF) - 1) == 0)
1351 flag = ofile_next_member(ofiles + i);
1352 while(flag == TRUE){
1353 /* No fat members in a fat file */
1354 if(ofiles[i].mh != NULL ||
1355 ofiles[i].mh64 != NULL ||
1356 ofiles[i].lto != NULL ||
1357 cmd_flags.ranlib == TRUE)
1358 add_member(ofiles + i);
1359 else{
1360 error("for architecture: %s file: %s(%.*s) "
1361 "is not an object file (not allowed "
1362 "in a library)",
1363 ofiles[i].arch_flag.name,
1364 cmd_flags.files[i],
1365 (int)ofiles[i].member_name_size,
1366 ofiles[i].member_name);
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;
1380 else
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;
1390 else{
1391 error("for architecture: %s file: %s is not an "
1392 "object file (not allowed in a library)",
1393 ofiles[i].arch_flag.name, cmd_flags.files[i]);
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);
1406 else
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);
1429 else{
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 ||
1447 #ifdef LTO_SUPPORT
1448 ofiles[i].lto != NULL ||
1449 #endif /* LTO_SUPPORT */
1450 cmd_flags.ranlib == TRUE){
1451 add_member(ofiles + i);
1453 else{
1454 error("file: %s(%.*s) is not an object file (not "
1455 "allowed in a library)", cmd_flags.files[i],
1456 (int)ofiles[i].member_name_size,
1457 ofiles[i].member_name);
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]);
1466 continue;
1468 add_member(ofiles + i);
1470 #ifdef LTO_SUPPORT
1471 else if(ofiles[i].file_type == OFILE_LLVM_BITCODE){
1472 if(cmd_flags.ranlib == TRUE){
1473 error("file: %s is not an archive", cmd_flags.files[i]);
1474 continue;
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]);
1482 continue;
1484 else{
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
1496 * belong to.
1498 if(narchs > 1){
1499 for(j = 0; j < narchs; j++){
1500 for(k = 0; k < archs[j].nmembers; k++){
1501 if(archs[j].members[k].mh == NULL &&
1502 #ifdef LTO_SUPPORT
1503 archs[j].members[k].lto == NULL &&
1504 #endif /* LTO_SUPPORT */
1505 archs[j].members[k].mh64 == NULL){
1506 error("library member: %s(%.*s) is not an "
1507 "object file (not allowed in a library "
1508 "with multiple architectures)",
1509 cmd_flags.files[i],
1510 (int)archs[j].members[k].
1511 input_base_name_size,
1512 archs[j].members[k].input_base_name);
1517 if(errors == 0)
1518 create_library(cmd_flags.files[i], ofiles + i);
1519 if(cmd_flags.nfiles > 1){
1520 ranlib_fat_error:
1521 free_archs();
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.
1542 static
1543 char *
1544 file_name_from_l_flag(
1545 char *l_flag)
1547 char *file_name, *p, *start;
1549 if(strncmp(l_flag, "-weak-l", 7) == 0)
1550 start = &l_flag[7];
1551 else
1552 start = &l_flag[2];
1553 p = strrchr(start, '.');
1554 if(p != NULL && strcmp(p, ".o") == 0){
1555 p = start;
1556 file_name = search_for_file(p);
1558 else{
1559 file_name = NULL;
1560 if(cmd_flags.dynamic == TRUE){
1561 if(cmd_flags.search_paths_first == TRUE){
1562 file_name = search_paths_for_lname(start);
1564 else{
1565 p = makestr("lib", start, ".dylib", NULL);
1566 file_name = search_for_file(p);
1567 free(p);
1568 if(file_name == NULL){
1569 p = makestr("lib", start, ".a", NULL);
1570 file_name = search_for_file(p);
1571 free(p);
1575 else{
1576 p = makestr("lib", start, ".a", NULL);
1577 file_name = search_for_file(p);
1578 free(p);
1581 if(file_name == NULL)
1582 error("can't locate file for: %s", l_flag);
1583 return(file_name);
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.
1591 static
1592 char *
1593 search_for_file(
1594 char *base_name)
1596 uint32_t i;
1597 char *file_name;
1599 for(i = 0; i < cmd_flags.nLdirs ; i++){
1600 if(cmd_flags.Ldirs[i][1] != 'L')
1601 continue;
1602 file_name = makestr(cmd_flags.Ldirs[i] + 2, "/", base_name, NULL);
1603 if(access(file_name, R_OK) != -1)
1604 return(file_name);
1605 free(file_name);
1607 for(i = 0; standard_dirs[i] != NULL ; i++){
1608 file_name = makestr(standard_dirs[i], base_name, NULL);
1609 if(access(file_name, R_OK) != -1)
1610 return(file_name);
1611 free(file_name);
1613 return(NULL);
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.
1625 static
1626 char *
1627 search_paths_for_lname(
1628 const char *lname_argument)
1630 uint32_t i;
1631 char *file_name, *dir;
1633 for(i = 0; i < cmd_flags.nLdirs ; i++){
1634 if(cmd_flags.Ldirs[i][1] != 'L')
1635 continue;
1636 dir = makestr(cmd_flags.Ldirs[i] + 2, "/", NULL);
1637 file_name = search_path_for_lname(dir, lname_argument);
1638 free(dir);
1639 if(file_name != NULL)
1640 return(file_name);
1642 for(i = 0; standard_dirs[i] != NULL ; i++){
1643 file_name = search_path_for_lname(standard_dirs[i], lname_argument);
1644 if(file_name != NULL)
1645 return(file_name);
1647 return(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.
1657 static
1658 char *
1659 search_path_for_lname(
1660 const char *dir,
1661 const char *lname_argument)
1663 char *file_name;
1665 file_name = makestr(dir, "/", "lib", lname_argument, ".dylib", NULL);
1666 if(access(file_name, R_OK) != -1)
1667 return(file_name);
1668 free(file_name);
1670 file_name = makestr(dir, "/", "lib", lname_argument, ".a", NULL);
1671 if(access(file_name, R_OK) != -1)
1672 return(file_name);
1673 free(file_name);
1675 return(NULL);
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).
1683 static
1684 void
1685 add_member(
1686 struct ofile *ofile)
1688 uint32_t i, j, size, ar_name_size;
1689 struct arch *arch;
1690 struct member *member;
1691 struct stat stat_buf;
1692 char *p, c, ar_name_buf[sizeof(ofile->member_ar_hdr->ar_name) + 1];
1693 char ar_size_buf[sizeof(ofile->member_ar_hdr->ar_size) + 1];
1694 const struct arch_flag *family_arch_flag;
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);
1703 return;
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);
1722 #ifdef LTO_SUPPORT
1723 else if(ofile->lto != NULL && ofile->file_type == OFILE_LLVM_BITCODE)
1724 size = rnd(ofile->file_size, 8);
1725 #endif /* LTO_SUPPORT */
1726 else
1727 size = rnd(ofile->member_size, 8);
1729 /* select or create an arch type to put this in */
1730 i = 0;
1731 if(ofile->mh != NULL ||
1732 ofile->mh64 != NULL){
1733 if(ofile->mh_cputype == 0){
1734 if(ofile->member_ar_hdr != NULL){
1735 error("file: %s(%.*s) cputype is zero (a reserved value)",
1736 ofile->file_name, (int)ofile->member_name_size,
1737 ofile->member_name);
1739 else
1740 error("file: %s cputype is zero (a reserved value)",
1741 ofile->file_name);
1742 return;
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);
1766 else
1767 warning("file: %s is a dynamic library, not added to "
1768 "the static library", ofile->file_name);
1770 return;
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)
1778 return;
1779 if(cmd_flags.arch_only_flag.cputype == CPU_TYPE_ARM){
1780 if(cmd_flags.arch_only_flag.cpusubtype !=
1781 ofile->mh_cpusubtype)
1782 return;
1786 for( ; i < narchs; i++){
1787 if(archs[i].arch_flag.cputype == ofile->mh_cputype){
1788 if(archs[i].arch_flag.cputype == CPU_TYPE_ARM &&
1789 archs[i].arch_flag.cpusubtype != ofile->mh_cpusubtype)
1790 continue;
1791 break;
1795 #ifdef LTO_SUPPORT
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)
1803 return;
1805 for( ; i < narchs; i++){
1806 if(archs[i].arch_flag.cputype == ofile->lto_cputype){
1807 if(archs[i].arch_flag.cputype == CPU_TYPE_ARM &&
1808 archs[i].arch_flag.cpusubtype != ofile->lto_cpusubtype)
1809 continue;
1810 break;
1814 #endif /* LTO_SUPPORT */
1815 if(narchs == 1 && archs[0].arch_flag.cputype == 0){
1816 i = 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;
1830 else{
1831 family_arch_flag =
1832 get_arch_family_from_cputype(ofile->mh_cputype);
1833 if(family_arch_flag != NULL)
1834 archs[narchs].arch_flag = *family_arch_flag;
1837 #ifdef LTO_SUPPORT
1838 else if(ofile->lto != NULL){
1839 if(ofile->lto_cputype == CPU_TYPE_ARM){
1840 archs[narchs].arch_flag.name = (char *)
1841 get_arch_name_from_types(
1842 ofile->lto_cputype, ofile->lto_cpusubtype);
1843 archs[narchs].arch_flag.cputype = ofile->lto_cputype;
1844 archs[narchs].arch_flag.cpusubtype = ofile->lto_cpusubtype;
1846 else{
1847 family_arch_flag =
1848 get_arch_family_from_cputype(ofile->lto_cputype);
1849 if(family_arch_flag != NULL)
1850 archs[narchs].arch_flag = *family_arch_flag;
1853 #endif /* LTO_SUPPORT */
1854 else
1855 archs[narchs].arch_flag.name = "unknown";
1856 narchs++;
1858 arch = archs + i;
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;
1870 else{
1871 arch->arch_flag.name =
1872 savestr("cputype 1234567890 cpusubtype 1234567890");
1873 if(arch->arch_flag.name != NULL)
1874 sprintf(arch->arch_flag.name, "cputype %u cpusubtype %u",
1875 ofile->mh_cputype, ofile->mh_cpusubtype &
1876 ~CPU_SUBTYPE_MASK);
1877 arch->arch_flag.cputype = ofile->mh_cputype;
1878 arch->arch_flag.cpusubtype = ofile->mh_cpusubtype;
1881 #ifdef LTO_SUPPORT
1882 if(arch->arch_flag.cputype == 0 &&
1883 (ofile->lto != NULL)){
1884 family_arch_flag = get_arch_family_from_cputype(ofile->lto_cputype);
1885 if(family_arch_flag != NULL){
1886 arch->arch_flag = *family_arch_flag;
1888 else{
1889 arch->arch_flag.name =
1890 savestr("cputype 1234567890 cpusubtype 1234567890");
1891 if(arch->arch_flag.name != NULL)
1892 sprintf(arch->arch_flag.name, "cputype %u cpusubtype %u",
1893 ofile->lto_cputype, ofile->lto_cpusubtype &
1894 ~CPU_SUBTYPE_MASK);
1895 arch->arch_flag.cputype = ofile->lto_cputype;
1896 arch->arch_flag.cpusubtype = ofile->lto_cpusubtype;
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));
1906 arch->nmembers++;
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, '/');
1918 if(p != NULL)
1919 p++;
1920 else
1921 p = ofile->file_name;
1922 member->input_base_name = p;
1923 member->input_base_name_size = strlen(p);
1924 member->member_name = member->input_base_name;
1926 * If we can use long names then force using them to allow 64-bit
1927 * objects to be aligned on an 8 byte boundary. This is needed
1928 * since the struct ar_hdr is not a multiple of 8. This is normally
1929 * done if the name does not fit in the archive header or contains
1930 * a space character then we use the extened format #1. The size
1931 * of the name is rounded up so the object file after the name will
1932 * be on an 8 byte boundary (including rounding the size of the
1933 * struct ar_hdr). The name will be padded with '\0's when it is
1934 * written out.
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));
1949 else{
1950 ar_name_size = 0;
1951 member->output_long_name = FALSE;
1953 * Truncate the file_name if needed and place in archive header.
1955 c = '\0';
1956 if(strlen(p) > sizeof(member->ar_hdr.ar_name)){
1957 c = p[sizeof(member->ar_hdr.ar_name)];
1958 p[sizeof(member->ar_hdr.ar_name)] = '\0';
1960 sprintf((char *)(&member->ar_hdr), "%-*s",
1961 (int)sizeof(member->ar_hdr.ar_name), p);
1962 if(c != '\0')
1963 p[sizeof(member->ar_hdr.ar_name)] = c;
1964 member->member_name_size = size_ar_name(&member->ar_hdr);
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),
1984 ARFMAG);
1986 else{
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;
2021 ar_name_size > 1 ;
2022 ar_name_size--){
2023 if(ofile->member_name[ar_name_size - 1] != '\0')
2024 break;
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));
2037 else{
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));
2056 else{
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) .
2064 ar_name_size = 0;
2065 member->output_long_name = FALSE;
2066 if(ofile->member_name != ofile->member_ar_hdr->ar_name){
2067 for(j = 0; j < sizeof(member->ar_hdr.ar_name) &&
2068 j < ofile->member_name_size &&
2069 ofile->member_name[j] != '\0'; j++)
2070 member->ar_hdr.ar_name[j] = ofile->member_name[j];
2071 for( ; j < sizeof(member->ar_hdr.ar_name); j++)
2072 member->ar_hdr.ar_name[j] = ' ';
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;
2099 #ifdef LTO_SUPPORT
2100 else if(ofile->file_type == OFILE_LLVM_BITCODE){
2101 member->object_addr = ofile->file_addr;
2102 member->object_size = ofile->file_size;
2103 member->lto = ofile->lto;
2104 member->object_byte_sex = get_byte_sex_from_flag(&arch->arch_flag);
2106 #endif /* LTO_SUPPORT */
2107 else{
2108 member->object_addr = ofile->member_addr;
2109 member->object_size = ofile->member_size;
2110 #ifdef LTO_SUPPORT
2111 if(ofile->lto != NULL){
2112 member->lto = ofile->lto;
2113 member->object_byte_sex = get_byte_sex_from_flag(
2114 &arch->arch_flag);
2116 #endif /* LTO_SUPPORT */
2121 * free_archs() frees the memory allocated that is pointed to by archs.
2123 static
2124 void
2125 free_archs(
2126 void)
2128 uint32_t i;
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);
2145 if(archs != NULL)
2146 free(archs);
2147 archs = NULL;
2148 narchs = 0;
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
2159 * contents was.
2161 static
2162 void
2163 create_library(
2164 char *output,
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;
2171 kern_return_t r;
2172 struct arch *arch;
2173 struct fat_header *fat_header;
2174 struct fat_arch *fat_arch;
2175 int fd;
2176 #ifndef __OPENSTEP__
2177 struct utimbuf timep;
2178 #else
2179 time_t timep[2];
2180 #endif
2181 struct stat stat_buf;
2182 struct ar_hdr toc_ar_hdr;
2183 enum bool some_tocs, same_toc, different_offsets;
2185 if(narchs == 0){
2186 if(cmd_flags.ranlib == TRUE){
2187 if(cmd_flags.q == FALSE)
2188 warning("empty library: %s (no table of contents added)",
2189 output);
2190 return;
2192 else{
2193 if(cmd_flags.dynamic == FALSE ||
2194 cmd_flags.no_files_ok == FALSE){
2195 if(cmd_flags.arch_only_flag.name != NULL)
2196 error("no library created (no object files in input "
2197 "files matching -arch_only %s)",
2198 cmd_flags.arch_only_flag.name);
2199 else
2200 error("no library created (no object files in input "
2201 "files)");
2202 return;
2207 if(cmd_flags.dynamic == TRUE){
2208 create_dynamic_shared_library(output);
2209 return;
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
2218 * architecture.
2220 if(narchs > 1){
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
2227 * thin .o files.
2229 if(cmd_flags.q == TRUE)
2230 exit(EXIT_SUCCESS);
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);
2240 else
2241 library_size = 0;
2242 some_tocs = FALSE;
2243 for(i = 0; i < narchs; i++){
2244 make_table_of_contents(archs + i, output);
2245 if(errors != 0)
2246 return;
2247 if(archs[i].toc_nranlibs != 0)
2248 some_tocs = TRUE;
2249 archs[i].size += SARMAG + archs[i].toc_size;
2250 library_size += archs[i].size;
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)
2258 exit(EXIT_SUCCESS);
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);
2268 return;
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
2288 * in place.
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;
2294 else{
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){
2338 same_toc = FALSE;
2339 for(i = 0; i < archs[0].toc_nranlibs; i++){
2340 for(j = 0; j < archs[0].nmembers; j++){
2341 if(archs[0].members[j].offset ==
2342 archs[0].toc_ranlibs[i].ran_off){
2343 archs[0].toc_ranlibs[i].ran_off =
2344 archs[0].members[j].input_member_offset;
2345 break;
2350 else{
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.
2356 same_toc = TRUE;
2357 for(i = 0; i < archs[0].toc_nranlibs; i++){
2358 if(archs[0].toc_ranlibs[i].ran_un.ran_strx !=
2359 ofile->toc_ranlibs[i].ran_un.ran_strx ||
2360 archs[0].toc_ranlibs[i].ran_off !=
2361 ofile->toc_ranlibs[i].ran_off){
2362 same_toc = FALSE;
2363 break;
2366 if(same_toc == TRUE){
2367 for(i = 0; i < archs[0].toc_strsize; i++){
2368 if(archs[0].toc_strings[i] != ofile->toc_strings[i]){
2369 same_toc = FALSE;
2370 break;
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 */
2386 p = library;
2387 memcpy(p, ARMAG, SARMAG);
2388 p += 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);
2397 return;
2399 if(write(fd, library, library_size) != (int)library_size){
2400 system_error("can't write output file: %s", output);
2401 return;
2403 if(close(fd) == -1){
2404 system_fatal("can't close output file: %s", output);
2405 return;
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
2413 * zero bytes.
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);
2429 return;
2431 #ifdef F_NOCACHE
2432 /* tell filesystem to NOT cache the file when reading or writing */
2433 (void)fcntl(fd, F_NOCACHE, 1);
2434 #endif
2437 * If there is more than one architecture then fill in the fat file
2438 * header and the fat_arch structures in the buffer.
2440 if(narchs > 1){
2441 fat_header = (struct fat_header *)library;
2442 fat_header->magic = FAT_MAGIC;
2443 fat_header->nfat_arch = narchs;
2444 offset = sizeof(struct fat_header) +
2445 sizeof(struct fat_arch) * narchs;
2446 fat_arch = (struct fat_arch *)(library + sizeof(struct fat_header));
2447 for(i = 0; i < narchs; i++){
2448 fat_arch[i].cputype = archs[i].arch_flag.cputype;
2449 fat_arch[i].cpusubtype = archs[i].arch_flag.cpusubtype;
2450 if(offset > UINT32_MAX)
2451 error("file too large to create as a fat file because "
2452 "offset field in struct fat_arch is only 32-bits and "
2453 "offset (%llu) to architecture %s exceeds that",
2454 offset, archs[i].arch_flag.name);
2455 fat_arch[i].offset = offset;
2456 if(archs[i].size > UINT32_MAX)
2457 error("file too large to create as a fat file because "
2458 "size field in struct fat_arch is only 32-bits and "
2459 "size (%llu) of architecture %s exceeds that",
2460 archs[i].size, archs[i].arch_flag.name);
2461 fat_arch[i].size = archs[i].size;
2462 fat_arch[i].align = 2;
2463 offset += archs[i].size;
2465 if(errors != 0){
2466 (void)unlink(output);
2467 return;
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;
2476 else
2477 offset = 0;
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;
2493 flush_start = p;
2494 arch = archs + i;
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);
2506 p += 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){
2513 if(narchs > 1)
2514 warning("warning for library: %s for architecture: %s the "
2515 "table of contents is empty (no object file members"
2516 " in the library define global symbols)", output,
2517 arch->arch_flag.name);
2518 else
2519 warning("warning for library: %s the table of contents is "
2520 "empty (no object file members in the library "
2521 "define global symbols)", output);
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.
2533 time_offsets[i] =
2534 (p - library) +
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,
2543 p - flush_start);
2546 * Put in the archive header and member contents for each member.
2548 for(j = 0; j < arch->nmembers; j++){
2549 flush_start = p;
2550 memcpy(p, (char *)&(arch->members[j].ar_hdr),
2551 sizeof(struct ar_hdr));
2552 p += sizeof(struct ar_hdr);
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++)
2597 *p++ = '\n';
2599 output_flush(library, library_size, fd, flush_start - library,
2600 p - flush_start);
2602 offset += arch->size;
2606 * Write the library to the file or flush the remaining buffer to the
2607 * file.
2609 if(cmd_flags.noflush == TRUE){
2610 if(write(fd, library, library_size) != (int)library_size){
2611 system_error("can't write output file: %s", output);
2612 return;
2615 else{
2616 final_output_flush(library, fd);
2618 if(close(fd) == -1){
2619 system_fatal("can't close output file: %s", output);
2620 return;
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);
2630 return;
2632 if((fd = open(output, O_WRONLY, 0)) == -1){
2633 system_error("can't open output file: %s", output);
2634 return;
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),
2645 SYMDEF,
2646 (int)sizeof(toc_ar_hdr.ar_date),
2647 (long int)stat_buf.st_mtime + 5);
2648 for(i = 0; i < narchs; i++){
2649 if(lseek(fd, time_offsets[i], L_SET) == -1){
2650 system_error("can't lseek in output file: %s", output);
2651 return;
2653 if(write(fd, &toc_ar_hdr.ar_date, sizeof(toc_ar_hdr.ar_date)) !=
2654 sizeof(toc_ar_hdr.ar_date)){
2655 system_error("can't write to output file: %s", output);
2656 return;
2659 if(close(fd) == -1){
2660 system_fatal("can't close output file: %s", output);
2661 return;
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)
2671 #else
2672 timep[0] = stat_buf.st_mtime;
2673 timep[1] = stat_buf.st_mtime;
2674 if(utime(output, timep) == -1)
2675 #endif
2677 system_fatal("can't set the modifiy times in output file: %s",
2678 output);
2679 return;
2681 if((r = vm_deallocate(mach_task_self(), (vm_address_t)library,
2682 library_size)) != KERN_SUCCESS){
2683 my_mach_error(r, "can't vm_deallocate() buffer for output file");
2684 return;
2689 * get_target_byte_sex() pick the byte sex to write the table of contents in
2690 * for the arch.
2692 static
2693 enum byte_sex
2694 get_target_byte_sex(
2695 struct arch *arch,
2696 enum byte_sex host_byte_sex)
2698 uint32_t i;
2699 enum byte_sex target_byte_sex;
2701 target_byte_sex = UNKNOWN_BYTE_SEX;
2702 for(i = 0;
2703 i < arch->nmembers && target_byte_sex == UNKNOWN_BYTE_SEX;
2704 i++){
2705 target_byte_sex = arch->members[i].object_byte_sex;
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
2721 * ranlibs
2722 * the strings for the ranlib structs
2724 static
2725 char *
2726 put_toc_member(
2727 char *p,
2728 struct arch *arch,
2729 enum byte_sex host_byte_sex,
2730 enum byte_sex target_byte_sex)
2732 uint32_t l;
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)
2746 l = SWAP_INT(l);
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,
2752 target_byte_sex);
2753 memcpy(p, (char *)arch->toc_ranlibs,
2754 arch->toc_nranlibs * sizeof(struct ranlib));
2755 p += arch->toc_nranlibs * sizeof(struct ranlib);
2757 l = arch->toc_strsize;
2758 if(target_byte_sex != host_byte_sex)
2759 l = SWAP_INT(l);
2760 memcpy(p, (char *)&l, sizeof(uint32_t));
2761 p += sizeof(uint32_t);
2763 memcpy(p, (char *)arch->toc_strings, arch->toc_strsize);
2764 p += arch->toc_strsize;
2766 return(p);
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.
2778 static
2779 void
2780 output_flush(
2781 char *library,
2782 uint64_t library_size,
2783 int fd,
2784 uint64_t offset,
2785 uint64_t size)
2787 uint64_t write_offset, write_size, host_pagesize;
2788 struct block **p, *block, *before, *after;
2789 kern_return_t r;
2791 host_pagesize = 0x2000;
2793 if(cmd_flags.noflush == TRUE)
2794 return;
2796 if(offset + size > library_size)
2797 fatal("internal error: output_flush(offset = %llu, size = %llu) "
2798 "out of range for library_size = %llu", offset, size,
2799 library_size);
2801 #ifdef DEBUG
2802 if(cmd_flags.debug & (1 << 2))
2803 print_block_list();
2804 if(cmd_flags.debug & (1 << 1))
2805 printf("output_flush(offset = %llu, size %llu)", offset, size);
2806 #endif /* DEBUG */
2808 if(size == 0){
2809 #ifdef DEBUG
2810 if(cmd_flags.debug & (1 << 1))
2811 printf("\n");
2812 #endif /* DEBUG */
2813 return;
2817 * Search through the ordered output blocks to find the block before the
2818 * new area and after the new area if any exist.
2820 before = NULL;
2821 after = NULL;
2822 p = &(output_blocks);
2823 while(*p){
2824 block = *p;
2825 if(offset < block->offset){
2826 after = block;
2827 break;
2829 else{
2830 before = block;
2832 p = &(block->next);
2836 * Check for overlap of the new area with the block before and after the
2837 * new area if there are such blocks.
2839 if(before != NULL){
2840 if(before->offset + before->size > offset){
2841 warning("internal error: output_flush(offset = %llu, size = "
2842 "%llu) overlaps with flushed block(offset = %llu, "
2843 "size = %llu)", offset, size, before->offset,
2844 before->size);
2845 printf("calling abort()\n");
2846 abort();
2849 if(after != NULL){
2850 if(offset + size > after->offset){
2851 warning("internal error: output_flush(offset = %llu, size = "
2852 "%llu) overlaps with flushed block(offset = %llu, "
2853 "size = %llu)", offset, size, after->offset,
2854 after->size);
2855 printf("calling abort()\n");
2856 abort();
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){
2888 write_offset = 0;
2889 before->written_offset = 0;
2891 else
2892 write_offset =before->written_offset + before->written_size;
2893 if(after->written_size == 0)
2894 write_size = trnc(after->offset + after->size -
2895 write_offset, host_pagesize);
2896 else
2897 write_size = trnc(after->written_offset - write_offset,
2898 host_pagesize);
2899 if(write_size != 0){
2900 before->written_size += write_size;
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);
2910 else{
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);
2919 if(write_size != 0)
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
2933 * new area.
2935 write_offset = rnd(offset, host_pagesize);
2936 if(after->written_size == 0)
2937 write_size = trnc(after->offset + after->size - write_offset,
2938 host_pagesize);
2939 else
2940 write_size = trnc(after->written_offset - write_offset,
2941 host_pagesize);
2942 if(write_size != 0){
2943 after->written_offset = write_offset;
2944 after->written_size += write_size;
2946 else if(write_offset != after->written_offset){
2947 after->written_offset = write_offset;
2949 after->offset = offset;
2950 after->size += size;
2952 else{
2954 * This is the case where the new area neither starts at the end of
2955 * the block just before it (if any) or ends where the block after
2956 * it (if any) starts. A new block is created and the new area is
2957 * is placed in it.
2959 write_offset = rnd(offset, host_pagesize);
2960 write_size = trnc(offset + size - write_offset, host_pagesize);
2961 block = get_block();
2962 block->offset = offset;
2963 block->size = size;
2964 block->written_offset = write_offset;
2965 block->written_size = write_size;
2967 * Insert this block in the ordered list in the correct place.
2969 if(before != NULL){
2970 block->next = before->next;
2971 before->next = block;
2973 else{
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){
2983 #ifdef DEBUG
2984 if((cmd_flags.debug & (1 << 1)) || (cmd_flags.debug & (1 << 0)))
2985 printf(" writing (write_offset = %llu write_size = %llu)\n",
2986 write_offset, write_size);
2987 #endif /* DEBUG */
2988 lseek(fd, write_offset, L_SET);
2989 if(write(fd, library + write_offset, write_size) !=
2990 (int)write_size)
2991 system_fatal("can't write to output file");
2992 if((r = vm_deallocate(mach_task_self(), (vm_address_t)(library +
2993 write_offset), write_size)) != KERN_SUCCESS)
2994 mach_fatal(r, "can't vm_deallocate() buffer for output file");
2996 #ifdef DEBUG
2997 else{
2998 if(cmd_flags.debug & (1 << 1))
2999 printf(" no write\n");
3001 #endif /* DEBUG */
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.
3008 static
3009 void
3010 final_output_flush(
3011 char *library,
3012 int fd)
3014 struct block *block;
3015 uint64_t write_offset, write_size;
3016 kern_return_t r;
3018 #ifdef DEBUG
3019 /* The compiler "warning: `write_offset' may be used uninitialized in */
3020 /* this function" can safely be ignored */
3021 write_offset = 0;
3022 if((cmd_flags.debug & (1 << 1)) || (cmd_flags.debug & (1 << 0))){
3023 printf("final_output_flush block_list:\n");
3024 print_block_list();
3026 #endif /* DEBUG */
3028 write_size = 0;
3029 block = output_blocks;
3030 if(block != NULL){
3031 if(block->offset != 0)
3032 fatal("internal error: first block not at offset 0");
3033 if(block->written_size != 0){
3034 if(block->written_offset != 0)
3035 fatal("internal error: first block written_offset not 0");
3036 write_offset = block->written_size;
3037 write_size = block->size - block->written_size;
3039 else{
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){
3047 #ifdef DEBUG
3048 if((cmd_flags.debug & (1 << 1)) || (cmd_flags.debug & (1 << 1)))
3049 printf(" writing (write_offset = %llu write_size = %llu)\n",
3050 write_offset, write_size);
3051 #endif /* DEBUG */
3052 lseek(fd, write_offset, L_SET);
3053 if(write(fd, library + write_offset, write_size) !=
3054 (int)write_size)
3055 system_fatal("can't write to output file");
3056 if((r = vm_deallocate(mach_task_self(), (vm_address_t)(library +
3057 write_offset), write_size)) != KERN_SUCCESS)
3058 mach_fatal(r, "can't vm_deallocate() buffer for output file");
3060 output_blocks = NULL;
3063 #ifdef DEBUG
3065 * print_block_list() prints the list of blocks. Used for debugging.
3067 static
3068 void
3069 print_block_list(void)
3071 struct block **p, *block;
3073 p = &(output_blocks);
3074 if(*p == NULL)
3075 printf("Empty block list\n");
3076 while(*p){
3077 block = *p;
3078 printf("block 0x%x\n", (unsigned int)block);
3079 printf(" offset %llu\n", block->offset);
3080 printf(" size %llu\n", block->size);
3081 printf(" written_offset %llu\n", block->written_offset);
3082 printf(" written_size %llu\n", block->written_size);
3083 printf(" next 0x%x\n", (unsigned int)(block->next));
3084 p = &(block->next);
3087 #endif /* DEBUG */
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.
3095 static
3096 struct block *
3097 get_block(void)
3099 struct block *block;
3101 block = allocate(sizeof(struct block));
3102 return(block);
3106 * remove_block() throws away the block specified. See comments in get_block().
3108 static
3109 void
3110 remove_block(
3111 struct block *block)
3113 free(block);
3117 * trnc() truncates the value 'v' to the power of two value 'r'. If v is
3118 * less than zero it returns zero.
3120 static
3121 uint32_t
3122 trnc(
3123 uint32_t v,
3124 uint32_t r)
3126 if(((int32_t)v) < 0)
3127 return(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.
3136 static
3137 void
3138 create_dynamic_shared_library(
3139 char *output)
3141 uint32_t i, j;
3142 char *p, *filelist;
3143 struct stat stat_buf;
3144 enum bool use_force_cpusubtype_ALL;
3145 const struct arch_flag *family_arch_flag;
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.
3151 if(narchs > 1)
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
3172 * library.
3174 for(i = 0; i < narchs || (i == 0 && narchs == 0); i++){
3175 reset_execute_list();
3176 add_execute_list_with_prefix("ld");
3177 if(narchs != 0 && cmd_flags.arch_only_flag.name == NULL)
3178 add_execute_list("-arch_multiple");
3179 if(archs != NULL){
3180 add_execute_list("-arch");
3181 if(use_force_cpusubtype_ALL == TRUE)
3182 add_execute_list(archs[i].arch_flag.name);
3183 else
3184 add_execute_list(cmd_flags.arch_only_flag.name);
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);
3226 else{
3227 if(narchs > 1){
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");
3237 filelist = NULL;
3238 for(j = 0; j < cmd_flags.nfiles; j++){
3239 if(cmd_flags.filelist[j] == NULL){
3240 add_execute_list(cmd_flags.files[j]);
3242 else{
3243 if(cmd_flags.filelist[j] != filelist){
3244 add_execute_list("-filelist");
3245 add_execute_list(cmd_flags.filelist[j]);
3246 filelist = cmd_flags.filelist[j];
3250 if(narchs <= 1){
3251 add_execute_list("-o");
3252 add_execute_list(cmd_flags.output);
3254 else{
3255 add_execute_list("-o");
3256 add_execute_list(makestr(cmd_flags.output, ".libtool.",
3257 archs[i].arch_flag.name, NULL));
3258 if(cmd_flags.final_output_specified == FALSE){
3259 add_execute_list("-final_output");
3260 add_execute_list(cmd_flags.output);
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
3268 * in a fat file.
3270 if(narchs > 1){
3271 reset_execute_list();
3272 add_execute_list_with_prefix("lipo");
3273 add_execute_list("-create");
3274 add_execute_list("-output");
3275 add_execute_list(cmd_flags.output);
3276 for(i = 0; i < narchs; i++){
3277 add_execute_list(makestr(cmd_flags.output, ".libtool.",
3278 archs[i].arch_flag.name, NULL));
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
3292 * output.
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.
3312 static
3313 void
3314 create_dynamic_shared_library_cleanup(
3315 int sig)
3317 uint32_t i;
3319 for(i = 0; i < narchs; i++){
3320 (void)unlink(makestr(cmd_flags.output, ".libtool.",
3321 archs[i].arch_flag.name, NULL));
3323 exit(EXIT_FAILURE);
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.
3331 static
3332 void
3333 make_table_of_contents(
3334 struct arch *arch,
3335 char *output)
3337 uint32_t i, j, k, r, s, nsects, ncmds, n_strx;
3338 struct member *member;
3339 struct load_command *lc;
3340 struct segment_command *sg;
3341 struct segment_command_64 *sg64;
3342 struct nlist *symbols;
3343 struct nlist_64 *symbols64;
3344 char *strings;
3345 enum bool sorted, is_toc_symbol;
3346 char *ar_name;
3347 struct section *section;
3348 struct section_64 *section64;
3349 uint8_t n_type, n_sect;
3350 #ifdef LTO_SUPPORT
3351 uint32_t nsyms;
3352 #endif /* LTO_SUPPORT */
3354 symbols = NULL;
3355 symbols64 = NULL;
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){
3363 nsects = 0;
3364 lc = member->load_commands;
3365 if(member->mh != NULL)
3366 ncmds = member->mh->ncmds;
3367 else
3368 ncmds = member->mh64->ncmds;
3369 for(j = 0; j < ncmds; j++){
3370 if(lc->cmd == LC_SYMTAB){
3371 if(member->st == NULL)
3372 member->st = (struct symtab_command *)lc;
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 *));
3387 else
3388 member->sections64 = allocate(nsects *
3389 sizeof(struct section_64 *));
3390 nsects = 0;
3391 lc = member->load_commands;
3392 for(j = 0; j < ncmds; j++){
3393 if(lc->cmd == LC_SEGMENT){
3394 sg = (struct segment_command *)lc;
3395 section = (struct section *)
3396 ((char *)sg + sizeof(struct segment_command));
3397 for(k = 0; k < sg->nsects; k++){
3398 member->sections[nsects++] = section++;
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());
3419 else{
3420 symbols64 = (struct nlist_64 *)(member->object_addr +
3421 member->st->symoff);
3422 if(member->object_byte_sex != get_host_byte_sex())
3423 swap_nlist_64(symbols64, member->st->nsyms,
3424 get_host_byte_sex());
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;
3433 else{
3434 n_strx = symbols64[j].n_un.n_strx;
3435 n_type = symbols64[j].n_type;
3436 n_sect = symbols64[j].n_sect;
3438 if(n_strx > member->st->strsize){
3439 warn_member(arch, member, "malformed object "
3440 "(symbol %u n_strx field extends past the "
3441 "end of the string table)", j);
3442 errors++;
3443 continue;
3445 if((n_type & N_TYPE) == N_SECT){
3446 if(n_sect == NO_SECT){
3447 warn_member(arch, member, "malformed object "
3448 "(symbol %u must not have NO_SECT for its "
3449 "n_sect field given its type (N_SECT))", j);
3450 errors++;
3451 continue;
3453 if(n_sect > nsects){
3454 warn_member(arch, member, "malformed object "
3455 "(symbol %u n_sect field greater than the "
3456 "number of sections in the file)", j);
3457 errors++;
3458 continue;
3461 if(member->mh != NULL)
3462 is_toc_symbol = toc_symbol(symbols + j,
3463 member->sections);
3464 else
3465 is_toc_symbol = toc_symbol_64(symbols64 + j,
3466 member->sections64);
3467 if(is_toc_symbol == TRUE){
3468 arch->toc_nranlibs++;
3469 arch->toc_strsize += strlen(strings + n_strx) + 1;
3473 else
3474 warn_member(arch, member, "has no symbols");
3476 #ifdef LTO_SUPPORT
3477 else if(member->lto != NULL){
3478 nsyms = lto_get_nsyms(member->lto);
3479 for(j = 0; j < nsyms; j++){
3480 if(lto_toc_symbol(member->lto, j, cmd_flags.c) == TRUE){
3481 arch->toc_nranlibs++;
3482 arch->toc_strsize +=
3483 strlen(lto_symbol_name(member->lto, j)) + 1;
3487 #endif /* LTO_SUPPORT */
3488 else{
3489 if(cmd_flags.ranlib == FALSE){
3490 warn_member(arch, member, "is not an object file");
3491 errors++;
3495 if(errors != 0)
3496 return;
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
3514 * real offset.
3516 r = 0;
3517 s = 0;
3518 for(i = 0; i < arch->nmembers; i++){
3519 member = arch->members + i;
3520 if(member->mh != NULL || member->mh64 != NULL){
3521 if(member->st != NULL && member->st->nsyms != 0){
3522 if(member->mh != NULL)
3523 symbols = (struct nlist *)(member->object_addr +
3524 member->st->symoff);
3525 else
3526 symbols64 = (struct nlist_64 *)(member->object_addr +
3527 member->st->symoff);
3528 strings = member->object_addr + member->st->stroff;
3529 for(j = 0; j < member->st->nsyms; j++){
3530 if(member->mh != NULL)
3531 n_strx = symbols[j].n_un.n_strx;
3532 else
3533 n_strx = symbols64[j].n_un.n_strx;
3534 if(n_strx > member->st->strsize)
3535 continue;
3536 if(member->mh != NULL)
3537 is_toc_symbol = toc_symbol(symbols + j,
3538 member->sections);
3539 else
3540 is_toc_symbol = toc_symbol_64(symbols64 + j,
3541 member->sections64);
3542 if(is_toc_symbol == TRUE){
3543 strcpy(arch->toc_strings + s,
3544 strings + n_strx);
3545 arch->tocs[r].name = arch->toc_strings + s;
3546 arch->tocs[r].index1 = i + 1;
3547 r++;
3548 s += strlen(strings + n_strx) + 1;
3551 if(member->object_byte_sex != get_host_byte_sex()){
3552 if(member->mh != NULL)
3553 swap_nlist(symbols, member->st->nsyms,
3554 member->object_byte_sex);
3555 else
3556 swap_nlist_64(symbols64, member->st->nsyms,
3557 member->object_byte_sex);
3561 #ifdef LTO_SUPPORT
3562 else if(member->lto != NULL){
3563 nsyms = lto_get_nsyms(member->lto);
3564 for(j = 0; j < nsyms; j++){
3565 if(lto_toc_symbol(member->lto, j, cmd_flags.c) == TRUE){
3566 strcpy(arch->toc_strings + s,
3567 lto_symbol_name(member->lto, j));
3568 arch->tocs[r].name = arch->toc_strings + s;
3569 arch->tocs[r].index1 = i + 1;
3570 r++;
3571 s += strlen(lto_symbol_name(member->lto, j)) + 1;
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
3595 * and
3596 * (rnd(sizeof(struct ar_hdr), 8) - sizeof(struct ar_hdr)
3597 * is 4 bytes.
3599 ar_name = AR_EFMT1 "20";
3600 arch->toc_name_size = 16;
3601 arch->toc_name = SYMDEF "\0\0\0\0\0\0\0";
3603 else{
3604 arch->toc_long_name = FALSE;
3605 ar_name = arch->toc_name;
3608 else{
3610 * Since the SYMDEF_SORTED is "__.SYMDEF SORTED" which contains
3611 * a space, it should use extended format #1 if we can use long
3612 * names.
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)
3621 * is 4 bytes.
3623 ar_name = AR_EFMT1 "20";
3625 else{
3626 arch->toc_long_name = FALSE;
3627 ar_name = arch->toc_name;
3631 else{
3632 sorted = FALSE;
3633 arch->toc_name = SYMDEF;
3634 arch->toc_name_size = sizeof(SYMDEF) - 1;
3635 if(cmd_flags.use_long_names == TRUE){
3636 arch->toc_long_name = TRUE;
3638 * This assumes that "__.SYMDEF\0\0\0\0\0\0\0" is 16 bytes and
3639 * (rnd(sizeof(struct ar_hdr), 8) - sizeof(struct ar_hdr)
3640 * is 4 bytes.
3642 ar_name = AR_EFMT1 "20";
3643 arch->toc_name_size = 16;
3644 arch->toc_name = SYMDEF "\0\0\0\0\0\0\0";
3646 else{
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
3661 * the strings
3663 arch->toc_size = sizeof(struct ar_hdr) +
3664 sizeof(uint32_t) +
3665 arch->toc_nranlibs * sizeof(struct ranlib) +
3666 sizeof(uint32_t) +
3667 arch->toc_strsize;
3668 /* add the size of the name is a long name is used */
3669 if(arch->toc_long_name == TRUE)
3670 arch->toc_size += arch->toc_name_size +
3671 (rnd(sizeof(struct ar_hdr), 8) -
3672 sizeof(struct ar_hdr));
3673 for(i = 0; i < arch->nmembers; i++)
3674 arch->members[i].offset += SARMAG + arch->toc_size;
3675 for(i = 0; i < arch->toc_nranlibs; i++){
3676 arch->toc_ranlibs[i].ran_un.ran_strx =
3677 arch->tocs[i].name - arch->toc_strings;
3678 arch->toc_ranlibs[i].ran_off =
3679 arch->members[arch->tocs[i].index1 - 1].offset;
3682 sprintf((char *)(&arch->toc_ar_hdr), "%-*s%-*ld%-*u%-*u%-*o%-*ld",
3683 (int)sizeof(arch->toc_ar_hdr.ar_name),
3684 ar_name,
3685 (int)sizeof(arch->toc_ar_hdr.ar_date),
3686 toc_time,
3687 (int)sizeof(arch->toc_ar_hdr.ar_uid),
3688 (unsigned short)getuid(),
3689 (int)sizeof(arch->toc_ar_hdr.ar_gid),
3690 (unsigned short)getgid(),
3691 (int)sizeof(arch->toc_ar_hdr.ar_mode),
3692 (unsigned int)toc_mode,
3693 (int)sizeof(arch->toc_ar_hdr.ar_size),
3694 (long)(arch->toc_size - sizeof(struct ar_hdr)));
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.
3706 static
3708 toc_name_qsort(
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.
3718 static
3720 toc_index1_qsort(
3721 const struct toc *toc1,
3722 const struct toc *toc2)
3724 if(toc1->index1 < toc2->index1)
3725 return(-1);
3726 if(toc1->index1 > toc2->index1)
3727 return(1);
3728 /* toc1->index1 == toc2->index1 */
3729 return(0);
3733 * toc_symbol() returns TRUE if the symbol is to be included in the table of
3734 * contents otherwise it returns FALSE.
3736 static
3737 enum bool
3738 toc_symbol(
3739 struct nlist *symbol,
3740 struct section **sections)
3742 return(toc(symbol->n_un.n_strx,
3743 symbol->n_type,
3744 symbol->n_value,
3745 (symbol->n_type & N_TYPE) == N_SECT &&
3746 sections[symbol->n_sect - 1]->flags & S_ATTR_NO_TOC));
3749 static
3750 enum bool
3751 toc_symbol_64(
3752 struct nlist_64 *symbol64,
3753 struct section_64 **sections64)
3755 return(toc(symbol64->n_un.n_strx,
3756 symbol64->n_type,
3757 symbol64->n_value,
3758 (symbol64->n_type & N_TYPE) == N_SECT &&
3759 sections64[symbol64->n_sect-1]->flags & S_ATTR_NO_TOC));
3762 static
3763 enum bool
3764 toc(
3765 uint32_t n_strx,
3766 uint8_t n_type,
3767 uint64_t n_value,
3768 enum bool attr_no_toc)
3770 /* if the name is NULL then it won't be in the table of contents */
3771 if(n_strx == 0)
3772 return(FALSE);
3773 /* if symbol is not external then it won't be in the toc */
3774 if((n_type & N_EXT) == 0)
3775 return(FALSE);
3776 /* if symbol is undefined then it won't be in the toc */
3777 if((n_type & N_TYPE) == N_UNDF && n_value == 0)
3778 return(FALSE);
3779 /* if symbol is common and the -c flag is not specified then ... */
3780 if((n_type & N_TYPE) == N_UNDF && n_value != 0 &&
3781 cmd_flags.c == FALSE)
3782 return(FALSE);
3783 /* if the symbols is in a section marked NO_TOC then ... */
3784 if(attr_no_toc != 0)
3785 return(FALSE);
3787 return(TRUE);
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.
3797 static
3798 enum bool
3799 check_sort_tocs(
3800 struct arch *arch,
3801 char *output,
3802 enum bool library_warnings)
3804 uint32_t i;
3805 enum bool multiple_defs;
3806 struct member *member;
3808 if(arch->toc_nranlibs == 0)
3809 return(TRUE);
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)
3820 return(FALSE);
3821 fprintf(stderr, "%s: same symbol defined in more than one "
3822 "member ", progname);
3823 if(narchs > 1)
3824 fprintf(stderr, "for architecture: %s ",
3825 arch->arch_flag.name);
3826 fprintf(stderr, "in: %s (table of contents will not be "
3827 "sorted)\n", output);
3828 multiple_defs = TRUE;
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)
3848 return(TRUE);
3849 else{
3850 for(i = 0; i < arch->toc_nranlibs; i++)
3851 if(((int)arch->tocs[i].index1) < 0)
3852 arch->tocs[i].index1 =
3853 -(arch->tocs[i].index1);
3854 return(FALSE);
3859 * warn_duplicate_member_names() generates a warning if two members end up with
3860 * the same ar_name. This is only a warning because ld(1) and this program
3861 * has no problems with it. Only if ar(1) were used to extract the files
3862 * would this be a problem (even the 4.4bsd ar(1) using long names can
3863 * get hosed by base names, the 4.3bsd ar(1) can't handle full 16 character
3864 * ar_names).
3866 static
3867 void
3868 warn_duplicate_member_names(
3869 void)
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,
3885 len) == 0){
3886 fprintf(stderr, "%s: warning ", progname);
3887 if(narchs > 1)
3888 fprintf(stderr, "for architecture: %s ",
3889 archs[i].arch_flag.name);
3890 fprintf(stderr, "same member name (%.*s) in output file "
3891 "used for input files: ", (int)len1,
3892 archs[i].members[j].member_name);
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);
3900 else
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);
3911 else
3912 fprintf(stderr, "%s (due to use of basename, truncation"
3913 ", blank padding or duplicate input files)\n",
3914 archs[i].members[j+1].input_file_name);
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.
3927 static
3929 member_name_qsort(
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.
3944 static
3946 member_offset_qsort(
3947 const struct member *member1,
3948 const struct member *member2)
3950 if(member1->offset < member2->offset)
3951 return(-1);
3952 if(member1->offset > member2->offset)
3953 return(1);
3954 /* member1->offset == member2->offset */
3955 return(0);
3959 * warn_member() is like the error routines it prints the program name the
3960 * member name specified and message specified.
3962 static
3963 void
3964 warn_member(
3965 struct arch *arch,
3966 struct member *member,
3967 const char *format, ...)
3969 va_list ap;
3971 fprintf(stderr, "%s: ", progname);
3972 if(narchs > 1)
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);
3979 else
3980 fprintf(stderr, "file: %s ", member->input_file_name);
3982 va_start(ap, format);
3983 vfprintf(stderr, format, ap);
3984 fprintf(stderr, "\n");
3985 va_end(ap);
3989 * Prints the message to cmd_flags.trace_file_path, or stderr if that
3990 * isn't set.
3992 static
3993 void
3994 ld_trace(
3995 const char *format, ...)
3997 static int trace_file = -1;
3998 char trace_buffer[MAXPATHLEN * 2];
3999 char *buffer_ptr;
4000 int length;
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);
4009 else{
4010 trace_file = fileno(stderr);
4013 va_list ap;
4015 va_start(ap, format);
4016 length = vsnprintf(trace_buffer, sizeof(trace_buffer), format, ap);
4017 va_end(ap);
4018 buffer_ptr = trace_buffer;
4019 while(length > 0){
4020 amount_written = write(trace_file, buffer_ptr, length);
4021 if(amount_written == -1)
4022 /* Failure to write shouldn't fail the build. */
4023 return;
4024 buffer_ptr += amount_written;
4025 length -= amount_written;