x86: libatomic: Do not assume ELF constructors run before IFUNC resolvers
PR libgcc/60790 x86: Do not assume ELF constructors run before IFUNC resolvers. * config/x86/host-config.h (libat_feat1_ecx, libat_feat1_edx): Remove declarations. (__libat_feat1, __libat_feat1_init): Declare. (FEAT1_REGISTER): Define. (load_feat1): New function. (IFUNC_COND_1): Adjust. * config/x86/init.c (libat_feat1_ecx, libat_feat1_edx) (init_cpuid): Remove definitions. (__libat_feat1): New variable. (__libat_feat1_init): New function. From-SVN: r260603
This commit is contained in:
parent
159440699b
commit
cb3c90cc42
@ -1,3 +1,18 @@
|
||||
2018-05-23 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
PR libgcc/60790
|
||||
x86: Do not assume ELF constructors run before IFUNC resolvers.
|
||||
* config/x86/host-config.h (libat_feat1_ecx, libat_feat1_edx):
|
||||
Remove declarations.
|
||||
(__libat_feat1, __libat_feat1_init): Declare.
|
||||
(FEAT1_REGISTER): Define.
|
||||
(load_feat1): New function.
|
||||
(IFUNC_COND_1): Adjust.
|
||||
* config/x86/init.c (libat_feat1_ecx, libat_feat1_edx)
|
||||
(init_cpuid): Remove definitions.
|
||||
(__libat_feat1): New variable.
|
||||
(__libat_feat1_init): New function.
|
||||
|
||||
2018-05-02 Tom de Vries <tom@codesourcery.com>
|
||||
|
||||
PR testsuite/85106
|
||||
|
@ -25,13 +25,39 @@
|
||||
#if HAVE_IFUNC
|
||||
#include <cpuid.h>
|
||||
|
||||
extern unsigned int libat_feat1_ecx HIDDEN;
|
||||
extern unsigned int libat_feat1_edx HIDDEN;
|
||||
#ifdef __x86_64__
|
||||
# define FEAT1_REGISTER ecx
|
||||
#else
|
||||
# define FEAT1_REGISTER edx
|
||||
#endif
|
||||
|
||||
/* Value of the CPUID feature register FEAT1_REGISTER for the cmpxchg
|
||||
bit for IFUNC_COND1 below. */
|
||||
extern unsigned int __libat_feat1 HIDDEN;
|
||||
|
||||
/* Initialize libat_feat1 and return its value. */
|
||||
unsigned int __libat_feat1_init (void) HIDDEN;
|
||||
|
||||
/* Return the value of the relevant feature register for the relevant
|
||||
cmpxchg bit, or 0 if there is no CPUID support. */
|
||||
static inline unsigned int
|
||||
__attribute__ ((const))
|
||||
load_feat1 (void)
|
||||
{
|
||||
/* See the store in __libat_feat1_init. */
|
||||
unsigned int feat1 = __atomic_load_n (&__libat_feat1, __ATOMIC_RELAXED);
|
||||
if (feat1 == 0)
|
||||
/* Assume that initialization has not happened yet. This may get
|
||||
called repeatedly if the CPU does not have any feature bits at
|
||||
all. */
|
||||
feat1 = __libat_feat1_init ();
|
||||
return feat1;
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
# define IFUNC_COND_1 (libat_feat1_ecx & bit_CMPXCHG16B)
|
||||
# define IFUNC_COND_1 (load_feat1 () & bit_CMPXCHG16B)
|
||||
#else
|
||||
# define IFUNC_COND_1 (libat_feat1_edx & bit_CMPXCHG8B)
|
||||
# define IFUNC_COND_1 (load_feat1 () & bit_CMPXCHG8B)
|
||||
#endif
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
@ -26,13 +26,17 @@
|
||||
|
||||
#if HAVE_IFUNC
|
||||
|
||||
unsigned int libat_feat1_ecx, libat_feat1_edx;
|
||||
unsigned int __libat_feat1;
|
||||
|
||||
static void __attribute__((constructor))
|
||||
init_cpuid (void)
|
||||
unsigned int
|
||||
__libat_feat1_init (void)
|
||||
{
|
||||
unsigned int eax, ebx;
|
||||
__get_cpuid (1, &eax, &ebx, &libat_feat1_ecx, &libat_feat1_edx);
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
FEAT1_REGISTER = 0;
|
||||
__get_cpuid (1, &eax, &ebx, &ecx, &edx);
|
||||
/* See the load in load_feat1. */
|
||||
__atomic_store_n (&__libat_feat1, FEAT1_REGISTER, __ATOMIC_RELAXED);
|
||||
return FEAT1_REGISTER;
|
||||
}
|
||||
|
||||
#endif /* HAVE_IFUNC */
|
||||
|
Loading…
Reference in New Issue
Block a user