Update the GCC3 infrastructure Stage 1/2. This commit generates the basic
[dragonfly.git] / gnu / usr.bin / cc3 / config / unwind-libunwind.c
1 /* Subroutines needed for unwinding stack frames via the libunwind API.
2    Copyright (C) 2002, 2003
3    Free Software Foundation, Inc.
4    Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5
6    This file is part of GCC.
7
8    GCC is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2, or (at your option)
11    any later version.
12
13    GCC is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with GCC; see the file COPYING.  If not, write to
20    the Free Software Foundation, 59 Temple Place - Suite 330,
21    Boston, MA 02111-1307, USA.  */
22
23 /* As a special exception, if you link this library with other files,
24    some of which are compiled with GCC, to produce an executable,
25    this library does not by itself cause the resulting executable
26    to be covered by the GNU General Public License.
27    This exception does not however invalidate any other reasons why
28    the executable file might be covered by the GNU General Public License.  */
29
30 /*
31  * $DragonFly: src/gnu/usr.bin/cc3/config/Attic/unwind-libunwind.c,v 1.1 2004/02/02 23:35:11 dillon Exp $
32  */
33 #include "tconfig.h"
34 #include "tsystem.h"
35 #include "unwind.h"
36
37 #ifndef __USING_SJLJ_EXCEPTIONS__
38
39 #define UNW_LOCAL_ONLY
40
41 #include <libunwind.h>
42
43 typedef struct {
44   _Unwind_Personality_Fn personality;
45 } _Unwind_FrameState;
46
47 struct _Unwind_Context {
48   unw_cursor_t cursor;
49 };
50
51 \f
52 /* First come the helper-routines that are needed by unwind.inc.  */
53
54 static _Unwind_Reason_Code
55 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
56 {
57   unw_proc_info_t pi;
58
59   if (unw_step (&context->cursor) <= 0)
60     return _URC_END_OF_STACK;
61
62   unw_get_proc_info(&context->cursor, &pi);
63   fs->personality = (_Unwind_Personality_Fn) pi.handler;
64
65   return _URC_NO_REASON;
66 }
67
68 #define uw_update_context(context,fs)   do { ; } while (0)
69
70 static inline _Unwind_Ptr
71 uw_identify_context (struct _Unwind_Context *context)
72 {
73   unw_word_t ip;
74   unw_get_reg (&context->cursor, UNW_REG_IP, &ip);
75   return (_Unwind_Ptr) ip;
76 }
77
78 #define uw_init_context(context)                \
79 do                                              \
80   {                                             \
81     unw_context_t uc;                           \
82     unw_getcontext (&uc);                       \
83     unw_init_local (&(context)->cursor, &uc);   \
84   }                                             \
85 while (0)
86
87 static inline void __attribute__ ((noreturn))
88 uw_install_context (struct _Unwind_Context *current __attribute__ ((unused)),
89                     struct _Unwind_Context *target)
90 {
91   unw_resume (&(target)->cursor);
92   abort ();
93 }
94
95 \f
96 /* Now come the helper-routines which may be called from an exception
97    handler.  The interface for these routines are defined by the C++
98    ABI.  See: http://www.codesourcery.com/cxx-abi/abi-eh.html */
99
100 _Unwind_Word
101 _Unwind_GetGR (struct _Unwind_Context *context, int index)
102 {
103   unw_word_t ret;
104
105   /* Note: here we depend on the fact that general registers are
106      expected to start with register number 0!  */
107   unw_get_reg (&context->cursor, index, &ret);
108   return ret;
109 }
110
111 /* Get the value of the CFA as saved in CONTEXT.  */
112
113 _Unwind_Word
114 _Unwind_GetCFA (struct _Unwind_Context *context)
115 {
116   /* ??? Is there any way to get this information?  */
117   return NULL;
118
119
120 /* Overwrite the saved value for register REG in CONTEXT with VAL.  */
121
122 void
123 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
124 {
125   /* Note: here we depend on the fact that general registers are
126      expected to start with register number 0!  */
127   unw_set_reg (&context->cursor, index, val);
128 }
129
130 /* Retrieve the return address for CONTEXT.  */
131
132 inline _Unwind_Ptr
133 _Unwind_GetIP (struct _Unwind_Context *context)
134 {
135   unw_word_t ret;
136
137   unw_get_reg (&context->cursor, UNW_REG_IP, &ret);
138   return ret;
139 }
140
141 /* Overwrite the return address for CONTEXT with VAL.  */
142
143 inline void
144 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
145 {
146   unw_set_reg (&context->cursor, UNW_REG_IP, val);
147 }
148
149 void *
150 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
151 {
152   unw_proc_info_t pi;
153
154   unw_get_proc_info(&context->cursor, &pi);
155   return (void *) pi.lsda;
156 }
157
158 _Unwind_Ptr
159 _Unwind_GetRegionStart (struct _Unwind_Context *context)
160 {
161   unw_proc_info_t pi;
162
163   unw_get_proc_info(&context->cursor, &pi);
164   return (_Unwind_Ptr) pi.start_ip;
165 }
166
167 void *
168 _Unwind_FindEnclosingFunction (void *pc)
169 {
170   return NULL;
171 }
172
173 #include "unwind.inc"
174
175 #endif /* !__USING_SJLJ_EXCEPTIONS__ */