/* __cxa_atexit backwards-compatibility support for Darwin.
   Copyright (C) 2006-2023 Free Software Foundation, Inc.

This file is part of GCC.

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

GCC 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 General Public License
for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

/* Don't do anything if we are compiling for a kext multilib. */
#ifdef __PIC__

#include "tconfig.h"
#include "tsystem.h"

#include <dlfcn.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

/* This file works around two different problems.

   The first problem is that there is no __cxa_atexit on Mac OS versions
   before 10.4.  It fixes this by providing a complete atexit and
   __cxa_atexit emulation called from the regular atexit.

   The second problem is that on all shipping versions of Mac OS,
   __cxa_finalize and exit() don't work right: they don't run routines
   that were registered while other atexit routines are running.  This
   is worked around by wrapping each atexit/__cxa_atexit routine with
   our own routine which ensures that any __cxa_atexit calls while it
   is running are honoured.

   There are still problems which this does not solve.  Before 10.4,
   shared objects linked with previous compilers won't have their
   atexit calls properly interleaved with code compiled with newer
   compilers.  Also, atexit routines registered from shared objects
   linked with previous compilers won't get the bug fix.  */

typedef int (*cxa_atexit_p)(void (*func) (void*), void* arg, const void* dso);
typedef void (*cxa_finalize_p)(const void *dso);
typedef int (*atexit_p)(void (*func)(void));

/* These are from "keymgr.h".  */
extern void *_keymgr_get_and_lock_processwide_ptr (unsigned key);
extern int _keymgr_get_and_lock_processwide_ptr_2 (unsigned, void **);
extern int _keymgr_set_and_unlock_processwide_ptr (unsigned key, void *ptr);

extern void *__keymgr_global[];
typedef struct _Sinfo_Node {
        unsigned int size ;             /*size of this node*/
        unsigned short major_version ;  /*API major version.*/
        unsigned short minor_version ;  /*API minor version.*/
        } _Tinfo_Node ;

#ifdef __ppc__
#define CHECK_KEYMGR_ERROR(e) \
  (((_Tinfo_Node *)__keymgr_global[2])->major_version >= 4 ? (e) : 0)
#else
#define CHECK_KEYMGR_ERROR(e) (e)
#endif

/* Our globals are stored under this keymgr index.  */
#define KEYMGR_ATEXIT_LIST	14

/* The different kinds of callback routines.  */
typedef void (*atexit_callback)(void);
typedef void (*cxa_atexit_callback)(void *);

/* This structure holds a routine to call.  There may be extra fields
   at the end of the structure that this code doesn't know about.  */
struct one_atexit_routine 
{
  union {
    atexit_callback ac;
    cxa_atexit_callback cac;
  } callback;
  /* has_arg is 0/2/4 if 'ac' is live, 1/3/5 if 'cac' is live.  
     Higher numbers indicate a later version of the structure that this
     code doesn't understand and will ignore.  */
  int has_arg;
  void * arg;
};

struct atexit_routine_list
{
  struct atexit_routine_list * next;
  struct one_atexit_routine r;
};

/* The various possibilities for status of atexit().  */
enum atexit_status {
  atexit_status_unknown = 0,
  atexit_status_missing = 1,
  atexit_status_broken = 2,
  atexit_status_working = 16
};

struct keymgr_atexit_list
{
  /* Version of this list.  This code knows only about version 0.
     If the version is higher than 0, this code may add new atexit routines
     but should not attempt to run the list.  */
  short version;
  /* 1 if an atexit routine is currently being run by this code, 0
     otherwise.  */
  char running_routines;
  /* Holds a value from 'enum atexit_status'.  */
  unsigned char atexit_status;
  /* The list of atexit and cxa_atexit routines registered.  If
   atexit_status_missing it contains all routines registered while
   linked with this code.  If atexit_status_broken it contains all
   routines registered during cxa_finalize while linked with this
   code.  */
  struct atexit_routine_list *l;
  /* &__cxa_atexit; set if atexit_status >= atexit_status_broken.  */
  cxa_atexit_p cxa_atexit_f;
  /* &__cxa_finalize; set if atexit_status >= atexit_status_broken.  */
  cxa_finalize_p cxa_finalize_f;
  /* &atexit; set if atexit_status >= atexit_status_working
     or atexit_status == atexit_status_missing.  */
  atexit_p atexit_f;
};

/* Return 0 if __cxa_atexit has the bug it has in Mac OS 10.4: it
   fails to call routines registered while an atexit routine is
   running.  Return 1 if it works properly, and -1 if an error occurred.  */

struct atexit_data 
{
  int result;
  cxa_atexit_p cxa_atexit;
};

static void cxa_atexit_check_2 (void *arg)
{
  ((struct atexit_data *)arg)->result = 1;
}

static void cxa_atexit_check_1 (void *arg)
{
  struct atexit_data * aed = arg;
  if (aed->cxa_atexit (cxa_atexit_check_2, arg, arg) != 0)
    aed->result = -1;
}

static int
check_cxa_atexit (cxa_atexit_p cxa_atexit, cxa_finalize_p cxa_finalize)
{
  struct atexit_data aed = { 0, cxa_atexit };

  /* We re-use &aed as the 'dso' parameter, since it's a unique address.  */
  if (cxa_atexit (cxa_atexit_check_1, &aed, &aed) != 0)
    return -1;
  cxa_finalize (&aed);
  if (aed.result == 0)
    {
      /* Call __cxa_finalize again to make sure that cxa_atexit_check_2
	 is removed from the list before AED goes out of scope.  */
      cxa_finalize (&aed);
      aed.result = 0;
    }
  return aed.result;
}

#ifdef __ppc__
/* This comes from Csu.  It works only before 10.4.  The prototype has
   been altered a bit to avoid casting.  */
extern int _dyld_func_lookup(const char *dyld_func_name,
     void *address) __attribute__((visibility("hidden")));

static void our_atexit (void);

/* We're running on 10.3.9.  Find the address of the system atexit()
   function.  So easy to say, so hard to do.  */
static atexit_p
find_atexit_10_3 (void)
{
  unsigned int (*dyld_image_count_fn)(void);
  const char *(*dyld_get_image_name_fn)(unsigned int image_index);
  const void *(*dyld_get_image_header_fn)(unsigned int image_index);
  const void *(*NSLookupSymbolInImage_fn)(const void *image, 
					  const char *symbolName,
					  unsigned int options);
  void *(*NSAddressOfSymbol_fn)(const void *symbol);
  unsigned i, count;
  
  /* Find some dyld functions.  */
  _dyld_func_lookup("__dyld_image_count", &dyld_image_count_fn);
  _dyld_func_lookup("__dyld_get_image_name", &dyld_get_image_name_fn);
  _dyld_func_lookup("__dyld_get_image_header", &dyld_get_image_header_fn);
  _dyld_func_lookup("__dyld_NSLookupSymbolInImage", &NSLookupSymbolInImage_fn);
  _dyld_func_lookup("__dyld_NSAddressOfSymbol", &NSAddressOfSymbol_fn);

  /* If any of these don't exist, that's an error.  */
  if (! dyld_image_count_fn || ! dyld_get_image_name_fn
      || ! dyld_get_image_header_fn || ! NSLookupSymbolInImage_fn
      || ! NSAddressOfSymbol_fn)
    return NULL;
  
  count = dyld_image_count_fn ();
  for (i = 0; i < count; i++)
    {
      const char * path = dyld_get_image_name_fn (i);
      const void * image;
      const void * symbol;
      
      if (strcmp (path, "/usr/lib/libSystem.B.dylib") != 0)
	continue;
      image = dyld_get_image_header_fn (i);
      if (! image)
	return NULL;
      /* '4' is NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR.  */
      symbol = NSLookupSymbolInImage_fn (image, "_atexit", 4);
      if (! symbol)
	return NULL;
      return NSAddressOfSymbol_fn (symbol);
    }
  return NULL;
}
#endif

/* Create (if necessary), find, lock, fill in, and return our globals.  
   Return NULL on error, in which case the globals will not be locked.  
   The caller should call keymgr_set_and_unlock.  */
static struct keymgr_atexit_list *
get_globals (void)
{
  struct keymgr_atexit_list * r;
  
#ifdef __ppc__
  /* 10.3.9 doesn't have _keymgr_get_and_lock_processwide_ptr_2 so the
     PPC side can't use it.  On 10.4 this just means the error gets
     reported a little later when
     _keymgr_set_and_unlock_processwide_ptr finds that the key was
     never locked.  */
  r = _keymgr_get_and_lock_processwide_ptr (KEYMGR_ATEXIT_LIST);
#else
  void * rr;
  if (_keymgr_get_and_lock_processwide_ptr_2 (KEYMGR_ATEXIT_LIST, &rr))
    return NULL;
  r = rr;
#endif
  
  if (r == NULL)
    {
      r = calloc (sizeof (struct keymgr_atexit_list), 1);
      if (! r)
	return NULL;
    }

  if (r->atexit_status == atexit_status_unknown)
    {
      void *handle;

      handle = dlopen ("/usr/lib/libSystem.B.dylib", RTLD_NOLOAD);
      if (!handle)
	{
#ifdef __ppc__
	  r->atexit_status = atexit_status_missing;
	  r->atexit_f = find_atexit_10_3 ();
	  if (! r->atexit_f)
	    goto error;
	  if (r->atexit_f (our_atexit))
	    goto error;
#else
	  goto error;
#endif
	}
      else
	{
	  int chk_result;

	  r->cxa_atexit_f = (cxa_atexit_p)dlsym (handle, "__cxa_atexit");
	  r->cxa_finalize_f = (cxa_finalize_p)dlsym (handle, "__cxa_finalize");
	  if (! r->cxa_atexit_f || ! r->cxa_finalize_f)
	    goto error;

	  chk_result = check_cxa_atexit (r->cxa_atexit_f, r->cxa_finalize_f);
	  if (chk_result == -1)
	    goto error;
	  else if (chk_result == 0)
	    r->atexit_status = atexit_status_broken;
	  else
	    {
	      r->atexit_f = (atexit_p)dlsym (handle, "atexit");
	      if (! r->atexit_f)
		goto error;
	      r->atexit_status = atexit_status_working;
	    }
	}
    }

  return r;
  
 error:
  _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, r);
  return NULL;
}

/* Add TO_ADD to ATEXIT_LIST.  ATEXIT_LIST may be NULL but is
   always the result of calling _keymgr_get_and_lock_processwide_ptr and
   so KEYMGR_ATEXIT_LIST is known to be locked; this routine is responsible
   for unlocking it.  */

static int
add_routine (struct keymgr_atexit_list * g,
	     const struct one_atexit_routine * to_add)
{
  struct atexit_routine_list * s
    = malloc (sizeof (struct atexit_routine_list));
  int result;
  
  if (!s)
    {
      _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
      return -1;
    }
  s->r = *to_add;
  s->next = g->l;
  g->l = s;
  result = _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
  return CHECK_KEYMGR_ERROR (result) == 0 ? 0 : -1;
}

/* This runs the routines in G->L up to STOP.  */
static struct keymgr_atexit_list *
run_routines (struct keymgr_atexit_list *g,
	      struct atexit_routine_list *stop)
{
  for (;;)
    {
      struct atexit_routine_list * cur = g->l;
      if (! cur || cur == stop)
	break;
      g->l = cur->next;
      _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);

      switch (cur->r.has_arg) {
      case 0: case 2: case 4:
	cur->r.callback.ac ();
	break;
      case 1: case 3: case 5:
	cur->r.callback.cac (cur->r.arg);
	break;
      default:
	/* Don't understand, so don't call it.  */
	break;
      }
      free (cur);

      g = _keymgr_get_and_lock_processwide_ptr (KEYMGR_ATEXIT_LIST);
      if (! g)
	break;
    }
  return g;
}

/* Call the routine described by ROUTINE_PARAM and then call any
   routines added to KEYMGR_ATEXIT_LIST while that routine was
   running, all with in_cxa_finalize set.  */

static void
cxa_atexit_wrapper (void* routine_param)
{
  struct one_atexit_routine * routine = routine_param;
  struct keymgr_atexit_list *g;
  struct atexit_routine_list * base = NULL;
  char prev_running = 0;
  
  g = _keymgr_get_and_lock_processwide_ptr (KEYMGR_ATEXIT_LIST);
  if (g)
    {
      prev_running = g->running_routines;
      g->running_routines = 1;
      base = g->l;
      _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
    }

  if (routine->has_arg)
    routine->callback.cac (routine->arg);
  else
    routine->callback.ac ();

  if (g)
    g = _keymgr_get_and_lock_processwide_ptr (KEYMGR_ATEXIT_LIST);
  if (g)
    g = run_routines (g, base);
  if (g)
    {
      g->running_routines = prev_running;
      _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
    }
}

#ifdef __ppc__
/* This code is used while running on 10.3.9, when __cxa_atexit doesn't
   exist in the system library.  10.3.9 only supported regular PowerPC,
   so this code isn't necessary on x86 or ppc64.  */

/* This routine is called from the system atexit(); it runs everything
   registered on the KEYMGR_ATEXIT_LIST.  */

static void
our_atexit (void)
{
  struct keymgr_atexit_list *g;
  char prev_running;

  g = _keymgr_get_and_lock_processwide_ptr (KEYMGR_ATEXIT_LIST);
  if (! g || g->version != 0 || g->atexit_status != atexit_status_missing)
    return;
  
  prev_running = g->running_routines;
  g->running_routines = 1;
  g = run_routines (g, NULL);
  if (! g)
    return;
  g->running_routines = prev_running;
  _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
}
#endif

/* This is our wrapper around atexit and __cxa_atexit.  It will return
   nonzero if an error occurs, and otherwise:
   - if in_cxa_finalize is set, or running on 10.3.9, add R to
     KEYMGR_ATEXIT_LIST; or
   - call the system __cxa_atexit to add cxa_atexit_wrapper with an argument
     that indicates how cxa_atexit_wrapper should call R.  */

static int
atexit_common (const struct one_atexit_routine *r, const void *dso)
{
  struct keymgr_atexit_list *g = get_globals ();

  if (! g)
    return -1;
  
  if (g->running_routines || g->atexit_status == atexit_status_missing)
    return add_routine (g, r);

  if (g->atexit_status >= atexit_status_working)
    {
      int result;
      if (r->has_arg)
	{
	  cxa_atexit_p cxa_atexit = g->cxa_atexit_f;
	  result = _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST,
							   g);
	  if (CHECK_KEYMGR_ERROR (result))
	    return -1;
	  return cxa_atexit (r->callback.cac, r->arg, dso);
	}
      else
	{
	  atexit_p atexit_f = g->atexit_f;
	  result = _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST,
							   g);
	  if (CHECK_KEYMGR_ERROR (result))
	    return -1;
	  return atexit_f (r->callback.ac);
	}
    }
  else
    {
      cxa_atexit_p cxa_atexit = g->cxa_atexit_f;
      struct one_atexit_routine *alloced;
      int result;

      result = _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
      if (CHECK_KEYMGR_ERROR (result))
	return -1;

      alloced = malloc (sizeof (struct one_atexit_routine));
      if (! alloced)
	return -1;
      *alloced = *r;
      return cxa_atexit (cxa_atexit_wrapper, alloced, dso);
    }
}

/* These are the actual replacement routines; they just funnel into
   atexit_common.  */

int __cxa_atexit (cxa_atexit_callback func, void* arg, 
		  const void* dso) __attribute__((visibility("hidden")));

int
__cxa_atexit (cxa_atexit_callback func, void* arg, const void* dso)
{
  struct one_atexit_routine r;
  r.callback.cac = func;
  r.has_arg = 1;
  r.arg = arg;
  return atexit_common (&r, dso);
}

int atexit (atexit_callback func) __attribute__((visibility("hidden")));

/* Use __dso_handle to allow even bundles that call atexit() to be unloaded
   on 10.4.  */
extern void __dso_handle;

int
atexit (atexit_callback func)
{
  struct one_atexit_routine r;
  r.callback.ac = func;
  r.has_arg = 0;
  return atexit_common (&r, &__dso_handle);
}

#endif /* __PIC__ */
