1 1.1 mrg /* KeyMgr backwards-compatibility support for Darwin. 2 1.1.1.11 mrg Copyright (C) 2001-2024 Free Software Foundation, Inc. 3 1.1 mrg 4 1.1 mrg This file is part of GCC. 5 1.1 mrg 6 1.1 mrg GCC is free software; you can redistribute it and/or modify it under 7 1.1 mrg the terms of the GNU General Public License as published by the Free 8 1.1 mrg Software Foundation; either version 3, or (at your option) any later 9 1.1 mrg version. 10 1.1 mrg 11 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 1.1 mrg for more details. 15 1.1 mrg 16 1.1 mrg Under Section 7 of GPL version 3, you are granted additional 17 1.1 mrg permissions described in the GCC Runtime Library Exception, version 18 1.1 mrg 3.1, as published by the Free Software Foundation. 19 1.1 mrg 20 1.1 mrg You should have received a copy of the GNU General Public License and 21 1.1 mrg a copy of the GCC Runtime Library Exception along with this program; 22 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 1.1 mrg <http://www.gnu.org/licenses/>. */ 24 1.1 mrg 25 1.1 mrg /* It is incorrect to include config.h here, because this file is being 26 1.1 mrg compiled for the target, and hence definitions concerning only the host 27 1.1 mrg do not apply. */ 28 1.1 mrg 29 1.1 mrg #include "tconfig.h" 30 1.1 mrg #include "tsystem.h" 31 1.1 mrg 32 1.1 mrg /* This file doesn't do anything useful on non-powerpc targets, since they 33 1.1 mrg don't have backwards compatibility anyway. */ 34 1.1 mrg 35 1.1 mrg #ifdef __ppc__ 36 1.1 mrg 37 1.1 mrg /* Homemade decls substituting for getsect.h and dyld.h, so cross 38 1.1 mrg compilation works. */ 39 1.1 mrg struct mach_header; 40 1.1 mrg extern char *getsectdatafromheader (struct mach_header *, const char *, 41 1.1 mrg const char *, unsigned long *); 42 1.1 mrg extern void _dyld_register_func_for_add_image 43 1.1 mrg (void (*) (struct mach_header *, unsigned long)); 44 1.1 mrg extern void _dyld_register_func_for_remove_image 45 1.1 mrg (void (*) (struct mach_header *, unsigned long)); 46 1.1 mrg 47 1.1 mrg extern void __darwin_gcc3_preregister_frame_info (void); 48 1.1 mrg 49 1.1 mrg /* These are from "keymgr.h". */ 50 1.1 mrg extern void _init_keymgr (void); 51 1.1 mrg extern void *_keymgr_get_and_lock_processwide_ptr (unsigned key); 52 1.1 mrg extern void _keymgr_set_and_unlock_processwide_ptr (unsigned key, void *ptr); 53 1.1 mrg 54 1.1 mrg extern void *__keymgr_global[]; 55 1.1 mrg typedef struct _Sinfo_Node { 56 1.1 mrg unsigned int size ; /*size of this node*/ 57 1.1 mrg unsigned short major_version ; /*API major version.*/ 58 1.1 mrg unsigned short minor_version ; /*API minor version.*/ 59 1.1 mrg } _Tinfo_Node ; 60 1.1 mrg 61 1.1 mrg /* KeyMgr 3.x is the first one supporting GCC3 stuff natively. */ 62 1.1 mrg #define KEYMGR_API_MAJOR_GCC3 3 63 1.1 mrg /* ... with these keys. */ 64 1.1 mrg #define KEYMGR_GCC3_LIVE_IMAGE_LIST 301 /* loaded images */ 65 1.1 mrg #define KEYMGR_GCC3_DW2_OBJ_LIST 302 /* Dwarf2 object list */ 66 1.1 mrg 67 1.1 mrg /* Node of KEYMGR_GCC3_LIVE_IMAGE_LIST. Info about each resident image. */ 68 1.1 mrg struct live_images { 69 1.1 mrg unsigned long this_size; /* sizeof (live_images) */ 70 1.1 mrg struct mach_header *mh; /* the image info */ 71 1.1 mrg unsigned long vm_slide; 72 1.1 mrg void (*destructor)(struct live_images *); /* destructor for this */ 73 1.1 mrg struct live_images *next; 74 1.1 mrg unsigned int examined_p; 75 1.1 mrg void *fde; 76 1.1 mrg void *object_info; 77 1.1 mrg unsigned long info[2]; /* Future use. */ 78 1.1 mrg }; 79 1.1 mrg 80 1.1 mrg 81 1.1 mrg /* These routines are used only on Darwin versions before 10.2. 83 1.1 mrg Later versions have equivalent code in the system. 84 1.1 mrg Eventually, they might go away, although it might be a long time... */ 85 1.1 mrg 86 1.1 mrg static void darwin_unwind_dyld_remove_image_hook 87 1.1 mrg (struct mach_header *m, unsigned long s); 88 1.1 mrg static void darwin_unwind_dyld_remove_image_hook 89 1.1 mrg (struct mach_header *m, unsigned long s); 90 1.1 mrg extern void __darwin_gcc3_preregister_frame_info (void); 91 1.1 mrg 92 1.1 mrg static void 93 1.1 mrg darwin_unwind_dyld_add_image_hook (struct mach_header *mh, unsigned long slide) 94 1.1 mrg { 95 1.1 mrg struct live_images *l = (struct live_images *)calloc (1, sizeof (*l)); 96 1.1 mrg l->mh = mh; 97 1.1 mrg l->vm_slide = slide; 98 1.1 mrg l->this_size = sizeof (*l); 99 1.1 mrg l->next = (struct live_images *) 100 1.1 mrg _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST); 101 1.1 mrg _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, l); 102 1.1 mrg } 103 1.1 mrg 104 1.1 mrg static void 105 1.1 mrg darwin_unwind_dyld_remove_image_hook (struct mach_header *m, unsigned long s) 106 1.1 mrg { 107 1.1 mrg struct live_images *top, **lip, *destroy = NULL; 108 1.1 mrg 109 1.1 mrg /* Look for it in the list of live images and delete it. */ 110 1.1 mrg 111 1.1 mrg top = (struct live_images *) 112 1.1 mrg _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST); 113 1.1 mrg for (lip = ⊤ *lip != NULL; lip = &(*lip)->next) 114 1.1 mrg { 115 1.1 mrg if ((*lip)->mh == m && (*lip)->vm_slide == s) 116 1.1 mrg { 117 1.1 mrg destroy = *lip; 118 1.1 mrg *lip = destroy->next; /* unlink DESTROY */ 119 1.1 mrg 120 1.1 mrg if (destroy->this_size != sizeof (*destroy)) /* sanity check */ 121 1.1 mrg abort (); 122 1.1 mrg 123 1.1 mrg break; 124 1.1 mrg } 125 1.1 mrg } 126 1.1 mrg _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, top); 127 1.1 mrg 128 1.1 mrg /* Now that we have unlinked this from the image list, toss it. */ 129 1.1 mrg if (destroy != NULL) 130 1.1 mrg { 131 1.1 mrg if (destroy->destructor != NULL) 132 1.1 mrg (*destroy->destructor) (destroy); 133 1.1 mrg free (destroy); 134 1.1 mrg } 135 1.1 mrg } 136 1.1 mrg 137 1.1 mrg void 138 1.1 mrg __darwin_gcc3_preregister_frame_info (void) 139 1.1 mrg { 140 1.1 mrg const _Tinfo_Node *info; 141 1.1 mrg _init_keymgr (); 142 1.1 mrg info = (_Tinfo_Node *)__keymgr_global[2]; 143 1.1 mrg if (info != NULL) 144 1.1 mrg { 145 1.1 mrg if (info->major_version >= KEYMGR_API_MAJOR_GCC3) 146 1.1 mrg return; 147 1.1 mrg /* Otherwise, use our own add_image_hooks. */ 148 1.1 mrg } 149 1.1 mrg 150 1.1 mrg _dyld_register_func_for_add_image (darwin_unwind_dyld_add_image_hook); 151 1.1 mrg _dyld_register_func_for_remove_image (darwin_unwind_dyld_remove_image_hook); 152 1.1 mrg } 153 1.1 mrg 154 #endif /* __ppc__ */ 155