2007-05-03 Ulrich Drepper Jakub Jelinek * crtstuff.c (HIDDEN_DTOR_LIST_END): New macro. (__do_global_dtors_aux): Use more paranoid loop to run destructors if HIDDEN_DTOR_LIST_END. (__DTOR_END__): Export as a hidden symbol when HIDDEN_DTOR_LIST_END. --- gcc/crtstuff.c.jj 2007-01-24 22:24:21.000000000 +0100 +++ gcc/crtstuff.c 2007-05-03 10:40:29.000000000 +0200 @@ -106,6 +107,11 @@ call_ ## FUNC (void) \ # define EH_FRAME_SECTION_CONST #endif +#if !defined(DTOR_LIST_END) && defined(OBJECT_FORMAT_ELF) \ + && defined(HAVE_GAS_HIDDEN) && !defined(FINI_ARRAY_SECTION_ASM_OP) +# define HIDDEN_DTOR_LIST_END +#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. @@ -265,10 +271,6 @@ extern void __cxa_finalize (void *) TARG static void __attribute__((used)) __do_global_dtors_aux (void) { -#ifndef FINI_ARRAY_SECTION_ASM_OP - static func_ptr *p = __DTOR_LIST__ + 1; - func_ptr f; -#endif /* !defined(FINI_ARRAY_SECTION_ASM_OP) */ static _Bool completed; if (__builtin_expect (completed, 0)) @@ -282,12 +284,32 @@ __do_global_dtors_aux (void) #ifdef FINI_ARRAY_SECTION_ASM_OP /* If we are using .fini_array then destructors will be run via that mechanism. */ +#elif defined(HIDDEN_DTOR_LIST_END) + { + /* Safer version that makes sure only .dtors function pointers are + called even if the static variable is maliciously changed. */ + extern func_ptr __DTOR_END__[] __attribute__((visibility ("hidden"))); + static size_t dtor_idx; + const size_t max_idx = __DTOR_END__ - __DTOR_LIST__ - 1; + func_ptr f; + + while (dtor_idx < max_idx) + { + f = __DTOR_LIST__[++dtor_idx]; + f (); + } + } #else /* !defined (FINI_ARRAY_SECTION_ASM_OP) */ - while ((f = *p)) - { - p++; - f (); - } + { + static func_ptr *p = __DTOR_LIST__ + 1; + func_ptr f; + + while ((f = *p)) + { + p++; + f (); + } + } #endif /* !defined(FINI_ARRAY_SECTION_ASM_OP) */ #ifdef USE_EH_FRAME_REGISTRY @@ -471,6 +493,17 @@ STATIC func_ptr __CTOR_END__[1] #ifdef DTOR_LIST_END DTOR_LIST_END; +#elif defined(HIDDEN_DTOR_LIST_END) +#ifdef DTORS_SECTION_ASM_OP +asm (DTORS_SECTION_ASM_OP); +#endif +func_ptr __DTOR_END__[1] + __attribute__ ((unused, +#ifndef DTORS_SECTION_ASM_OP + section(".dtors"), +#endif + aligned(sizeof(func_ptr)), visibility ("hidden"))) + = { (func_ptr) 0 }; #elif defined(DTORS_SECTION_ASM_OP) asm (DTORS_SECTION_ASM_OP); STATIC func_ptr __DTOR_END__[1]