diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-05-04 19:20:28 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-05-04 19:20:28 +0000 |
commit | f9e6c0d4c699dd789d0b6a3aec31e163824ea2e4 (patch) | |
tree | c944a3efeda877a1fae18ad5d3e9fb158bc98ab0 /gcc/crtstuff.c | |
parent | f86a5520bcdd33dc16b789c2882c606c6e920cfb (diff) | |
download | gcc-f9e6c0d4c699dd789d0b6a3aec31e163824ea2e4.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124444 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/crtstuff.c')
-rw-r--r-- | gcc/crtstuff.c | 50 |
1 files changed, 41 insertions, 9 deletions
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] |