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)
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. */
26 #if USING_SJLJ_EXCEPTIONS
28 #ifdef DONT_USE_BUILTIN_SETJMP
31 #define setjmp __builtin_setjmp
32 #define longjmp __builtin_longjmp
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. */
48 /* This is how data is returned from the personality routine to
49 the target function's handler. */
52 /* These are filled in once by the target function before any
53 exceptions are expected to be handled. */
54 _Unwind_Personality_Fn personality
;
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
));
68 struct _Unwind_Context
70 struct SjLj_Function_Context
*fc
;
75 _Unwind_Personality_Fn personality
;
79 /* Manage the chain of registered function contexts. */
81 /* Single threaded fallback chain. */
82 static struct SjLj_Function_Context
*fc_static
;
85 static __gthread_key_t fc_key
;
86 static int use_fc_key
= -1;
89 fc_key_dtor (void *ptr
)
91 __gthread_key_dtor (fc_key
, ptr
);
97 use_fc_key
= __gthread_key_create (&fc_key
, fc_key_dtor
) == 0;
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)
110 _Unwind_SjLj_Register (struct SjLj_Function_Context
*fc
)
118 fc
->prev
= __gthread_getspecific (fc_key
);
119 __gthread_setspecific (fc_key
, fc
);
124 fc
->prev
= fc_static
;
129 static inline struct SjLj_Function_Context
*
130 _Unwind_SjLj_GetContext (void)
137 return __gthread_getspecific (fc_key
);
143 _Unwind_SjLj_SetContext (struct SjLj_Function_Context
*fc
)
150 __gthread_setspecific (fc_key
, fc
);
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. */
166 _Unwind_GetGR (struct _Unwind_Context
*context
, int index
)
168 return context
->fc
->data
[index
];
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. */
180 _Unwind_GetIP (struct _Unwind_Context
*context
)
182 return context
->fc
->call_site
+ 1;
185 /* Set the return landing pad index in CONTEXT. */
188 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
190 context
->fc
->call_site
= val
- 1;
194 _Unwind_GetLanguageSpecificData (struct _Unwind_Context
*context
)
196 return context
->fc
->lsda
;
200 _Unwind_GetRegionStart (struct _Unwind_Context
*context
)
207 _Unwind_GetDataRelBase (struct _Unwind_Context
*context
)
213 _Unwind_GetTextRelBase (struct _Unwind_Context
*context
)
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
;
229 fs
->personality
= context
->fc
->personality
;
230 return _URC_NO_REASON
;
235 uw_update_context (struct _Unwind_Context
*context
,
236 _Unwind_FrameState
*fs
__attribute__((unused
)) )
238 context
->fc
= context
->fc
->prev
;
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) \
251 _Unwind_SjLj_SetContext ((TARGET)->fc); \
252 longjmp ((TARGET)->fc->jbuf, 1); \
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 */