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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [unwind-sjlj.c] - Blame information for rev 858

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

Line No. Rev Author Line
1 38 julius
/* SJLJ exception handling and frame unwind runtime interface routines.
2
   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
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 longjmp __builtin_longjmp
49
#endif
50
 
51
/* The setjmp side is dealt with in the except.c file.  */
52
#undef setjmp
53
#define setjmp setjmp_should_not_be_used_in_this_file
54
 
55
 
56
/* This structure is allocated on the stack of the target function.
57
   This must match the definition created in except.c:init_eh.  */
58
struct SjLj_Function_Context
59
{
60
  /* This is the chain through all registered contexts.  It is
61
     filled in by _Unwind_SjLj_Register.  */
62
  struct SjLj_Function_Context *prev;
63
 
64
  /* This is assigned in by the target function before every call
65
     to the index of the call site in the lsda.  It is assigned by
66
     the personality routine to the landing pad index.  */
67
  int call_site;
68
 
69
  /* This is how data is returned from the personality routine to
70
     the target function's handler.  */
71
  _Unwind_Word data[4];
72
 
73
  /* These are filled in once by the target function before any
74
     exceptions are expected to be handled.  */
75
  _Unwind_Personality_Fn personality;
76
  void *lsda;
77
 
78
#ifdef DONT_USE_BUILTIN_SETJMP
79
  /* We don't know what sort of alignment requirements the system
80
     jmp_buf has.  We over estimated in except.c, and now we have
81
     to match that here just in case the system *didn't* have more
82
     restrictive requirements.  */
83
  jmp_buf jbuf __attribute__((aligned));
84
#else
85
  void *jbuf[];
86
#endif
87
};
88
 
89
struct _Unwind_Context
90
{
91
  struct SjLj_Function_Context *fc;
92
};
93
 
94
typedef struct
95
{
96
  _Unwind_Personality_Fn personality;
97
} _Unwind_FrameState;
98
 
99
 
100
/* Manage the chain of registered function contexts.  */
101
 
102
/* Single threaded fallback chain.  */
103
static struct SjLj_Function_Context *fc_static;
104
 
105
#if __GTHREADS
106
static __gthread_key_t fc_key;
107
static int use_fc_key = -1;
108
 
109
static void
110
fc_key_init (void)
111
{
112
  use_fc_key = __gthread_key_create (&fc_key, 0) == 0;
113
}
114
 
115
static void
116
fc_key_init_once (void)
117
{
118
  static __gthread_once_t once = __GTHREAD_ONCE_INIT;
119
  if (__gthread_once (&once, fc_key_init) != 0 || use_fc_key < 0)
120
    use_fc_key = 0;
121
}
122
#endif
123
 
124
void
125
_Unwind_SjLj_Register (struct SjLj_Function_Context *fc)
126
{
127
#if __GTHREADS
128
  if (use_fc_key < 0)
129
    fc_key_init_once ();
130
 
131
  if (use_fc_key)
132
    {
133
      fc->prev = __gthread_getspecific (fc_key);
134
      __gthread_setspecific (fc_key, fc);
135
    }
136
  else
137
#endif
138
    {
139
      fc->prev = fc_static;
140
      fc_static = fc;
141
    }
142
}
143
 
144
static inline struct SjLj_Function_Context *
145
_Unwind_SjLj_GetContext (void)
146
{
147
#if __GTHREADS
148
  if (use_fc_key < 0)
149
    fc_key_init_once ();
150
 
151
  if (use_fc_key)
152
    return __gthread_getspecific (fc_key);
153
#endif
154
  return fc_static;
155
}
156
 
157
static inline void
158
_Unwind_SjLj_SetContext (struct SjLj_Function_Context *fc)
159
{
160
#if __GTHREADS
161
  if (use_fc_key < 0)
162
    fc_key_init_once ();
163
 
164
  if (use_fc_key)
165
    __gthread_setspecific (fc_key, fc);
166
  else
167
#endif
168
    fc_static = fc;
169
}
170
 
171
void
172
_Unwind_SjLj_Unregister (struct SjLj_Function_Context *fc)
173
{
174
  _Unwind_SjLj_SetContext (fc->prev);
175
}
176
 
177
 
178
/* Get/set the return data value at INDEX in CONTEXT.  */
179
 
180
_Unwind_Word
181
_Unwind_GetGR (struct _Unwind_Context *context, int index)
182
{
183
  return context->fc->data[index];
184
}
185
 
186
/* Get the value of the CFA as saved in CONTEXT.  */
187
 
188
_Unwind_Word
189
_Unwind_GetCFA (struct _Unwind_Context *context __attribute__((unused)))
190
{
191
  /* ??? Ideally __builtin_setjmp places the CFA in the jmpbuf.  */
192
 
193
#ifndef DONT_USE_BUILTIN_SETJMP
194
  /* This is a crude imitation of the CFA: the saved stack pointer.
195
     This is roughly the CFA of the frame before CONTEXT.  When using the
196
     DWARF-2 unwinder _Unwind_GetCFA returns the CFA of the frame described
197
     by CONTEXT instead; but for DWARF-2 the cleanups associated with
198
     CONTEXT have already been run, and for SJLJ they have not yet been.  */
199
  if (context->fc != NULL)
200
    return (_Unwind_Word) context->fc->jbuf[2];
201
#endif
202
 
203
  /* Otherwise we're out of luck for now.  */
204
  return (_Unwind_Word) 0;
205
}
206
 
207
void
208
_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
209
{
210
  context->fc->data[index] = val;
211
}
212
 
213
/* Get the call-site index as saved in CONTEXT.  */
214
 
215
_Unwind_Ptr
216
_Unwind_GetIP (struct _Unwind_Context *context)
217
{
218
  return context->fc->call_site + 1;
219
}
220
 
221
_Unwind_Ptr
222
_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
223
{
224
  *ip_before_insn = 0;
225
  return context->fc->call_site + 1;
226
}
227
 
228
/* Set the return landing pad index in CONTEXT.  */
229
 
230
void
231
_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
232
{
233
  context->fc->call_site = val - 1;
234
}
235
 
236
void *
237
_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
238
{
239
  return context->fc->lsda;
240
}
241
 
242
_Unwind_Ptr
243
_Unwind_GetRegionStart (struct _Unwind_Context *context __attribute__((unused)) )
244
{
245
  return 0;
246
}
247
 
248
void *
249
_Unwind_FindEnclosingFunction (void *pc __attribute__((unused)))
250
{
251
  return NULL;
252
}
253
 
254
#ifndef __ia64__
255
_Unwind_Ptr
256
_Unwind_GetDataRelBase (struct _Unwind_Context *context __attribute__((unused)) )
257
{
258
  return 0;
259
}
260
 
261
_Unwind_Ptr
262
_Unwind_GetTextRelBase (struct _Unwind_Context *context __attribute__((unused)) )
263
{
264
  return 0;
265
}
266
#endif
267
 
268
static inline _Unwind_Reason_Code
269
uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
270
{
271
  if (context->fc == NULL)
272
    {
273
      fs->personality = NULL;
274
      return _URC_END_OF_STACK;
275
    }
276
  else
277
    {
278
      fs->personality = context->fc->personality;
279
      return _URC_NO_REASON;
280
    }
281
}
282
 
283
static inline void
284
uw_update_context (struct _Unwind_Context *context,
285
                   _Unwind_FrameState *fs __attribute__((unused)) )
286
{
287
  context->fc = context->fc->prev;
288
}
289
 
290
static void
291
uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
292
{
293
  _Unwind_SjLj_Unregister (context->fc);
294
  uw_update_context (context, fs);
295
}
296
 
297
static inline void
298
uw_init_context (struct _Unwind_Context *context)
299
{
300
  context->fc = _Unwind_SjLj_GetContext ();
301
}
302
 
303
static void __attribute__((noreturn))
304
uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
305
                    struct _Unwind_Context *target)
306
{
307
  _Unwind_SjLj_SetContext (target->fc);
308
  longjmp (target->fc->jbuf, 1);
309
}
310
 
311
static inline _Unwind_Ptr
312
uw_identify_context (struct _Unwind_Context *context)
313
{
314
  return (_Unwind_Ptr) context->fc;
315
}
316
 
317
 
318
/* Play games with unwind symbols so that we can have call frame
319
   and sjlj symbols in the same shared library.  Not that you can
320
   use them simultaneously...  */
321
#define _Unwind_RaiseException          _Unwind_SjLj_RaiseException
322
#define _Unwind_ForcedUnwind            _Unwind_SjLj_ForcedUnwind
323
#define _Unwind_Resume                  _Unwind_SjLj_Resume
324
#define _Unwind_Resume_or_Rethrow       _Unwind_SjLj_Resume_or_Rethrow
325
 
326
#include "unwind.inc"
327
 
328
#endif /* USING_SJLJ_EXCEPTIONS */

powered by: WebSVN 2.1.0

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