X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Funwind-sjlj.c;h=c71e79858eec3ea6e512377f1d58faebd4bff12c;hb=a1ef431d4728e13196caceb616d9c131888e65ca;hp=46f30ae1d8f46a2e6fd82e2662399dc525803378;hpb=0ff1830753ddd90564639afac3d3013187f0c8a6;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/unwind-sjlj.c b/gcc/unwind-sjlj.c index 46f30ae1d8f..c71e79858ee 100644 --- a/gcc/unwind-sjlj.c +++ b/gcc/unwind-sjlj.c @@ -1,11 +1,12 @@ -/* DWARF2 exception handling and frame unwind runtime interface routines. - Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +/* SJLJ exception handling and frame unwind runtime interface routines. + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, + 2009 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, but WITHOUT @@ -13,17 +14,23 @@ 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. + + 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 + . */ #include "tconfig.h" #include "tsystem.h" +#include "coretypes.h" +#include "tm.h" #include "unwind.h" #include "gthr.h" -#if USING_SJLJ_EXCEPTIONS +#ifdef __USING_SJLJ_EXCEPTIONS__ #ifdef DONT_USE_BUILTIN_SETJMP #ifndef inhibit_libc @@ -33,10 +40,14 @@ typedef void *jmp_buf[JMP_BUF_SIZE]; extern void longjmp(jmp_buf, int) __attribute__((noreturn)); #endif #else -#define setjmp __builtin_setjmp #define longjmp __builtin_longjmp #endif +/* The setjmp side is dealt with in the except.c file. */ +#undef setjmp +#define setjmp setjmp_should_not_be_used_in_this_file + + /* This structure is allocated on the stack of the target function. This must match the definition created in except.c:init_eh. */ struct SjLj_Function_Context @@ -62,7 +73,7 @@ struct SjLj_Function_Context #ifdef DONT_USE_BUILTIN_SETJMP /* We don't know what sort of alignment requirements the system jmp_buf has. We over estimated in except.c, and now we have - to match that here just in case the system *didn't* have more + to match that here just in case the system *didn't* have more restrictive requirements. */ jmp_buf jbuf __attribute__((aligned)); #else @@ -75,7 +86,7 @@ struct _Unwind_Context struct SjLj_Function_Context *fc; }; -typedef struct +typedef struct { _Unwind_Personality_Fn personality; } _Unwind_FrameState; @@ -91,15 +102,9 @@ static __gthread_key_t fc_key; static int use_fc_key = -1; static void -fc_key_dtor (void *ptr) -{ - __gthread_key_dtor (fc_key, ptr); -} - -static void fc_key_init (void) { - use_fc_key = __gthread_key_create (&fc_key, fc_key_dtor) == 0; + use_fc_key = __gthread_key_create (&fc_key, 0) == 0; } static void @@ -173,6 +178,27 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index) return context->fc->data[index]; } +/* Get the value of the CFA as saved in CONTEXT. */ + +_Unwind_Word +_Unwind_GetCFA (struct _Unwind_Context *context __attribute__((unused))) +{ + /* ??? Ideally __builtin_setjmp places the CFA in the jmpbuf. */ + +#ifndef DONT_USE_BUILTIN_SETJMP + /* This is a crude imitation of the CFA: the saved stack pointer. + This is roughly the CFA of the frame before CONTEXT. When using the + DWARF-2 unwinder _Unwind_GetCFA returns the CFA of the frame described + by CONTEXT instead; but for DWARF-2 the cleanups associated with + CONTEXT have already been run, and for SJLJ they have not yet been. */ + if (context->fc != NULL) + return (_Unwind_Word) context->fc->jbuf[2]; +#endif + + /* Otherwise we're out of luck for now. */ + return (_Unwind_Word) 0; +} + void _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val) { @@ -187,6 +213,16 @@ _Unwind_GetIP (struct _Unwind_Context *context) return context->fc->call_site + 1; } +_Unwind_Ptr +_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn) +{ + *ip_before_insn = 0; + if (context->fc != NULL) + return context->fc->call_site + 1; + else + return 0; +} + /* Set the return landing pad index in CONTEXT. */ void @@ -202,20 +238,26 @@ _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context) } _Unwind_Ptr -_Unwind_GetRegionStart (struct _Unwind_Context *context) +_Unwind_GetRegionStart (struct _Unwind_Context *context __attribute__((unused)) ) { return 0; } +void * +_Unwind_FindEnclosingFunction (void *pc __attribute__((unused))) +{ + return NULL; +} + #ifndef __ia64__ _Unwind_Ptr -_Unwind_GetDataRelBase (struct _Unwind_Context *context) +_Unwind_GetDataRelBase (struct _Unwind_Context *context __attribute__((unused)) ) { return 0; } _Unwind_Ptr -_Unwind_GetTextRelBase (struct _Unwind_Context *context) +_Unwind_GetTextRelBase (struct _Unwind_Context *context __attribute__((unused)) ) { return 0; } @@ -243,20 +285,26 @@ uw_update_context (struct _Unwind_Context *context, context->fc = context->fc->prev; } -static inline void +static void +uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs) +{ + _Unwind_SjLj_Unregister (context->fc); + uw_update_context (context, fs); +} + +static inline void uw_init_context (struct _Unwind_Context *context) { context->fc = _Unwind_SjLj_GetContext (); } -/* ??? There appear to be bugs in integrate.c wrt __builtin_longjmp and - virtual-stack-vars. An inline version of this segfaults on Sparc. */ -#define uw_install_context(CURRENT, TARGET) \ - do { \ - _Unwind_SjLj_SetContext ((TARGET)->fc); \ - longjmp ((TARGET)->fc->jbuf, 1); \ - } while (0) - +static void __attribute__((noreturn)) +uw_install_context (struct _Unwind_Context *current __attribute__((unused)), + struct _Unwind_Context *target) +{ + _Unwind_SjLj_SetContext (target->fc); + longjmp (target->fc->jbuf, 1); +} static inline _Unwind_Ptr uw_identify_context (struct _Unwind_Context *context) @@ -271,6 +319,7 @@ uw_identify_context (struct _Unwind_Context *context) #define _Unwind_RaiseException _Unwind_SjLj_RaiseException #define _Unwind_ForcedUnwind _Unwind_SjLj_ForcedUnwind #define _Unwind_Resume _Unwind_SjLj_Resume +#define _Unwind_Resume_or_Rethrow _Unwind_SjLj_Resume_or_Rethrow #include "unwind.inc"