Mercurial > hg > CbC > CbC_gcc
annotate gcc/unwind-c.c @ 90:99e7b6776dd1
implemeted __rectype expression. add CbC-exanples/fact-rectype.s
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 25 Dec 2011 04:04:42 +0900 |
parents | 77e2b8dfacca |
children |
rev | line source |
---|---|
0 | 1 /* Supporting functions for C exception handling. |
2 Copyright (C) 2002, 2003, 2009 Free Software Foundation, Inc. | |
3 Contributed by Aldy Hernandez <aldy@quesejoda.com>. | |
4 Shamelessly stolen from the Java front end. | |
5 | |
6 This file is part of GCC. | |
7 | |
8 GCC is free software; you can redistribute it and/or modify it under | |
9 the terms of the GNU General Public License as published by the Free | |
10 Software Foundation; either version 3, or (at your option) any later | |
11 version. | |
12 | |
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 Under Section 7 of GPL version 3, you are granted additional | |
19 permissions described in the GCC Runtime Library Exception, version | |
20 3.1, as published by the Free Software Foundation. | |
21 | |
22 You should have received a copy of the GNU General Public License and | |
23 a copy of the GCC Runtime Library Exception along with this program; | |
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
25 <http://www.gnu.org/licenses/>. */ | |
26 | |
27 #include "tconfig.h" | |
28 #include "tsystem.h" | |
29 #include "unwind.h" | |
30 #define NO_SIZE_OF_ENCODED_VALUE | |
31 #include "unwind-pe.h" | |
32 | |
33 typedef struct | |
34 { | |
35 _Unwind_Ptr Start; | |
36 _Unwind_Ptr LPStart; | |
37 _Unwind_Ptr ttype_base; | |
38 const unsigned char *TType; | |
39 const unsigned char *action_table; | |
40 unsigned char ttype_encoding; | |
41 unsigned char call_site_encoding; | |
42 } lsda_header_info; | |
43 | |
44 static const unsigned char * | |
45 parse_lsda_header (struct _Unwind_Context *context, const unsigned char *p, | |
46 lsda_header_info *info) | |
47 { | |
48 _uleb128_t tmp; | |
49 unsigned char lpstart_encoding; | |
50 | |
51 info->Start = (context ? _Unwind_GetRegionStart (context) : 0); | |
52 | |
53 /* Find @LPStart, the base to which landing pad offsets are relative. */ | |
54 lpstart_encoding = *p++; | |
55 if (lpstart_encoding != DW_EH_PE_omit) | |
56 p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart); | |
57 else | |
58 info->LPStart = info->Start; | |
59 | |
60 /* Find @TType, the base of the handler and exception spec type data. */ | |
61 info->ttype_encoding = *p++; | |
62 if (info->ttype_encoding != DW_EH_PE_omit) | |
63 { | |
64 p = read_uleb128 (p, &tmp); | |
65 info->TType = p + tmp; | |
66 } | |
67 else | |
68 info->TType = 0; | |
69 | |
70 /* The encoding and length of the call-site table; the action table | |
71 immediately follows. */ | |
72 info->call_site_encoding = *p++; | |
73 p = read_uleb128 (p, &tmp); | |
74 info->action_table = p + tmp; | |
75 | |
76 return p; | |
77 } | |
78 | |
79 #ifdef __ARM_EABI_UNWINDER__ | |
80 /* ARM EABI personality routines must also unwind the stack. */ | |
81 #define CONTINUE_UNWINDING \ | |
82 do \ | |
83 { \ | |
84 if (__gnu_unwind_frame (ue_header, context) != _URC_OK) \ | |
85 return _URC_FAILURE; \ | |
86 return _URC_CONTINUE_UNWIND; \ | |
87 } \ | |
88 while (0) | |
89 #else | |
90 #define CONTINUE_UNWINDING return _URC_CONTINUE_UNWIND | |
91 #endif | |
92 | |
93 #ifdef __USING_SJLJ_EXCEPTIONS__ | |
94 #define PERSONALITY_FUNCTION __gcc_personality_sj0 | |
95 #define __builtin_eh_return_data_regno(x) x | |
96 #else | |
97 #define PERSONALITY_FUNCTION __gcc_personality_v0 | |
98 #endif | |
99 | |
100 #ifdef __ARM_EABI_UNWINDER__ | |
101 _Unwind_Reason_Code | |
102 PERSONALITY_FUNCTION (_Unwind_State, struct _Unwind_Exception *, | |
103 struct _Unwind_Context *); | |
104 | |
105 _Unwind_Reason_Code | |
106 PERSONALITY_FUNCTION (_Unwind_State state, | |
107 struct _Unwind_Exception * ue_header, | |
108 struct _Unwind_Context * context) | |
109 #else | |
110 _Unwind_Reason_Code | |
111 PERSONALITY_FUNCTION (int, _Unwind_Action, _Unwind_Exception_Class, | |
112 struct _Unwind_Exception *, struct _Unwind_Context *); | |
113 | |
114 _Unwind_Reason_Code | |
115 PERSONALITY_FUNCTION (int version, | |
116 _Unwind_Action actions, | |
117 _Unwind_Exception_Class exception_class ATTRIBUTE_UNUSED, | |
118 struct _Unwind_Exception *ue_header, | |
119 struct _Unwind_Context *context) | |
120 #endif | |
121 { | |
122 lsda_header_info info; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
123 const unsigned char *language_specific_data, *p; |
0 | 124 _Unwind_Ptr landing_pad, ip; |
125 int ip_before_insn = 0; | |
126 | |
127 #ifdef __ARM_EABI_UNWINDER__ | |
128 if ((state & _US_ACTION_MASK) != _US_UNWIND_FRAME_STARTING) | |
129 CONTINUE_UNWINDING; | |
130 | |
131 /* The dwarf unwinder assumes the context structure holds things like the | |
132 function and LSDA pointers. The ARM implementation caches these in | |
133 the exception header (UCB). To avoid rewriting everything we make the | |
134 virtual IP register point at the UCB. */ | |
135 ip = (_Unwind_Ptr) ue_header; | |
136 _Unwind_SetGR (context, 12, ip); | |
137 #else | |
138 if (version != 1) | |
139 return _URC_FATAL_PHASE1_ERROR; | |
140 | |
141 /* Currently we only support cleanups for C. */ | |
142 if ((actions & _UA_CLEANUP_PHASE) == 0) | |
143 CONTINUE_UNWINDING; | |
144 #endif | |
145 | |
146 language_specific_data = (const unsigned char *) | |
147 _Unwind_GetLanguageSpecificData (context); | |
148 | |
149 /* If no LSDA, then there are no handlers or cleanups. */ | |
150 if (! language_specific_data) | |
151 CONTINUE_UNWINDING; | |
152 | |
153 /* Parse the LSDA header. */ | |
154 p = parse_lsda_header (context, language_specific_data, &info); | |
155 #ifdef HAVE_GETIPINFO | |
156 ip = _Unwind_GetIPInfo (context, &ip_before_insn); | |
157 #else | |
158 ip = _Unwind_GetIP (context); | |
159 #endif | |
160 if (! ip_before_insn) | |
161 --ip; | |
162 landing_pad = 0; | |
163 | |
164 #ifdef __USING_SJLJ_EXCEPTIONS__ | |
165 /* The given "IP" is an index into the call-site table, with two | |
166 exceptions -- -1 means no-action, and 0 means terminate. But | |
167 since we're using uleb128 values, we've not got random access | |
168 to the array. */ | |
169 if ((int) ip <= 0) | |
170 return _URC_CONTINUE_UNWIND; | |
171 else | |
172 { | |
173 _uleb128_t cs_lp, cs_action; | |
174 do | |
175 { | |
176 p = read_uleb128 (p, &cs_lp); | |
177 p = read_uleb128 (p, &cs_action); | |
178 } | |
179 while (--ip); | |
180 | |
181 /* Can never have null landing pad for sjlj -- that would have | |
182 been indicated by a -1 call site index. */ | |
183 landing_pad = (_Unwind_Ptr)cs_lp + 1; | |
184 goto found_something; | |
185 } | |
186 #else | |
187 /* Search the call-site table for the action associated with this IP. */ | |
188 while (p < info.action_table) | |
189 { | |
190 _Unwind_Ptr cs_start, cs_len, cs_lp; | |
191 _uleb128_t cs_action; | |
192 | |
193 /* Note that all call-site encodings are "absolute" displacements. */ | |
194 p = read_encoded_value (0, info.call_site_encoding, p, &cs_start); | |
195 p = read_encoded_value (0, info.call_site_encoding, p, &cs_len); | |
196 p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp); | |
197 p = read_uleb128 (p, &cs_action); | |
198 | |
199 /* The table is sorted, so if we've passed the ip, stop. */ | |
200 if (ip < info.Start + cs_start) | |
201 p = info.action_table; | |
202 else if (ip < info.Start + cs_start + cs_len) | |
203 { | |
204 if (cs_lp) | |
205 landing_pad = info.LPStart + cs_lp; | |
206 goto found_something; | |
207 } | |
208 } | |
209 #endif | |
210 | |
211 /* IP is not in table. No associated cleanups. */ | |
212 /* ??? This is where C++ calls std::terminate to catch throw | |
213 from a destructor. */ | |
214 CONTINUE_UNWINDING; | |
215 | |
216 found_something: | |
217 if (landing_pad == 0) | |
218 { | |
219 /* IP is present, but has a null landing pad. | |
220 No handler to be run. */ | |
221 CONTINUE_UNWINDING; | |
222 } | |
223 | |
224 _Unwind_SetGR (context, __builtin_eh_return_data_regno (0), | |
225 (_Unwind_Ptr) ue_header); | |
226 _Unwind_SetGR (context, __builtin_eh_return_data_regno (1), 0); | |
227 _Unwind_SetIP (context, landing_pad); | |
228 return _URC_INSTALL_CONTEXT; | |
229 } |