OSDN Git Service

2010-05-07 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / collect2.c
index 42db3cb..99d9be4 100644 (file)
@@ -940,8 +940,10 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
 
   if (lto_objects.first)
     {
+      const char *opts;
       char **lto_c_argv;
       const char **lto_c_ptr;
+      const char *cp;
       const char **p, **q, **r;
       const char **lto_o_ptr;
       struct lto_object *list;
@@ -952,15 +954,52 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
       if (!lto_wrapper)
        fatal ("COLLECT_LTO_WRAPPER must be set.");
 
-      num_lto_c_args++;
-
       /* There is at least one object file containing LTO info,
          so we need to run the LTO back end and relink.  */
 
+      /* Get compiler options passed down from the parent `gcc' command.
+         These must be passed to the LTO back end.  */
+      opts = getenv ("COLLECT_GCC_OPTIONS");
+
+      /* Increment the argument count by the number of inherited options.
+         Some arguments may be filtered out later.  Again, an upper bound
+         suffices.  */
+
+      cp = opts;
+
+      while (cp && *cp)
+        {
+          extract_string (&cp);
+          num_lto_c_args++;
+        }
+      obstack_free (&temporary_obstack, temporary_firstobj);
+
+      if (debug)
+       num_lto_c_args++;
+
+      /* Increment the argument count by the number of initial
+        arguments added below.  */
+      num_lto_c_args += 9;
+
       lto_c_argv = (char **) xcalloc (sizeof (char *), num_lto_c_args);
       lto_c_ptr = CONST_CAST2 (const char **, char **, lto_c_argv);
 
       *lto_c_ptr++ = lto_wrapper;
+      *lto_c_ptr++ = c_file_name;
+
+      cp = opts;
+
+      while (cp && *cp)
+        {
+          const char *s = extract_string (&cp);
+
+         /* Pass the option or argument to the wrapper.  */
+         *lto_c_ptr++ = xstrdup (s);
+        }
+      obstack_free (&temporary_obstack, temporary_firstobj);
+
+      if (debug)
+       *lto_c_ptr++ = xstrdup ("-debug");
 
       /* Add LTO objects to the wrapper command line.  */
       for (list = lto_objects.first; list; list = list->next)
@@ -1207,7 +1246,7 @@ main (int argc, char **argv)
            use_verbose = true;
            lto_mode = LTO_MODE_LTO;
          }
-        else if (! strncmp (argv[i], "-fwhopr", 7) && ! use_plugin)
+        else if (! strcmp (argv[i], "-fwhopr") && ! use_plugin)
          {
            use_verbose = true;
            lto_mode = LTO_MODE_WHOPR;
@@ -1482,8 +1521,7 @@ main (int argc, char **argv)
              break;
 
             case 'f':
-             if (strcmp (arg, "-flto") == 0
-                 || strncmp (arg, "-fwhopr", 7) == 0)
+             if (strcmp (arg, "-flto") == 0 || strcmp (arg, "-fwhopr") == 0)
                {
 #ifdef ENABLE_LTO
                  /* Do not pass LTO flag to the linker. */
@@ -1779,7 +1817,7 @@ main (int argc, char **argv)
        if (export_file != 0 && export_file[0])
          maybe_unlink (export_file);
 #endif
-       if (lto_mode != LTO_MODE_NONE)
+       if (lto_mode)
          maybe_run_lto_and_relink (ld1_argv, object_lst, object, false);
 
        maybe_unlink (c_file);
@@ -2525,24 +2563,16 @@ write_aix_file (FILE *stream, struct id *list)
 \f
 #ifdef OBJECT_FORMAT_NONE
 
-/* Check to make sure the file is an LTO object file.  */
+/* Check to make sure the file is an ELF file.  LTO objects must
+   be in ELF format.  */
 
 static bool
-maybe_lto_object_file (const char *prog_name)
+is_elf_or_coff (const char *prog_name)
 {
   FILE *f;
-  unsigned char buf[4];
-  int i;
-
-  static unsigned char elfmagic[4] = { 0x7f, 'E', 'L', 'F' };
-  static unsigned char coffmagic[2] = { 0x4c, 0x01 };
-  static unsigned char coffmagic_x64[2] = { 0x64, 0x86 };
-  static unsigned char machomagic[4][4] = {
-    { 0xcf, 0xfa, 0xed, 0xfe },
-    { 0xce, 0xfa, 0xed, 0xfe },
-    { 0xfe, 0xed, 0xfa, 0xcf },
-    { 0xfe, 0xed, 0xfa, 0xce }
-  };
+  char buf[4];
+  static char magic[4] = { 0x7f, 'E', 'L', 'F' };
+  static char coffmag[2] = { 0x4c, 0x01 };
 
   f = fopen (prog_name, "rb");
   if (f == NULL)
@@ -2550,16 +2580,8 @@ maybe_lto_object_file (const char *prog_name)
   if (fread (buf, sizeof (buf), 1, f) != 1)
     buf[0] = 0;
   fclose (f);
-
-  if (memcmp (buf, elfmagic, sizeof (elfmagic)) == 0
-      || memcmp (buf, coffmagic, sizeof (coffmagic)) == 0
-      || memcmp (buf, coffmagic_x64, sizeof (coffmagic_x64)) == 0)
-    return true;
-  for (i = 0; i < 4; i++)
-    if (memcmp (buf, machomagic[i], sizeof (machomagic[i])) == 0)
-      return true;
-
-  return false;
+  return memcmp (buf, magic, sizeof (magic)) == 0
+       || memcmp (buf, coffmag, sizeof (coffmag)) == 0;
 }
 
 /* Generic version to scan the name list of the loaded program for
@@ -2589,7 +2611,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.  */
-  if (which_pass == PASS_LTOINFO && !maybe_lto_object_file (prog_name))
+  if (which_pass == PASS_LTOINFO && !is_elf_or_coff (prog_name))
     return;
 
   /* If we do not have an `nm', complain.  */