/* KeyMgr backwards-compatibility support for Darwin.
   Copyright (C) 2001-2025 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/>.  */

/* It is incorrect to include config.h here, because this file is being
   compiled for the target, and hence definitions concerning only the host
   do not apply.  */

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

/* This file doesn't do anything useful on non-powerpc targets, since they
   don't have backwards compatibility anyway.  */

#ifdef __ppc__

/* Homemade decls substituting for getsect.h and dyld.h, so cross
   compilation works.  */
struct mach_header;
extern char *getsectdatafromheader (struct mach_header *, const char *,
				    const char *, unsigned long *);
extern void _dyld_register_func_for_add_image
  (void (*) (struct mach_header *, unsigned long));
extern void _dyld_register_func_for_remove_image
  (void (*) (struct mach_header *, unsigned long));

extern void __darwin_gcc3_preregister_frame_info (void);

/* These are from "keymgr.h".  */
extern void _init_keymgr (void);
extern void *_keymgr_get_and_lock_processwide_ptr (unsigned key);
extern void _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 ;

/* KeyMgr 3.x is the first one supporting GCC3 stuff natively.  */
#define KEYMGR_API_MAJOR_GCC3           3
/* ... with these keys.  */
#define KEYMGR_GCC3_LIVE_IMAGE_LIST	301     /* loaded images  */
#define KEYMGR_GCC3_DW2_OBJ_LIST	302     /* Dwarf2 object list  */

/* Node of KEYMGR_GCC3_LIVE_IMAGE_LIST.  Info about each resident image.  */
struct live_images {
  unsigned long this_size;                      /* sizeof (live_images)  */
  struct mach_header *mh;                       /* the image info  */
  unsigned long vm_slide;
  void (*destructor)(struct live_images *);     /* destructor for this  */
  struct live_images *next;
  unsigned int examined_p;
  void *fde;
  void *object_info;
  unsigned long info[2];                        /* Future use.  */
};


/* These routines are used only on Darwin versions before 10.2.
   Later versions have equivalent code in the system.
   Eventually, they might go away, although it might be a long time...  */

static void darwin_unwind_dyld_remove_image_hook
  (struct mach_header *m, unsigned long s);
static void darwin_unwind_dyld_remove_image_hook
  (struct mach_header *m, unsigned long s);
extern void __darwin_gcc3_preregister_frame_info (void);

static void
darwin_unwind_dyld_add_image_hook (struct mach_header *mh, unsigned long slide)
{
  struct live_images *l = (struct live_images *)calloc (1, sizeof (*l));
  l->mh = mh;
  l->vm_slide = slide;
  l->this_size = sizeof (*l);
  l->next = (struct live_images *)
	_keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);
  _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, l);
}

static void
darwin_unwind_dyld_remove_image_hook (struct mach_header *m, unsigned long s)
{
  struct live_images *top, **lip, *destroy = NULL;

  /* Look for it in the list of live images and delete it.  */

  top = (struct live_images *)
	   _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);
  for (lip = &top; *lip != NULL; lip = &(*lip)->next)
    {
      if ((*lip)->mh == m && (*lip)->vm_slide == s)
        {
          destroy = *lip;
          *lip = destroy->next;			/* unlink DESTROY  */

          if (destroy->this_size != sizeof (*destroy))	/* sanity check  */
            abort ();

          break;
        }
    }
  _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, top);

  /* Now that we have unlinked this from the image list, toss it.  */
  if (destroy != NULL)
    {
      if (destroy->destructor != NULL)
	(*destroy->destructor) (destroy);
      free (destroy);
    }
}

void
__darwin_gcc3_preregister_frame_info (void)
{
  const _Tinfo_Node *info;
  _init_keymgr ();
  info = (_Tinfo_Node *)__keymgr_global[2];
  if (info != NULL)
    {
      if (info->major_version >= KEYMGR_API_MAJOR_GCC3)
	return;
      /* Otherwise, use our own add_image_hooks.  */
    }

  _dyld_register_func_for_add_image (darwin_unwind_dyld_add_image_hook);
  _dyld_register_func_for_remove_image (darwin_unwind_dyld_remove_image_hook);
}

#endif  /* __ppc__ */
