Lower __builtin_flt_rounds into LLVM intrinsic
[llvm-gcc-4.2.git] / driverdriver.c
blob9fbbefcd2420770d8b24df4cdc2e6deb975620fc
1 /* APPLE LOCAL file driver driver */
2 /* Darwin driver program that handles -arch commands and invokes
3 appropriate compiler driver.
4 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <errno.h>
29 #include <mach-o/arch.h>
30 #include <limits.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <sys/wait.h>
34 #include <regex.h>
35 #include "libiberty.h"
36 #include "filenames.h"
37 #include "stdbool.h"
38 /* Hack!.
39 Pay the price for including darwin.h. */
40 typedef int tree;
41 typedef int rtx;
42 #define GTY(x) /* nothing */
43 #define USED_FOR_TARGET 1
44 /* Include darwin.h for SWITCH_TAKES_ARG and
45 WORD_SWIATCH_TAKES_ARG. */
47 #include "darwin.h"
49 /* Include gcc.h for DEFAULT_SWITCH_TAKES_ARG and
50 DEFAULT_WORD_SWIATCH_TAKES_ARG. */
52 #include "gcc.h"
54 /* This program name. */
55 const char *progname;
57 /* driver prefix. */
58 const char *driver_exec_prefix;
60 /* driver prefix length. */
61 int prefix_len;
63 /* current working directory. */
64 char *curr_dir;
66 /* Use if -o flag is absent. */
67 const char *final_output = "a.out";
69 /* Variabless to track presence and/or absence of important command
70 line options. */
71 int compile_only_request = 0;
72 int asm_output_request = 0;
73 int dash_capital_m_seen = 0;
74 int preprocessed_output_request = 0;
75 int ima_is_used = 0;
76 int dash_dynamiclib_seen = 0;
77 int verbose_flag = 0;
78 int save_temps_seen = 0;
80 /* Support at the max 10 arch. at a time. This is historical limit. */
81 #define MAX_ARCHES 10
83 /* Name of user supplied architectures. */
84 const char *arches[MAX_ARCHES];
86 /* -arch counter. */
87 static int num_arches;
89 /* Input filenames. */
90 struct input_filename
92 const char *name;
93 int index;
94 struct input_filename *next;
96 struct input_filename *in_files;
97 struct input_filename *last_infile;
99 static int num_infiles;
101 /* User specified output file name. */
102 const char *output_filename = NULL;
104 /* Output file names used for arch specific driver invocation. These
105 are input file names for 'lipo'. */
106 const char **out_files;
107 static int num_outfiles;
109 /* Architecture names used by config.guess does not match the names
110 used by NXGet... Use this hand coded mapping to connect them. */
111 struct arch_config_guess_map
113 const char *arch_name;
114 const char *config_string;
117 struct arch_config_guess_map arch_config_map [] =
119 {"i386", "i686"},
120 {"ppc", "powerpc"},
121 {"ppc64", "powerpc"},
122 {"x86_64", "i686"},
123 {NULL, NULL}
126 /* List of interpreted command line flags. Supply this to gcc driver. */
127 const char **new_argv;
128 int new_argc;
130 /* Argument list for 'lipo'. */
131 const char **lipo_argv;
133 /* Info about the sub process. Need one subprocess for each arch plus
134 additional one for 'lipo'. */
135 struct command
137 const char *prog;
138 const char **argv;
139 int pid;
140 } commands[MAX_ARCHES+1];
142 /* total number of argc. */
143 static int total_argc;
145 static int greatest_status = 0;
146 static int signal_count = 0;
148 #ifndef SWITCH_TAKES_ARG
149 #define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
150 #endif
152 #ifndef WORD_SWITCH_TAKES_ARG
153 #define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
154 #endif
157 /* Local function prototypes. */
158 static const char * get_arch_name (const char *);
159 static char * get_driver_name (const char *);
160 static void delete_out_files (void);
161 static char * strip_path_and_suffix (const char *, const char *);
162 static void initialize (void);
163 static void final_cleanup (void);
164 static int do_wait (int, const char *);
165 static void do_lipo (int, const char *);
166 static void do_compile (const char **, int);
167 static void do_compile_separately (void);
168 static void do_lipo_separately (void);
169 static int add_arch_options (int, const char **, int);
170 static int remove_arch_options (const char**, int);
171 static void add_arch (const char *);
172 static const char *resolve_symlink (const char *, char *, int, int);
173 static const char *resolve_path_to_executable (const char *filename);
174 static int get_prog_name_len (const char *prog);
176 /* Find arch name for the given input string. If input name is NULL then local
177 arch name is used. */
179 static const char *
180 get_arch_name (const char *name)
182 const NXArchInfo * a_info;
183 const NXArchInfo * all_info;
184 cpu_type_t cputype;
185 struct arch_config_guess_map *map;
186 const char *aname;
188 if (name)
190 /* Find config name based on arch name. */
191 aname = NULL;
192 map = arch_config_map;
193 while (map->arch_name)
195 if (!strcmp (map->arch_name, name))
196 return name;
197 else map++;
199 a_info = NXGetArchInfoFromName (name);
201 else
202 a_info = NXGetLocalArchInfo ();
204 if (!a_info)
205 fatal ("Invalid arch name : %s", name);
207 all_info = NXGetAllArchInfos();
209 if (!all_info)
210 fatal ("Unable to get architecture information");
212 /* Find first arch. that matches cputype. */
213 cputype = a_info->cputype;
215 while (all_info->name)
217 if (all_info->cputype == cputype)
218 break;
219 else
220 all_info++;
223 return all_info->name;
226 /* Find driver name based on input arch name. */
228 static char *
229 get_driver_name (const char *arch_name)
231 char *driver_name;
232 const char *config_name;
233 int len;
234 int index;
235 struct arch_config_guess_map *map;
237 /* find config name based on arch name. */
238 config_name = NULL;
239 map = arch_config_map;
240 while (map->arch_name)
242 if (!strcmp (map->arch_name, arch_name))
244 config_name = map->config_string;
245 break;
247 else map++;
250 if (!config_name)
251 fatal ("Unable to guess config name for arch %s", arch_name);
253 len = strlen (config_name) + strlen (PDN) + prefix_len + 1;
254 driver_name = (char *) malloc (sizeof (char) * len);
255 driver_name[0] = '\0';
257 if (driver_exec_prefix)
258 strcpy (driver_name, driver_exec_prefix);
259 strcat (driver_name, config_name);
260 strcat (driver_name, PDN);
262 return driver_name;
265 /* Delete out_files. */
267 static void
268 delete_out_files (void)
270 const char *temp;
271 struct stat st;
272 int i = 0;
274 for (i = 0, temp = out_files[i];
275 temp && i < total_argc * MAX_ARCHES;
276 temp = out_files[++i])
277 if (stat (temp, &st) >= 0 && S_ISREG (st.st_mode))
278 unlink (temp);
282 /* Put fatal error message on stderr and exit. */
284 void
285 fatal (const char *msgid, ...)
287 va_list ap;
289 va_start (ap, msgid);
291 fprintf (stderr, "%s: ", progname);
292 vfprintf (stderr, msgid, ap);
293 va_end (ap);
294 fprintf (stderr, "\n");
295 delete_out_files ();
296 exit (1);
299 /* Print error message and exit. */
301 static void
302 pfatal_pexecute (const char *errmsg_fmt, const char *errmsg_arg)
304 if (errmsg_arg)
306 int save_errno = errno;
308 /* Space for trailing '\0' is in %s. */
309 char *msg = (char *) malloc (strlen (errmsg_fmt) + strlen (errmsg_arg));
310 sprintf (msg, errmsg_fmt, errmsg_arg);
311 errmsg_fmt = msg;
313 errno = save_errno;
316 fprintf (stderr,"%s: %s: %s\n", progname, errmsg_fmt, xstrerror (errno));
317 delete_out_files ();
318 exit (1);
321 #ifdef DEBUG
322 static void
323 debug_command_line (const char **debug_argv, int debug_argc)
325 int i;
327 fprintf (stderr,"%s: debug_command_line\n", progname);
328 fprintf (stderr,"%s: arg count = %d\n", progname, debug_argc);
330 for (i = 0; debug_argv[i]; i++)
331 fprintf (stderr,"%s: arg [%d] %s\n", progname, i, debug_argv[i]);
333 #endif
335 /* Strip directory name from the input file name and replace file name
336 suffix with new. */
338 static char *
339 strip_path_and_suffix (const char *full_name, const char *new_suffix)
341 char *name;
342 char *p;
344 if (!full_name || !new_suffix)
345 return NULL;
347 /* Strip path name. */
348 p = (char *)full_name + strlen (full_name);
349 while (p != full_name && !IS_DIR_SEPARATOR (p[-1]))
350 --p;
352 /* Now 'p' is a file name with suffix. */
353 name = (char *) malloc (strlen (p) + 1 + strlen (new_suffix));
355 strcpy (name, p);
357 p = name + strlen (name);
358 while (p != name && *p != '.')
359 --p;
361 /* If did not reach at the beginning of name then '.' is found.
362 Replace '.' with NULL. */
363 if (p != name)
364 *p = '\0';
366 strcat (name, new_suffix);
367 return name;
370 /* Initialization */
372 static void
373 initialize (void)
376 int i;
378 /* Let's count, how many additional arguments driver driver will supply
379 to compiler driver:
381 Each "-arch" "<blah>" is replaced by approriate "-mcpu=<blah>".
382 That leaves one additional arg space available.
384 Note that only one -m* is supplied to each compiler driver. Which
385 means, extra "-arch" "<blah>" are removed from the original command
386 line. But lets not count how many additional slots are available.
388 Driver driver may need to specify temp. output file name, say
389 "-o" "foobar". That needs two extra argments.
391 Sometimes linker wants one additional "-Wl,-arch_multiple".
393 Sometimes linker wants to see "-final_output" "outputname".
395 In the end, we may need five extra arguments, plus one extra
396 space for the NULL terminator. */
398 new_argv = (const char **) malloc ((total_argc + 6) * sizeof (const char *));
399 if (!new_argv)
400 abort ();
402 /* First slot, new_argv[0] is reserved for the driver name. */
403 new_argc = 1;
405 /* For each -arch, three arguments are needed.
406 For example, "-arch" "ppc" "file". Additional slots are for
407 "lipo" "-create" "-o" "outputfilename" and the NULL. */
408 lipo_argv = (const char **) malloc ((total_argc * 3 + 5) * sizeof (const char *));
409 if (!lipo_argv)
410 abort ();
412 /* Need separate out_files for each arch, max is MAX_ARCHES.
413 Need separate out_files for each input file. */
415 out_files = (const char **) malloc ((total_argc * MAX_ARCHES) * sizeof (const char *));
416 if (!out_files)
417 abort ();
419 num_arches = 0;
420 num_infiles = 0;
422 in_files = NULL;
423 last_infile = NULL;
425 for (i = 0; i < (MAX_ARCHES + 1); i++)
427 commands[i].prog = NULL;
428 commands[i].argv = NULL;
429 commands[i].pid = 0;
433 /* Cleanup. */
435 static void
436 final_cleanup (void)
438 int i;
439 struct input_filename *next;
440 delete_out_files ();
441 free (new_argv);
442 free (lipo_argv);
443 free (out_files);
445 for (i = 0, next = in_files;
446 i < num_infiles && next;
447 i++)
449 next = in_files->next;
450 free (in_files);
451 in_files = next;
455 /* Wait for the process pid and return appropriate code. */
457 static int
458 do_wait (int pid, const char *prog)
460 int status = 0;
461 int ret = 0;
463 pid = pwait (pid, &status, 0);
465 if (WIFSIGNALED (status))
467 if (!signal_count &&
468 WEXITSTATUS (status) > greatest_status)
469 greatest_status = WEXITSTATUS (status);
470 ret = -1;
472 else if (WIFEXITED (status)
473 && WEXITSTATUS (status) >= 1)
475 if (WEXITSTATUS (status) > greatest_status)
476 greatest_status = WEXITSTATUS (status);
477 signal_count++;
478 ret = -1;
480 return ret;
483 /* Invoke 'lipo' and combine and all output files. */
485 static void
486 do_lipo (int start_outfile_index, const char *out_file)
488 int i, j, pid;
489 char *errmsg_fmt, *errmsg_arg;
491 /* Populate lipo arguments. */
492 lipo_argv[0] = "lipo";
493 lipo_argv[1] = "-create";
494 lipo_argv[2] = "-o";
495 lipo_argv[3] = out_file;
497 /* Already 4 lipo arguments are set. Now add all lipo inputs. */
498 j = 4;
499 for (i = 0; i < num_arches; i++)
500 lipo_argv[j++] = out_files[start_outfile_index + i];
502 /* Add the NULL at the end. */
503 lipo_argv[j++] = NULL;
505 #ifdef DEBUG
506 debug_command_line (lipo_argv, j);
507 #endif
509 if (verbose_flag)
511 for (i = 0; lipo_argv[i]; i++)
512 fprintf (stderr, "%s ", lipo_argv[i]);
513 fprintf (stderr, "\n");
515 pid = pexecute (lipo_argv[0], (char *const *)lipo_argv, progname, NULL, &errmsg_fmt,
516 &errmsg_arg, PEXECUTE_SEARCH | PEXECUTE_ONE);
518 if (pid == -1)
519 pfatal_pexecute (errmsg_fmt, errmsg_arg);
521 do_wait (pid, lipo_argv[0]);
524 /* Invoke compiler for all architectures. */
526 static void
527 do_compile (const char **current_argv, int current_argc)
529 char *errmsg_fmt, *errmsg_arg;
530 int index = 0;
532 int dash_o_index = current_argc;
533 int of_index = current_argc + 1;
534 int argc_count = current_argc + 2;
536 while (index < num_arches)
538 int additional_arch_options = 0;
540 current_argv[0] = get_driver_name (get_arch_name (arches[index]));
542 /* setup output file. */
543 out_files[num_outfiles] = make_temp_file (".out");
544 current_argv[dash_o_index] = "-o";
545 current_argv[of_index] = out_files [num_outfiles];
546 num_outfiles++;
548 /* Add arch option as the last option. Do not add any other option
549 before removing this option. */
550 additional_arch_options = add_arch_options (index, current_argv, argc_count);
551 argc_count += additional_arch_options;
553 commands[index].prog = current_argv[0];
554 commands[index].argv = current_argv;
556 current_argv[argc_count] = NULL;
558 #ifdef DEBUG
559 debug_command_line (current_argv, argc_count);
560 #endif
561 commands[index].pid = pexecute (current_argv[0],
562 (char *const *)current_argv,
563 progname, NULL,
564 &errmsg_fmt,
565 &errmsg_arg,
566 PEXECUTE_SEARCH | PEXECUTE_ONE);
568 if (commands[index].pid == -1)
569 pfatal_pexecute (errmsg_fmt, errmsg_arg);
571 do_wait (commands[index].pid, commands[index].prog);
572 fflush (stdout);
574 /* Remove the last arch option added in the current_argv list. */
575 if (additional_arch_options)
576 argc_count -= remove_arch_options (current_argv, argc_count);
577 index++;
581 /* Invoke compiler for each input file separately.
582 Construct command line for each invocation with one input file. */
584 static void
585 do_compile_separately (void)
587 const char **new_new_argv;
588 int i, new_new_argc;
589 struct input_filename *current_ifn;
591 if (num_infiles == 1 || ima_is_used)
592 abort ();
594 /* Total number of arguments in separate compiler invocation is :
595 total number of original arguments - total no input files + one input
596 file + "-o" + output file . */
597 new_new_argv = (const char **) malloc ((new_argc - num_infiles + 4) * sizeof (const char *));
598 if (!new_new_argv)
599 abort ();
601 for (current_ifn = in_files; current_ifn && current_ifn->name;
602 current_ifn = current_ifn->next)
604 struct input_filename *ifn = in_files;
605 int go_back = 0;
606 new_new_argc = 1;
608 for (i = 1; i < new_argc; i++)
611 if (ifn && ifn->name && !strcmp (new_argv[i], ifn->name))
613 /* This argument is one of the input file. */
615 if (!strcmp (new_argv[i], current_ifn->name))
617 /* If it is current input file name then add it in the new
618 list. */
619 new_new_argv[new_new_argc++] = new_argv[i];
621 /* This input file can not appear in
622 again on the command line so next time look for next input
623 file. */
624 ifn = ifn->next;
626 else
628 /* This argument is not a input file name. Add it into new
629 list. */
630 new_new_argv[new_new_argc++] = new_argv[i];
634 /* OK now we have only one input file and all other arguments. */
635 do_compile (new_new_argv, new_new_argc);
639 /* Invoke 'lipo' on set of output files and create multile FAT binaries. */
641 static void
642 do_lipo_separately (void)
644 int ifn_index;
645 struct input_filename *ifn;
646 for (ifn_index = 0, ifn = in_files;
647 ifn_index < num_infiles && ifn && ifn->name;
648 ifn_index++, ifn = ifn->next)
649 do_lipo (ifn_index * num_arches,
650 strip_path_and_suffix (ifn->name, ".o"));
653 /* Replace -arch <blah> options with appropriate "-mcpu=<blah>" OR
654 "-march=<blah>". INDEX is the index in arches[] table. */
656 static int
657 add_arch_options (int index, const char **current_argv, int arch_index)
659 int count;
661 /* We are adding 1 argument for selected arches. */
662 count = 1;
664 #ifdef DEBUG
665 fprintf (stderr, "%s: add_arch_options: %s\n", progname, arches[index]);
666 #endif
668 if (!strcmp (arches[index], "ppc601"))
669 current_argv[arch_index] = "-mcpu=601";
670 else if (!strcmp (arches[index], "ppc603"))
671 current_argv[arch_index] = "-mcpu=603";
672 else if (!strcmp (arches[index], "ppc604"))
673 current_argv[arch_index] = "-mcpu=604";
674 else if (!strcmp (arches[index], "ppc604e"))
675 current_argv[arch_index] = "-mcpu=604e";
676 else if (!strcmp (arches[index], "ppc750"))
677 current_argv[arch_index] = "-mcpu=750";
678 else if (!strcmp (arches[index], "ppc7400"))
679 current_argv[arch_index] = "-mcpu=7400";
680 else if (!strcmp (arches[index], "ppc7450"))
681 current_argv[arch_index] = "-mcpu=7450";
682 else if (!strcmp (arches[index], "ppc970"))
683 current_argv[arch_index] = "-mcpu=970";
684 else if (!strcmp (arches[index], "ppc64"))
685 current_argv[arch_index] = "-m64";
686 else if (!strcmp (arches[index], "i486"))
687 current_argv[arch_index] = "-march=i486";
688 else if (!strcmp (arches[index], "i586"))
689 current_argv[arch_index] = "-march=i586";
690 else if (!strcmp (arches[index], "i686"))
691 current_argv[arch_index] = "-march=i686";
692 else if (!strcmp (arches[index], "pentium"))
693 current_argv[arch_index] = "-march=pentium";
694 else if (!strcmp (arches[index], "pentium2"))
695 current_argv[arch_index] = "-march=pentium2";
696 else if (!strcmp (arches[index], "pentpro"))
697 current_argv[arch_index] = "-march=pentiumpro";
698 else if (!strcmp (arches[index], "pentIIm3"))
699 current_argv[arch_index] = "-march=pentium2";
700 else if (!strcmp (arches[index], "x86_64"))
701 current_argv[arch_index] = "-m64";
702 else
703 count = 0;
705 return count;
708 /* Remove the last option, which is arch option, added by
709 add_arch_options. Return how count of arguments removed. */
710 static int
711 remove_arch_options (const char **current_argv, int arch_index)
713 #ifdef DEBUG
714 fprintf (stderr, "%s: Removing argument no %d\n", progname, arch_index);
715 #endif
717 current_argv[arch_index] = '\0';
719 #ifdef DEBUG
720 debug_command_line (current_argv, arch_index);
721 #endif
723 return 1;
726 /* Add new arch request. */
727 void
728 add_arch (const char *new_arch)
730 int i;
732 /* User can say cc -arch ppc -arch ppc foo.c
733 Do not invoke ppc compiler twice in this case. */
734 for (i = 0; i < num_arches; i++)
736 if (!strcmp (arches[i], new_arch))
737 return;
740 arches[num_arches] = new_arch;
741 num_arches++;
744 /* Rewrite the command line as requested in the QA_OVERRIDE_GCC3_OPTIONS
745 environment variable -- used for testing the compiler, working around bugs
746 in the Apple build environment, etc.
748 The override string is made up of a set of space-separated clauses. The
749 first letter of each clause describes what's to be done:
750 +string Add string as a new argument (at the end of the command line).
751 Multi-word command lines can be added with +x +y
752 s/x/y/ substitute x for y in the command line. X must be an entire
753 argument, and can be a regular expression as accepted by the
754 POSIX regexp code. Y will be substituted as a single argument,
755 and will not have regexp replacements added in.
756 xoption Removes argument matching option
757 Xoption Removes argument matching option and following word
758 Ox Removes any optimization flags in command line and replaces
759 with -Ox.
762 Here's some examples:
764 s/precomp-trustfile=foo//
765 +-fexplore-antartica
766 +-fast
767 s/-fsetvalue=* //
768 x-fwritable-strings
769 s/-O[0-2]/-Osize/
771 X-o +-o +foo.o
773 Option substitutions are processed from left to right; matches and changes
774 are cumulative. An error in processing one element (such as trying to
775 remove an element and successor when the match is at the end) cause the
776 particular change to stop, but additional changes in the environment
777 variable to be applied.
779 Key details:
780 * we always want to be able to adjust optimization levels for testing
781 * adding options is a common task
782 * substitution and deletion are less common.
784 If the first character of the environment variable is #, changes are
785 silent. If not, diagnostics are written to stderr explaining what
786 changes are being performed.
790 char **arg_array;
791 int arg_array_size=0;
792 int arg_count = 0;
793 int confirm_changes = 1;
794 const int ARG_ARRAY_INCREMENT_SIZE = 8;
795 #define FALSE 0
797 /* Routines for the argument array. The argument array routines are
798 responsible for allocation and deallocation of all objects in the
799 array */
801 void read_args (int argc, char **argv)
803 int i;
805 arg_array_size = argc+10;
806 arg_count = argc;
807 arg_array = (char**) malloc(sizeof(char*)*arg_array_size);
809 for (i=0;i<argc;i++) {
810 arg_array[i] = malloc (strlen (argv[i])+1);
811 strcpy (arg_array[i], argv[i]);
815 /* Insert the argument before pos. */
816 void insert_arg(int pos, char *arg_to_insert)
818 int i;
819 char *newArg = malloc (strlen (arg_to_insert)+1);
820 strcpy(newArg, arg_to_insert);
822 if (arg_count == arg_array_size) {
823 /* expand array */
824 arg_array_size = arg_count + ARG_ARRAY_INCREMENT_SIZE;
825 arg_array = (char**) realloc (arg_array, arg_array_size);
828 for (i = arg_count; i > pos; i--) {
829 arg_array[i+1] = arg_array[i];
832 arg_array[pos] = newArg;
833 arg_count++;
835 if (confirm_changes)
836 fprintf(stderr,"### Adding argument %s at position %d\n",arg_to_insert, pos);
840 void replace_arg (char *str, int pos) {
841 char *newArg = malloc(strlen(str)+1);
842 strcpy(newArg,str);
844 if (confirm_changes)
845 fprintf (stderr,"### Replacing %s with %s\n",arg_array[pos], str);
847 free (arg_array[pos]);
848 arg_array[pos] = newArg;
851 void append_arg (char *str)
853 char *new_arg = malloc (strlen (str)+1);
854 strcpy (new_arg, str);
855 if (confirm_changes)
856 fprintf(stderr,"### Adding argument %s at end\n", str);
858 if (arg_count == arg_array_size) {
859 /* expand array */
860 arg_array_size = arg_count + ARG_ARRAY_INCREMENT_SIZE;
861 arg_array = (char**) realloc (arg_array, arg_array_size);
864 arg_array[arg_count++] = new_arg;
867 void delete_arg(int pos) {
868 int i;
870 if (confirm_changes)
871 fprintf(stderr,"### Deleting argument %s\n",arg_array[pos]);
873 free (arg_array[pos]);
875 for (i=pos; i < arg_count; i++)
876 arg_array[i] = arg_array[i+1];
878 arg_count--;
881 /* Changing optimization levels is a common testing pattern --
882 we've got a special option that searches for and replaces anything
883 beginning with -O */
884 void replace_optimization_level (char *new_level) {
885 int i;
886 int optionFound = 0;
887 char *new_opt = malloc(strlen(new_opt)+3);
888 sprintf(new_opt, "-O%s",new_level);
891 for (i=0;i<arg_count;i++) {
892 if (strncmp(arg_array[i],"-O",2) == 0) {
893 replace_arg (new_opt, i);
894 optionFound = 1;
895 break;
899 if (optionFound == 0)
900 /* No optimization level? Add it! */
901 append_arg (new_opt);
903 free (new_opt);
906 /* Returns a NULL terminated string holding whatever was in the original
907 string at that point. This must be freed by the caller. */
909 char *arg_string(char *str, int begin, int len) {
910 char *new_str = malloc(len+1);
911 strncpy(new_str,&str[begin],len);
912 new_str[len] = '\0';
913 return new_str;
916 /* Given a search-and-replace string of the form
917 s/x/y/
919 do search and replace on the arg list. Make sure to check that the
920 string is sane -- that it has all the proper slashes that are necessary.
921 The search string can be a regular expression, but the replace string
922 must be a literal; the search must also be for a full argument, not for
923 a chain of arguments. The result will be treated as a single argument.
925 Return true if success, false if bad failure.
928 bool search_and_replace (char *str) {
929 regex_t regexp_search_struct;
930 int searchLen;
931 int replaceLen;
932 int i;
933 int err;
935 char *searchStr;
936 char *replaceStr;
937 char *replacedStr;
938 const int ERRSIZ = 512;
939 char errbuf[ERRSIZ];
942 if (str[0] != '/') {
943 return false;
946 searchLen = strcspn (str + 1, "/\0");
948 if (str[1 + searchLen] != '/')
949 return false;
951 replaceLen = strcspn(str+1+searchLen+1, "/\0");
953 if (str[1 + searchLen + 1 +replaceLen] != '/')
954 return false;
956 searchStr = arg_string(str, 1, searchLen);
957 replaceStr = arg_string (str, 1 + searchLen + 1, replaceLen);
959 if ((err = regcomp(&regexp_search_struct, searchStr, REG_EXTENDED)) != 0) {
960 regerror(err, &regexp_search_struct, errbuf, ERRSIZ);
961 fprintf(stderr,"%s",errbuf);
962 return false;
965 for (i=0;i<arg_count;i++) {
966 regmatch_t matches[5];
967 if (regexec (&regexp_search_struct, arg_array[i],
968 5, matches, 0) == 0) {
969 if ((matches[0].rm_eo - matches[0].rm_so) == strlen (arg_array[i])) {
970 /* Success! Change the string. */
971 replace_arg(replaceStr,i);
972 break;
977 regfree (&regexp_search_struct);
978 free (searchStr);
979 free (replaceStr);
981 return true;
985 /* Given a string, return the argument number where the first match occurs. */
986 int find_arg (char *str) {
987 int i;
988 int matchIndex = -1;
990 for (i=0;i<arg_count;i++) {
991 if (strcmp(arg_array[i],str) == 0) {
992 matchIndex = i;
993 break;
997 return matchIndex;
1000 void rewrite_command_line (char *override_options_line, int *argc, char ***argv){
1001 int line_pos = 0;
1003 read_args (*argc, *argv);
1005 if (override_options_line[0] == '#')
1007 confirm_changes = 0;
1008 line_pos++;
1012 if (confirm_changes)
1013 fprintf (stderr, "### QA_OVERRIDE_GCC3_OPTIONS: %s\n",
1014 override_options_line);
1016 /* Loop through all commands in the file */
1018 while (override_options_line[line_pos] != '\0')
1020 char first_char;
1021 char *searchStr;
1022 char *arg;
1023 int search_index;
1024 int arg_len;
1026 /* Any spaces in between options don't count. */
1027 if (override_options_line[line_pos] == ' ')
1029 line_pos++;
1030 continue;
1033 /* The first non-space character is the command. */
1034 first_char = override_options_line[line_pos];
1035 line_pos++;
1036 arg_len = strcspn(override_options_line+line_pos, " ");
1038 switch (first_char) {
1039 case '+':
1040 /* Add an argument to the end of the arg list */
1041 arg = arg_string (override_options_line,
1042 line_pos,
1043 arg_len);
1044 append_arg (arg);
1045 free (arg);
1046 break;
1048 case 'x':
1049 /* Delete a matching argument */
1050 searchStr = arg_string(override_options_line, line_pos, arg_len);
1051 if ((search_index = find_arg(searchStr)) != -1) {
1052 delete_arg(search_index);
1054 free (searchStr);
1055 break;
1057 case 'X':
1058 /* Delete a matching argument and the argument following. */
1059 searchStr = arg_string(override_options_line, line_pos, arg_len);
1060 if ((search_index = find_arg(searchStr)) != -1) {
1061 if (search_index >= arg_count -1) {
1062 if (confirm_changes)
1063 fprintf(stderr,"Not enough arguments to do X\n");
1064 } else {
1065 delete_arg(search_index); /* Delete the matching argument */
1066 delete_arg(search_index); /* Delete the following argument */
1069 free (searchStr);
1070 break;
1072 case 'O':
1073 /* Change the optimization level to the specified value, and
1074 remove any optimization arguments. This is a separate command
1075 because we often want is to substitute our favorite
1076 optimization level for whatever the project normally wants.
1077 As we probably care about this a lot (for things like
1078 testing file sizes at different optimization levels) we
1079 make a special rewrite clause. */
1080 arg = arg_string (override_options_line, line_pos, arg_len);
1081 replace_optimization_level(arg);
1082 free (arg);
1083 break;
1084 case 's':
1085 /* Search for the regexp passed in, and replace a matching argument
1086 with the provided replacement string */
1087 searchStr = arg_string (override_options_line, line_pos, arg_len);
1088 search_and_replace (searchStr);
1089 free (searchStr);
1090 break;
1092 default:
1093 fprintf(stderr,"### QA_OVERRIDE_GCC3_OPTIONS: invalid string (pos %d)\n",
1094 line_pos);
1095 break;
1097 line_pos += arg_len;
1099 *argc = arg_count;
1100 *argv = arg_array;
1103 /* Given a path to a file, potentially containing a directory name, return the
1104 number of characters at the end of the path that make up the filename part of
1105 the path. */
1107 static int
1108 get_prog_name_len (const char *prog)
1110 int result = 0;
1111 const char *progend = prog + strlen(prog);
1112 const char *progname = progend;
1113 while (progname != prog && !IS_DIR_SEPARATOR (progname[-1]))
1114 --progname;
1115 return progend-progname;
1118 /* Return true iff the path is an executable file and not a directory. */
1120 static bool
1121 is_x_file (const char *path)
1123 struct stat st;
1124 if (access (path, X_OK))
1125 return false;
1126 if (stat (path, &st) == -1)
1127 return false;
1128 if (S_ISDIR (st.st_mode))
1129 return false;
1130 return true;
1133 /* Given a FILENAME of an executable (for example "gcc") search the PATH
1134 environment variable to find out which directory it is in and return a fully
1135 qualified path to the executable.
1138 static const char *
1139 resolve_path_to_executable (const char *filename)
1141 char path_buffer[2*PATH_MAX+1];
1142 char *PATH = getenv ("PATH");
1143 if (PATH == 0) return filename; /* PATH not set */
1145 do {
1146 unsigned prefix_size;
1147 struct stat st;
1148 char *colon = strchr (PATH, ':');
1150 /* If we didn't find a :, use the whole last chunk. */
1151 prefix_size = colon ? colon-PATH : strlen (PATH);
1153 /* Form the full path. */
1154 memcpy (path_buffer, PATH, prefix_size);
1155 path_buffer[prefix_size] = '/';
1156 strcpy (path_buffer+prefix_size+1, filename);
1158 /* Check to see if this file is executable, if so, return it. */
1159 if (is_x_file (path_buffer))
1160 return strdup (path_buffer);
1161 PATH = colon ? colon+1 : PATH+prefix_size;
1162 } while (PATH[0]);
1164 return filename;
1167 /* If prog is a symlink, we want to rewrite prog to an absolute location,
1168 symlink_buffer contains the destination of the symlink. Glue these pieces
1169 together to form an absolute path. */
1171 static const char *
1172 resolve_symlink (const char *prog, char *symlink_buffer,
1173 int argv_0_len, int prog_len)
1175 /* If the link isn't to an absolute path, prefix it with the argv[0]
1176 directory. */
1177 if (!IS_ABSOLUTE_PATH (symlink_buffer))
1179 int prefix_len = argv_0_len - prog_len;
1180 memmove (symlink_buffer+prefix_len, symlink_buffer,
1181 PATH_MAX-prefix_len+1);
1182 memcpy (symlink_buffer, prog, prefix_len);
1184 return strdup(symlink_buffer);
1187 /* Main entry point. This is gcc driver driver!
1188 Interpret -arch flag from the list of input arguments. Invoke appropriate
1189 compiler driver. 'lipo' the results if more than one -arch is supplied. */
1191 main (int argc, const char **argv)
1193 size_t i;
1194 int l, pid, argv_0_len, prog_len;
1195 char *errmsg_fmt, *errmsg_arg;
1196 char *override_option_str = NULL;
1197 char path_buffer[2*PATH_MAX+1];
1198 int linklen;
1200 total_argc = argc;
1201 prog_len = 0;
1203 argv_0_len = strlen (argv[0]);
1205 /* Get the progname, required by pexecute () and program location. */
1206 prog_len = get_prog_name_len (argv[0]);
1208 /* If argv[0] is all program name (no slashes), search the PATH environment
1209 variable to get the fully resolved path to the executable. */
1210 if (prog_len == argv_0_len)
1212 #ifdef DEBUG
1213 progname = argv[0] + argv_0_len - prog_len;
1214 fprintf (stderr,"%s: before PATH resolution, full progname = %s\n",
1215 argv[0]+argv_0_len-prog_len, argv[0]);
1216 #endif
1217 argv[0] = resolve_path_to_executable (argv[0]);
1218 prog_len = get_prog_name_len (argv[0]);
1219 argv_0_len = strlen(argv[0]);
1222 /* If argv[0] is a symbolic link, use the directory of the pointed-to file
1223 to find compiler components. */
1225 if ((linklen = readlink (argv[0], path_buffer, PATH_MAX)) != -1)
1227 /* readlink succeeds if argv[0] is a symlink. path_buffer now contains
1228 the file referenced. */
1229 path_buffer[linklen] = '\0';
1230 #ifdef DEBUG
1231 progname = argv[0] + argv_0_len - prog_len;
1232 fprintf (stderr, "%s: before symlink, full prog = %s target = %s\n",
1233 progname, argv[0], path_buffer);
1234 #endif
1235 argv[0] = resolve_symlink(argv[0], path_buffer, argv_0_len, prog_len);
1236 argv_0_len = strlen(argv[0]);
1238 /* Get the progname, required by pexecute () and program location. */
1239 prog_len = get_prog_name_len (argv[0]);
1241 #ifdef DEBUG
1242 progname = argv[0] + argv_0_len - prog_len;
1243 printf("%s: ARGV[0] after symlink = %s\n", progname, argv[0]);
1244 #endif
1247 progname = argv[0] + argv_0_len - prog_len;
1249 /* Setup driver prefix. */
1250 prefix_len = argv_0_len - prog_len;
1251 curr_dir = (char *) malloc (sizeof (char) * (prefix_len + 1));
1252 strncpy (curr_dir, argv[0], prefix_len);
1253 curr_dir[prefix_len] = '\0';
1254 driver_exec_prefix = (argv[0], "/usr/bin", curr_dir);
1256 #ifdef DEBUG
1257 fprintf (stderr,"%s: full progname = %s\n", progname, argv[0]);
1258 fprintf (stderr,"%s: progname = %s\n", progname, progname);
1259 fprintf (stderr,"%s: driver_exec_prefix = %s\n", progname, driver_exec_prefix);
1260 #endif
1262 /* Before we get too far, rewrite the command line with any requested overrides */
1263 if ((override_option_str = getenv ("QA_OVERRIDE_GCC3_OPTIONS")) != NULL)
1264 rewrite_command_line(override_option_str, &argc, (char***)&argv);
1268 initialize ();
1270 /* Process arguments. Take appropriate actions when
1271 -arch, -c, -S, -E, -o is encountered. Find input file name. */
1272 for (i = 1; i < argc; i++)
1274 if (!strcmp (argv[i], "-arch"))
1276 if (i + 1 >= argc)
1277 abort ();
1279 add_arch (argv[i+1]);
1280 i++;
1282 else if (!strcmp (argv[i], "-c"))
1284 new_argv[new_argc++] = argv[i];
1285 compile_only_request = 1;
1287 else if (!strcmp (argv[i], "-S"))
1289 new_argv[new_argc++] = argv[i];
1290 asm_output_request = 1;
1292 else if (!strcmp (argv[i], "-E"))
1294 new_argv[new_argc++] = argv[i];
1295 preprocessed_output_request = 1;
1297 else if (!strcmp (argv[i], "-MD") || !strcmp (argv[i], "-MMD"))
1299 new_argv[new_argc++] = argv[i];
1300 dash_capital_m_seen = 1;
1302 else if (!strcmp (argv[i], "-dynamiclib"))
1304 new_argv[new_argc++] = argv[i];
1305 dash_dynamiclib_seen = 1;
1307 else if (!strcmp (argv[i], "-v"))
1309 new_argv[new_argc++] = argv[i];
1310 verbose_flag = 1;
1312 else if (!strcmp (argv[i], "-o"))
1314 if (i + 1 >= argc)
1315 abort ();
1317 output_filename = argv[i+1];
1318 i++;
1320 else if ((! strcmp (argv[i], "-pass-exit-codes"))
1321 || (! strcmp (argv[i], "-print-search-dirs"))
1322 || (! strcmp (argv[i], "-print-libgcc-file-name"))
1323 || (! strncmp (argv[i], "-print-file-name=", 17))
1324 || (! strncmp (argv[i], "-print-prog-name=", 17))
1325 || (! strcmp (argv[i], "-print-multi-lib"))
1326 || (! strcmp (argv[i], "-print-multi-directory"))
1327 || (! strcmp (argv[i], "-print-multi-os-directory"))
1328 || (! strcmp (argv[i], "-ftarget-help"))
1329 || (! strcmp (argv[i], "-fhelp"))
1330 || (! strcmp (argv[i], "+e"))
1331 || (! strncmp (argv[i], "-Wa,",4))
1332 || (! strncmp (argv[i], "-Wp,",4))
1333 || (! strncmp (argv[i], "-Wl,",4))
1334 || (! strncmp (argv[i], "-l", 2))
1335 || (! strncmp (argv[i], "-weak-l", 7))
1336 || (! strncmp (argv[i], "-specs=", 7))
1337 || (! strcmp (argv[i], "-ObjC"))
1338 || (! strcmp (argv[i], "-fobjC"))
1339 || (! strcmp (argv[i], "-ObjC++"))
1340 || (! strcmp (argv[i], "-time"))
1341 || (! strcmp (argv[i], "-###"))
1342 || (! strcmp (argv[i], "-fconstant-cfstrings"))
1343 || (! strcmp (argv[i], "-fno-constant-cfstrings"))
1344 || (! strcmp (argv[i], "-static-libgcc"))
1345 || (! strcmp (argv[i], "-shared-libgcc"))
1346 || (! strcmp (argv[i], "-pipe"))
1349 new_argv[new_argc++] = argv[i];
1351 else if (! strcmp (argv[i], "-save-temps")
1352 || ! strcmp (argv[i], "--save-temps"))
1354 new_argv[new_argc++] = argv[i];
1355 save_temps_seen = 1;
1357 else if ((! strcmp (argv[i], "-Xlinker"))
1358 || (! strcmp (argv[i], "-Xassembler"))
1359 || (! strcmp (argv[i], "-Xpreprocessor"))
1360 || (! strcmp (argv[i], "-l"))
1361 || (! strcmp (argv[i], "-weak_library"))
1362 || (! strcmp (argv[i], "-weak_framework"))
1363 || (! strcmp (argv[i], "-specs"))
1364 || (! strcmp (argv[i], "-framework"))
1367 new_argv[new_argc++] = argv[i];
1368 i++;
1369 new_argv[new_argc++] = argv[i];
1371 else if (argv[i][0] == '-' && argv[i][1] != 0)
1373 const char *p = &argv[i][1];
1374 int c = *p;
1376 /* First copy this flag itself. */
1377 new_argv[new_argc++] = argv[i];
1379 if (argv[i][1] == 'M')
1380 dash_capital_m_seen = 1;
1382 /* Now copy this flag's arguments, if any, appropriately. */
1383 if ((SWITCH_TAKES_ARG (c) > (p[1] != 0))
1384 || WORD_SWITCH_TAKES_ARG (p))
1386 int j = 0;
1387 int n_args = WORD_SWITCH_TAKES_ARG (p);
1388 if (n_args == 0)
1390 /* Count only the option arguments in separate argv elements. */
1391 n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
1393 if (i + n_args >= argc)
1394 fatal ("argument to `-%s' is missing", p);
1397 while ( j < n_args)
1399 i++;
1400 new_argv[new_argc++] = argv[i];
1401 j++;
1406 else
1408 struct input_filename *ifn;
1409 new_argv[new_argc++] = argv[i];
1410 ifn = (struct input_filename *) malloc (sizeof (struct input_filename));
1411 ifn->name = argv[i];
1412 ifn->index = i;
1413 ifn->next = NULL;
1414 num_infiles++;
1416 if (last_infile)
1417 last_infile->next = ifn;
1418 else
1419 in_files = ifn;
1421 last_infile = ifn;
1425 #if 0
1426 if (num_infiles == 0)
1427 fatal ("no input files");
1428 #endif
1430 if (num_arches > 1)
1432 if (preprocessed_output_request
1433 || save_temps_seen
1434 || asm_output_request
1435 || dash_capital_m_seen)
1436 fatal ("-E, -S, -save-temps and -M options are not allowed with multiple -arch flags");
1438 /* If -arch is not present OR Only one -arch <blah> is specified.
1439 Invoke appropriate compiler driver. FAT build is not required in this
1440 case. */
1442 if (num_arches == 0 || num_arches == 1)
1445 /* If no -arch is specified than use host compiler driver. */
1446 if (num_arches == 0)
1447 new_argv[0] = get_driver_name (get_arch_name (NULL));
1448 else if (num_arches == 1)
1450 /* Find compiler driver based on -arch <foo> and add approriate
1451 -m* argument. */
1452 new_argv[0] = get_driver_name (get_arch_name (arches[0]));
1453 new_argc = new_argc + add_arch_options (0, new_argv, new_argc);
1457 #ifdef DEBUG
1458 printf ("%s: invoking single driver name = %s\n", progname, new_argv[0]);
1459 #endif
1461 /* Re insert output file name. */
1462 if (output_filename)
1464 new_argv[new_argc++] = "-o";
1465 new_argv[new_argc++] = output_filename;
1468 /* Add the NULL. */
1469 new_argv[new_argc] = NULL;
1471 #ifdef DEBUG
1472 debug_command_line (new_argv, new_argc);
1473 #endif
1475 pid = pexecute (new_argv[0], (char *const *)new_argv, progname, NULL,
1476 &errmsg_fmt, &errmsg_arg, PEXECUTE_SEARCH | PEXECUTE_ONE);
1478 if (pid == -1)
1479 pfatal_pexecute (errmsg_fmt, errmsg_arg);
1481 do_wait (pid, new_argv[0]);
1483 else
1485 /* Handle multiple -arch <blah>. */
1487 /* If more than one input files are supplied but only one output filename
1488 is present then IMA will be used. */
1489 if (num_infiles > 1 && !compile_only_request)
1490 ima_is_used = 1;
1492 /* Linker wants to know this in case of multiple -arch. */
1493 if (!compile_only_request && !dash_dynamiclib_seen)
1494 new_argv[new_argc++] = "-Wl,-arch_multiple";
1497 /* If only one input file is specified OR IMA is used then expected output
1498 is one FAT binary. */
1499 if (num_infiles == 1 || ima_is_used)
1501 const char *out_file;
1503 /* Create output file name based on
1504 input filename, if required. */
1505 if (compile_only_request && !output_filename && num_infiles == 1)
1506 out_file = strip_path_and_suffix (in_files->name, ".o");
1507 else
1508 out_file = (output_filename ? output_filename : final_output);
1511 /* Linker wants to know name of output file using one extra arg. */
1512 if (!compile_only_request)
1514 char *oname = (char *)(output_filename ? output_filename : final_output);
1515 char *n = malloc (sizeof (char) * (strlen (oname) + 5));
1516 strcpy (n, "-Wl,");
1517 strcat (n, oname);
1518 new_argv[new_argc++] = "-Wl,-final_output";
1519 new_argv[new_argc++] = n;
1522 /* Compile file(s) for each arch and lipo 'em together. */
1523 do_compile (new_argv, new_argc);
1525 /* Make FAT binary by combining individual output files for each
1526 architecture, using 'lipo'. */
1527 do_lipo (0, out_file);
1529 else
1531 /* Multiple input files are present and IMA is not used.
1532 Which means need to generate multiple FAT files. */
1533 do_compile_separately ();
1534 do_lipo_separately ();
1538 final_cleanup ();
1539 free (curr_dir);
1540 return greatest_status;