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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [unwind-sjlj.c] - Blame information for rev 757

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

Line No. Rev Author Line
1 734 jeremybenn
/* SJLJ exception handling and frame unwind runtime interface routines.
2
   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006,
3
   2009, 2011 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 3, or (at your option)
10
   any later version.
11
 
12
   GCC is distributed in the hope that it will be useful, but WITHOUT
13
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15
   License for more details.
16
 
17
   Under Section 7 of GPL version 3, you are granted additional
18
   permissions described in the GCC Runtime Library Exception, version
19
   3.1, as published by the Free Software Foundation.
20
 
21
   You should have received a copy of the GNU General Public License and
22
   a copy of the GCC Runtime Library Exception along with this program;
23
   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24
   <http://www.gnu.org/licenses/>.  */
25
 
26
#include "tconfig.h"
27
#include "tsystem.h"
28
#include "coretypes.h"
29
#include "tm.h"
30
#include "libgcc_tm.h"
31
#include "unwind.h"
32
#include "gthr.h"
33
 
34
#ifdef __USING_SJLJ_EXCEPTIONS__
35
 
36
#ifdef DONT_USE_BUILTIN_SETJMP
37
#ifndef inhibit_libc
38
#include <setjmp.h>
39
#else
40
typedef void *jmp_buf[JMP_BUF_SIZE];
41
extern void longjmp(jmp_buf, int) __attribute__((noreturn));
42
#endif
43
#else
44
#define longjmp __builtin_longjmp
45
#endif
46
 
47
/* The setjmp side is dealt with in the except.c file.  */
48
#undef setjmp
49
#define setjmp setjmp_should_not_be_used_in_this_file
50
 
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
_Unwind_Ptr
218
_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
219
{
220
  *ip_before_insn = 0;
221
  if (context->fc != NULL)
222
    return context->fc->call_site + 1;
223
  else
224
    return 0;
225
}
226
 
227
/* Set the return landing pad index in CONTEXT.  */
228
 
229
void
230
_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
231
{
232
  context->fc->call_site = val - 1;
233
}
234
 
235
void *
236
_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
237
{
238
  return context->fc->lsda;
239
}
240
 
241
_Unwind_Ptr
242
_Unwind_GetRegionStart (struct _Unwind_Context *context __attribute__((unused)) )
243
{
244
  return 0;
245
}
246
 
247
void *
248
_Unwind_FindEnclosingFunction (void *pc __attribute__((unused)))
249
{
250
  return NULL;
251
}
252
 
253
#ifndef __ia64__
254
_Unwind_Ptr
255
_Unwind_GetDataRelBase (struct _Unwind_Context *context __attribute__((unused)) )
256
{
257
  return 0;
258
}
259
 
260
_Unwind_Ptr
261
_Unwind_GetTextRelBase (struct _Unwind_Context *context __attribute__((unused)) )
262
{
263
  return 0;
264
}
265
#endif
266
 
267
static inline _Unwind_Reason_Code
268
uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
269
{
270
  if (context->fc == NULL)
271
    {
272
      fs->personality = NULL;
273
      return _URC_END_OF_STACK;
274
    }
275
  else
276
    {
277
      fs->personality = context->fc->personality;
278
      return _URC_NO_REASON;
279
    }
280
}
281
 
282
static inline void
283
uw_update_context (struct _Unwind_Context *context,
284
                   _Unwind_FrameState *fs __attribute__((unused)) )
285
{
286
  context->fc = context->fc->prev;
287
}
288
 
289
static void
290
uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
291
{
292
  _Unwind_SjLj_Unregister (context->fc);
293
  uw_update_context (context, fs);
294
}
295
 
296
static inline void
297
uw_init_context (struct _Unwind_Context *context)
298
{
299
  context->fc = _Unwind_SjLj_GetContext ();
300
}
301
 
302
static void __attribute__((noreturn))
303
uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
304
                    struct _Unwind_Context *target)
305
{
306
  _Unwind_SjLj_SetContext (target->fc);
307
  longjmp (target->fc->jbuf, 1);
308
}
309
 
310
static inline _Unwind_Ptr
311
uw_identify_context (struct _Unwind_Context *context)
312
{
313
  return (_Unwind_Ptr) context->fc;
314
}
315
 
316
 
317
/* Play games with unwind symbols so that we can have call frame
318
   and sjlj symbols in the same shared library.  Not that you can
319
   use them simultaneously...  */
320
#define _Unwind_RaiseException          _Unwind_SjLj_RaiseException
321
#define _Unwind_ForcedUnwind            _Unwind_SjLj_ForcedUnwind
322
#define _Unwind_Resume                  _Unwind_SjLj_Resume
323
#define _Unwind_Resume_or_Rethrow       _Unwind_SjLj_Resume_or_Rethrow
324
 
325
#include "unwind.inc"
326
 
327
#endif /* USING_SJLJ_EXCEPTIONS */

powered by: WebSVN 2.1.0

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