i386.c (legitimize_tls_address): Generate tls_initial_exec_64_sun only when !TARGET_X32.
[gcc.git] / gcc / collect2.c
index cf39693f653d5f4b92f9df97d706e8168b5cfbe7..9ee12c7a50267c643450a554b7d044886cf91cc4 100644 (file)
@@ -1,7 +1,7 @@
 /* Collect static initialization info into data structures that can be
    traversed by C++ initialization and finalization routines.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.
    Contributed by Chris Smith (csmith@convex.com).
    Heavily modified by Michael Meissner (meissner@cygnus.com),
@@ -237,6 +237,12 @@ static const char *target_system_root = TARGET_SYSTEM_ROOT;
 static const char *target_system_root = "";
 #endif
 
+/* Whether we may unlink the output file, which should be set as soon as we
+   know we have successfully produced it.  This is typically useful to prevent
+   blindly attempting to unlink a read-only output that the target linker
+   would leave untouched.  */
+bool may_unlink_output_file = false;
+
 /* Structure to hold all the directories in which to search for files to
    execute.  */
 
@@ -323,9 +329,6 @@ static void write_c_file_glob (FILE *, const char *);
 #ifdef SCAN_LIBRARIES
 static void scan_libraries (const char *);
 #endif
-#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
-static int is_in_args (const char *, const char **, const char **);
-#endif
 #ifdef COLLECT_EXPORT_LIST
 #if 0
 static int is_in_list (const char *, struct id *);
@@ -839,7 +842,7 @@ add_lto_object (struct lto_object_list *list, const char *name)
    files contain LTO info.  The linker command line LTO_LD_ARGV
    represents the linker command that would produce a final executable
    without the use of LTO. OBJECT_LST is a vector of object file names
-   appearing in LTO_LD_ARGV that are to be considerd for link-time
+   appearing in LTO_LD_ARGV that are to be considered for link-time
    recompilation, where OBJECT is a pointer to the last valid element.
    (This awkward convention avoids an impedance mismatch with the
    usage of similarly-named variables in main().)  The elements of
@@ -1021,7 +1024,7 @@ int
 main (int argc, char **argv)
 {
   static const char *const ld_suffix   = "ld";
-  static const char *const plugin_ld_suffix = PLUGIN_LD;
+  static const char *const plugin_ld_suffix = PLUGIN_LD_SUFFIX;
   static const char *const real_ld_suffix = "real-ld";
   static const char *const collect_ld_suffix = "collect-ld";
   static const char *const nm_suffix   = "nm";
@@ -1091,6 +1094,9 @@ main (int argc, char **argv)
   const char **ld2;
   char **object_lst;
   const char **object;
+#ifdef TARGET_AIX_VERSION
+  int object_nbr = argc;
+#endif
   int first_file;
   int num_c_args;
   char **old_argv;
@@ -1440,6 +1446,60 @@ main (int argc, char **argv)
                         "configuration");
 #endif
                }
+#ifdef TARGET_AIX_VERSION
+             else
+               {
+                 /* File containing a list of input files to process.  */
+
+                 FILE *stream;
+                  char buf[MAXPATHLEN + 2];
+                 /* Number of additionnal object files.  */
+                 int add_nbr = 0;
+                 /* Maximum of additionnal object files before vector
+                    expansion.  */
+                 int add_max = 0;
+                 const char *list_filename = arg + 2;
+
+                 /* Accept -fFILENAME and -f FILENAME.  */
+                 if (*list_filename == '\0' && argv[1])
+                   {
+                     ++argv;
+                     list_filename = *argv;
+                     *ld1++ = *ld2++ = *argv;
+                   }
+
+                 stream = fopen (list_filename, "r");
+                 if (stream == NULL)
+                   fatal_error ("can't open %s: %m", list_filename);
+
+                 while (fgets (buf, sizeof buf, stream) != NULL)
+                   {
+                     /* Remove end of line.  */
+                     int len = strlen (buf);
+                     if (len >= 1 && buf[len - 1] =='\n')
+                       buf[len - 1] = '\0';
+
+                     /* Put on object vector.
+                        Note: we only expanse vector here, so we must keep
+                        extra space for remaining arguments.  */
+                     if (add_nbr >= add_max)
+                       {
+                         int pos =
+                           object - CONST_CAST2 (const char **, char **,
+                                                 object_lst);
+                         add_max = (add_max == 0) ? 16 : add_max * 2;
+                         object_lst = XRESIZEVEC (char *, object_lst,
+                                                   object_nbr + add_max);
+                         object = CONST_CAST2 (const char **, char **,
+                                               object_lst) + pos;
+                         object_nbr += add_max;
+                       }
+                     *object++ = xstrdup (buf);
+                     add_nbr++;
+                   }
+                 fclose (stream);
+               }
+#endif
               break;
 
            case 'l':
@@ -1467,15 +1527,6 @@ main (int argc, char **argv)
            case 'L':
              add_prefix (&cmdline_lib_dirs, arg+2);
              break;
-#else
-#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
-           case 'L':
-             if (is_in_args (arg,
-                             CONST_CAST2 (const char **, char **, ld1_argv),
-                             ld1 - 1))
-               --ld1;
-             break;
-#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
 #endif
 
            case 'o':
@@ -2050,15 +2101,22 @@ fork_execute (const char *prog, char **argv)
   do_wait (prog, pex);
 }
 \f
-/* Unlink a file unless we are debugging.  */
+/* Unlink FILE unless we are debugging or this is the output_file
+   and we may not unlink it.  */
 
 static void
 maybe_unlink (const char *file)
 {
-  if (!debug)
-    unlink_if_ordinary (file);
-  else
-    notice ("[Leaving %s]\n", file);
+  if (debug)
+    {
+      notice ("[Leaving %s]\n", file);
+      return;
+    }
+
+  if (file == output_file && !may_unlink_output_file)
+    return;
+
+  unlink_if_ordinary (file);
 }
 
 /* Call maybe_unlink on the NULL-terminated list, FILE_LIST.  */
@@ -2178,22 +2236,6 @@ write_list (FILE *stream, const char *prefix, struct id *list)
     }
 }
 
-#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
-/* Given a STRING, return nonzero if it occurs in the list in range
-   [ARGS_BEGIN,ARGS_END).  */
-
-static int
-is_in_args (const char *string, const char **args_begin,
-           const char **args_end)
-{
-  const char **args_pointer;
-  for (args_pointer = args_begin; args_pointer != args_end; ++args_pointer)
-    if (strcmp (string, *args_pointer) == 0)
-      return 1;
-  return 0;
-}
-#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
-
 #ifdef COLLECT_EXPORT_LIST
 /* This function is really used only on AIX, but may be useful.  */
 #if 0
@@ -2525,7 +2567,7 @@ scan_prog_file (const char *prog_name, scanpass which_pass,
 
   /* LTO objects must be in a known format.  This check prevents
      us from accepting an archive containing LTO objects, which
-     gcc cannnot currently handle.  */
+     gcc cannot currently handle.  */
   if (which_pass == PASS_LTOINFO && !maybe_lto_object_file (prog_name))
     return;