1117395Skan/* KeyMgr backwards-compatibility support for Darwin. 2169689Skan Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. 3117395Skan 4117395SkanThis file is part of GCC. 5117395Skan 6117395SkanGCC is free software; you can redistribute it and/or modify it under 7117395Skanthe terms of the GNU General Public License as published by the Free 8117395SkanSoftware Foundation; either version 2, or (at your option) any later 9117395Skanversion. 10117395Skan 11117395SkanIn addition to the permissions in the GNU General Public License, the 12117395SkanFree Software Foundation gives you unlimited permission to link the 13117395Skancompiled version of this file into combinations with other programs, 14117395Skanand to distribute those combinations without any restriction coming 15117395Skanfrom the use of this file. (The General Public License restrictions 16117395Skando apply in other respects; for example, they cover modification of 17117395Skanthe file, and distribution when not linked into a combine 18117395Skanexecutable.) 19117395Skan 20117395SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY 21117395SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or 22117395SkanFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 23117395Skanfor more details. 24117395Skan 25117395SkanYou should have received a copy of the GNU General Public License 26117395Skanalong with GCC; see the file COPYING. If not, write to the Free 27169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 28169689Skan02110-1301, USA. */ 29117395Skan 30117395Skan/* It is incorrect to include config.h here, because this file is being 31117395Skan compiled for the target, and hence definitions concerning only the host 32117395Skan do not apply. */ 33117395Skan 34117395Skan#include "tconfig.h" 35117395Skan#include "tsystem.h" 36117395Skan 37169689Skan/* This file doesn't do anything useful on non-powerpc targets, since they 38169689Skan don't have backwards compatibility anyway. */ 39169689Skan 40169689Skan#ifdef __ppc__ 41169689Skan 42117395Skan/* Homemade decls substituting for getsect.h and dyld.h, so cross 43117395Skan compilation works. */ 44117395Skanstruct mach_header; 45117395Skanextern char *getsectdatafromheader (struct mach_header *, const char *, 46117395Skan const char *, unsigned long *); 47117395Skanextern void _dyld_register_func_for_add_image 48117395Skan (void (*) (struct mach_header *, unsigned long)); 49117395Skanextern void _dyld_register_func_for_remove_image 50117395Skan (void (*) (struct mach_header *, unsigned long)); 51117395Skan 52117395Skanextern void __darwin_gcc3_preregister_frame_info (void); 53117395Skan 54117395Skan/* These are from "keymgr.h". */ 55117395Skanextern void _init_keymgr (void); 56117395Skanextern void *_keymgr_get_and_lock_processwide_ptr (unsigned key); 57117395Skanextern void _keymgr_set_and_unlock_processwide_ptr (unsigned key, void *ptr); 58117395Skan 59117395Skanextern void *__keymgr_global[]; 60117395Skantypedef struct _Sinfo_Node { 61117395Skan unsigned int size ; /*size of this node*/ 62117395Skan unsigned short major_version ; /*API major version.*/ 63117395Skan unsigned short minor_version ; /*API minor version.*/ 64117395Skan } _Tinfo_Node ; 65117395Skan 66117395Skan/* KeyMgr 3.x is the first one supporting GCC3 stuff natively. */ 67117395Skan#define KEYMGR_API_MAJOR_GCC3 3 68117395Skan/* ... with these keys. */ 69117395Skan#define KEYMGR_GCC3_LIVE_IMAGE_LIST 301 /* loaded images */ 70117395Skan#define KEYMGR_GCC3_DW2_OBJ_LIST 302 /* Dwarf2 object list */ 71117395Skan 72117395Skan/* Node of KEYMGR_GCC3_LIVE_IMAGE_LIST. Info about each resident image. */ 73117395Skanstruct live_images { 74117395Skan unsigned long this_size; /* sizeof (live_images) */ 75117395Skan struct mach_header *mh; /* the image info */ 76117395Skan unsigned long vm_slide; 77117395Skan void (*destructor)(struct live_images *); /* destructor for this */ 78117395Skan struct live_images *next; 79117395Skan unsigned int examined_p; 80117395Skan void *fde; 81117395Skan void *object_info; 82117395Skan unsigned long info[2]; /* Future use. */ 83117395Skan}; 84117395Skan 85117395Skan 86117395Skan/* These routines are used only on Darwin versions before 10.2. 87117395Skan Later versions have equivalent code in the system. 88117395Skan Eventually, they might go away, although it might be a long time... */ 89117395Skan 90117395Skanstatic void darwin_unwind_dyld_remove_image_hook 91117395Skan (struct mach_header *m, unsigned long s); 92117395Skanstatic void darwin_unwind_dyld_remove_image_hook 93117395Skan (struct mach_header *m, unsigned long s); 94117395Skanextern void __darwin_gcc3_preregister_frame_info (void); 95117395Skan 96117395Skanstatic void 97117395Skandarwin_unwind_dyld_add_image_hook (struct mach_header *mh, unsigned long slide) 98117395Skan{ 99117395Skan struct live_images *l = (struct live_images *)calloc (1, sizeof (*l)); 100117395Skan l->mh = mh; 101117395Skan l->vm_slide = slide; 102117395Skan l->this_size = sizeof (*l); 103117395Skan l->next = (struct live_images *) 104117395Skan _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST); 105117395Skan _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, l); 106117395Skan} 107117395Skan 108117395Skanstatic void 109117395Skandarwin_unwind_dyld_remove_image_hook (struct mach_header *m, unsigned long s) 110117395Skan{ 111117395Skan struct live_images *top, **lip, *destroy = NULL; 112117395Skan 113117395Skan /* Look for it in the list of live images and delete it. */ 114117395Skan 115117395Skan top = (struct live_images *) 116117395Skan _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST); 117117395Skan for (lip = ⊤ *lip != NULL; lip = &(*lip)->next) 118117395Skan { 119117395Skan if ((*lip)->mh == m && (*lip)->vm_slide == s) 120117395Skan { 121117395Skan destroy = *lip; 122117395Skan *lip = destroy->next; /* unlink DESTROY */ 123117395Skan 124117395Skan if (destroy->this_size != sizeof (*destroy)) /* sanity check */ 125117395Skan abort (); 126117395Skan 127117395Skan break; 128117395Skan } 129117395Skan } 130117395Skan _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, top); 131117395Skan 132117395Skan /* Now that we have unlinked this from the image list, toss it. */ 133117395Skan if (destroy != NULL) 134117395Skan { 135117395Skan if (destroy->destructor != NULL) 136117395Skan (*destroy->destructor) (destroy); 137117395Skan free (destroy); 138117395Skan } 139117395Skan} 140117395Skan 141117395Skanvoid 142117395Skan__darwin_gcc3_preregister_frame_info (void) 143117395Skan{ 144117395Skan const _Tinfo_Node *info; 145117395Skan _init_keymgr (); 146117395Skan info = (_Tinfo_Node *)__keymgr_global[2]; 147117395Skan if (info != NULL) 148117395Skan { 149117395Skan if (info->major_version >= KEYMGR_API_MAJOR_GCC3) 150117395Skan return; 151117395Skan /* Otherwise, use our own add_image_hooks. */ 152117395Skan } 153117395Skan 154117395Skan _dyld_register_func_for_add_image (darwin_unwind_dyld_add_image_hook); 155117395Skan _dyld_register_func_for_remove_image (darwin_unwind_dyld_remove_image_hook); 156117395Skan} 157169689Skan 158169689Skan#endif /* __ppc__ */ 159