163d1a8abSmrg /* KeyMgr backwards-compatibility support for Darwin.
2*ec02198aSmrg Copyright (C) 2001-2020 Free Software Foundation, Inc.
363d1a8abSmrg
463d1a8abSmrg This file is part of GCC.
563d1a8abSmrg
663d1a8abSmrg GCC is free software; you can redistribute it and/or modify it under
763d1a8abSmrg the terms of the GNU General Public License as published by the Free
863d1a8abSmrg Software Foundation; either version 3, or (at your option) any later
963d1a8abSmrg version.
1063d1a8abSmrg
1163d1a8abSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1263d1a8abSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
1363d1a8abSmrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1463d1a8abSmrg for more details.
1563d1a8abSmrg
1663d1a8abSmrg Under Section 7 of GPL version 3, you are granted additional
1763d1a8abSmrg permissions described in the GCC Runtime Library Exception, version
1863d1a8abSmrg 3.1, as published by the Free Software Foundation.
1963d1a8abSmrg
2063d1a8abSmrg You should have received a copy of the GNU General Public License and
2163d1a8abSmrg a copy of the GCC Runtime Library Exception along with this program;
2263d1a8abSmrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2363d1a8abSmrg <http://www.gnu.org/licenses/>. */
2463d1a8abSmrg
2563d1a8abSmrg /* It is incorrect to include config.h here, because this file is being
2663d1a8abSmrg compiled for the target, and hence definitions concerning only the host
2763d1a8abSmrg do not apply. */
2863d1a8abSmrg
2963d1a8abSmrg #include "tconfig.h"
3063d1a8abSmrg #include "tsystem.h"
3163d1a8abSmrg
3263d1a8abSmrg /* This file doesn't do anything useful on non-powerpc targets, since they
3363d1a8abSmrg don't have backwards compatibility anyway. */
3463d1a8abSmrg
3563d1a8abSmrg #ifdef __ppc__
3663d1a8abSmrg
3763d1a8abSmrg /* Homemade decls substituting for getsect.h and dyld.h, so cross
3863d1a8abSmrg compilation works. */
3963d1a8abSmrg struct mach_header;
4063d1a8abSmrg extern char *getsectdatafromheader (struct mach_header *, const char *,
4163d1a8abSmrg const char *, unsigned long *);
4263d1a8abSmrg extern void _dyld_register_func_for_add_image
4363d1a8abSmrg (void (*) (struct mach_header *, unsigned long));
4463d1a8abSmrg extern void _dyld_register_func_for_remove_image
4563d1a8abSmrg (void (*) (struct mach_header *, unsigned long));
4663d1a8abSmrg
4763d1a8abSmrg extern void __darwin_gcc3_preregister_frame_info (void);
4863d1a8abSmrg
4963d1a8abSmrg /* These are from "keymgr.h". */
5063d1a8abSmrg extern void _init_keymgr (void);
5163d1a8abSmrg extern void *_keymgr_get_and_lock_processwide_ptr (unsigned key);
5263d1a8abSmrg extern void _keymgr_set_and_unlock_processwide_ptr (unsigned key, void *ptr);
5363d1a8abSmrg
5463d1a8abSmrg extern void *__keymgr_global[];
5563d1a8abSmrg typedef struct _Sinfo_Node {
5663d1a8abSmrg unsigned int size ; /*size of this node*/
5763d1a8abSmrg unsigned short major_version ; /*API major version.*/
5863d1a8abSmrg unsigned short minor_version ; /*API minor version.*/
5963d1a8abSmrg } _Tinfo_Node ;
6063d1a8abSmrg
6163d1a8abSmrg /* KeyMgr 3.x is the first one supporting GCC3 stuff natively. */
6263d1a8abSmrg #define KEYMGR_API_MAJOR_GCC3 3
6363d1a8abSmrg /* ... with these keys. */
6463d1a8abSmrg #define KEYMGR_GCC3_LIVE_IMAGE_LIST 301 /* loaded images */
6563d1a8abSmrg #define KEYMGR_GCC3_DW2_OBJ_LIST 302 /* Dwarf2 object list */
6663d1a8abSmrg
6763d1a8abSmrg /* Node of KEYMGR_GCC3_LIVE_IMAGE_LIST. Info about each resident image. */
6863d1a8abSmrg struct live_images {
6963d1a8abSmrg unsigned long this_size; /* sizeof (live_images) */
7063d1a8abSmrg struct mach_header *mh; /* the image info */
7163d1a8abSmrg unsigned long vm_slide;
7263d1a8abSmrg void (*destructor)(struct live_images *); /* destructor for this */
7363d1a8abSmrg struct live_images *next;
7463d1a8abSmrg unsigned int examined_p;
7563d1a8abSmrg void *fde;
7663d1a8abSmrg void *object_info;
7763d1a8abSmrg unsigned long info[2]; /* Future use. */
7863d1a8abSmrg };
7963d1a8abSmrg
8063d1a8abSmrg
8163d1a8abSmrg /* These routines are used only on Darwin versions before 10.2.
8263d1a8abSmrg Later versions have equivalent code in the system.
8363d1a8abSmrg Eventually, they might go away, although it might be a long time... */
8463d1a8abSmrg
8563d1a8abSmrg static void darwin_unwind_dyld_remove_image_hook
8663d1a8abSmrg (struct mach_header *m, unsigned long s);
8763d1a8abSmrg static void darwin_unwind_dyld_remove_image_hook
8863d1a8abSmrg (struct mach_header *m, unsigned long s);
8963d1a8abSmrg extern void __darwin_gcc3_preregister_frame_info (void);
9063d1a8abSmrg
9163d1a8abSmrg static void
darwin_unwind_dyld_add_image_hook(struct mach_header * mh,unsigned long slide)9263d1a8abSmrg darwin_unwind_dyld_add_image_hook (struct mach_header *mh, unsigned long slide)
9363d1a8abSmrg {
9463d1a8abSmrg struct live_images *l = (struct live_images *)calloc (1, sizeof (*l));
9563d1a8abSmrg l->mh = mh;
9663d1a8abSmrg l->vm_slide = slide;
9763d1a8abSmrg l->this_size = sizeof (*l);
9863d1a8abSmrg l->next = (struct live_images *)
9963d1a8abSmrg _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);
10063d1a8abSmrg _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, l);
10163d1a8abSmrg }
10263d1a8abSmrg
10363d1a8abSmrg static void
darwin_unwind_dyld_remove_image_hook(struct mach_header * m,unsigned long s)10463d1a8abSmrg darwin_unwind_dyld_remove_image_hook (struct mach_header *m, unsigned long s)
10563d1a8abSmrg {
10663d1a8abSmrg struct live_images *top, **lip, *destroy = NULL;
10763d1a8abSmrg
10863d1a8abSmrg /* Look for it in the list of live images and delete it. */
10963d1a8abSmrg
11063d1a8abSmrg top = (struct live_images *)
11163d1a8abSmrg _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);
11263d1a8abSmrg for (lip = ⊤ *lip != NULL; lip = &(*lip)->next)
11363d1a8abSmrg {
11463d1a8abSmrg if ((*lip)->mh == m && (*lip)->vm_slide == s)
11563d1a8abSmrg {
11663d1a8abSmrg destroy = *lip;
11763d1a8abSmrg *lip = destroy->next; /* unlink DESTROY */
11863d1a8abSmrg
11963d1a8abSmrg if (destroy->this_size != sizeof (*destroy)) /* sanity check */
12063d1a8abSmrg abort ();
12163d1a8abSmrg
12263d1a8abSmrg break;
12363d1a8abSmrg }
12463d1a8abSmrg }
12563d1a8abSmrg _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, top);
12663d1a8abSmrg
12763d1a8abSmrg /* Now that we have unlinked this from the image list, toss it. */
12863d1a8abSmrg if (destroy != NULL)
12963d1a8abSmrg {
13063d1a8abSmrg if (destroy->destructor != NULL)
13163d1a8abSmrg (*destroy->destructor) (destroy);
13263d1a8abSmrg free (destroy);
13363d1a8abSmrg }
13463d1a8abSmrg }
13563d1a8abSmrg
13663d1a8abSmrg void
__darwin_gcc3_preregister_frame_info(void)13763d1a8abSmrg __darwin_gcc3_preregister_frame_info (void)
13863d1a8abSmrg {
13963d1a8abSmrg const _Tinfo_Node *info;
14063d1a8abSmrg _init_keymgr ();
14163d1a8abSmrg info = (_Tinfo_Node *)__keymgr_global[2];
14263d1a8abSmrg if (info != NULL)
14363d1a8abSmrg {
14463d1a8abSmrg if (info->major_version >= KEYMGR_API_MAJOR_GCC3)
14563d1a8abSmrg return;
14663d1a8abSmrg /* Otherwise, use our own add_image_hooks. */
14763d1a8abSmrg }
14863d1a8abSmrg
14963d1a8abSmrg _dyld_register_func_for_add_image (darwin_unwind_dyld_add_image_hook);
15063d1a8abSmrg _dyld_register_func_for_remove_image (darwin_unwind_dyld_remove_image_hook);
15163d1a8abSmrg }
15263d1a8abSmrg
15363d1a8abSmrg #endif /* __ppc__ */
154