diff options
Diffstat (limited to 'libgcc/crtstuff.c')
-rw-r--r-- | libgcc/crtstuff.c | 104 |
1 files changed, 99 insertions, 5 deletions
diff --git a/libgcc/crtstuff.c b/libgcc/crtstuff.c index 66b2cdf2446..77b8d4201cd 100644 --- a/libgcc/crtstuff.c +++ b/libgcc/crtstuff.c @@ -127,6 +127,10 @@ call_ ## FUNC (void) \ # define HIDDEN_DTOR_LIST_END #endif +#if !defined(USE_TM_CLONE_REGISTRY) && defined(OBJECT_FORMAT_ELF) +# define USE_TM_CLONE_REGISTRY 1 +#endif + /* We do not want to add the weak attribute to the declarations of these routines in unwind-dw2-fde.h because that will cause the definition of these symbols to be weak as well. @@ -163,6 +167,10 @@ extern void __do_global_ctors_1 (void); /* Likewise for _Jv_RegisterClasses. */ extern void _Jv_RegisterClasses (void *) TARGET_ATTRIBUTE_WEAK; +/* Likewise for transactional memory clone tables. */ +extern void _ITM_registerTMCloneTable (void *, size_t) TARGET_ATTRIBUTE_WEAK; +extern void _ITM_deregisterTMCloneTable (void *) TARGET_ATTRIBUTE_WEAK; + #ifdef OBJECT_FORMAT_ELF /* Declare a pointer to void function type. */ @@ -242,6 +250,55 @@ STATIC void *__JCR_LIST__[] = { }; #endif /* JCR_SECTION_NAME */ +#if USE_TM_CLONE_REGISTRY +STATIC func_ptr __TMC_LIST__[] + __attribute__((used, section(".tm_clone_table"), aligned(sizeof(void*)))) + = { }; +# ifdef HAVE_GAS_HIDDEN +extern func_ptr __TMC_END__[] __attribute__((__visibility__ ("hidden"))); +# endif + +static inline void +deregister_tm_clones (void) +{ + void (*fn) (void *); + +#ifdef HAVE_GAS_HIDDEN + if (__TMC_END__ - __TMC_LIST__ == 0) + return; +#else + if (__TMC_LIST__[0] == NULL) + return; +#endif + + fn = _ITM_deregisterTMCloneTable; + __asm ("" : "+r" (fn)); + if (fn) + fn (__TMC_LIST__); +} + +static inline void +register_tm_clones (void) +{ + void (*fn) (void *, size_t); + size_t size; + +#ifdef HAVE_GAS_HIDDEN + size = (__TMC_END__ - __TMC_LIST__) / 2; +#else + for (size = 0; __TMC_LIST__[size * 2] != NULL; size++) + continue; +#endif + if (size == 0) + return; + + fn = _ITM_registerTMCloneTable; + __asm ("" : "+r" (fn)); + if (fn) + fn (__TMC_LIST__, size); +} +#endif /* USE_TM_CLONE_REGISTRY */ + #if defined(INIT_SECTION_ASM_OP) || defined(INIT_ARRAY_SECTION_ASM_OP) #ifdef OBJECT_FORMAT_ELF @@ -331,6 +388,10 @@ __do_global_dtors_aux (void) } #endif /* !defined(FINI_ARRAY_SECTION_ASM_OP) */ +#if USE_TM_CLONE_REGISTRY + deregister_tm_clones (); +#endif /* USE_TM_CLONE_REGISTRY */ + #ifdef USE_EH_FRAME_REGISTRY #ifdef CRT_GET_RFIB_DATA /* If we used the new __register_frame_info_bases interface, @@ -362,7 +423,9 @@ __do_global_dtors_aux_1 (void) CRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, __do_global_dtors_aux_1) #endif -#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME) +#if defined(USE_EH_FRAME_REGISTRY) \ + || defined(JCR_SECTION_NAME) \ + || defined(USE_TM_CLONE_REGISTRY) /* Stick a call to __register_frame_info into the .init section. For some reason calls with no arguments work more reliably in .init, so stick the call in another function. */ @@ -383,6 +446,7 @@ frame_dummy (void) __register_frame_info (__EH_FRAME_BEGIN__, &object); #endif /* CRT_GET_RFIB_DATA */ #endif /* USE_EH_FRAME_REGISTRY */ + #ifdef JCR_SECTION_NAME if (__JCR_LIST__[0]) { @@ -392,6 +456,10 @@ frame_dummy (void) register_classes (__JCR_LIST__); } #endif /* JCR_SECTION_NAME */ + +#if USE_TM_CLONE_REGISTRY + register_tm_clones (); +#endif /* USE_TM_CLONE_REGISTRY */ } #ifdef INIT_SECTION_ASM_OP @@ -401,7 +469,7 @@ static func_ptr __frame_dummy_init_array_entry[] __attribute__ ((__used__, section(".init_array"))) = { frame_dummy }; #endif /* !defined(INIT_SECTION_ASM_OP) */ -#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */ +#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME || USE_TM_CLONE_REGISTRY */ #else /* OBJECT_FORMAT_ELF */ @@ -458,13 +526,19 @@ __do_global_dtors (void) for (p = __DTOR_LIST__ + 1; (f = *p); p++) f (); +#if USE_TM_CLONE_REGISTRY + deregister_tm_clones (); +#endif /* USE_TM_CLONE_REGISTRY */ + #ifdef USE_EH_FRAME_REGISTRY if (__deregister_frame_info) __deregister_frame_info (__EH_FRAME_BEGIN__); #endif } -#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME) +#if defined(USE_EH_FRAME_REGISTRY) \ + || defined(JCR_SECTION_NAME) \ + || defined(USE_TM_CLONE_REGISTRY) /* A helper function for __do_global_ctors, which is in crtend.o. Here in crtbegin.o, we can reference a couple of symbols not visible there. Plus, since we're before libgcc.a, we have no problems referencing @@ -477,6 +551,7 @@ __do_global_ctors_1(void) if (__register_frame_info) __register_frame_info (__EH_FRAME_BEGIN__, &object); #endif + #ifdef JCR_SECTION_NAME if (__JCR_LIST__[0]) { @@ -486,8 +561,12 @@ __do_global_ctors_1(void) register_classes (__JCR_LIST__); } #endif + +#if USE_TM_CLONE_REGISTRY + register_tm_clones (); +#endif /* USE_TM_CLONE_REGISTRY */ } -#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME */ +#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME || USE_TM_CLONE_REGISTRY */ #else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */ #error "What are you doing with crtstuff.c, then?" @@ -571,6 +650,19 @@ STATIC void *__JCR_END__[1] = { 0 }; #endif /* JCR_SECTION_NAME */ +#if USE_TM_CLONE_REGISTRY +# ifndef HAVE_GAS_HIDDEN +static +# endif +func_ptr __TMC_END__[] + __attribute__((used, section(".tm_clone_table"), aligned(sizeof(void *)))) +# ifdef HAVE_GAS_HIDDEN + __attribute__((__visibility__ ("hidden"))) = { }; +# else + = { 0, 0 }; +# endif +#endif /* USE_TM_CLONE_REGISTRY */ + #ifdef INIT_ARRAY_SECTION_ASM_OP /* If we are using .init_array, there is nothing to do. */ @@ -635,7 +727,9 @@ void __do_global_ctors (void) { func_ptr *p; -#if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME) +#if defined(USE_EH_FRAME_REGISTRY) \ + || defined(JCR_SECTION_NAME) \ + || defined(USE_TM_CLONE_REGISTRY) __do_global_ctors_1(); #endif for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) |