This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[lto][patch] Temporary fix for undefined symbols when linking with archives containing LTO objects


Collect2 is scanning all the input files with nm, which scans archives
as well as regular objects. For any archive libraries that do contain
LTO symbols, collect2 counts them as LTO files and passes them to WPA,
then *leaves them out* of the final link (assuming that WPA has
replaced them with real .o files). I've added a quick check in
scan_prog_file to make sure that the file is ELF before counting it as
an LTO object.

A more ambitious fix would be to unpack the archive and send the
member .o files to WPA, but that can come later if we deem it
necessary for collect2 to handle that case. As I understand it, it was
a deliberate decision to restrict collect2 to regular objects,
assuming that the linker plugin will take care of it eventually.

-cary


2008-11-26  Cary Coutant  <ccoutant@google.com>

	* collect2.c (is_elf): New function.
	(scan_prog_file): Require LTO object to be in ELF format.


Index: collect2.c
===================================================================
--- collect2.c	(revision 142225)
+++ collect2.c	(working copy)
@@ -308,6 +308,9 @@ static void write_c_file_stat (FILE *, c
 #ifndef LD_INIT_SWITCH
 static void write_c_file_glob (FILE *, const char *);
 #endif
+#ifdef OBJECT_FORMAT_NONE
+static bool is_elf (const char *);
+#endif
 static void scan_prog_file (const char *, enum pass);
 #ifdef SCAN_LIBRARIES
 static void scan_libraries (const char *);
@@ -2455,6 +2458,25 @@ write_aix_file (FILE *stream, struct id
 
 #ifdef OBJECT_FORMAT_NONE

+/* Check to make sure the file is an ELF file.  LTO objects must
+   be in the ELF format for now.  */
+
+static bool
+is_elf (const char *prog_name)
+{
+  FILE *f;
+  char buf[4];
+  static char magic[4] = { 0x7f, 'E', 'L', 'F' };
+
+  f = fopen (prog_name, "r");
+  if (f == NULL)
+    return false;
+  if (fread (buf, sizeof(buf), 1, f) != 1)
+    buf[0] = 0;
+  fclose (f);
+  return memcmp (buf, magic, sizeof(magic)) == 0;
+}
+
 /* Generic version to scan the name list of the loaded program for
    the symbols g++ uses for static constructors and destructors.

@@ -2484,6 +2506,12 @@ scan_prog_file (const char *prog_name, e
   if (which_pass == PASS_SECOND)
     return;

+  /* LTO objects must be in ELF format.  This check prevents
+     us from accepting an archive containing LTO objects, which
+     gcc cannnot currently handle.  */
+  if (which_pass == PASS_LTOINFO && !is_elf (prog_name))
+    return;
+
   /* If we do not have an `nm', complain.  */
   if (nm_file_name == 0)
     fatal ("cannot find 'nm'");


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]