X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Funwind-dw2-fde-darwin.c;h=a672e936d5bdf0f1cef956f896a982caef9f9ff4;hb=f3c9277e8d292c983a70d13c4feb45dd7bf22ed3;hp=8bd161f2c038f308bf4332b80c12a2e0f11d40c8;hpb=5a8b6e6a1022a117dcee6d4ec929bb306d909973;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/unwind-dw2-fde-darwin.c b/gcc/unwind-dw2-fde-darwin.c index 8bd161f2c03..a672e936d5b 100644 --- a/gcc/unwind-dw2-fde-darwin.c +++ b/gcc/unwind-dw2-fde-darwin.c @@ -1,10 +1,11 @@ -/* Copyright (C) 2001, 2002 Free Software Foundation, Inc. +/* Copyright (C) 2001, 2002, 2003, 2005, 2009, 2010 + Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, @@ -12,21 +13,19 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING. If not, write to - the Free Software Foundation, 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. -/* As a special exception, if you link this library with other files, - some of which are compiled with GCC, to produce an executable, - this library does not by itself cause the resulting executable - to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ /* Locate the FDE entry for a given address, using Darwin's keymgr support. */ #include "tconfig.h" +#include "tsystem.h" #include #include #include "dwarf2.h" @@ -41,8 +40,8 @@ typedef int __gthread_mutex_t; #define __gthread_mutex_lock(x) (void)(x) #define __gthread_mutex_unlock(x) (void)(x) -static fde * _Unwind_Find_registered_FDE (void *pc, - struct dwarf_eh_bases *bases); +static const fde * _Unwind_Find_registered_FDE (void *pc, + struct dwarf_eh_bases *bases); #define _Unwind_Find_FDE _Unwind_Find_registered_FDE #include "unwind-dw2-fde.c" @@ -57,8 +56,11 @@ extern void _keymgr_set_and_unlock_processwide_ptr (int, void *); extern void _keymgr_unlock_processwide_ptr (int); struct mach_header; +struct mach_header_64; extern char *getsectdatafromheader (struct mach_header*, const char*, - const char *, unsigned long *); + const char *, unsigned long *); +extern char *getsectdatafromheader_64 (struct mach_header_64*, const char*, + const char *, unsigned long *); /* This is referenced from KEYMGR_GCC3_DW2_OBJ_LIST. */ struct km_object_info { @@ -86,37 +88,61 @@ enum { ALLOCED_IMAGE_MASK = 2, /* The FDE entries were allocated by malloc, and must be freed. This isn't used by newer libgcc versions. */ - IMAGE_IS_TEXT_MASK = 4 /* This image is in the TEXT segment. */ + IMAGE_IS_TEXT_MASK = 4, /* This image is in the TEXT segment. */ + DESTRUCTOR_MAY_BE_CALLED_LIVE = 8 /* The destructor may be called on an + object that's part of the live + image list. */ }; -/* Delete any data we allocated on a live_images structure. - IMAGE has already been removed from the KEYMGR_GCC3_LIVE_IMAGE_LIST. - Called by KeyMgr (which will delete the struct after we return.) */ +/* Delete any data we allocated on a live_images structure. Either + IMAGE has already been removed from the + KEYMGR_GCC3_LIVE_IMAGE_LIST and the struct will be deleted + after we return, or that list is locked and we're being called + because this object might be about to be unloaded. Called by + KeyMgr. */ -static void +static void live_image_destructor (struct live_images *image) { if (image->object_info) { - /* Free any sorted arrays. */ - __deregister_frame_info_bases (image->fde); + struct km_object_info *the_obj_info; + + the_obj_info = + _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST); + if (the_obj_info) + { + seen_objects = the_obj_info->seen_objects; + unseen_objects = the_obj_info->unseen_objects; + + /* Free any sorted arrays. */ + __deregister_frame_info_bases (image->fde); + + the_obj_info->seen_objects = seen_objects; + the_obj_info->unseen_objects = unseen_objects; + } + _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST, + the_obj_info); free (image->object_info); image->object_info = NULL; if (image->examined_p & ALLOCED_IMAGE_MASK) free (image->fde); + image->fde = NULL; } + image->examined_p = 0; + image->destructor = NULL; } /* Run through the list of live images. If we can allocate memory, give each unseen image a new `struct object'. Even if we can't, check whether the PC is inside the FDE of each unseen image. */ - -static inline fde * + +static inline const fde * examine_objects (void *pc, struct dwarf_eh_bases *bases, int dont_alloc) { - fde *result = NULL; + const fde *result = NULL; struct live_images *image; image = _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST); @@ -124,31 +150,40 @@ examine_objects (void *pc, struct dwarf_eh_bases *bases, int dont_alloc) for (; image != NULL; image = image->next) if ((image->examined_p & EXAMINED_IMAGE_MASK) == 0) { - char *fde; + char *fde = NULL; unsigned long sz; - + + /* For ppc only check whether or not we have __DATA eh frames. */ +#ifdef __ppc__ fde = getsectdatafromheader (image->mh, "__DATA", "__eh_frame", &sz); +#endif + if (fde == NULL) { +#if __LP64__ + fde = getsectdatafromheader_64 ((struct mach_header_64 *) image->mh, + "__TEXT", "__eh_frame", &sz); +#else fde = getsectdatafromheader (image->mh, "__TEXT", "__eh_frame", &sz); +#endif if (fde != NULL) image->examined_p |= IMAGE_IS_TEXT_MASK; } - + /* If .eh_frame is empty, don't register at all. */ if (fde != NULL && sz > 0) { char *real_fde = (fde + image->vm_slide); struct object *ob = NULL; struct object panicob; - + if (! dont_alloc) ob = calloc (1, sizeof (struct object)); dont_alloc |= ob == NULL; if (dont_alloc) ob = &panicob; - + ob->pc_begin = (void *)-1; ob->tbase = 0; ob->dbase = 0; @@ -156,34 +191,44 @@ examine_objects (void *pc, struct dwarf_eh_bases *bases, int dont_alloc) ob->s.i = 0; ob->s.b.encoding = DW_EH_PE_omit; ob->fde_end = real_fde + sz; - + + image->fde = real_fde; + + result = search_object (ob, pc); + if (! dont_alloc) { - ob->next = unseen_objects; - unseen_objects = ob; - + struct object **p; + image->destructor = live_image_destructor; image->object_info = ob; - - image->examined_p |= EXAMINED_IMAGE_MASK; + + image->examined_p |= (EXAMINED_IMAGE_MASK + | DESTRUCTOR_MAY_BE_CALLED_LIVE); + + /* Insert the object into the classified list. */ + for (p = &seen_objects; *p ; p = &(*p)->next) + if ((*p)->pc_begin < ob->pc_begin) + break; + ob->next = *p; + *p = ob; } - image->fde = real_fde; - - result = search_object (ob, pc); + if (result) { int encoding; - + _Unwind_Ptr func; + bases->tbase = ob->tbase; bases->dbase = ob->dbase; - + encoding = ob->s.b.encoding; if (ob->s.b.mixed_encoding) encoding = get_fde_encoding (result); - read_encoded_value_with_base (encoding, + read_encoded_value_with_base (encoding, base_from_object (encoding, ob), - result->pc_begin, - (_Unwind_Ptr *)&bases->func); + result->pc_begin, &func); + bases->func = (void *) func; break; } } @@ -196,25 +241,25 @@ examine_objects (void *pc, struct dwarf_eh_bases *bases, int dont_alloc) return result; } -fde * +const fde * _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) { struct km_object_info *the_obj_info; - fde *ret = NULL; + const fde *ret = NULL; - the_obj_info = + the_obj_info = _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST); if (! the_obj_info) the_obj_info = calloc (1, sizeof (*the_obj_info)); - + if (the_obj_info != NULL) { seen_objects = the_obj_info->seen_objects; unseen_objects = the_obj_info->unseen_objects; - + ret = _Unwind_Find_registered_FDE (pc, bases); } - + /* OK, didn't find it in the list of FDEs we've seen before, so go through and look at the new ones. */ if (ret == NULL) @@ -224,8 +269,20 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) { the_obj_info->seen_objects = seen_objects; the_obj_info->unseen_objects = unseen_objects; - _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST, - the_obj_info); } + _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST, + the_obj_info); return ret; } + +void * +_darwin10_Unwind_FindEnclosingFunction (void *pc) +{ + struct dwarf_eh_bases bases; + const struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases); + if (fde) + return bases.func; + else + return NULL; +} +