OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [unwind-sjlj.c] - Blame information for rev 20

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/* SJLJ exception handling and frame unwind runtime interface routines.
2
   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3
   Free Software Foundation, Inc.
4
 
5
   This file is part of GCC.
6
 
7
   GCC is free software; you can redistribute it and/or modify it
8
   under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 2, or (at your option)
10
   any later version.
11
 
12
   In addition to the permissions in the GNU General Public License, the
13
   Free Software Foundation gives you unlimited permission to link the
14
   compiled version of this file into combinations with other programs,
15
   and to distribute those combinations without any restriction coming
16
   from the use of this file.  (The General Public License restrictions
17
   do apply in other respects; for example, they cover modification of
18
   the file, and distribution when not linked into a combined
19
   executable.)
20
 
21
   GCC is distributed in the hope that it will be useful, but WITHOUT
22
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
24
   License for more details.
25
 
26
   You should have received a copy of the GNU General Public License
27
   along with GCC; see the file COPYING.  If not, write to the Free
28
   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
29
   02110-1301, USA.  */
30
 
31
#include "tconfig.h"
32
#include "tsystem.h"
33
#include "coretypes.h"
34
#include "tm.h"
35
#include "unwind.h"
36
#include "gthr.h"
37
 
38
#ifdef __USING_SJLJ_EXCEPTIONS__
39
 
40
#ifdef DONT_USE_BUILTIN_SETJMP
41
#ifndef inhibit_libc
42
#include <setjmp.h>
43
#else
44
typedef void *jmp_buf[JMP_BUF_SIZE];
45
extern void longjmp(jmp_buf, int) __attribute__((noreturn));
46
#endif
47
#else
48
#define setjmp __builtin_setjmp
49
#define longjmp __builtin_longjmp
50
#endif
51
 
52
/* This structure is allocated on the stack of the target function.
53
   This must match the definition created in except.c:init_eh.  */
54
struct SjLj_Function_Context
55
{
56
  /* This is the chain through all registered contexts.  It is
57
     filled in by _Unwind_SjLj_Register.  */
58
  struct SjLj_Function_Context *prev;
59
 
60
  /* This is assigned in by the target function before every call
61
     to the index of the call site in the lsda.  It is assigned by
62
     the personality routine to the landing pad index.  */
63
  int call_site;
64
 
65
  /* This is how data is returned from the personality routine to
66
     the target function's handler.  */
67
  _Unwind_Word data[4];
68
 
69
  /* These are filled in once by the target function before any
70
     exceptions are expected to be handled.  */
71
  _Unwind_Personality_Fn personality;
72
  void *lsda;
73
 
74
#ifdef DONT_USE_BUILTIN_SETJMP
75
  /* We don't know what sort of alignment requirements the system
76
     jmp_buf has.  We over estimated in except.c, and now we have
77
     to match that here just in case the system *didn't* have more
78
     restrictive requirements.  */
79
  jmp_buf jbuf __attribute__((aligned));
80
#else
81
  void *jbuf[];
82
#endif
83
};
84
 
85
struct _Unwind_Context
86
{
87
  struct SjLj_Function_Context *fc;
88
};
89
 
90
typedef struct
91
{
92
  _Unwind_Personality_Fn personality;
93
} _Unwind_FrameState;
94
 
95
 
96
/* Manage the chain of registered function contexts.  */
97
 
98
/* Single threaded fallback chain.  */
99
static struct SjLj_Function_Context *fc_static;
100
 
101
#if __GTHREADS
102
static __gthread_key_t fc_key;
103
static int use_fc_key = -1;
104
 
105
static void
106
fc_key_init (void)
107
{
108
  use_fc_key = __gthread_key_create (&fc_key, 0) == 0;
109
}
110
 
111
static void
112
fc_key_init_once (void)
113
{
114
  static __gthread_once_t once = __GTHREAD_ONCE_INIT;
115
  if (__gthread_once (&once, fc_key_init) != 0 || use_fc_key < 0)
116
    use_fc_key = 0;
117
}
118
#endif
119
 
120
void
121
_Unwind_SjLj_Register (struct SjLj_Function_Context *fc)
122
{
123
#if __GTHREADS
124
  if (use_fc_key < 0)
125
    fc_key_init_once ();
126
 
127
  if (use_fc_key)
128
    {
129
      fc->prev = __gthread_getspecific (fc_key);
130
      __gthread_setspecific (fc_key, fc);
131
    }
132
  else
133
#endif
134
    {
135
      fc->prev = fc_static;
136
      fc_static = fc;
137
    }
138
}
139
 
140
static inline struct SjLj_Function_Context *
141
_Unwind_SjLj_GetContext (void)
142
{
143
#if __GTHREADS
144
  if (use_fc_key < 0)
145
    fc_key_init_once ();
146
 
147
  if (use_fc_key)
148
    return __gthread_getspecific (fc_key);
149
#endif
150
  return fc_static;
151
}
152
 
153
static inline void
154
_Unwind_SjLj_SetContext (struct SjLj_Function_Context *fc)
155
{
156
#if __GTHREADS
157
  if (use_fc_key < 0)
158
    fc_key_init_once ();
159
 
160
  if (use_fc_key)
161
    __gthread_setspecific (fc_key, fc);
162
  else
163
#endif
164
    fc_static = fc;
165
}
166
 
167
void
168
_Unwind_SjLj_Unregister (struct SjLj_Function_Context *fc)
169
{
170
  _Unwind_SjLj_SetContext (fc->prev);
171
}
172
 
173
 
174
/* Get/set the return data value at INDEX in CONTEXT.  */
175
 
176
_Unwind_Word
177
_Unwind_GetGR (struct _Unwind_Context *context, int index)
178
{
179
  return context->fc->data[index];
180
}
181
 
182
/* Get the value of the CFA as saved in CONTEXT.  */
183
 
184
_Unwind_Word
185
_Unwind_GetCFA (struct _Unwind_Context *context __attribute__((unused)))
186
{
187
  /* ??? Ideally __builtin_setjmp places the CFA in the jmpbuf.  */
188
 
189
#ifndef DONT_USE_BUILTIN_SETJMP
190
  /* This is a crude imitation of the CFA: the saved stack pointer.
191
     This is roughly the CFA of the frame before CONTEXT.  When using the
192
     DWARF-2 unwinder _Unwind_GetCFA returns the CFA of the frame described
193
     by CONTEXT instead; but for DWARF-2 the cleanups associated with
194
     CONTEXT have already been run, and for SJLJ they have not yet been.  */
195
  if (context->fc != NULL)
196
    return (_Unwind_Word) context->fc->jbuf[2];
197
#endif
198
 
199
  /* Otherwise we're out of luck for now.  */
200
  return (_Unwind_Word) 0;
201
}
202
 
203
void
204
_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
205
{
206
  context->fc->data[index] = val;
207
}
208
 
209
/* Get the call-site index as saved in CONTEXT.  */
210
 
211
_Unwind_Ptr
212
_Unwind_GetIP (struct _Unwind_Context *context)
213
{
214
  return context->fc->call_site + 1;
215
}
216
 
217
/* Set the return landing pad index in CONTEXT.  */
218
 
219
void
220
_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
221
{
222
  context->fc->call_site = val - 1;
223
}
224
 
225
void *
226
_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
227
{
228
  return context->fc->lsda;
229
}
230
 
231
_Unwind_Ptr
232
_Unwind_GetRegionStart (struct _Unwind_Context *context __attribute__((unused)) )
233
{
234
  return 0;
235
}
236
 
237
void *
238
_Unwind_FindEnclosingFunction (void *pc __attribute__((unused)))
239
{
240
  return NULL;
241
}
242
 
243
#ifndef __ia64__
244
_Unwind_Ptr
245
_Unwind_GetDataRelBase (struct _Unwind_Context *context __attribute__((unused)) )
246
{
247
  return 0;
248
}
249
 
250
_Unwind_Ptr
251
_Unwind_GetTextRelBase (struct _Unwind_Context *context __attribute__((unused)) )
252
{
253
  return 0;
254
}
255
#endif
256
 
257
static inline _Unwind_Reason_Code
258
uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
259
{
260
  if (context->fc == NULL)
261
    {
262
      fs->personality = NULL;
263
      return _URC_END_OF_STACK;
264
    }
265
  else
266
    {
267
      fs->personality = context->fc->personality;
268
      return _URC_NO_REASON;
269
    }
270
}
271
 
272
static inline void
273
uw_update_context (struct _Unwind_Context *context,
274
                   _Unwind_FrameState *fs __attribute__((unused)) )
275
{
276
  context->fc = context->fc->prev;
277
}
278
 
279
static void
280
uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
281
{
282
  _Unwind_SjLj_Unregister (context->fc);
283
  uw_update_context (context, fs);
284
}
285
 
286
static inline void
287
uw_init_context (struct _Unwind_Context *context)
288
{
289
  context->fc = _Unwind_SjLj_GetContext ();
290
}
291
 
292
static void __attribute__((noreturn))
293
uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
294
                    struct _Unwind_Context *target)
295
{
296
  _Unwind_SjLj_SetContext (target->fc);
297
  longjmp (target->fc->jbuf, 1);
298
}
299
 
300
static inline _Unwind_Ptr
301
uw_identify_context (struct _Unwind_Context *context)
302
{
303
  return (_Unwind_Ptr) context->fc;
304
}
305
 
306
 
307
/* Play games with unwind symbols so that we can have call frame
308
   and sjlj symbols in the same shared library.  Not that you can
309
   use them simultaneously...  */
310
#define _Unwind_RaiseException          _Unwind_SjLj_RaiseException
311
#define _Unwind_ForcedUnwind            _Unwind_SjLj_ForcedUnwind
312
#define _Unwind_Resume                  _Unwind_SjLj_Resume
313
#define _Unwind_Resume_or_Rethrow       _Unwind_SjLj_Resume_or_Rethrow
314
 
315
#include "unwind.inc"
316
 
317
#endif /* USING_SJLJ_EXCEPTIONS */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.