* doc/contrib.texi: Fix alphabetical order. Fix typos. Improve
[official-gcc.git] / gcc / unwind-sjlj.c
bloba6360a1720e28a5a77afc2fbfe579ee8a52916e4
1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 #include "tconfig.h"
22 #include "tsystem.h"
23 #include "unwind.h"
24 #include "gthr.h"
26 #if USING_SJLJ_EXCEPTIONS
28 #ifdef DONT_USE_BUILTIN_SETJMP
29 #include <setjmp.h>
30 #else
31 #define setjmp __builtin_setjmp
32 #define longjmp __builtin_longjmp
33 #endif
35 /* This structure is allocated on the stack of the target function.
36 This must match the definition created in except.c:init_eh. */
37 struct SjLj_Function_Context
39 /* This is the chain through all registered contexts. It is
40 filled in by _Unwind_SjLj_Register. */
41 struct SjLj_Function_Context *prev;
43 /* This is assigned in by the target function before every call
44 to the index of the call site in the lsda. It is assigned by
45 the personality routine to the landing pad index. */
46 int call_site;
48 /* This is how data is returned from the personality routine to
49 the target function's handler. */
50 _Unwind_Word data[4];
52 /* These are filled in once by the target function before any
53 exceptions are expected to be handled. */
54 _Unwind_Personality_Fn personality;
55 void *lsda;
57 #ifdef DONT_USE_BUILTIN_SETJMP
58 /* We don't know what sort of alignment requirements the system
59 jmp_buf has. We over estimated in except.c, and now we have
60 to match that here just in case the system *didn't* have more
61 restrictive requirements. */
62 jmp_buf jbuf __attribute__((aligned));
63 #else
64 void *jbuf[];
65 #endif
68 struct _Unwind_Context
70 struct SjLj_Function_Context *fc;
73 typedef struct
75 _Unwind_Personality_Fn personality;
76 } _Unwind_FrameState;
79 /* Manage the chain of registered function contexts. */
81 /* Single threaded fallback chain. */
82 static struct SjLj_Function_Context *fc_static;
84 #if __GTHREADS
85 static __gthread_key_t fc_key;
86 static int use_fc_key = -1;
88 static void
89 fc_key_dtor (void *ptr)
91 __gthread_key_dtor (fc_key, ptr);
94 static void
95 fc_key_init (void)
97 use_fc_key = __gthread_key_create (&fc_key, fc_key_dtor) == 0;
100 static void
101 fc_key_init_once (void)
103 static __gthread_once_t once = __GTHREAD_ONCE_INIT;
104 if (__gthread_once (&once, fc_key_init) != 0 || use_fc_key < 0)
105 use_fc_key = 0;
107 #endif
109 void
110 _Unwind_SjLj_Register (struct SjLj_Function_Context *fc)
112 #if __GTHREADS
113 if (use_fc_key < 0)
114 fc_key_init_once ();
116 if (use_fc_key)
118 fc->prev = __gthread_getspecific (fc_key);
119 __gthread_setspecific (fc_key, fc);
121 else
122 #endif
124 fc->prev = fc_static;
125 fc_static = fc;
129 static inline struct SjLj_Function_Context *
130 _Unwind_SjLj_GetContext (void)
132 #if __GTHREADS
133 if (use_fc_key < 0)
134 fc_key_init_once ();
136 if (use_fc_key)
137 return __gthread_getspecific (fc_key);
138 #endif
139 return fc_static;
142 static inline void
143 _Unwind_SjLj_SetContext (struct SjLj_Function_Context *fc)
145 #if __GTHREADS
146 if (use_fc_key < 0)
147 fc_key_init_once ();
149 if (use_fc_key)
150 __gthread_setspecific (fc_key, fc);
151 else
152 #endif
153 fc_static = fc;
156 void
157 _Unwind_SjLj_Unregister (struct SjLj_Function_Context *fc)
159 _Unwind_SjLj_SetContext (fc->prev);
163 /* Get/set the return data value at INDEX in CONTEXT. */
165 _Unwind_Word
166 _Unwind_GetGR (struct _Unwind_Context *context, int index)
168 return context->fc->data[index];
171 void
172 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
174 context->fc->data[index] = val;
177 /* Get the call-site index as saved in CONTEXT. */
179 _Unwind_Ptr
180 _Unwind_GetIP (struct _Unwind_Context *context)
182 return context->fc->call_site + 1;
185 /* Set the return landing pad index in CONTEXT. */
187 void
188 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
190 context->fc->call_site = val - 1;
193 void *
194 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
196 return context->fc->lsda;
199 _Unwind_Ptr
200 _Unwind_GetRegionStart (struct _Unwind_Context *context)
202 return 0;
205 #ifndef __ia64__
206 _Unwind_Ptr
207 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
209 return 0;
212 _Unwind_Ptr
213 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
215 return 0;
217 #endif
219 static inline _Unwind_Reason_Code
220 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
222 if (context->fc == NULL)
224 fs->personality = NULL;
225 return _URC_END_OF_STACK;
227 else
229 fs->personality = context->fc->personality;
230 return _URC_NO_REASON;
234 static inline void
235 uw_update_context (struct _Unwind_Context *context,
236 _Unwind_FrameState *fs __attribute__((unused)) )
238 context->fc = context->fc->prev;
241 static inline void
242 uw_init_context (struct _Unwind_Context *context)
244 context->fc = _Unwind_SjLj_GetContext ();
247 /* ??? There appear to be bugs in integrate.c wrt __builtin_longjmp and
248 virtual-stack-vars. An inline version of this segfaults on Sparc. */
249 #define uw_install_context(CURRENT, TARGET) \
250 do { \
251 _Unwind_SjLj_SetContext ((TARGET)->fc); \
252 longjmp ((TARGET)->fc->jbuf, 1); \
253 } while (0)
256 static inline _Unwind_Ptr
257 uw_identify_context (struct _Unwind_Context *context)
259 return (_Unwind_Ptr) context->fc;
263 /* Play games with unwind symbols so that we can have call frame
264 and sjlj symbols in the same shared library. Not that you can
265 use them simultaneously... */
266 #define _Unwind_RaiseException _Unwind_SjLj_RaiseException
267 #define _Unwind_ForcedUnwind _Unwind_SjLj_ForcedUnwind
268 #define _Unwind_Resume _Unwind_SjLj_Resume
270 #include "unwind.inc"
272 #endif /* USING_SJLJ_EXCEPTIONS */