]> gcc.gnu.org Git - gcc.git/blame - gcc/unwind-sjlj.c
* gcc.c-torture/execute/divmod-1.c: Convert to ANSI.
[gcc.git] / gcc / unwind-sjlj.c
CommitLineData
52a11cbf
RH
1/* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
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.
10
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.
15
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. */
20
21#include "tconfig.h"
22#include "tsystem.h"
23#include "unwind.h"
24#include "gthr.h"
25
26#if USING_SJLJ_EXCEPTIONS
27
28#ifdef DONT_USE_BUILTIN_SETJMP
29#include <setjmp.h>
30#else
31#define setjmp __builtin_setjmp
32#define longjmp __builtin_longjmp
33#endif
34
35/* This structure is allocated on the stack of the target function.
36 This must match the definition created in except.c:init_eh. */
37struct SjLj_Function_Context
38{
39 /* This is the chain through all registered contexts. It is
40 filled in by _Unwind_SjLj_Register. */
41 struct SjLj_Function_Context *prev;
42
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;
47
48 /* This is how data is returned from the personality routine to
49 the target function's handler. */
50 _Unwind_Word data[4];
51
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;
56
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
66};
67
68struct _Unwind_Context
69{
70 struct SjLj_Function_Context *fc;
71};
72
73typedef struct
74{
75 _Unwind_Personality_Fn personality;
76} _Unwind_FrameState;
77
78\f
79/* Manage the chain of registered function contexts. */
80
81/* Single threaded fallback chain. */
82static struct SjLj_Function_Context *fc_static;
83
84#if __GTHREADS
85static __gthread_key_t fc_key;
86static int use_fc_key = -1;
87
88static void
89fc_key_dtor (void *ptr)
90{
91 __gthread_key_dtor (fc_key, ptr);
92}
93
94static void
95fc_key_init (void)
96{
97 use_fc_key = __gthread_key_create (&fc_key, fc_key_dtor) == 0;
98}
99
100static void
101fc_key_init_once (void)
102{
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;
106}
107#endif
108
109void
110_Unwind_SjLj_Register (struct SjLj_Function_Context *fc)
111{
112#if __GTHREADS
113 if (use_fc_key < 0)
114 fc_key_init_once ();
115
116 if (use_fc_key)
117 {
118 fc->prev = __gthread_getspecific (fc_key);
119 __gthread_setspecific (fc_key, fc);
120 }
121 else
122#endif
123 {
124 fc->prev = fc_static;
125 fc_static = fc;
126 }
127}
128
129static inline struct SjLj_Function_Context *
130_Unwind_SjLj_GetContext (void)
131{
132#if __GTHREADS
133 if (use_fc_key < 0)
134 fc_key_init_once ();
135
136 if (use_fc_key)
137 return __gthread_getspecific (fc_key);
138#endif
139 return fc_static;
140}
141
142static inline void
143_Unwind_SjLj_SetContext (struct SjLj_Function_Context *fc)
144{
145#if __GTHREADS
146 if (use_fc_key < 0)
147 fc_key_init_once ();
148
149 if (use_fc_key)
150 __gthread_setspecific (fc_key, fc);
151 else
152#endif
153 fc_static = fc;
154}
155
156void
157_Unwind_SjLj_Unregister (struct SjLj_Function_Context *fc)
158{
159 _Unwind_SjLj_SetContext (fc->prev);
160}
161
162\f
163/* Get/set the return data value at INDEX in CONTEXT. */
164
165_Unwind_Word
166_Unwind_GetGR (struct _Unwind_Context *context, int index)
167{
168 return context->fc->data[index];
169}
170
171void
172_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
173{
174 context->fc->data[index] = val;
175}
176
177/* Get the call-site index as saved in CONTEXT. */
178
179_Unwind_Ptr
180_Unwind_GetIP (struct _Unwind_Context *context)
181{
182 return context->fc->call_site + 1;
183}
184
185/* Set the return landing pad index in CONTEXT. */
186
187void
188_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
189{
190 context->fc->call_site = val - 1;
191}
192
193void *
194_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
195{
196 return context->fc->lsda;
197}
198
199_Unwind_Ptr
200_Unwind_GetRegionStart (struct _Unwind_Context *context)
201{
202 return 0;
203}
204
48941cb8
RH
205#ifndef __ia64__
206_Unwind_Ptr
207_Unwind_GetDataRelBase (struct _Unwind_Context *context)
208{
209 return 0;
210}
211
212_Unwind_Ptr
213_Unwind_GetTextRelBase (struct _Unwind_Context *context)
214{
215 return 0;
216}
217#endif
52a11cbf
RH
218\f
219static inline _Unwind_Reason_Code
220uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
221{
222 if (context->fc == NULL)
223 {
224 fs->personality = NULL;
225 return _URC_END_OF_STACK;
226 }
227 else
228 {
229 fs->personality = context->fc->personality;
230 return _URC_NO_REASON;
231 }
232}
233
234static inline void
235uw_update_context (struct _Unwind_Context *context,
236 _Unwind_FrameState *fs __attribute__((unused)) )
237{
238 context->fc = context->fc->prev;
239}
240
241static inline void
242uw_init_context (struct _Unwind_Context *context)
243{
244 context->fc = _Unwind_SjLj_GetContext ();
245}
246
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)
254
255
256static inline _Unwind_Ptr
257uw_identify_context (struct _Unwind_Context *context)
258{
259 return (_Unwind_Ptr) context->fc;
260}
261
262
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
269
270#include "unwind.inc"
271
272#endif /* USING_SJLJ_EXCEPTIONS */
This page took 0.209999 seconds and 5 git commands to generate.