172445Sassar/* KeyMgr backwards-compatibility support for Darwin. 2233294Sstas Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. 3233294Sstas 4233294SstasThis file is part of GCC. 572445Sassar 6233294SstasGCC is free software; you can redistribute it and/or modify it under 7233294Sstasthe terms of the GNU General Public License as published by the Free 8233294SstasSoftware Foundation; either version 2, or (at your option) any later 972445Sassarversion. 10233294Sstas 11233294SstasIn addition to the permissions in the GNU General Public License, the 1272445SassarFree Software Foundation gives you unlimited permission to link the 13233294Sstascompiled version of this file into combinations with other programs, 14233294Sstasand to distribute those combinations without any restriction coming 15233294Sstasfrom the use of this file. (The General Public License restrictions 1672445Sassardo apply in other respects; for example, they cover modification of 17233294Sstasthe file, and distribution when not linked into a combine 18233294Sstasexecutable.) 19233294Sstas 2072445SassarGCC is distributed in the hope that it will be useful, but WITHOUT ANY 21233294SstasWARRANTY; without even the implied warranty of MERCHANTABILITY or 22233294SstasFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 23233294Sstasfor more details. 24233294Sstas 25233294SstasYou should have received a copy of the GNU General Public License 26233294Sstasalong with GCC; see the file COPYING. If not, write to the Free 27233294SstasSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 28233294Sstas02110-1301, USA. */ 29233294Sstas 30233294Sstas/* It is incorrect to include config.h here, because this file is being 31233294Sstas compiled for the target, and hence definitions concerning only the host 3272445Sassar do not apply. */ 3372445Sassar 3472445Sassar#include "tconfig.h" 3572445Sassar#include "tsystem.h" 3672445Sassar 3772445Sassar/* This file doesn't do anything useful on non-powerpc targets, since they 3872445Sassar don't have backwards compatibility anyway. */ 3972445Sassar 4090926Snectar#ifdef __ppc__ 4190926Snectar 4272445Sassar/* Homemade decls substituting for getsect.h and dyld.h, so cross 4372445Sassar compilation works. */ 4472445Sassarstruct mach_header; 4572445Sassarextern char *getsectdatafromheader (struct mach_header *, const char *, 4672445Sassar const char *, unsigned long *); 4772445Sassarextern void _dyld_register_func_for_add_image 4872445Sassar (void (*) (struct mach_header *, unsigned long)); 4990926Snectarextern void _dyld_register_func_for_remove_image 5072445Sassar (void (*) (struct mach_header *, unsigned long)); 5172445Sassar 5272445Sassarextern void __darwin_gcc3_preregister_frame_info (void); 5372445Sassar 5472445Sassar/* These are from "keymgr.h". */ 5572445Sassarextern void _init_keymgr (void); 5690926Snectarextern void *_keymgr_get_and_lock_processwide_ptr (unsigned key); 5790926Snectarextern void _keymgr_set_and_unlock_processwide_ptr (unsigned key, void *ptr); 58178825Sdfr 5972445Sassarextern void *__keymgr_global[]; 6090926Snectartypedef struct _Sinfo_Node { 6172445Sassar unsigned int size ; /*size of this node*/ 6272445Sassar unsigned short major_version ; /*API major version.*/ 6390926Snectar unsigned short minor_version ; /*API minor version.*/ 6490926Snectar } _Tinfo_Node ; 6590926Snectar 6690926Snectar/* KeyMgr 3.x is the first one supporting GCC3 stuff natively. */ 6790926Snectar#define KEYMGR_API_MAJOR_GCC3 3 6890926Snectar/* ... with these keys. */ 6990926Snectar#define KEYMGR_GCC3_LIVE_IMAGE_LIST 301 /* loaded images */ 7090926Snectar#define KEYMGR_GCC3_DW2_OBJ_LIST 302 /* Dwarf2 object list */ 7172445Sassar 72178825Sdfr/* Node of KEYMGR_GCC3_LIVE_IMAGE_LIST. Info about each resident image. */ 73178825Sdfrstruct live_images { 7472445Sassar unsigned long this_size; /* sizeof (live_images) */ 75233294Sstas struct mach_header *mh; /* the image info */ 7672445Sassar unsigned long vm_slide; 7772445Sassar void (*destructor)(struct live_images *); /* destructor for this */ 7872445Sassar struct live_images *next; 7972445Sassar unsigned int examined_p; 8072445Sassar void *fde; 8172445Sassar void *object_info; 8272445Sassar unsigned long info[2]; /* Future use. */ 8372445Sassar}; 8472445Sassar 8572445Sassar 8672445Sassar/* These routines are used only on Darwin versions before 10.2. 8772445Sassar Later versions have equivalent code in the system. 8872445Sassar Eventually, they might go away, although it might be a long time... */ 8972445Sassar 9072445Sassarstatic void darwin_unwind_dyld_remove_image_hook 9172445Sassar (struct mach_header *m, unsigned long s); 9272445Sassarstatic void darwin_unwind_dyld_remove_image_hook 9372445Sassar (struct mach_header *m, unsigned long s); 9472445Sassarextern void __darwin_gcc3_preregister_frame_info (void); 9572445Sassar 9672445Sassarstatic void 9772445Sassardarwin_unwind_dyld_add_image_hook (struct mach_header *mh, unsigned long slide) 9872445Sassar{ 9972445Sassar struct live_images *l = (struct live_images *)calloc (1, sizeof (*l)); 10072445Sassar l->mh = mh; 10172445Sassar l->vm_slide = slide; 10272445Sassar l->this_size = sizeof (*l); 10372445Sassar l->next = (struct live_images *) 10472445Sassar _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST); 10572445Sassar _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, l); 10672445Sassar} 10772445Sassar 10872445Sassarstatic void 10990926Snectardarwin_unwind_dyld_remove_image_hook (struct mach_header *m, unsigned long s) 11072445Sassar{ 11172445Sassar struct live_images *top, **lip, *destroy = NULL; 11272445Sassar 11372445Sassar /* Look for it in the list of live images and delete it. */ 11472445Sassar 11572445Sassar top = (struct live_images *) 11672445Sassar _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST); 11772445Sassar for (lip = ⊤ *lip != NULL; lip = &(*lip)->next) 11872445Sassar { 11972445Sassar if ((*lip)->mh == m && (*lip)->vm_slide == s) 12072445Sassar { 121233294Sstas destroy = *lip; 12272445Sassar *lip = destroy->next; /* unlink DESTROY */ 12372445Sassar 12472445Sassar if (destroy->this_size != sizeof (*destroy)) /* sanity check */ 125233294Sstas abort (); 12672445Sassar 12772445Sassar break; 12872445Sassar } 12972445Sassar } 13090926Snectar _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, top); 131233294Sstas 13272445Sassar /* Now that we have unlinked this from the image list, toss it. */ 13372445Sassar if (destroy != NULL) 13472445Sassar { 13572445Sassar if (destroy->destructor != NULL) 13672445Sassar (*destroy->destructor) (destroy); 13772445Sassar free (destroy); 13872445Sassar } 13972445Sassar} 14072445Sassar 14172445Sassarvoid 14272445Sassar__darwin_gcc3_preregister_frame_info (void) 14372445Sassar{ 14472445Sassar const _Tinfo_Node *info; 14572445Sassar _init_keymgr (); 14672445Sassar info = (_Tinfo_Node *)__keymgr_global[2]; 14772445Sassar if (info != NULL) 14872445Sassar { 14972445Sassar if (info->major_version >= KEYMGR_API_MAJOR_GCC3) 15072445Sassar return; 15172445Sassar /* Otherwise, use our own add_image_hooks. */ 15290926Snectar } 15372445Sassar 15472445Sassar _dyld_register_func_for_add_image (darwin_unwind_dyld_add_image_hook); 15572445Sassar _dyld_register_func_for_remove_image (darwin_unwind_dyld_remove_image_hook); 15672445Sassar} 15772445Sassar 15872445Sassar#endif /* __ppc__ */ 159178825Sdfr