OSDN Git Service

crtstuff: adjust tm clones for no attribute hidden
[pf3gnuchains/gcc-fork.git] / libgcc / crtstuff.c
index 66b2cdf..77b8d42 100644 (file)
@@ -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--)