From 3fc95619f64d0e1424489936c6b1cf9cf33c5ddc Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 4 May 2007 19:20:28 +0000 Subject: [PATCH] crtstuff.c (HIDDEN_DTOR_LIST_END): New macro. * 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. Co-Authored-By: Jakub Jelinek From-SVN: r124444 --- gcc/ChangeLog | 8 ++++++++ gcc/crtstuff.c | 50 +++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 809f3c85442..fd08e9054ab 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2007-05-04 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. + 2007-05-04 Jakub Jelinek * varasm.c (align_variable): Don't increase alignment for diff --git a/gcc/crtstuff.c b/gcc/crtstuff.c index e847ad04760..fc57d45afc8 100644 --- a/gcc/crtstuff.c +++ b/gcc/crtstuff.c @@ -106,6 +106,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 +270,6 @@ extern void __cxa_finalize (void *) TARGET_ATTRIBUTE_WEAK; 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 +283,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 +492,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]