Patchwork PR debug/46749

login
register
mail settings
Submitter Mike Stump
Date Dec. 7, 2010, 5:16 p.m.
Message ID <78772AEA-A032-4018-9DA6-78EA50F7FE92@comcast.net>
Download mbox | patch
Permalink /patch/74584/
State New
Headers show

Comments

Mike Stump - Dec. 7, 2010, 5:16 p.m.
This fixes PR debug/46749, an LTO bug in debug information on darwin.  This bug comes about because darwin leaves the debug information in the .o files instead of copying that information into the a.out and lto removes temporary .o files by the time collect2 finishes running.  Before dsymutil was run after collect2 finished, which is now just too late.

I've tested x86_64-darwin10 with the C languages and fortran, and built a linux cross compiler.

I'll give people a chance to comment, but I was planning on checking this in soon.  Any objections?


2010-12-07  Mike Stump  <mikestump@comcast.net>

	PR debug/46749
	* config/darwin.h (COLLECT_RUN_DSYMUTIL): Add.
	(DSYMUTIL_SPEC): Use `linker' flags instead to handle lto better.
	* config/darwin9.h (COLLECT_RUN_DSYMUTIL): Add.
	(DSYMUTIL_SPEC): Use `linker' flags instead to handle lto better.
	* collect2.c (post_ld_pass): Add.
	(process_args): Add.
	(maybe_run_lto_and_relink): Call post_ld_pass after ld.
	(main): Likewise.  Call process_args.
2010-12-07  Mike Stump  <mikestump@comcast.net>

	PR debug/46749
	* config/darwin.h (COLLECT_RUN_DSYMUTIL): Add.
	(DSYMUTIL_SPEC): Use `linker' flags instead to handle lto better.
	* config/darwin9.h (COLLECT_RUN_DSYMUTIL): Add.
	(DSYMUTIL_SPEC): Use `linker' flags instead to handle lto better.
	* collect2.c (post_ld_pass): Add.
	(process_args): Add.
	(maybe_run_lto_and_relink): Call post_ld_pass after ld.
	(main): Likewise.  Call process_args.

Patch

Index: config/darwin.h
===================================================================
--- config/darwin.h	(revision 167507)
+++ config/darwin.h	(working copy)
@@ -188,11 +188,16 @@  extern GTY(()) int darwin_ms_struct;
 
 #define DSYMUTIL_SPEC \
    "%{!fdump=*:%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
+    %{v} \
+    %{gdwarf-2:%{!gstabs*:%{!g0: -idsym}}}\
     %{.c|.cc|.C|.cpp|.cp|.c++|.cxx|.CPP|.m|.mm: \
-    %{gdwarf-2:%{!gstabs*:%{!g0: " DSYMUTIL " %{o*:%*}%{!o:a.out}}}}}}}}}}}}"
+    %{gdwarf-2:%{!gstabs*:%{!g0: -dsym}}}}}}}}}}}"
 
 #define LINK_COMMAND_SPEC LINK_COMMAND_SPEC_A DSYMUTIL_SPEC
 
+/* Tell collet2 to run dsymutil for us as necessary.  */
+#define COLLECT_RUN_DSYMUTIL 1
+
 /* We only want one instance of %G, since libSystem (Darwin's -lc) does not depend
    on libgcc.  */
 #undef  LINK_GCC_C_SEQUENCE_SPEC
Index: config/darwin9.h
===================================================================
--- config/darwin9.h	(revision 167507)
+++ config/darwin9.h	(working copy)
@@ -27,9 +27,14 @@  along with GCC; see the file COPYING3.  If not see
 #undef DSYMUTIL_SPEC
 #define DSYMUTIL_SPEC \
    "%{!fdump=*:%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
+    %{v} \
+    %{g*:%{!gstabs*:%{!g0: -idsym}}}\
     %{.c|.cc|.C|.cpp|.cp|.c++|.cxx|.CPP|.m|.mm|.s: \
-    %{g*:%{!gstabs*:%{!g0: " DSYMUTIL " %{o*:%*}%{!o:a.out}}}}}}}}}}}}"
+    %{g*:%{!gstabs*:%{!g0: -dsym}}}}}}}}}}}"
 
+/* Tell collet2 to run dsymutil for us as necessary.  */
+#define COLLECT_RUN_DSYMUTIL 1
+
 /* libSystem contains unwind information for signal frames.  */
 #define DARWIN_LIBSYSTEM_HAS_UNWIND
 
Index: collect2.c
===================================================================
--- collect2.c	(revision 167507)
+++ collect2.c	(working copy)
@@ -333,6 +333,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 +1056,7 @@  maybe_run_lto_and_relink (char **lto_ld_argv, char
       /* 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 +1065,8 @@  maybe_run_lto_and_relink (char **lto_ld_argv, char
     {
       /* 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);
     }
 }
 
@@ -1151,6 +1155,8 @@  main (int argc, char **argv)
   if (argv != old_argv)
     at_file_supplied = 1;
 
+  process_args (&argc, argv);
+
   num_c_args = argc + 9;
 
   no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
@@ -1764,6 +1770,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);
@@ -1835,6 +1843,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;
@@ -1920,7 +1930,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.  */
@@ -3203,3 +3216,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