OSDN Git Service

2010-12-02 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / gcc.c
index fb98171..d6f0a08 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -35,10 +35,6 @@ compilation is specified by a string called a "spec".  */
 #include "coretypes.h"
 #include "multilib.h" /* before tm.h */
 #include "tm.h"
-#include <signal.h>
-#if ! defined( SIGCHLD ) && defined( SIGCLD )
-#  define SIGCHLD SIGCLD
-#endif
 #include "xregex.h"
 #include "obstack.h"
 #include "intl.h"
@@ -49,18 +45,6 @@ compilation is specified by a string called a "spec".  */
 #include "opts.h"
 #include "vec.h"
 
-#ifdef HAVE_MMAP_FILE
-# include <sys/mman.h>
-# ifdef HAVE_MINCORE
-/* This is on Solaris.  */
-#  include <sys/types.h>
-# endif
-#endif
-
-#ifndef MAP_FAILED
-# define MAP_FAILED ((void *)-1)
-#endif
-
 /* By default there is no special suffix for target executables.  */
 /* FIXME: when autoconf is fixed, remove the host check - dj */
 #if defined(TARGET_EXECUTABLE_SUFFIX) && defined(HOST_EXECUTABLE_SUFFIX)
@@ -88,10 +72,6 @@ static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
 #define LIBRARY_PATH_ENV "LIBRARY_PATH"
 #endif
 
-#ifndef HAVE_KILL
-#define kill(p,s) raise(s)
-#endif
-
 /* If a stage of compilation returns an exit status >= 1,
    compilation of that file ceases.  */
 
@@ -284,6 +264,7 @@ static const char *print_asm_header_spec_function (int, const char **);
 static const char *compare_debug_dump_opt_spec_function (int, const char **);
 static const char *compare_debug_self_opt_spec_function (int, const char **);
 static const char *compare_debug_auxbase_opt_spec_function (int, const char **);
+static const char *pass_through_libs_spec_func (int, const char **);
 \f
 /* The Specs Language
 
@@ -656,8 +637,7 @@ proper position among the other output files.  */
     -plugin %(linker_plugin_file) \
     -plugin-opt=%(lto_wrapper) \
     -plugin-opt=-fresolution=%u.res \
-    %{static|static-libgcc:-plugin-opt=-pass-through=%(lto_libgcc)}    \
-    %{static:-plugin-opt=-pass-through=-lc}    \
+    %{!nostdlib:%{!nodefaultlibs:%:pass-through-libs(%(link_gcc_c_sequence))}} \
     } \
     %{flto*:%<fcompare-debug*} \
     %{flto*} %l " LINK_PIE_SPEC \
@@ -712,7 +692,6 @@ static const char *linker_name_spec = LINKER_NAME;
 static const char *linker_plugin_file_spec = "";
 static const char *lto_wrapper_spec = "";
 static const char *lto_gcc_spec = "";
-static const char *lto_libgcc_spec = "";
 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;
@@ -1197,7 +1176,6 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("linker_plugin_file",      &linker_plugin_file_spec),
   INIT_STATIC_SPEC ("lto_wrapper",             &lto_wrapper_spec),
   INIT_STATIC_SPEC ("lto_gcc",                 &lto_gcc_spec),
-  INIT_STATIC_SPEC ("lto_libgcc",              &lto_libgcc_spec),
   INIT_STATIC_SPEC ("link_libgcc",             &link_libgcc_spec),
   INIT_STATIC_SPEC ("md_exec_prefix",          &md_exec_prefix),
   INIT_STATIC_SPEC ("md_startfile_prefix",     &md_startfile_prefix),
@@ -1242,6 +1220,7 @@ static const struct spec_function static_spec_functions[] =
   { "compare-debug-dump-opt",  compare_debug_dump_opt_spec_function },
   { "compare-debug-self-opt",  compare_debug_self_opt_spec_function },
   { "compare-debug-auxbase-opt", compare_debug_auxbase_opt_spec_function },
+  { "pass-through-libs",       pass_through_libs_spec_func },
 #ifdef EXTRA_SPEC_FUNCTIONS
   EXTRA_SPEC_FUNCTIONS
 #endif
@@ -3507,7 +3486,7 @@ process_command (unsigned int decoded_options_count,
   struct cl_option_handlers handlers;
   unsigned int j;
 
-  GET_ENVIRONMENT (gcc_exec_prefix, "GCC_EXEC_PREFIX");
+  gcc_exec_prefix = getenv ("GCC_EXEC_PREFIX");
 
   n_switches = 0;
   n_infiles = 0;
@@ -3612,7 +3591,7 @@ process_command (unsigned int decoded_options_count,
   /* COMPILER_PATH and LIBRARY_PATH have values
      that are lists of directory names with colons.  */
 
-  GET_ENVIRONMENT (temp, "COMPILER_PATH");
+  temp = getenv ("COMPILER_PATH");
   if (temp)
     {
       const char *startp, *endp;
@@ -3646,7 +3625,7 @@ process_command (unsigned int decoded_options_count,
        }
     }
 
-  GET_ENVIRONMENT (temp, LIBRARY_PATH_ENV);
+  temp = getenv (LIBRARY_PATH_ENV);
   if (temp && *cross_compile == '0')
     {
       const char *startp, *endp;
@@ -3679,7 +3658,7 @@ process_command (unsigned int decoded_options_count,
     }
 
   /* Use LPATH like LIBRARY_PATH (for the CMU build program).  */
-  GET_ENVIRONMENT (temp, "LPATH");
+  temp = getenv ("LPATH");
   if (temp && *cross_compile == '0')
     {
       const char *startp, *endp;
@@ -6074,6 +6053,7 @@ main (int argc, char **argv)
   int num_linker_inputs = 0;
   char *explicit_link_files;
   char *specs_file;
+  char *lto_wrapper_file;
   const char *p;
   struct user_specs *uptr;
   char **old_argv = argv;
@@ -6412,9 +6392,10 @@ main (int argc, char **argv)
 
   /* Set up to remember the pathname of the lto wrapper. */
 
-  lto_wrapper_spec = find_a_file (&exec_prefixes, "lto-wrapper", X_OK, false);
-  if (lto_wrapper_spec)
+  lto_wrapper_file = find_a_file (&exec_prefixes, "lto-wrapper", X_OK, false);
+  if (lto_wrapper_file)
     {
+      lto_wrapper_spec = lto_wrapper_file;
       obstack_init (&collect_obstack);
       obstack_grow (&collect_obstack, "COLLECT_LTO_WRAPPER=",
                    sizeof ("COLLECT_LTO_WRAPPER=") - 1);
@@ -6758,7 +6739,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
       int i;
 
       for (i = 0; i < n_infiles ; i++)
-       if (infiles[i].language && infiles[i].language[0] != '*')
+       if (infiles[i].incompiler
+           || (infiles[i].language && infiles[i].language[0] != '*'))
          {
            set_input (infiles[i].name);
            break;
@@ -6803,11 +6785,6 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
                                                 false);
          if (!linker_plugin_file_spec)
            fatal_error ("-fuse-linker-plugin, but " LTOPLUGINSONAME " not found");
-
-         lto_libgcc_spec = find_a_file (&startfile_prefixes, "libgcc.a",
-                                        R_OK, true);
-         if (!lto_libgcc_spec)
-           fatal_error ("could not find libgcc.a");
        }
       lto_gcc_spec = argv[0];
 
@@ -8188,3 +8165,46 @@ compare_debug_auxbase_opt_spec_function (int arg,
 
   return name;
 }
+
+/* %:pass-through-libs spec function.  Finds all -l options and input
+   file names in the lib spec passed to it, and makes a list of them
+   prepended with the plugin option to cause them to be passed through
+   to the final link after all the new object files have been added.  */
+
+const char *
+pass_through_libs_spec_func (int argc, const char **argv)
+{
+  char *prepended = xstrdup (" ");
+  int n;
+  /* Shlemiel the painter's algorithm.  Innately horrible, but at least
+     we know that there will never be more than a handful of strings to
+     concat, and it's only once per run, so it's not worth optimising.  */
+  for (n = 0; n < argc; n++)
+    {
+      char *old = prepended;
+      /* Anything that isn't an option is a full path to an output
+         file; pass it through if it ends in '.a'.  Among options,
+        pass only -l.  */
+      if (argv[n][0] == '-' && argv[n][1] == 'l')
+       {
+         const char *lopt = argv[n] + 2;
+         /* Handle both joined and non-joined -l options.  If for any
+            reason there's a trailing -l with no joined or following
+            arg just discard it.  */
+         if (!*lopt && ++n >= argc)
+           break;
+         else if (!*lopt)
+           lopt = argv[n];
+         prepended = concat (prepended, "-plugin-opt=-pass-through=-l",
+               lopt, " ", NULL);
+       }
+      else if (!strcmp (".a", argv[n] + strlen (argv[n]) - 2))
+       {
+         prepended = concat (prepended, "-plugin-opt=-pass-through=",
+               argv[n], " ", NULL);
+       }
+      if (prepended != old)
+       free (old);
+    }
+  return prepended;
+}