xref: /netbsd-src/external/gpl3/gcc/dist/libgcc/config/rs6000/cxa_finalize.c (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1*b1e83836Smrg /* Copyright (C) 1999-2022 Free Software Foundation, Inc.
248fb7bfaSmrg 
348fb7bfaSmrg    NOTE: This source is derived from an old version taken from the GNU C
448fb7bfaSmrg    Library (glibc).
548fb7bfaSmrg 
648fb7bfaSmrg This file is part of GCC.
748fb7bfaSmrg 
848fb7bfaSmrg GCC is free software; you can redistribute it and/or modify it under
948fb7bfaSmrg the terms of the GNU General Public License as published by the Free
1048fb7bfaSmrg Software Foundation; either version 3, or (at your option) any later
1148fb7bfaSmrg version.
1248fb7bfaSmrg 
1348fb7bfaSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1448fb7bfaSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
1548fb7bfaSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1648fb7bfaSmrg for more details.
1748fb7bfaSmrg 
1848fb7bfaSmrg Under Section 7 of GPL version 3, you are granted additional
1948fb7bfaSmrg permissions described in the GCC Runtime Library Exception, version
2048fb7bfaSmrg 3.1, as published by the Free Software Foundation.
2148fb7bfaSmrg 
2248fb7bfaSmrg You should have received a copy of the GNU General Public License and
2348fb7bfaSmrg a copy of the GCC Runtime Library Exception along with this program;
2448fb7bfaSmrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2548fb7bfaSmrg <http://www.gnu.org/licenses/>.  */
2648fb7bfaSmrg 
2748fb7bfaSmrg #include <assert.h>
2848fb7bfaSmrg #include <stdlib.h>
2948fb7bfaSmrg #include "exit.h"
3048fb7bfaSmrg 
3148fb7bfaSmrg 
3248fb7bfaSmrg static boolean_t
catomic_compare_and_exchange_bool_acq(long * mem,long newval,long oldval)3348fb7bfaSmrg catomic_compare_and_exchange_bool_acq (long *mem, long newval, long oldval)
3448fb7bfaSmrg {
354d5abbe8Smrg   return ! __atomic_compare_exchange (mem, &oldval, &newval, 0,
3648fb7bfaSmrg 				      __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
3748fb7bfaSmrg }
3848fb7bfaSmrg 
3948fb7bfaSmrg /* If D is non-NULL, call all functions registered with `__cxa_atexit'
4048fb7bfaSmrg    with the same dso handle.  Otherwise, if D is NULL, call all of the
4148fb7bfaSmrg    registered handlers.  */
4248fb7bfaSmrg void
__cxa_finalize(void * d)4348fb7bfaSmrg __cxa_finalize (void *d)
4448fb7bfaSmrg {
4548fb7bfaSmrg   struct exit_function_list *funcs;
4648fb7bfaSmrg 
4748fb7bfaSmrg  restart:
4848fb7bfaSmrg   for (funcs = __exit_funcs; funcs; funcs = funcs->next)
4948fb7bfaSmrg     {
5048fb7bfaSmrg       struct exit_function *f;
5148fb7bfaSmrg 
5248fb7bfaSmrg       for (f = &funcs->fns[funcs->idx - 1]; f >= &funcs->fns[0]; --f)
5348fb7bfaSmrg 	{
5448fb7bfaSmrg 	  void (*cxafn) (void *arg, int status);
5548fb7bfaSmrg 	  void *cxaarg;
5648fb7bfaSmrg 
5748fb7bfaSmrg 	  if ((d == NULL || d == f->func.cxa.dso_handle)
5848fb7bfaSmrg 	      /* We don't want to run this cleanup more than once.  */
5948fb7bfaSmrg 	      && (cxafn = f->func.cxa.fn,
6048fb7bfaSmrg 		  cxaarg = f->func.cxa.arg,
6148fb7bfaSmrg 		  ! catomic_compare_and_exchange_bool_acq (&f->flavor, ef_free,
6248fb7bfaSmrg 							   ef_cxa)))
6348fb7bfaSmrg 	    {
6448fb7bfaSmrg 	      uint64_t check = __new_exitfn_called;
6548fb7bfaSmrg 
6648fb7bfaSmrg #ifdef PTR_DEMANGLE
6748fb7bfaSmrg 	      PTR_DEMANGLE (cxafn);
6848fb7bfaSmrg #endif
6948fb7bfaSmrg 	      cxafn (cxaarg, 0);
7048fb7bfaSmrg 
7148fb7bfaSmrg 	      /* It is possible that that last exit function registered
7248fb7bfaSmrg 		 more exit functions.  Start the loop over.  */
7348fb7bfaSmrg 	      if (__builtin_expect (check != __new_exitfn_called, 0))
7448fb7bfaSmrg 		goto restart;
7548fb7bfaSmrg 	    }
7648fb7bfaSmrg 	}
7748fb7bfaSmrg     }
7848fb7bfaSmrg 
7948fb7bfaSmrg   /* Remove the registered fork handlers.  We do not have to
8048fb7bfaSmrg      unregister anything if the program is going to terminate anyway.  */
8148fb7bfaSmrg #ifdef UNREGISTER_ATFORK
8248fb7bfaSmrg   if (d != NULL)
8348fb7bfaSmrg     UNREGISTER_ATFORK (d);
8448fb7bfaSmrg #endif
8548fb7bfaSmrg }
86