]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/gcc.c
Use -z ignore instead of --as-needed on Solaris
[thirdparty/gcc.git] / gcc / gcc.c
index 764ee1bf36fd11ca0833fb36a78061b66665733e..27072f007743429a6b8f121408af5d00b182d18e 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1,8 +1,5 @@
 /* Compiler driver program that can handle many languages.
-   Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-   2010, 2011, 2012
-   Free Software Foundation, Inc.
+   Copyright (C) 1987-2013 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -268,6 +265,7 @@ 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 **);
 static const char *replace_extension_spec_func (int, const char **);
+static char *convert_white_space (char *);
 \f
 /* The Specs Language
 
@@ -551,7 +549,9 @@ proper position among the other output files.  */
 #else
 #define ADD_STATIC_LIBASAN_LIBS
 #endif
-#ifdef HAVE_LD_STATIC_DYNAMIC
+#ifdef LIBASAN_EARLY_SPEC
+#define LIBASAN_SPEC ADD_STATIC_LIBASAN_LIBS
+#elif defined(HAVE_LD_STATIC_DYNAMIC)
 #define LIBASAN_SPEC "%{static-libasan:" LD_STATIC_OPTION \
                     "} -lasan %{static-libasan:" LD_DYNAMIC_OPTION "}" \
                     ADD_STATIC_LIBASAN_LIBS
@@ -560,6 +560,32 @@ proper position among the other output files.  */
 #endif
 #endif
 
+#ifndef LIBASAN_EARLY_SPEC
+#define LIBASAN_EARLY_SPEC ""
+#endif
+
+#ifndef LIBTSAN_SPEC
+#ifdef STATIC_LIBTSAN_LIBS
+#define ADD_STATIC_LIBTSAN_LIBS \
+  " %{static-libtsan:" STATIC_LIBTSAN_LIBS "}"
+#else
+#define ADD_STATIC_LIBTSAN_LIBS
+#endif
+#ifdef LIBTSAN_EARLY_SPEC
+#define LIBTSAN_SPEC ADD_STATIC_LIBTSAN_LIBS
+#elif defined(HAVE_LD_STATIC_DYNAMIC)
+#define LIBTSAN_SPEC "%{static-libtsan:" LD_STATIC_OPTION \
+                    "} -ltsan %{static-libtsan:" LD_DYNAMIC_OPTION "}" \
+                    ADD_STATIC_LIBTSAN_LIBS
+#else
+#define LIBTSAN_SPEC "-ltsan" ADD_STATIC_LIBTSAN_LIBS
+#endif
+#endif
+
+#ifndef LIBTSAN_EARLY_SPEC
+#define LIBTSAN_EARLY_SPEC ""
+#endif
+
 /* config.h can define LIBGCC_SPEC to override how and when libgcc.a is
    included.  */
 #ifndef LIBGCC_SPEC
@@ -601,7 +627,7 @@ proper position among the other output files.  */
      && defined(HAVE_AS_GDWARF2_DEBUG_FLAG) && defined(HAVE_AS_GSTABS_DEBUG_FLAG)
 #  define ASM_DEBUG_SPEC                                               \
       (PREFERRED_DEBUGGING_TYPE == DBX_DEBUG                           \
-       ? "%{!g0:%{gdwarf-2*:--gdwarf2}%{!gdwarf-2*:%{g*:--gstabs}}}" ASM_MAP   \
+       ? "%{!g0:%{gdwarf*:--gdwarf2}%{!gdwarf*:%{g*:--gstabs}}}" ASM_MAP       \
        : "%{!g0:%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}}}" ASM_MAP)
 # else
 #  if defined(DBX_DEBUGGING_INFO) && defined(HAVE_AS_GSTABS_DEBUG_FLAG)
@@ -679,6 +705,21 @@ proper position among the other output files.  */
     %e-fuse-linker-plugin is not supported in this configuration}"
 #endif
 
+/* Linker command line options for -fsanitize= early on the command line.  */
+#ifndef SANITIZER_EARLY_SPEC
+#define SANITIZER_EARLY_SPEC "\
+%{!nostdlib:%{!nodefaultlibs:%{fsanitize=address:" LIBASAN_EARLY_SPEC "} \
+    %{fsanitize=thread:" LIBTSAN_EARLY_SPEC "}}}"
+#endif
+
+/* Linker command line options for -fsanitize= late on the command line.  */
+#ifndef SANITIZER_SPEC
+#define SANITIZER_SPEC "\
+%{!nostdlib:%{!nodefaultlibs:%{fsanitize=address:" LIBASAN_SPEC "\
+    %{static:%ecannot specify -static with -fsanitize=address}}\
+    %{fsanitize=thread:" LIBTSAN_SPEC "\
+    %{!pie:%{!shared:%e-fsanitize=thread linking must be done with -pie or -shared}}}}}"
+#endif
 
 /* -u* was put back because both BSD and SysV seem to support it.  */
 /* %{static:} simply prevents an error message if the target machine
@@ -694,16 +735,16 @@ proper position among the other output files.  */
 %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
     %(linker) " \
     LINK_PLUGIN_SPEC \
-    "%{flto|flto=*:%<fcompare-debug*} \
+   "%{flto|flto=*:%<fcompare-debug*} \
     %{flto} %{flto=*} %l " LINK_PIE_SPEC \
-   "%X %{o*} %{e*} %{N} %{n} %{r}\
+   "%{fuse-ld=*:-fuse-ld=%*}\
+    %X %{o*} %{e*} %{N} %{n} %{r}\
     %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}}\
-    %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
+    %{static:} %{L*} %(mfwrap) %(link_libgcc) " SANITIZER_EARLY_SPEC " %o\
     %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)}\
     %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\
     %(mflib) " STACK_SPLIT_SPEC "\
-    %{fprofile-arcs|fprofile-generate*|coverage:-lgcov}\
-    %{fsanitize=address:" LIBASAN_SPEC "}\
+    %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} " SANITIZER_SPEC " \
     %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\
     %{!nostdlib:%{!nostartfiles:%E}} %{T*} }}}}}}"
 #endif
@@ -847,6 +888,7 @@ static const char *multilib_select;
 static const char *multilib_matches;
 static const char *multilib_defaults;
 static const char *multilib_exclusions;
+static const char *multilib_reuse;
 
 /* Check whether a particular argument is a default argument.  */
 
@@ -1240,6 +1282,7 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("multilib_matches",                &multilib_matches),
   INIT_STATIC_SPEC ("multilib_exclusions",     &multilib_exclusions),
   INIT_STATIC_SPEC ("multilib_options",                &multilib_options),
+  INIT_STATIC_SPEC ("multilib_reuse",          &multilib_reuse),
   INIT_STATIC_SPEC ("linker",                  &linker_name_spec),
   INIT_STATIC_SPEC ("linker_plugin_file",      &linker_plugin_file_spec),
   INIT_STATIC_SPEC ("lto_wrapper",             &lto_wrapper_spec),
@@ -1318,7 +1361,8 @@ init_gcc_specs (struct obstack *obstack, const char *shared_name,
                "%{!static:%{!static-libgcc:"
 #if USE_LD_AS_NEEDED
                "%{!shared-libgcc:",
-               static_name, " --as-needed ", shared_name, " --no-as-needed"
+               static_name, " " LD_AS_NEEDED_OPTION " ",
+               shared_name, " " LD_NO_AS_NEEDED_OPTION
                "}"
                "%{shared-libgcc:",
                shared_name, "%{!shared: ", static_name, "}"
@@ -6315,6 +6359,13 @@ main (int argc, char **argv)
     obstack_1grow (&multilib_obstack, 0);
     multilib_exclusions = XOBFINISH (&multilib_obstack, const char *);
 
+    q = multilib_reuse_raw;
+    while ((p = *q++) != (char *) 0)
+      obstack_grow (&multilib_obstack, p, strlen (p));
+
+    obstack_1grow (&multilib_obstack, 0);
+    multilib_reuse = XOBFINISH (&multilib_obstack, const char *);
+
     need_space = FALSE;
     for (i = 0; i < ARRAY_SIZE (multilib_defaults_raw); i++)
       {
@@ -6578,6 +6629,7 @@ main (int argc, char **argv)
                                    X_OK, false);
   if (lto_wrapper_file)
     {
+      lto_wrapper_file = convert_white_space (lto_wrapper_file);
       lto_wrapper_spec = lto_wrapper_file;
       obstack_init (&collect_obstack);
       obstack_grow (&collect_obstack, "COLLECT_LTO_WRAPPER=",
@@ -6704,7 +6756,7 @@ main (int argc, char **argv)
     {
       printf (_("%s %s%s\n"), progname, pkgversion_string,
              version_string);
-      printf ("Copyright %s 2012 Free Software Foundation, Inc.\n",
+      printf ("Copyright %s 2013 Free Software Foundation, Inc.\n",
              _("(C)"));
       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"),
@@ -6988,12 +7040,13 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
                              + strlen (fuse_linker_plugin), 0))
 #endif
            {
-             linker_plugin_file_spec = find_a_file (&exec_prefixes,
-                                                    LTOPLUGINSONAME, R_OK,
-                                                    false);
-             if (!linker_plugin_file_spec)
+             char *temp_spec = find_a_file (&exec_prefixes,
+                                            LTOPLUGINSONAME, R_OK,
+                                            false);
+             if (!temp_spec)
                fatal_error ("-fuse-linker-plugin, but %s not found",
                             LTOPLUGINSONAME);
+             linker_plugin_file_spec = convert_white_space (temp_spec);
            }
 #endif
          lto_gcc_spec = argv[0];
@@ -7528,6 +7581,12 @@ set_multilib_dir (void)
 
   first = 1;
   p = multilib_select;
+
+  /* Append multilib reuse rules if any.  With those rules, we can reuse
+     one multilib for certain different options sets.  */
+  if (strlen (multilib_reuse) > 0)
+    p = concat (p, multilib_reuse, NULL);
+
   while (*p != '\0')
     {
       /* Ignore newlines.  */
@@ -7544,8 +7603,8 @@ set_multilib_dir (void)
          if (*p == '\0')
            {
            invalid_select:
-             fatal_error ("multilib select %qs is invalid",
-                          multilib_select);
+             fatal_error ("multilib select %qs %qs is invalid",
+                          multilib_select, multilib_reuse);
            }
          ++p;
        }
@@ -8483,3 +8542,51 @@ replace_extension_spec_func (int argc, const char **argv)
   free (name);
   return result;
 }
+
+/* Insert backslash before spaces in ORIG (usually a file path), to 
+   avoid being broken by spec parser.
+
+   This function is needed as do_spec_1 treats white space (' ' and '\t')
+   as the end of an argument. But in case of -plugin /usr/gcc install/xxx.so,
+   the file name should be treated as a single argument rather than being
+   broken into multiple. Solution is to insert '\\' before the space in a 
+   file name.
+   
+   This function converts and only converts all occurrence of ' ' 
+   to '\\' + ' ' and '\t' to '\\' + '\t'.  For example:
+   "a b"  -> "a\\ b"
+   "a  b" -> "a\\ \\ b"
+   "a\tb" -> "a\\\tb"
+   "a\\ b" -> "a\\\\ b"
+
+   orig: input null-terminating string that was allocated by xalloc. The
+   memory it points to might be freed in this function. Behavior undefined
+   if ORIG wasn't xalloced or was freed already at entry.
+
+   Return: ORIG if no conversion needed. Otherwise a newly allocated string
+   that was converted from ORIG.  */
+
+static char *
+convert_white_space (char *orig)
+{
+  int len, number_of_space = 0;
+
+  for (len = 0; orig[len]; len++)
+    if (orig[len] == ' ' || orig[len] == '\t') number_of_space++;
+
+  if (number_of_space)
+    {
+      char *new_spec = (char *) xmalloc (len + number_of_space + 1);
+      int j, k;
+      for (j = 0, k = 0; j <= len; j++, k++)
+       {
+         if (orig[j] == ' ' || orig[j] == '\t')
+           new_spec[k++] = '\\';
+         new_spec[k] = orig[j];
+       }
+      free (orig);
+      return new_spec;
+  }
+  else
+    return orig;
+}