unwind-dw2-fde-darwin.c revision 169689
1169689Skan/* Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. 2117395Skan 3132718Skan This file is part of GCC. 4117395Skan 5132718Skan GCC is free software; you can redistribute it and/or modify 6117395Skan it under the terms of the GNU General Public License as published by 7117395Skan the Free Software Foundation; either version 2, or (at your option) 8117395Skan any later version. 9117395Skan 10132718Skan GCC is distributed in the hope that it will be useful, 11117395Skan but WITHOUT ANY WARRANTY; without even the implied warranty of 12117395Skan MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13117395Skan GNU General Public License for more details. 14117395Skan 15117395Skan You should have received a copy of the GNU General Public License 16132718Skan along with GCC; see the file COPYING. If not, write to 17169689Skan the Free Software Foundation, 51 Franklin Street, Fifth Floor, 18169689Skan Boston, MA 02110-1301, USA. */ 19117395Skan 20117395Skan/* As a special exception, if you link this library with other files, 21117395Skan some of which are compiled with GCC, to produce an executable, 22117395Skan this library does not by itself cause the resulting executable 23117395Skan to be covered by the GNU General Public License. 24117395Skan This exception does not however invalidate any other reasons why 25117395Skan the executable file might be covered by the GNU General Public License. */ 26117395Skan 27117395Skan/* Locate the FDE entry for a given address, using Darwin's keymgr support. */ 28117395Skan 29117395Skan#include "tconfig.h" 30169689Skan#include "tsystem.h" 31117395Skan#include <string.h> 32117395Skan#include <stdlib.h> 33117395Skan#include "dwarf2.h" 34117395Skan#include "unwind.h" 35117395Skan#define NO_BASE_OF_ENCODED_VALUE 36117395Skan#define DWARF2_OBJECT_END_PTR_EXTENSION 37117395Skan#include "unwind-pe.h" 38117395Skan#include "unwind-dw2-fde.h" 39117395Skan/* Carefully don't include gthr.h. */ 40117395Skan 41117395Skantypedef int __gthread_mutex_t; 42117395Skan#define __gthread_mutex_lock(x) (void)(x) 43117395Skan#define __gthread_mutex_unlock(x) (void)(x) 44117395Skan 45132718Skanstatic const fde * _Unwind_Find_registered_FDE (void *pc, 46132718Skan struct dwarf_eh_bases *bases); 47117395Skan 48117395Skan#define _Unwind_Find_FDE _Unwind_Find_registered_FDE 49117395Skan#include "unwind-dw2-fde.c" 50117395Skan#undef _Unwind_Find_FDE 51117395Skan 52117395Skan/* KeyMgr stuff. */ 53117395Skan#define KEYMGR_GCC3_LIVE_IMAGE_LIST 301 /* loaded images */ 54117395Skan#define KEYMGR_GCC3_DW2_OBJ_LIST 302 /* Dwarf2 object list */ 55117395Skan 56117395Skanextern void *_keymgr_get_and_lock_processwide_ptr (int); 57117395Skanextern void _keymgr_set_and_unlock_processwide_ptr (int, void *); 58117395Skanextern void _keymgr_unlock_processwide_ptr (int); 59117395Skan 60117395Skanstruct mach_header; 61169689Skanstruct mach_header_64; 62117395Skanextern char *getsectdatafromheader (struct mach_header*, const char*, 63169689Skan const char *, unsigned long *); 64169689Skanextern char *getsectdatafromheader_64 (struct mach_header_64*, const char*, 65169689Skan const char *, unsigned long *); 66117395Skan 67117395Skan/* This is referenced from KEYMGR_GCC3_DW2_OBJ_LIST. */ 68117395Skanstruct km_object_info { 69117395Skan struct object *seen_objects; 70117395Skan struct object *unseen_objects; 71117395Skan unsigned spare[2]; 72117395Skan}; 73117395Skan 74117395Skan/* Node of KEYMGR_GCC3_LIVE_IMAGE_LIST. Info about each resident image. */ 75117395Skanstruct live_images { 76117395Skan unsigned long this_size; /* sizeof (live_images) */ 77117395Skan struct mach_header *mh; /* the image info */ 78117395Skan unsigned long vm_slide; 79117395Skan void (*destructor)(struct live_images *); /* destructor for this */ 80117395Skan struct live_images *next; 81117395Skan unsigned int examined_p; 82117395Skan void *fde; 83117395Skan void *object_info; 84117395Skan unsigned long info[2]; /* Future use. */ 85117395Skan}; 86117395Skan 87117395Skan/* Bits in the examined_p field of struct live_images. */ 88117395Skanenum { 89117395Skan EXAMINED_IMAGE_MASK = 1, /* We've seen this one. */ 90117395Skan ALLOCED_IMAGE_MASK = 2, /* The FDE entries were allocated by 91117395Skan malloc, and must be freed. This isn't 92117395Skan used by newer libgcc versions. */ 93117395Skan IMAGE_IS_TEXT_MASK = 4, /* This image is in the TEXT segment. */ 94117395Skan DESTRUCTOR_MAY_BE_CALLED_LIVE = 8 /* The destructor may be called on an 95117395Skan object that's part of the live 96117395Skan image list. */ 97117395Skan}; 98117395Skan 99117395Skan/* Delete any data we allocated on a live_images structure. Either 100117395Skan IMAGE has already been removed from the 101117395Skan KEYMGR_GCC3_LIVE_IMAGE_LIST and the struct will be deleted 102117395Skan after we return, or that list is locked and we're being called 103117395Skan because this object might be about to be unloaded. Called by 104117395Skan KeyMgr. */ 105117395Skan 106132718Skanstatic void 107117395Skanlive_image_destructor (struct live_images *image) 108117395Skan{ 109117395Skan if (image->object_info) 110117395Skan { 111132718Skan struct km_object_info *the_obj_info; 112117395Skan 113132718Skan the_obj_info = 114132718Skan _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST); 115132718Skan if (the_obj_info) 116132718Skan { 117132718Skan seen_objects = the_obj_info->seen_objects; 118132718Skan unseen_objects = the_obj_info->unseen_objects; 119132718Skan 120132718Skan /* Free any sorted arrays. */ 121132718Skan __deregister_frame_info_bases (image->fde); 122132718Skan 123132718Skan the_obj_info->seen_objects = seen_objects; 124132718Skan the_obj_info->unseen_objects = unseen_objects; 125132718Skan } 126132718Skan _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST, 127132718Skan the_obj_info); 128132718Skan 129117395Skan free (image->object_info); 130117395Skan image->object_info = NULL; 131117395Skan if (image->examined_p & ALLOCED_IMAGE_MASK) 132117395Skan free (image->fde); 133117395Skan image->fde = NULL; 134117395Skan } 135117395Skan image->examined_p = 0; 136117395Skan image->destructor = NULL; 137117395Skan} 138117395Skan 139117395Skan/* Run through the list of live images. If we can allocate memory, 140117395Skan give each unseen image a new `struct object'. Even if we can't, 141117395Skan check whether the PC is inside the FDE of each unseen image. 142117395Skan */ 143132718Skan 144132718Skanstatic inline const fde * 145117395Skanexamine_objects (void *pc, struct dwarf_eh_bases *bases, int dont_alloc) 146117395Skan{ 147132718Skan const fde *result = NULL; 148117395Skan struct live_images *image; 149117395Skan 150117395Skan image = _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST); 151117395Skan 152117395Skan for (; image != NULL; image = image->next) 153117395Skan if ((image->examined_p & EXAMINED_IMAGE_MASK) == 0) 154117395Skan { 155169689Skan char *fde = NULL; 156117395Skan unsigned long sz; 157132718Skan 158169689Skan /* For ppc only check whether or not we have __DATA eh frames. */ 159169689Skan#ifdef __ppc__ 160117395Skan fde = getsectdatafromheader (image->mh, "__DATA", "__eh_frame", &sz); 161169689Skan#endif 162169689Skan 163117395Skan if (fde == NULL) 164117395Skan { 165169689Skan#if __LP64__ 166169689Skan fde = getsectdatafromheader_64 ((struct mach_header_64 *) image->mh, 167169689Skan "__TEXT", "__eh_frame", &sz); 168169689Skan#else 169117395Skan fde = getsectdatafromheader (image->mh, "__TEXT", 170117395Skan "__eh_frame", &sz); 171169689Skan#endif 172117395Skan if (fde != NULL) 173117395Skan image->examined_p |= IMAGE_IS_TEXT_MASK; 174117395Skan } 175132718Skan 176117395Skan /* If .eh_frame is empty, don't register at all. */ 177117395Skan if (fde != NULL && sz > 0) 178117395Skan { 179117395Skan char *real_fde = (fde + image->vm_slide); 180117395Skan struct object *ob = NULL; 181117395Skan struct object panicob; 182132718Skan 183117395Skan if (! dont_alloc) 184117395Skan ob = calloc (1, sizeof (struct object)); 185117395Skan dont_alloc |= ob == NULL; 186117395Skan if (dont_alloc) 187117395Skan ob = &panicob; 188132718Skan 189117395Skan ob->pc_begin = (void *)-1; 190117395Skan ob->tbase = 0; 191117395Skan ob->dbase = 0; 192117395Skan ob->u.single = (struct dwarf_fde *)real_fde; 193117395Skan ob->s.i = 0; 194117395Skan ob->s.b.encoding = DW_EH_PE_omit; 195117395Skan ob->fde_end = real_fde + sz; 196132718Skan 197132718Skan image->fde = real_fde; 198132718Skan 199132718Skan result = search_object (ob, pc); 200132718Skan 201117395Skan if (! dont_alloc) 202117395Skan { 203132718Skan struct object **p; 204132718Skan 205117395Skan image->destructor = live_image_destructor; 206117395Skan image->object_info = ob; 207132718Skan 208132718Skan image->examined_p |= (EXAMINED_IMAGE_MASK 209117395Skan | DESTRUCTOR_MAY_BE_CALLED_LIVE); 210132718Skan 211132718Skan /* Insert the object into the classified list. */ 212132718Skan for (p = &seen_objects; *p ; p = &(*p)->next) 213132718Skan if ((*p)->pc_begin < ob->pc_begin) 214132718Skan break; 215132718Skan ob->next = *p; 216132718Skan *p = ob; 217117395Skan } 218132718Skan 219117395Skan if (result) 220117395Skan { 221117395Skan int encoding; 222169689Skan _Unwind_Ptr func; 223132718Skan 224117395Skan bases->tbase = ob->tbase; 225117395Skan bases->dbase = ob->dbase; 226132718Skan 227117395Skan encoding = ob->s.b.encoding; 228117395Skan if (ob->s.b.mixed_encoding) 229117395Skan encoding = get_fde_encoding (result); 230132718Skan read_encoded_value_with_base (encoding, 231117395Skan base_from_object (encoding, ob), 232169689Skan result->pc_begin, &func); 233169689Skan bases->func = (void *) func; 234117395Skan break; 235117395Skan } 236117395Skan } 237117395Skan else 238117395Skan image->examined_p |= EXAMINED_IMAGE_MASK; 239117395Skan } 240117395Skan 241117395Skan _keymgr_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST); 242117395Skan 243117395Skan return result; 244117395Skan} 245117395Skan 246132718Skanconst fde * 247117395Skan_Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) 248117395Skan{ 249117395Skan struct km_object_info *the_obj_info; 250132718Skan const fde *ret = NULL; 251117395Skan 252132718Skan the_obj_info = 253117395Skan _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST); 254117395Skan if (! the_obj_info) 255117395Skan the_obj_info = calloc (1, sizeof (*the_obj_info)); 256132718Skan 257117395Skan if (the_obj_info != NULL) 258117395Skan { 259117395Skan seen_objects = the_obj_info->seen_objects; 260117395Skan unseen_objects = the_obj_info->unseen_objects; 261132718Skan 262117395Skan ret = _Unwind_Find_registered_FDE (pc, bases); 263117395Skan } 264132718Skan 265117395Skan /* OK, didn't find it in the list of FDEs we've seen before, 266117395Skan so go through and look at the new ones. */ 267117395Skan if (ret == NULL) 268117395Skan ret = examine_objects (pc, bases, the_obj_info == NULL); 269117395Skan 270117395Skan if (the_obj_info != NULL) 271117395Skan { 272117395Skan the_obj_info->seen_objects = seen_objects; 273117395Skan the_obj_info->unseen_objects = unseen_objects; 274117395Skan } 275132718Skan _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST, 276132718Skan the_obj_info); 277117395Skan return ret; 278117395Skan} 279