OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / collect2.c
index 465a98a..373483b 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
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Contributed by Chris Smith (csmith@convex.com).
    Heavily modified by Michael Meissner (meissner@cygnus.com),
@@ -30,10 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
-#include <signal.h>
-#if ! defined( SIGCHLD ) && defined( SIGCLD )
-#  define SIGCHLD SIGCLD
-#endif
+#include "filenames.h"
 
 /* TARGET_64BIT may be defined to use driver specific functionality. */
 #undef TARGET_64BIT
@@ -337,6 +334,8 @@ static void write_aix_file (FILE *, struct id *);
 static char *resolve_lib_name (const char *);
 #endif
 static char *extract_string (const char **);
+static void post_ld_pass (bool);
+static void process_args (int *argcp, char **argv);
 
 /* Enumerations describing which pass this is for scanning the
    program file ...  */
@@ -822,7 +821,7 @@ static void
 prefix_from_env (const char *env, struct path_prefix *pprefix)
 {
   const char *p;
-  GET_ENVIRONMENT (p, env);
+  p = getenv (env);
 
   if (p)
     prefix_from_string (p, pprefix);
@@ -954,7 +953,7 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
       size_t num_files;
 
       if (!lto_wrapper)
-       fatal ("COLLECT_LTO_WRAPPER must be set.");
+       fatal ("COLLECT_LTO_WRAPPER must be set");
 
       num_lto_c_args++;
 
@@ -1058,6 +1057,7 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
       /* Run the linker again, this time replacing the object files
          optimized by the LTO with the temporary file generated by the LTO.  */
       fork_execute ("ld", out_lto_ld_argv);
+      post_ld_pass (true);
       free (lto_ld_argv);
 
       maybe_unlink_list (lto_o_files);
@@ -1066,7 +1066,8 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
     {
       /* Our caller is relying on us to do the link
          even though there is no LTO back end work to be done.  */
-      fork_execute  ("ld", lto_ld_argv);
+      fork_execute ("ld", lto_ld_argv);
+      post_ld_pass (false);
     }
 }
 \f
@@ -1150,13 +1151,13 @@ main (int argc, char **argv)
   int num_c_args;
   char **old_argv;
 
-  bool use_verbose = false;
-
   old_argv = argv;
   expandargv (&argc, &argv);
   if (argv != old_argv)
     at_file_supplied = 1;
 
+  process_args (&argc, argv);
+
   num_c_args = argc + 9;
 
   no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
@@ -1196,29 +1197,26 @@ main (int argc, char **argv)
 
   /* Parse command line early for instances of -debug.  This allows
      the debug flag to be set before functions like find_a_file()
-     are called.  We also look for the -flto or -fwhopr flag to know
+     are called.  We also look for the -flto or -flto-partition=none flag to know
      what LTO mode we are in.  */
   {
     int i;
+    bool no_partition = false;
 
     for (i = 1; argv[i] != NULL; i ++)
       {
        if (! strcmp (argv[i], "-debug"))
          debug = true;
-        else if (! strcmp (argv[i], "-flto") && ! use_plugin)
-         {
-           use_verbose = true;
-           lto_mode = LTO_MODE_LTO;
-         }
-        else if (! strncmp (argv[i], "-fwhopr", 7) && ! use_plugin)
-         {
-           use_verbose = true;
-           lto_mode = LTO_MODE_WHOPR;
-         }
+        else if (! strcmp (argv[i], "-flto-partition=none"))
+         no_partition = true;
+        else if ((! strncmp (argv[i], "-flto=", 6)
+                 || ! strcmp (argv[i], "-flto")) && ! use_plugin)
+         lto_mode = LTO_MODE_WHOPR;
+       else if (!strncmp (argv[i], "-fno-lto", 8))
+         lto_mode = LTO_MODE_NONE;
         else if (! strcmp (argv[i], "-plugin"))
          {
            use_plugin = true;
-           use_verbose = true;
            lto_mode = LTO_MODE_NONE;
          }
 #ifdef COLLECT_EXPORT_LIST
@@ -1239,6 +1237,8 @@ main (int argc, char **argv)
 #endif
       }
     vflag = debug;
+    if (no_partition && lto_mode == LTO_MODE_WHOPR)
+      lto_mode = LTO_MODE_LTO;
   }
 
 #ifndef DEFAULT_A_OUT_NAME
@@ -1431,11 +1431,6 @@ main (int argc, char **argv)
              *c_ptr++ = xstrdup (q);
            }
        }
-      if (use_verbose && *q == '-' && q[1] == 'v' && q[2] == 0)
-       {
-         /* Turn on trace in collect2 if needed.  */
-         vflag = true;
-       }
     }
   obstack_free (&temporary_obstack, temporary_firstobj);
   *c_ptr++ = "-fno-profile-arcs";
@@ -1485,8 +1480,7 @@ main (int argc, char **argv)
              break;
 
             case 'f':
-             if (strcmp (arg, "-flto") == 0
-                 || strncmp (arg, "-fwhopr", 7) == 0)
+             if (strncmp (arg, "-flto", 5) == 0)
                {
 #ifdef ENABLE_LTO
                  /* Do not pass LTO flag to the linker. */
@@ -1688,13 +1682,7 @@ main (int argc, char **argv)
   *c_ptr = *ld1 = *object = (char *) 0;
 
   if (vflag)
-    {
-      notice ("collect2 version %s", version_string);
-#ifdef TARGET_VERSION
-      TARGET_VERSION;
-#endif
-      fprintf (stderr, "\n");
-    }
+    notice ("collect2 version %s\n", version_string);
 
   if (helpflag)
     {
@@ -1779,6 +1767,8 @@ main (int argc, char **argv)
 #endif
        if (lto_mode != LTO_MODE_NONE)
          maybe_run_lto_and_relink (ld1_argv, object_lst, object, false);
+       else
+         post_ld_pass (false);
 
        maybe_unlink (c_file);
        maybe_unlink (o_file);
@@ -1850,6 +1840,8 @@ main (int argc, char **argv)
 #ifdef COLLECT_EXPORT_LIST
       maybe_unlink (export_file);
 #endif
+      post_ld_pass (false);
+
       maybe_unlink (c_file);
       maybe_unlink (o_file);
       return 0;
@@ -1935,7 +1927,10 @@ main (int argc, char **argv)
   if (lto_mode)
     maybe_run_lto_and_relink (ld2_argv, object_lst, object, true);
   else
-    fork_execute ("ld", ld2_argv);
+    {
+      fork_execute ("ld", ld2_argv);
+      post_ld_pass (false);
+    }
 
   /* Let scan_prog_file do any final mods (OSF/rose needs this for
      constructors/destructors in shared libraries.  */
@@ -2314,12 +2309,8 @@ write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED)
   int frames = (frame_tables.number > 0);
 
   /* Figure out name of output_file, stripping off .so version.  */
-  p = strrchr (output_file, '/');
-  if (p == 0)
-    p = output_file;
-  else
-    p++;
-  q = p;
+  q = p = lbasename (output_file);
+
   while (q)
     {
       q = strchr (q,'.');
@@ -2330,7 +2321,7 @@ write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED)
        }
       else
        {
-         if (strncmp (q, SHLIB_SUFFIX, strlen (SHLIB_SUFFIX)) == 0)
+         if (filename_ncmp (q, SHLIB_SUFFIX, strlen (SHLIB_SUFFIX)) == 0)
            {
              q += strlen (SHLIB_SUFFIX);
              break;
@@ -3192,10 +3183,10 @@ resolve_lib_name (const char *name)
       for (; list; list = list->next)
        {
          /* The following lines are needed because path_prefix list
-            may contain directories both with trailing '/' and
+            may contain directories both with trailing DIR_SEPARATOR and
             without it.  */
          const char *p = "";
-         if (list->prefix[strlen(list->prefix)-1] != '/')
+         if (!IS_DIR_SEPARATOR (list->prefix[strlen(list->prefix)-1]))
            p = "/";
          for (j = 0; j < 2; j++)
            {
@@ -3218,3 +3209,67 @@ resolve_lib_name (const char *name)
   return (NULL);
 }
 #endif /* COLLECT_EXPORT_LIST */
+
+#ifdef COLLECT_RUN_DSYMUTIL
+static int flag_dsym = false;
+static int flag_idsym = false;
+
+static void
+process_args (int *argcp, char **argv) {
+  int i, j;
+  int argc = *argcp;
+  for (i=0; i<argc; ++i)
+    {
+      if (strcmp (argv[i], "-dsym") == 0)
+       {
+         flag_dsym = true;
+         /* Remove the flag, as we handle all processing for it.  */
+         j = i;
+         do
+           argv[j] = argv[j+1];
+         while (++j < argc);
+         --i;
+         argc = --(*argcp);
+       }
+      else if (strcmp (argv[i], "-idsym") == 0)
+       {
+         flag_idsym = true;
+         /* Remove the flag, as we handle all processing for it.  */
+         j = i;
+         do
+           argv[j] = argv[j+1];
+         while (++j < argc);
+         --i;
+         argc = --(*argcp);
+       }
+    }
+}
+
+static void
+do_dsymutil (const char *output_file) {
+  const char *dsymutil = DSYMUTIL + 1;
+  struct pex_obj *pex;
+  char **real_argv = XCNEWVEC (char *, 3);
+  const char ** argv = CONST_CAST2 (const char **, char **,
+                                   real_argv);
+
+  argv[0] = dsymutil;
+  argv[1] = output_file;
+  argv[2] = (char *) 0;
+
+  pex = collect_execute (dsymutil, real_argv, NULL, NULL, PEX_LAST | PEX_SEARCH);
+  do_wait (dsymutil, pex);
+}
+
+static void
+post_ld_pass (bool temp_file) {
+  if (!(temp_file && flag_idsym) && !flag_dsym)
+    return;
+      
+  do_dsymutil (output_file);
+}
+#else
+static void
+process_args (int *argcp ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) { }
+static void post_ld_pass (bool temp_file ATTRIBUTE_UNUSED) { }
+#endif