/* Copyright (C) 1999-2018 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <assert.h>
#include <stdlib.h>
#include "exit.h"
#include <fork.h>
#include <sysdep.h>
#include <stdint.h>

/* If D is non-NULL, call all functions registered with `__cxa_atexit'
   with the same dso handle.  Otherwise, if D is NULL, call all of the
   registered handlers.  */
void
__cxa_finalize (void *d)
{
  struct exit_function_list *funcs;

  __libc_lock_lock (__exit_funcs_lock);

 restart:
  for (funcs = __exit_funcs; funcs; funcs = funcs->next)
    {
      struct exit_function *f;

      for (f = &funcs->fns[funcs->idx - 1]; f >= &funcs->fns[0]; --f)
	if ((d == NULL || d == f->func.cxa.dso_handle) && f->flavor == ef_cxa)
	  {
	    const uint64_t check = __new_exitfn_called;
	    void (*cxafn) (void *arg, int status) = f->func.cxa.fn;
	    void *cxaarg = f->func.cxa.arg;

	    /* We don't want to run this cleanup more than once.  The Itanium
	       C++ ABI requires that multiple calls to __cxa_finalize not
	       result in calling termination functions more than once.  One
	       potential scenario where that could happen is with a concurrent
	       dlclose and exit, where the running dlclose must at some point
	       release the list lock, an exiting thread may acquire it, and
	       without setting flavor to ef_free, might re-run this destructor
	       which could result in undefined behaviour.  Therefore we must
	       set flavor to ef_free to avoid calling this destructor again.
	       Note that the concurrent exit must also take the dynamic loader
	       lock (for library finalizer processing) and therefore will
	       block while dlclose completes the processing of any in-progress
	       exit functions. Lastly, once we release the list lock for the
	       entry marked ef_free, we must not read from that entry again
	       since it may have been reused by the time we take the list lock
	       again.  Lastly the detection of new registered exit functions is
	       based on a monotonically incrementing counter, and there is an
	       ABA if between the unlock to run the exit function and the
	       re-lock after completion the user registers 2^64 exit functions,
	       the implementation will not detect this and continue without
	       executing any more functions.

	       One minor issue remains: A registered exit function that is in
	       progress by a call to dlclose() may not completely finish before
	       the next registered exit function is run. This may, according to
	       some readings of POSIX violate the requirement that functions
	       run in effective LIFO order.  This should probably be fixed in a
	       future implementation to ensure the functions do not run in
	       parallel.  */
	    f->flavor = ef_free;

#ifdef PTR_DEMANGLE
	    PTR_DEMANGLE (cxafn);
#endif
	    /* Unlock the list while we call a foreign function.  */
	    __libc_lock_unlock (__exit_funcs_lock);
	    cxafn (cxaarg, 0);
	    __libc_lock_lock (__exit_funcs_lock);

	    /* It is possible that that last exit function registered
	       more exit functions.  Start the loop over.  */
	    if (__glibc_unlikely (check != __new_exitfn_called))
	      goto restart;
	  }
    }

  /* Also remove the quick_exit handlers, but do not call them.  */
  for (funcs = __quick_exit_funcs; funcs; funcs = funcs->next)
    {
      struct exit_function *f;

      for (f = &funcs->fns[funcs->idx - 1]; f >= &funcs->fns[0]; --f)
	if (d == NULL || d == f->func.cxa.dso_handle)
	  f->flavor = ef_free;
    }

  /* Remove the registered fork handlers.  We do not have to
     unregister anything if the program is going to terminate anyway.  */
#ifdef UNREGISTER_ATFORK
  if (d != NULL)
    UNREGISTER_ATFORK (d);
#endif
  __libc_lock_unlock (__exit_funcs_lock);
}
