Description:
 * This patch fixes the crash issues faced when using -static-libgcc & 
-static-libgo on AIX
    On AIX, do not call shared library initializers when linking statically.
    This fixes a bug where frame tables are registered twice at runtime, one 
time by the shared library initializer and one time by the main program 
initializer, because when linking statically frame tables from the shared 
library end up in the main program after the first collect2 pass. This breaks 
_Unwind_Find_FDE’s non-overlapping objects assumption.

Tests:
 * AIX: Build: SUCCESS
   - build made by means of gmake in trunk.
   - patch generated by: 
        cd gcc-svn-trunk/
        svn diff gcc/ChangeLog gcc/collect2.c 

ChangeLog:
   +       gcc/collect2.c: manage static link
   +       gcc/ChangeLog: Description
   

Regards,

Tony Reix


ATOS / Bull SAS
ATOS Expert
IBM Coop Architect & Technical Leader

Office : +33 (0) 4 76 29 72 67
1 rue de Provence - 38432 Échirolles - France
www.atos.net

--- ./gcc/ChangeLog	(revision 261620)
+++ ./gcc/ChangeLog	(working copy)
@@ -1,3 +1,13 @@
+2018-06-15  Tony Reix  <tony.r...@atos.net>
+
+	* collect2.c: On AIX, do not call shared library initializers
+	when linking statically.  This fixes a bug where frame tables
+	are registered twice at runtime, one time by the shared library
+	initializer and one time by the main program initializer,
+	because when linking statically frame tables from the shared
+	library end up in the main program after the first collect2 pass.
+	This breaks _Unwind_Find_FDE's non-overlapping objects assumption.
+
 2018-06-15  Richard Biener  <rguent...@suse.de>
 
 	PR middle-end/86076
--- ./gcc/collect2.c	(revision 261597)
+++ ./gcc/collect2.c	(working copy)
@@ -201,6 +201,7 @@ static enum lto_mode_d lto_mode = LTO_MODE_NONE;
 bool helpflag;			/* true if --help */
 
 static int shared_obj;			/* true if -shared */
+static int static_obj;			/* true if -static */
 
 static const char *c_file;		/* <xxx>.c for constructor/destructor list.  */
 static const char *o_file;		/* <xxx>.o for constructor/destructor list.  */
@@ -255,6 +256,7 @@ bool may_unlink_output_file = false;
 #ifdef COLLECT_EXPORT_LIST
 /* Lists to keep libraries to be scanned for global constructors/destructors.  */
 static struct head libs;                    /* list of libraries */
+static struct head static_libs;             /* list of statically linked libraries */
 static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
 static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
 static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
@@ -320,9 +322,7 @@ static void write_c_file_glob (FILE *, const char
 static void scan_libraries (const char *);
 #endif
 #ifdef COLLECT_EXPORT_LIST
-#if 0
 static int is_in_list (const char *, struct id *);
-#endif
 static void write_aix_file (FILE *, struct id *);
 static char *resolve_lib_name (const char *);
 #endif
@@ -911,6 +911,7 @@ main (int argc, char **argv)
   int first_file;
   int num_c_args;
   char **old_argv;
+  bool is_static = false;
   int i;
 
   for (i = 0; i < USE_LD_MAX; i++)
@@ -1241,6 +1242,8 @@ main (int argc, char **argv)
 	*c_ptr++ = xstrdup (q);
       if (strcmp (q, "-shared") == 0)
 	shared_obj = 1;
+      if (strcmp (q, "-static") == 0)
+	static_obj = 1;
       if (*q == '-' && q[1] == 'B')
 	{
 	  *c_ptr++ = xstrdup (q);
@@ -1269,6 +1272,7 @@ main (int argc, char **argv)
   /* Parse arguments.  Remember output file spec, pass the rest to ld.  */
   /* After the first file, put in the c++ rt0.  */
 
+  is_static = static_obj;
   first_file = 1;
   while ((arg = *++argv) != (char *) 0)
     {
@@ -1374,6 +1378,14 @@ main (int argc, char **argv)
 #endif
               break;
 
+#ifdef COLLECT_EXPORT_LIST
+	    case 'b':
+	      if (!strcmp (arg, "-bstatic"))
+		is_static = true;
+	      else if (!strcmp (arg, "-bdynamic") || !strcmp (arg, "-bshared"))
+		is_static = false;
+	      break;
+#endif
 	    case 'l':
 	      if (first_file)
 		{
@@ -1390,6 +1402,8 @@ main (int argc, char **argv)
 
 		/* Saving a full library name.  */
 		add_to_list (&libs, s);
+		if (is_static)
+		    add_to_list (&static_libs, s);
 	      }
 #endif
 	      break;
@@ -1490,6 +1504,8 @@ main (int argc, char **argv)
 	    {
 	      /* Saving a full library name.  */
 	      add_to_list (&libs, arg);
+	      if (is_static)
+		add_to_list (&static_libs, arg);
 	    }
 #endif
 	}
@@ -1501,6 +1517,8 @@ main (int argc, char **argv)
     {
       fprintf (stderr, "List of libraries:\n");
       dump_list (stderr, "\t", libs.first);
+      fprintf (stderr, "List of statically linked libraries:\n");
+      dump_list (stderr, "\t", static_libs.first);
     }
 
   /* The AIX linker will discard static constructors in object files if
@@ -1525,9 +1543,11 @@ main (int argc, char **argv)
       this_filter &= ~SCAN_DWEH;
 #endif
 
+    /* Scan object files.  */
     while (export_object_lst < object)
       scan_prog_file (*export_object_lst++, PASS_OBJ, this_filter);
 
+    /* Scan libraries.  */
     for (; list; list = list->next)
       scan_prog_file (list->name, PASS_FIRST, this_filter);
 
@@ -1975,7 +1995,6 @@ write_list (FILE *stream, const char *prefix, stru
 
 #ifdef COLLECT_EXPORT_LIST
 /* This function is really used only on AIX, but may be useful.  */
-#if 0
 static int
 is_in_list (const char *prefix, struct id *list)
 {
@@ -1986,7 +2005,6 @@ is_in_list (const char *prefix, struct id *list)
     }
     return 0;
 }
-#endif
 #endif /* COLLECT_EXPORT_LIST */
 
 /* Added for debugging purpose.  */
@@ -2818,7 +2836,8 @@ scan_prog_file (const char *prog_name, scanpass wh
 			case SYM_AIXI:
 			  if (! (filter & SCAN_CTOR))
 			    break;
-			  if (is_shared && !aixlazy_flag)
+			  if (is_shared && !aixlazy_flag && !static_obj
+			      && ! is_in_list (prog_name, static_libs.first))
 			    add_to_list (&constructors, name);
 			  break;
 

Reply via email to