89e841759cf9013309f77e437c5bb290a62971ca
[gcc.git] / gcc / 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 #include "tconfig.h"
31 #include "tsystem.h"
32 #include "unwind.h"
33
34 #ifndef __USING_SJLJ_EXCEPTIONS__
35
36 #define UNW_LOCAL_ONLY
37
38 #include <libunwind.h>
39
40 typedef struct {
41 _Unwind_Personality_Fn personality;
42 } _Unwind_FrameState;
43
44 struct _Unwind_Context {
45 unw_cursor_t cursor;
46 };
47
48 \f
49 /* First come the helper-routines that are needed by unwind.inc. */
50
51 static _Unwind_Reason_Code
52 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
53 {
54 unw_proc_info_t pi;
55
56 if (unw_step (&context->cursor) <= 0)
57 return _URC_END_OF_STACK;
58
59 unw_get_proc_info(&context->cursor, &pi);
60 fs->personality = (_Unwind_Personality_Fn) pi.handler;
61
62 return _URC_NO_REASON;
63 }
64
65 #define uw_update_context(context,fs) do { ; } while (0)
66
67 static inline _Unwind_Ptr
68 uw_identify_context (struct _Unwind_Context *context)
69 {
70 unw_word_t ip;
71 unw_get_reg (&context->cursor, UNW_REG_IP, &ip);
72 return (_Unwind_Ptr) ip;
73 }
74
75 #define uw_init_context(context) \
76 do \
77 { \
78 unw_context_t uc; \
79 unw_getcontext (&uc); \
80 unw_init_local (&(context)->cursor, &uc); \
81 } \
82 while (0)
83
84 static inline void __attribute__ ((noreturn))
85 uw_install_context (struct _Unwind_Context *current __attribute__ ((unused)),
86 struct _Unwind_Context *target)
87 {
88 unw_resume (&(target)->cursor);
89 abort ();
90 }
91
92 \f
93 /* Now come the helper-routines which may be called from an exception
94 handler. The interface for these routines are defined by the C++
95 ABI. See: http://www.codesourcery.com/cxx-abi/abi-eh.html */
96
97 _Unwind_Word
98 _Unwind_GetGR (struct _Unwind_Context *context, int index)
99 {
100 unw_word_t ret;
101
102 /* Note: here we depend on the fact that general registers are
103 expected to start with register number 0! */
104 unw_get_reg (&context->cursor, index, &ret);
105 return ret;
106 }
107
108 /* Get the value of the CFA as saved in CONTEXT. */
109
110 _Unwind_Word
111 _Unwind_GetCFA (struct _Unwind_Context *context)
112 {
113 unw_word_t ret;
114
115 unw_get_reg (&context->cursor, UNW_IA64_SP, &ret);
116 return ret;
117 }
118
119 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
120
121 void
122 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
123 {
124 /* Note: here we depend on the fact that general registers are
125 expected to start with register number 0! */
126 unw_set_reg (&context->cursor, index, val);
127 }
128
129 /* Retrieve the return address for CONTEXT. */
130
131 inline _Unwind_Ptr
132 _Unwind_GetIP (struct _Unwind_Context *context)
133 {
134 unw_word_t ret;
135
136 unw_get_reg (&context->cursor, UNW_REG_IP, &ret);
137 return ret;
138 }
139
140 /* Overwrite the return address for CONTEXT with VAL. */
141
142 inline void
143 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
144 {
145 unw_set_reg (&context->cursor, UNW_REG_IP, val);
146 }
147
148 void *
149 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
150 {
151 unw_proc_info_t pi;
152
153 unw_get_proc_info(&context->cursor, &pi);
154 return (void *) pi.lsda;
155 }
156
157 _Unwind_Ptr
158 _Unwind_GetRegionStart (struct _Unwind_Context *context)
159 {
160 unw_proc_info_t pi;
161
162 unw_get_proc_info(&context->cursor, &pi);
163 return (_Unwind_Ptr) pi.start_ip;
164 }
165
166 void *
167 _Unwind_FindEnclosingFunction (void *pc)
168 {
169 return NULL;
170 }
171
172 #ifdef UNW_TARGET_IA64
173
174 _Unwind_Word
175 _Unwind_GetBSP (struct _Unwind_Context *context)
176 {
177 unw_word_t ret;
178
179 unw_get_reg (&context->cursor, UNW_IA64_BSP, &ret);
180 return ret;
181 }
182
183 #endif
184
185 #include "unwind.inc"
186
187 #endif /* !__USING_SJLJ_EXCEPTIONS__ */