OSDN Git Service

* target-def.h: Remove usage of OBJECT_FORMAT_ROSE.
[pf3gnuchains/gcc-fork.git] / gcc / gcc.c
index 3a36d35..110495f 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1,6 +1,6 @@
 /* Compiler driver program that can handle many languages.
    Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -202,7 +202,23 @@ static int report_times;
 /* Nonzero means place this string before uses of /, so that include
    and library files can be found in an alternate location.  */
 
+#ifdef TARGET_SYSTEM_ROOT
 static const char *target_system_root = TARGET_SYSTEM_ROOT;
+#else
+static const char *target_system_root = 0;
+#endif
+
+/* Nonzero means pass the updated target_system_root to the compiler.  */
+
+static int target_system_root_changed;
+
+/* Nonzero means append this string to target_system_root.  */
+
+static const char *target_sysroot_suffix = 0;
+
+/* Nonzero means append this string to target_system_root for headers.  */
+
+static const char *target_sysroot_hdrs_suffix = 0;
 
 /* Nonzero means write "temp" files in source directory
    and use the source file's name in them, and don't delete them.  */
@@ -317,6 +333,7 @@ static char *save_string    PARAMS ((const char *, int));
 static void set_collect_gcc_options PARAMS ((void));
 static int do_spec_1           PARAMS ((const char *, int, const char *));
 static int do_spec_2           PARAMS ((const char *));
+static void do_option_spec     PARAMS ((const char *, const char *));
 static void do_self_spec       PARAMS ((const char *));
 static const char *find_file   PARAMS ((const char *));
 static int is_directory                PARAMS ((const char *, const char *, int));
@@ -440,12 +457,9 @@ or with constant text in a single argument.
        except that %g, %u, and %U do not currently support additional
        SUFFIX characters following %O as they would following, for
        example, `.o'.
- %p    substitutes the standard macro predefinitions for the
-       current target machine.  Use this when running cpp.
- %P    like %p, but puts `__' before and after the name of each macro.
-       (Except macros that already have __.)
-       This is for ANSI C.
- %I    Substitute a -iprefix option made from GCC_EXEC_PREFIX.
+ %I    Substitute any of -iprefix (made from GCC_EXEC_PREFIX), -isysroot
+       (made from TARGET_SYSTEM_ROOT), and -isystem (made from COMPILER_PATH
+       and -B options) as necessary.
  %s     current argument is the name of a library or startup file of some sort.
         Search for that file in a standard list of directories
        and substitute the full name found.
@@ -456,12 +470,6 @@ or with constant text in a single argument.
  %X    Output the accumulated linker options specified by compilations.
  %Y    Output the accumulated assembler options specified by compilations.
  %Z    Output the accumulated preprocessor options specified by compilations.
- %v1   Substitute the major version number of GCC.
-       (For version 2.5.3, this is 2.)
- %v2   Substitute the minor version number of GCC.
-       (For version 2.5.3, this is 5.)
- %v3   Substitute the patch level number of GCC.
-       (For version 2.5.3, this is 3.)
  %a     process ASM_SPEC as a spec.
         This allows config.h to specify part of the spec for running as.
  %A    process ASM_FINAL_SPEC as a spec.  A capital A is actually
@@ -665,6 +673,14 @@ proper position among the other output files.  */
 #define LINK_GCC_C_SEQUENCE_SPEC "%G %L %G"
 #endif
 
+#ifndef LINK_PIE_SPEC
+#ifdef HAVE_LD_PIE
+#define LINK_PIE_SPEC "%{pie:-pie} "
+#else
+#define LINK_PIE_SPEC "%{pie:} "
+#endif
+#endif
+
 /* -u* was put back because both BSD and SysV seem to support it.  */
 /* %{static:} simply prevents an error message if the target machine
    doesn't handle -static.  */
@@ -674,8 +690,8 @@ proper position among the other output files.  */
 #ifndef LINK_COMMAND_SPEC
 #define LINK_COMMAND_SPEC "\
 %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
-    %(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r} %{s} %{t}\
-    %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
+    %(linker) %l " LINK_PIE_SPEC "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
+    %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
     %{static:} %{L*} %(link_libgcc) %o %{fprofile-arcs:-lgcov}\
     %{!nostdlib:%{!nodefaultlibs:%(link_gcc_c_sequence)}}\
     %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
@@ -695,9 +711,16 @@ proper position among the other output files.  */
 # define STARTFILE_PREFIX_SPEC ""
 #endif
 
+#ifndef SYSROOT_SUFFIX_SPEC
+# define SYSROOT_SUFFIX_SPEC ""
+#endif
+
+#ifndef SYSROOT_HEADERS_SUFFIX_SPEC
+# define SYSROOT_HEADERS_SUFFIX_SPEC ""
+#endif
+
 static const char *asm_debug;
 static const char *cpp_spec = CPP_SPEC;
-static const char *cpp_predefines = CPP_PREDEFINES;
 static const char *cc1_spec = CC1_SPEC;
 static const char *cc1plus_spec = CC1PLUS_SPEC;
 static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
@@ -713,6 +736,8 @@ static const char *linker_name_spec = LINKER_NAME;
 static const char *link_command_spec = LINK_COMMAND_SPEC;
 static const char *link_libgcc_spec = LINK_LIBGCC_SPEC;
 static const char *startfile_prefix_spec = STARTFILE_PREFIX_SPEC;
+static const char *sysroot_suffix_spec = SYSROOT_SUFFIX_SPEC;
+static const char *sysroot_hdrs_suffix_spec = SYSROOT_HEADERS_SUFFIX_SPEC;
 
 /* Standard options to cpp, cc1, and as, to reduce duplication in specs.
    There should be no need to override these in target dependent files,
@@ -730,16 +755,13 @@ static const char *trad_capable_cpp =
    therefore no dependency entry, confuses make into thinking a .o
    file that happens to exist is up-to-date.  */
 static const char *cpp_unique_options =
-"%{C:%{!E:%eGNU C does not support -C without using -E}}\
- %{CC:%{!E:%eGNU C does not support -CC without using -E}}\
+"%{C|CC:%{!E:%eGCC does not support -C or -CC without -E}}\
  %{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*} %{P} %I\
  %{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\
  %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
  %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
  %{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}}\
- %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2 -D__GNUC_PATCHLEVEL__=%v3}\
- %{!undef:%{!ansi:%{!std=*:%p}%{std=gnu*:%p}} %P} %{trigraphs}\
- %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
+ %{trigraphs} %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
  %{E|M|MM:%W{o*}}";
 
 /* This contains cpp options which are common with cc1_options and are passed
@@ -801,6 +823,19 @@ static const char *const multilib_defaults_raw[] = MULTILIB_DEFAULTS;
 
 static const char *const driver_self_specs[] = { DRIVER_SELF_SPECS };
 
+#ifndef OPTION_DEFAULT_SPECS
+#define OPTION_DEFAULT_SPECS { "", "" }
+#endif
+
+struct default_spec
+{
+  const char *name;
+  const char *spec;
+};
+
+static const struct default_spec
+  option_default_specs[] = { OPTION_DEFAULT_SPECS };
+
 struct user_specs
 {
   struct user_specs *next;
@@ -809,30 +844,10 @@ struct user_specs
 
 static struct user_specs *user_specs_head, *user_specs_tail;
 
-/* This defines which switch letters take arguments.  */
-
-#define DEFAULT_SWITCH_TAKES_ARG(CHAR) \
-  ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \
-   || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \
-   || (CHAR) == 'I' || (CHAR) == 'm' || (CHAR) == 'x' \
-   || (CHAR) == 'L' || (CHAR) == 'A' || (CHAR) == 'B' || (CHAR) == 'b')
-
 #ifndef SWITCH_TAKES_ARG
 #define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
 #endif
 
-/* This defines which multi-letter switches take arguments.  */
-
-#define DEFAULT_WORD_SWITCH_TAKES_ARG(STR)             \
- (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext")     \
-  || !strcmp (STR, "Tbss") || !strcmp (STR, "include") \
-  || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \
-  || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \
-  || !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \
-  || !strcmp (STR, "isystem") || !strcmp (STR, "-param") \
-  || !strcmp (STR, "specs") \
-  || !strcmp (STR, "MF") || !strcmp (STR, "MT") || !strcmp (STR, "MQ"))
-
 #ifndef WORD_SWITCH_TAKES_ARG
 #define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
 #endif
@@ -905,11 +920,12 @@ static const struct compiler default_compilers[] =
       %{!E:%{!M:%{!MM:\
           %{traditional|ftraditional:\
 %eGNU C no longer supports -traditional without -E}\
-         %{save-temps|traditional-cpp:%(trad_capable_cpp) \
-               %(cpp_options) %b.i \n\
-                   cc1 -fpreprocessed %b.i %(cc1_options)}\
-         %{!save-temps:%{!traditional-cpp:\
-               cc1 %(cpp_unique_options) %(cc1_options)}}\
+         %{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
+               %(cpp_options) -o %{save-temps:%b.i} %{!save-temps:%g.i} \n\
+                   cc1 -fpreprocessed %{save-temps:%b.i} %{!save-temps:%g.i} \
+                       %(cc1_options)}\
+         %{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\
+               cc1 %(cpp_unique_options) %(cc1_options)}}}\
         %{!fsyntax-only:%(invoke_as)}}}}", 0},
   {"-",
    "%{!E:%e-E required when input is from standard input}\
@@ -920,15 +936,16 @@ static const struct compiler default_compilers[] =
       external preprocessor if -save-temps is given.  */
      "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
       %{!E:%{!M:%{!MM:\
-         %{save-temps|traditional-cpp:%(trad_capable_cpp) \
-               %(cpp_options) %b.i \n\
-                   cc1 -fpreprocessed %b.i %(cc1_options)\
-                        -o %g.s %{!o*:--output-pch=%i.pch}\
+         %{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
+               %(cpp_options) -o %{save-temps:%b.i} %{!save-temps:%g.i} \n\
+                   cc1 -fpreprocessed %{save-temps:%b.i} %{!save-temps:%g.i} \
+                       %(cc1_options)\
+                        -o %g.s %{!o*:--output-pch=%i.gch}\
                         %W{o*:--output-pch=%*}%V}\
-         %{!save-temps:%{!traditional-cpp:\
+         %{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\
                cc1 %(cpp_unique_options) %(cc1_options)\
-                    -o %g.s %{!o*:--output-pch=%i.pch}\
-                    %W{o*:--output-pch=%*}%V}}}}}", 0},
+                    -o %g.s %{!o*:--output-pch=%i.gch}\
+                    %W{o*:--output-pch=%*}%V}}}}}}", 0},
   {".i", "@cpp-output", 0},
   {"@cpp-output",
    "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0},
@@ -951,7 +968,7 @@ static const struct compiler default_compilers[] =
    , 0},
   
 #include "specs.h"
-  /* Mark end of table */
+  /* Mark end of table */
   {0, 0, 0}
 };
 
@@ -1032,6 +1049,7 @@ static const struct option_map option_map[] =
    {"--library-directory", "-L", "a"},
    {"--machine", "-m", "aj"},
    {"--machine-", "-m", "*j"},
+   {"--no-integrated-cpp", "-no-integrated-cpp", 0},
    {"--no-line-commands", "-P", 0},
    {"--no-precompiled-includes", "-noprecomp", 0},
    {"--no-standard-includes", "-nostdinc", 0},
@@ -1043,6 +1061,7 @@ static const struct option_map option_map[] =
    {"--param", "--param", "a"},
    {"--pedantic", "-pedantic", 0},
    {"--pedantic-errors", "-pedantic-errors", 0},
+   {"--pie", "-pie", 0},
    {"--pipe", "-pipe", 0},
    {"--prefix", "-B", "a"},
    {"--preprocess", "-E", 0},
@@ -1484,7 +1503,6 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("libgcc",                  &libgcc_spec),
   INIT_STATIC_SPEC ("startfile",               &startfile_spec),
   INIT_STATIC_SPEC ("switches_need_spaces",    &switches_need_spaces),
-  INIT_STATIC_SPEC ("predefines",              &cpp_predefines),
   INIT_STATIC_SPEC ("cross_compile",           &cross_compile),
   INIT_STATIC_SPEC ("version",                 &compiler_version),
   INIT_STATIC_SPEC ("multilib",                        &multilib_select),
@@ -1499,6 +1517,8 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("md_startfile_prefix",     &md_startfile_prefix),
   INIT_STATIC_SPEC ("md_startfile_prefix_1",   &md_startfile_prefix_1),
   INIT_STATIC_SPEC ("startfile_prefix_spec",   &startfile_prefix_spec),
+  INIT_STATIC_SPEC ("sysroot_suffix_spec",     &sysroot_suffix_spec),
+  INIT_STATIC_SPEC ("sysroot_hdrs_suffix_spec",        &sysroot_hdrs_suffix_spec),
 };
 
 #ifdef EXTRA_SPECS             /* additional specs needed */
@@ -1759,7 +1779,7 @@ set_spec (name, spec)
 
   /* Free the old spec.  */
   if (old_spec && sl->alloc_p)
-    free ((PTR) old_spec);
+    free ((void *) old_spec);
 
   sl->alloc_p = 1;
 }
@@ -2058,7 +2078,7 @@ read_specs (filename, main_p)
 
              set_spec (p2, *(sl->ptr_spec));
              if (sl->alloc_p)
-               free ((PTR) *(sl->ptr_spec));
+               free ((void *) *(sl->ptr_spec));
 
              *(sl->ptr_spec) = "";
              sl->alloc_p = 0;
@@ -2573,7 +2593,7 @@ add_prefix (pprefix, prefix, component, priority, require_machine_suffix,
        prev = &(*prev)->next)
     ;
 
-  /* Keep track of the longest prefix */
+  /* Keep track of the longest prefix */
 
   prefix = update_path (prefix, component);
   len = strlen (prefix);
@@ -2589,7 +2609,7 @@ add_prefix (pprefix, prefix, component, priority, require_machine_suffix,
   if (warn)
     *warn = 0;
 
-  /* Insert after PREV */
+  /* Insert after PREV */
   pl->next = (*prev);
   (*prev) = pl;
 }
@@ -2611,7 +2631,10 @@ add_sysrooted_prefix (pprefix, prefix, component, priority,
 
   if (target_system_root)
     {
+      if (target_sysroot_suffix)
+         prefix = concat (target_sysroot_suffix, prefix, NULL);
       prefix = concat (target_system_root, prefix, NULL);
+
       /* We have to override this because GCC's notion of sysroot
         moves along with GCC.  */
       component = "GCC";
@@ -2784,7 +2807,7 @@ execute ()
        pfatal_pexecute (errmsg_fmt, errmsg_arg);
 
       if (string != commands[i].prog)
-       free ((PTR) string);
+       free ((void *) string);
     }
 
   execution_count++;
@@ -3039,7 +3062,7 @@ display_help ()
   fputs (_("  -o <file>                Place the output into <file>\n"), stdout);
   fputs (_("\
   -x <language>            Specify the language of the following input files\n\
-                           Permissable languages include: c c++ assembler none\n\
+                           Permissible languages include: c c++ assembler none\n\
                            'none' means revert to the default behavior of\n\
                            guessing the language based on the file's extension\n\
 "), stdout);
@@ -3379,7 +3402,7 @@ process_command (argc, argv)
        {
          /* translate_options () has turned --version into -fversion.  */
          printf (_("%s (GCC) %s\n"), programname, version_string);
-         fputs (_("Copyright (C) 2002 Free Software Foundation, Inc.\n"),
+         fputs (_("Copyright (C) 2003 Free Software Foundation, Inc.\n"),
                 stdout);
          fputs (_("This is free software; see the source for copying conditions.  There is NO\n\
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"),
@@ -3830,14 +3853,23 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
              concat (tooldir_prefix, "lib", dir_separator_str, NULL),
              "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
 
+#if defined(TARGET_SYSTEM_ROOT_RELOCATABLE) && !defined(VMS)
+  /* If the normal TARGET_SYSTEM_ROOT is inside of $exec_prefix,
+     then consider it to relocate with the rest of the GCC installation
+     if GCC_EXEC_PREFIX is set.
+     ``make_relative_prefix'' is not compiled for VMS, so don't call it.  */
   if (target_system_root && gcc_exec_prefix)
     {
       char *tmp_prefix = make_relative_prefix (argv[0],
                                               standard_bindir_prefix,
                                               target_system_root);
       if (tmp_prefix && access_check (tmp_prefix, F_OK) == 0)
-       target_system_root = tmp_prefix;
+       {
+         target_system_root = tmp_prefix;
+         target_system_root_changed = 1;
+       }
     }
+#endif
 
   /* More prefixes are enabled in main, after we read the specs file
      and determine whether this is cross-compilation or not.  */
@@ -4158,7 +4190,7 @@ set_collect_gcc_options ()
    sans all directory names, and basename_length is the number
    of characters starting there excluding the suffix .c or whatever.  */
 
-const char *input_filename;
+static const char *input_filename;
 static int input_file_number;
 size_t input_filename_length;
 static int basename_length;
@@ -4228,6 +4260,9 @@ static int
 do_spec_2 (spec)
      const char *spec;
 {
+  const char *string;
+  int result;
+
   clear_args ();
   arg_going = 0;
   delete_this_arg = 0;
@@ -4236,7 +4271,22 @@ do_spec_2 (spec)
   input_from_pipe = 0;
   suffix_subst = NULL;
 
-  return do_spec_1 (spec, 0, NULL);
+  result = do_spec_1 (spec, 0, NULL);
+
+  /* End any pending argument.  */
+  if (arg_going)
+    {
+      obstack_1grow (&obstack, 0);
+      string = obstack_finish (&obstack);
+      if (this_is_library_file)
+       string = find_file (string);
+      store_arg (string, delete_this_arg, this_is_output_file);
+      if (this_is_output_file)
+       outfiles[input_file_number] = string;
+      arg_going = 0;
+    }
+
+  return result;
 }
 
 
@@ -4244,6 +4294,57 @@ do_spec_2 (spec)
    of the switches/n_switches array.  */
 
 static void
+do_option_spec (name, spec)
+     const char *name;
+     const char *spec;
+{
+  unsigned int i, value_count, value_len;
+  const char *p, *q, *value;
+  char *tmp_spec, *tmp_spec_p;
+
+  if (configure_default_options[0].name == NULL)
+    return;
+
+  for (i = 0; i < ARRAY_SIZE (configure_default_options); i++)
+    if (strcmp (configure_default_options[i].name, name) == 0)
+      break;
+  if (i == ARRAY_SIZE (configure_default_options))
+    return;
+
+  value = configure_default_options[i].value;
+  value_len = strlen (value);
+
+  /* Compute the size of the final spec.  */
+  value_count = 0;
+  p = spec;
+  while ((p = strstr (p, "%(VALUE)")) != NULL)
+    {
+      p ++;
+      value_count ++;
+    }
+
+  /* Replace each %(VALUE) by the specified value.  */
+  tmp_spec = alloca (strlen (spec) + 1
+                    + value_count * (value_len - strlen ("%(VALUE)")));
+  tmp_spec_p = tmp_spec;
+  q = spec;
+  while ((p = strstr (q, "%(VALUE)")) != NULL)
+    {
+      memcpy (tmp_spec_p, q, p - q);
+      tmp_spec_p = tmp_spec_p + (p - q);
+      memcpy (tmp_spec_p, value, value_len);
+      tmp_spec_p += value_len;
+      q = p + strlen ("%(VALUE)");
+    }
+  strcpy (tmp_spec_p, q);
+
+  do_self_spec (tmp_spec);
+}
+
+/* Process the given spec string and add any new options to the end
+   of the switches/n_switches array.  */
+
+static void
 do_self_spec (spec)
      const char *spec;
 {
@@ -4691,7 +4792,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
                for (t = temp_names; t; t = t->next)
                  if (t->length == suffix_length
                      && strncmp (t->suffix, suffix, suffix_length) == 0
-                     && t->unique == (c == 'u' || c == 'j'))
+                     && t->unique == (c == 'u' || c == 'U' || c == 'j'))
                    break;
 
                /* Make a new association if needed.  %u and %j
@@ -4712,7 +4813,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
                      }
                    else
                      t->suffix = save_string (suffix, suffix_length);
-                   t->unique = (c == 'u' || c == 'j');
+                   t->unique = (c == 'u' || c == 'U' || c == 'j');
                    temp_filename = make_temp_file (t->suffix);
                    temp_filename_length = strlen (temp_filename);
                    t->filename = temp_filename;
@@ -4746,6 +4847,18 @@ do_spec_1 (spec, inswitch, soft_matched_part)
                  do_spec_1 (" ", 0, NULL);
                }
 
+             if (target_system_root_changed ||
+                 (target_system_root && target_sysroot_hdrs_suffix))
+               {
+                 do_spec_1 ("-isysroot", 1, NULL);
+                 /* Make this a separate argument.  */
+                 do_spec_1 (" ", 0, NULL);
+                 do_spec_1 (target_system_root, 1, NULL);
+                 if (target_sysroot_hdrs_suffix)
+                   do_spec_1 (target_sysroot_hdrs_suffix, 1, NULL);
+                 do_spec_1 (" ", 0, NULL);
+               }
+
              for (; pl; pl = pl->next)
                {
                  do_spec_1 ("-isystem", 1, NULL);
@@ -4949,173 +5062,17 @@ do_spec_1 (spec, inswitch, soft_matched_part)
              }
            break;
 
-         case 'p':
-           {
-             char *x = (char *) alloca (strlen (cpp_predefines) + 1);
-             char *buf = x;
-             const char *y;
-
-             /* Copy all of the -D options in CPP_PREDEFINES into BUF.  */
-             y = cpp_predefines;
-             while (*y != 0)
-               {
-                 if (! strncmp (y, "-D", 2))
-                   /* Copy the whole option.  */
-                   while (*y && *y != ' ' && *y != '\t')
-                     *x++ = *y++;
-                 else if (*y == ' ' || *y == '\t')
-                   /* Copy whitespace to the result.  */
-                   *x++ = *y++;
-                 /* Don't copy other options.  */
-                 else
-                   y++;
-               }
-
-             *x = 0;
-
-             value = do_spec_1 (buf, 0, NULL);
-             if (value != 0)
-               return value;
-           }
-           break;
-
-         case 'P':
-           {
-             char *x = (char *) alloca (strlen (cpp_predefines) * 4 + 1);
-             char *buf = x;
-             const char *y;
-
-             /* Copy all of CPP_PREDEFINES into BUF,
-                but force them all into the reserved name space if they
-                aren't already there.  The reserved name space is all
-                identifiers beginning with two underscores or with one
-                underscore and a capital letter.  We do the forcing by
-                adding up to two underscores to the beginning and end
-                of each symbol. e.g. mips, _mips, mips_, and _mips_ all
-                become __mips__.  */
-             y = cpp_predefines;
-             while (*y != 0)
-               {
-                 if (! strncmp (y, "-D", 2))
-                   {
-                     int flag = 0;
-
-                     *x++ = *y++;
-                     *x++ = *y++;
-
-                     if (*y != '_'
-                         || (*(y + 1) != '_'
-                             && ! ISUPPER ((unsigned char) *(y + 1))))
-                       {
-                         /* Stick __ at front of macro name.  */
-                         if (*y != '_')
-                           *x++ = '_';
-                         *x++ = '_';
-                         /* Arrange to stick __ at the end as well.  */
-                         flag = 1;
-                       }
-
-                     /* Copy the macro name.  */
-                     while (*y && *y != '=' && *y != ' ' && *y != '\t')
-                       *x++ = *y++;
-
-                     if (flag)
-                       {
-                         if (x[-1] != '_')
-                           {
-                             if (x[-2] != '_')
-                               *x++ = '_';
-                             *x++ = '_';
-                           }
-                       }
-
-                     /* Copy the value given, if any.  */
-                     while (*y && *y != ' ' && *y != '\t')
-                       *x++ = *y++;
-                   }
-                 else if (*y == ' ' || *y == '\t')
-                   /* Copy whitespace to the result.  */
-                   *x++ = *y++;
-                 /* Don't copy -A options  */
-                 else
-                   y++;
-               }
-             *x++ = ' ';
-
-             /* Copy all of CPP_PREDEFINES into BUF,
-                but put __ after every -D.  */
-             y = cpp_predefines;
-             while (*y != 0)
-               {
-                 if (! strncmp (y, "-D", 2))
-                   {
-                     y += 2;
-
-                     if (*y != '_'
-                         || (*(y + 1) != '_'
-                             && ! ISUPPER ((unsigned char) *(y + 1))))
-                       {
-                         /* Stick -D__ at front of macro name.  */
-                         *x++ = '-';
-                         *x++ = 'D';
-                         if (*y != '_')
-                           *x++ = '_';
-                         *x++ = '_';
-
-                         /* Copy the macro name.  */
-                         while (*y && *y != '=' && *y != ' ' && *y != '\t')
-                           *x++ = *y++;
-
-                         /* Copy the value given, if any.  */
-                         while (*y && *y != ' ' && *y != '\t')
-                           *x++ = *y++;
-                       }
-                     else
-                       {
-                         /* Do not copy this macro - we have just done it before */
-                         while (*y && *y != ' ' && *y != '\t')
-                           y++;
-                       }
-                   }
-                 else if (*y == ' ' || *y == '\t')
-                   /* Copy whitespace to the result.  */
-                   *x++ = *y++;
-                 /* Don't copy -A options.  */
-                 else
-                   y++;
-               }
-             *x++ = ' ';
-
-             /* Copy all of the -A options in CPP_PREDEFINES into BUF.  */
-             y = cpp_predefines;
-             while (*y != 0)
-               {
-                 if (! strncmp (y, "-A", 2))
-                   /* Copy the whole option.  */
-                   while (*y && *y != ' ' && *y != '\t')
-                     *x++ = *y++;
-                 else if (*y == ' ' || *y == '\t')
-                   /* Copy whitespace to the result.  */
-                   *x++ = *y++;
-                 /* Don't copy other options.  */
-                 else
-                   y++;
-               }
-
-             *x = 0;
-
-             value = do_spec_1 (buf, 0, NULL);
-             if (value != 0)
-               return value;
-           }
-           break;
-
          case 'R':
            /* We assume there is a directory
               separator at the end of this string.  */
            if (target_system_root)
-             obstack_grow (&obstack, target_system_root, 
-                           strlen (target_system_root));
+             { 
+               obstack_grow (&obstack, target_system_root, 
+                             strlen (target_system_root));
+               if (target_sysroot_suffix)
+                 obstack_grow (&obstack, target_sysroot_suffix, 
+                               strlen (target_sysroot_suffix));
+             }
            break;
 
          case 'S':
@@ -5278,63 +5235,6 @@ do_spec_1 (spec, inswitch, soft_matched_part)
            }
            break;
 
-         case 'v':
-           {
-             int c1 = *p++;  /* Select first or second version number.  */
-             const char *v = compiler_version;
-             const char *q;
-             static const char zeroc = '0';
-
-             /* The format of the version string is
-                ([^0-9]*-)?[0-9]+[.][0-9]+([.][0-9]+)?([- ].*)?  */
-
-             /* Ignore leading non-digits.  i.e. "foo-" in "foo-2.7.2".  */
-             while (! ISDIGIT (*v))
-               v++;
-             if (v > compiler_version && v[-1] != '-')
-               abort ();
-
-             /* If desired, advance to second version number.  */
-             if (c1 >= '2')
-               {
-                 /* Set V after the first period.  */
-                 while (ISDIGIT (*v))
-                   v++;
-                 if (*v != '.')
-                   abort ();
-                 v++;
-               }
-
-             /* If desired, advance to third version number.
-                 But don't complain if it's not present */
-             if (c1 == '3')
-               {
-                 /* Set V after the second period.  */
-                 while (ISDIGIT (*v))
-                   v++;
-                 if ((*v != 0) && (*v != ' ') && (*v != '.') && (*v != '-'))
-                   abort ();
-                 if (*v != 0)
-                   v++;
-               }
-
-             /* Set Q at the next period or at the end.  */
-             q = v;
-             while (ISDIGIT (*q))
-               q++;
-             if (*q != 0 && q > v && *q != ' ' && *q != '.' && *q != '-')
-               abort ();
-
-             if (q > v)
-               /* Put that part into the command.  */
-               obstack_grow (&obstack, v, q - v);
-             else
-               /* Default to "0" */
-               obstack_grow (&obstack, &zeroc, 1);
-             arg_going = 1;
-           }
-           break;
-
          default:
            error ("spec failure: unrecognized spec option '%c'", c);
            break;
@@ -6232,6 +6132,12 @@ main (argc, argv)
   if (access (specs_file, R_OK) == 0)
     read_specs (specs_file, TRUE);
 
+  /* Process any configure-time defaults specified for the command line
+     options, via OPTION_DEFAULT_SPECS.  */
+  for (i = 0; i < ARRAY_SIZE (option_default_specs); i++)
+    do_option_spec (option_default_specs[i].name,
+                   option_default_specs[i].spec);
+
   /* Process DRIVER_SELF_SPECS, adding any new options to the end
      of the command line.  */
 
@@ -6249,6 +6155,26 @@ main (argc, argv)
        }
     }
 
+  /* Process sysroot_suffix_spec.  */
+  if (*sysroot_suffix_spec != 0
+      && do_spec_2 (sysroot_suffix_spec) == 0)
+    {
+      if (argbuf_index > 1)
+        error ("spec failure: more than one arg to SYSROOT_SUFFIX_SPEC.");
+      else if (argbuf_index == 1)
+        target_sysroot_suffix = xstrdup (argbuf[argbuf_index -1]);
+    }
+
+  /* Process sysroot_hdrs_suffix_spec.  */
+  if (*sysroot_hdrs_suffix_spec != 0
+      && do_spec_2 (sysroot_hdrs_suffix_spec) == 0)
+    {
+      if (argbuf_index > 1)
+        error ("spec failure: more than one arg to SYSROOT_HEADERS_SUFFIX_SPEC.");
+      else if (argbuf_index == 1)
+        target_sysroot_hdrs_suffix = xstrdup (argbuf[argbuf_index -1]);
+    }
+
   /* Look for startfiles in the standard places.  */
   if (*startfile_prefix_spec != 0
       && do_spec_2 (startfile_prefix_spec) == 0
@@ -6710,7 +6636,7 @@ pfatal_pexecute (errmsg_fmt, errmsg_arg)
   pfatal_with_name (errmsg_fmt);
 }
 
-/* Output an error message and exit */
+/* Output an error message and exit */
 
 void
 fancy_abort ()
@@ -6718,43 +6644,44 @@ fancy_abort ()
   fatal ("internal gcc abort");
 }
 \f
-/* Output an error message and exit */
+/* Output an error message and exit */
 
 void
-fatal VPARAMS ((const char *msgid, ...))
+fatal (const char *msgid, ...)
 {
-  VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, const char *, msgid);
+  va_list ap;
+  
+  va_start (ap, msgid);
 
   fprintf (stderr, "%s: ", programname);
   vfprintf (stderr, _(msgid), ap);
-  VA_CLOSE (ap);
+  va_end (ap);
   fprintf (stderr, "\n");
   delete_temp_files ();
   exit (1);
 }
 
 void
-error VPARAMS ((const char *msgid, ...))
+error (const char *msgid, ...)
 {
-  VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, const char *, msgid);
-
+  va_list ap;
+  
+  va_start (ap, msgid);
   fprintf (stderr, "%s: ", programname);
   vfprintf (stderr, _(msgid), ap);
-  VA_CLOSE (ap);
+  va_end (ap);
 
   fprintf (stderr, "\n");
 }
 
 static void
-notice VPARAMS ((const char *msgid, ...))
+notice (const char *msgid, ...)
 {
-  VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, const char *, msgid);
-
+  va_list ap;
+  
+  va_start (ap, msgid);
   vfprintf (stderr, _(msgid), ap);
-  VA_CLOSE (ap);
+  va_end (ap);
 }
 \f
 static inline void
@@ -6847,7 +6774,8 @@ next_member:
              else if (p[0] == 'W' && p[1] == '{')
                p = validate_switches (p+2);
            }
-         if (*p) p++;
+         else
+           p++;
        }
 
       if (*p) p++;