xref: /netbsd-src/external/gpl3/gcc.old/dist/libgcc/config/rs6000/cxa_finalize.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
1*8feb0f0bSmrg /* Copyright (C) 1999-2020 Free Software Foundation, Inc.
236ac495dSmrg 
336ac495dSmrg    NOTE: This source is derived from an old version taken from the GNU C
436ac495dSmrg    Library (glibc).
536ac495dSmrg 
636ac495dSmrg This file is part of GCC.
736ac495dSmrg 
836ac495dSmrg GCC is free software; you can redistribute it and/or modify it under
936ac495dSmrg the terms of the GNU General Public License as published by the Free
1036ac495dSmrg Software Foundation; either version 3, or (at your option) any later
1136ac495dSmrg version.
1236ac495dSmrg 
1336ac495dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1436ac495dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
1536ac495dSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1636ac495dSmrg for more details.
1736ac495dSmrg 
1836ac495dSmrg Under Section 7 of GPL version 3, you are granted additional
1936ac495dSmrg permissions described in the GCC Runtime Library Exception, version
2036ac495dSmrg 3.1, as published by the Free Software Foundation.
2136ac495dSmrg 
2236ac495dSmrg You should have received a copy of the GNU General Public License and
2336ac495dSmrg a copy of the GCC Runtime Library Exception along with this program;
2436ac495dSmrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2536ac495dSmrg <http://www.gnu.org/licenses/>.  */
2636ac495dSmrg 
2736ac495dSmrg #include <assert.h>
2836ac495dSmrg #include <stdlib.h>
2936ac495dSmrg #include "exit.h"
3036ac495dSmrg 
3136ac495dSmrg 
3236ac495dSmrg static boolean_t
catomic_compare_and_exchange_bool_acq(long * mem,long newval,long oldval)3336ac495dSmrg catomic_compare_and_exchange_bool_acq (long *mem, long newval, long oldval)
3436ac495dSmrg {
3536ac495dSmrg   return ! __atomic_compare_exchange (mem, &oldval, &newval, 0,
3636ac495dSmrg 				      __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
3736ac495dSmrg }
3836ac495dSmrg 
3936ac495dSmrg /* If D is non-NULL, call all functions registered with `__cxa_atexit'
4036ac495dSmrg    with the same dso handle.  Otherwise, if D is NULL, call all of the
4136ac495dSmrg    registered handlers.  */
4236ac495dSmrg void
__cxa_finalize(void * d)4336ac495dSmrg __cxa_finalize (void *d)
4436ac495dSmrg {
4536ac495dSmrg   struct exit_function_list *funcs;
4636ac495dSmrg 
4736ac495dSmrg  restart:
4836ac495dSmrg   for (funcs = __exit_funcs; funcs; funcs = funcs->next)
4936ac495dSmrg     {
5036ac495dSmrg       struct exit_function *f;
5136ac495dSmrg 
5236ac495dSmrg       for (f = &funcs->fns[funcs->idx - 1]; f >= &funcs->fns[0]; --f)
5336ac495dSmrg 	{
5436ac495dSmrg 	  void (*cxafn) (void *arg, int status);
5536ac495dSmrg 	  void *cxaarg;
5636ac495dSmrg 
5736ac495dSmrg 	  if ((d == NULL || d == f->func.cxa.dso_handle)
5836ac495dSmrg 	      /* We don't want to run this cleanup more than once.  */
5936ac495dSmrg 	      && (cxafn = f->func.cxa.fn,
6036ac495dSmrg 		  cxaarg = f->func.cxa.arg,
6136ac495dSmrg 		  ! catomic_compare_and_exchange_bool_acq (&f->flavor, ef_free,
6236ac495dSmrg 							   ef_cxa)))
6336ac495dSmrg 	    {
6436ac495dSmrg 	      uint64_t check = __new_exitfn_called;
6536ac495dSmrg 
6636ac495dSmrg #ifdef PTR_DEMANGLE
6736ac495dSmrg 	      PTR_DEMANGLE (cxafn);
6836ac495dSmrg #endif
6936ac495dSmrg 	      cxafn (cxaarg, 0);
7036ac495dSmrg 
7136ac495dSmrg 	      /* It is possible that that last exit function registered
7236ac495dSmrg 		 more exit functions.  Start the loop over.  */
7336ac495dSmrg 	      if (__builtin_expect (check != __new_exitfn_called, 0))
7436ac495dSmrg 		goto restart;
7536ac495dSmrg 	    }
7636ac495dSmrg 	}
7736ac495dSmrg     }
7836ac495dSmrg 
7936ac495dSmrg   /* Remove the registered fork handlers.  We do not have to
8036ac495dSmrg      unregister anything if the program is going to terminate anyway.  */
8136ac495dSmrg #ifdef UNREGISTER_ATFORK
8236ac495dSmrg   if (d != NULL)
8336ac495dSmrg     UNREGISTER_ATFORK (d);
8436ac495dSmrg #endif
8536ac495dSmrg }
86