Blame SOURCES/gcc8-pr60790.patch

0e3697
	PR libgcc/60790
0e3697
	x86: Do not assume ELF constructors run before IFUNC resolvers.
0e3697
	* config/x86/host-config.h (libat_feat1_ecx, libat_feat1_edx):
0e3697
	Remove declarations.
0e3697
	(__libat_feat1, __libat_feat1_init): Declare.
0e3697
	(FEAT1_REGISTER): Define.
0e3697
	(load_feat1): New function.
0e3697
	(IFUNC_COND_1): Adjust.
0e3697
	* config/x86/init.c (libat_feat1_ecx, libat_feat1_edx)
0e3697
	(init_cpuid): Remove definitions.
0e3697
	(__libat_feat1): New variable.
0e3697
	(__libat_feat1_init): New function.
0e3697
0e3697
--- libatomic/config/x86/host-config.h	(revision 264990)
0e3697
+++ libatomic/config/x86/host-config.h	(working copy)
0e3697
@@ -25,13 +25,39 @@
0e3697
 #if HAVE_IFUNC
0e3697
 #include <cpuid.h>
0e3697
 
0e3697
-extern unsigned int libat_feat1_ecx HIDDEN;
0e3697
-extern unsigned int libat_feat1_edx HIDDEN;
0e3697
+#ifdef __x86_64__
0e3697
+# define FEAT1_REGISTER ecx
0e3697
+#else
0e3697
+# define FEAT1_REGISTER edx
0e3697
+#endif
0e3697
 
0e3697
+/* Value of the CPUID feature register FEAT1_REGISTER for the cmpxchg
0e3697
+   bit for IFUNC_COND1 below.  */
0e3697
+extern unsigned int __libat_feat1 HIDDEN;
0e3697
+
0e3697
+/* Initialize libat_feat1 and return its value.  */
0e3697
+unsigned int __libat_feat1_init (void) HIDDEN;
0e3697
+
0e3697
+/* Return the value of the relevant feature register for the relevant
0e3697
+   cmpxchg bit, or 0 if there is no CPUID support.  */
0e3697
+static inline unsigned int
0e3697
+__attribute__ ((const))
0e3697
+load_feat1 (void)
0e3697
+{
0e3697
+  /* See the store in __libat_feat1_init.  */
0e3697
+  unsigned int feat1 = __atomic_load_n (&__libat_feat1, __ATOMIC_RELAXED);
0e3697
+  if (feat1 == 0)
0e3697
+    /* Assume that initialization has not happened yet.  This may get
0e3697
+       called repeatedly if the CPU does not have any feature bits at
0e3697
+       all.  */
0e3697
+    feat1 = __libat_feat1_init ();
0e3697
+  return feat1;
0e3697
+}
0e3697
+
0e3697
 #ifdef __x86_64__
0e3697
-# define IFUNC_COND_1	(libat_feat1_ecx & bit_CMPXCHG16B)
0e3697
+# define IFUNC_COND_1	(load_feat1 () & bit_CMPXCHG16B)
0e3697
 #else
0e3697
-# define IFUNC_COND_1	(libat_feat1_edx & bit_CMPXCHG8B)
0e3697
+# define IFUNC_COND_1	(load_feat1 () & bit_CMPXCHG8B)
0e3697
 #endif
0e3697
 
0e3697
 #ifdef __x86_64__
0e3697
--- libatomic/config/x86/init.c	(revision 264990)
0e3697
+++ libatomic/config/x86/init.c	(working copy)
0e3697
@@ -26,13 +26,17 @@
0e3697
 
0e3697
 #if HAVE_IFUNC
0e3697
 
0e3697
-unsigned int libat_feat1_ecx, libat_feat1_edx;
0e3697
+unsigned int __libat_feat1;
0e3697
 
0e3697
-static void __attribute__((constructor))
0e3697
-init_cpuid (void)
0e3697
+unsigned int
0e3697
+__libat_feat1_init (void)
0e3697
 {
0e3697
-  unsigned int eax, ebx;
0e3697
-  __get_cpuid (1, &eax, &ebx, &libat_feat1_ecx, &libat_feat1_edx);
0e3697
+  unsigned int eax, ebx, ecx, edx;
0e3697
+  FEAT1_REGISTER = 0;
0e3697
+  __get_cpuid (1, &eax, &ebx, &ecx, &edx;;
0e3697
+  /* See the load in load_feat1.  */
0e3697
+  __atomic_store_n (&__libat_feat1, FEAT1_REGISTER, __ATOMIC_RELAXED);
0e3697
+  return FEAT1_REGISTER;
0e3697
 }
0e3697
 
0e3697
 #endif /* HAVE_IFUNC */