OSDN Git Service

Unify handling of runtime support functions.
[pf3gnuchains/gcc-fork.git] / gcc / collect2.c
index df91d34..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,6 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "filenames.h"
 
 /* TARGET_64BIT may be defined to use driver specific functionality. */
 #undef TARGET_64BIT
@@ -333,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 ...  */
@@ -1054,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);
@@ -1062,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
@@ -1146,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");
@@ -1206,14 +1211,12 @@ main (int argc, char **argv)
          no_partition = true;
         else if ((! strncmp (argv[i], "-flto=", 6)
                  || ! strcmp (argv[i], "-flto")) && ! use_plugin)
-         {
-           use_verbose = true;
-           lto_mode = LTO_MODE_WHOPR;
-         }
+         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
@@ -1234,7 +1237,7 @@ main (int argc, char **argv)
 #endif
       }
     vflag = debug;
-    if (no_partition)
+    if (no_partition && lto_mode == LTO_MODE_WHOPR)
       lto_mode = LTO_MODE_LTO;
   }
 
@@ -1428,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";
@@ -1684,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)
     {
@@ -1775,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);
@@ -1846,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;
@@ -1931,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.  */
@@ -2310,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,'.');
@@ -2326,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;
@@ -3188,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++)
            {
@@ -3214,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