unwind-dw2.c revision 1.3.8.2 1 1.3.8.2 tls /* DWARF2 exception handling and frame unwind runtime interface routines.
2 1.3.8.2 tls Copyright (C) 1997-2013 Free Software Foundation, Inc.
3 1.3.8.2 tls
4 1.3.8.2 tls This file is part of GCC.
5 1.3.8.2 tls
6 1.3.8.2 tls GCC is free software; you can redistribute it and/or modify it
7 1.3.8.2 tls under the terms of the GNU General Public License as published by
8 1.3.8.2 tls the Free Software Foundation; either version 3, or (at your option)
9 1.3.8.2 tls any later version.
10 1.3.8.2 tls
11 1.3.8.2 tls GCC is distributed in the hope that it will be useful, but WITHOUT
12 1.3.8.2 tls ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 1.3.8.2 tls or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 1.3.8.2 tls License for more details.
15 1.3.8.2 tls
16 1.3.8.2 tls Under Section 7 of GPL version 3, you are granted additional
17 1.3.8.2 tls permissions described in the GCC Runtime Library Exception, version
18 1.3.8.2 tls 3.1, as published by the Free Software Foundation.
19 1.3.8.2 tls
20 1.3.8.2 tls You should have received a copy of the GNU General Public License and
21 1.3.8.2 tls a copy of the GCC Runtime Library Exception along with this program;
22 1.3.8.2 tls see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 1.3.8.2 tls <http://www.gnu.org/licenses/>. */
24 1.3.8.2 tls
25 1.3.8.2 tls #include "tconfig.h"
26 1.3.8.2 tls #include "tsystem.h"
27 1.3.8.2 tls #include "coretypes.h"
28 1.3.8.2 tls #include "tm.h"
29 1.3.8.2 tls #include "libgcc_tm.h"
30 1.3.8.2 tls #include "dwarf2.h"
31 1.3.8.2 tls #include "unwind.h"
32 1.3.8.2 tls #ifdef __USING_SJLJ_EXCEPTIONS__
33 1.3.8.2 tls # define NO_SIZE_OF_ENCODED_VALUE
34 1.3.8.2 tls #endif
35 1.3.8.2 tls #include "unwind-pe.h"
36 1.3.8.2 tls #include "unwind-dw2-fde.h"
37 1.3.8.2 tls #include "gthr.h"
38 1.3.8.2 tls #include "unwind-dw2.h"
39 1.3.8.2 tls
40 1.3.8.2 tls #ifdef HAVE_SYS_SDT_H
41 1.3.8.2 tls #include <sys/sdt.h>
42 1.3.8.2 tls #endif
43 1.3.8.2 tls
44 1.3.8.2 tls #ifndef __USING_SJLJ_EXCEPTIONS__
45 1.3.8.2 tls
46 1.3.8.2 tls #ifndef STACK_GROWS_DOWNWARD
47 1.3.8.2 tls #define STACK_GROWS_DOWNWARD 0
48 1.3.8.2 tls #else
49 1.3.8.2 tls #undef STACK_GROWS_DOWNWARD
50 1.3.8.2 tls #define STACK_GROWS_DOWNWARD 1
51 1.3.8.2 tls #endif
52 1.3.8.2 tls
53 1.3.8.2 tls /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
54 1.3.8.2 tls #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
55 1.3.8.2 tls #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
56 1.3.8.2 tls #endif
57 1.3.8.2 tls
58 1.3.8.2 tls #ifndef DWARF_REG_TO_UNWIND_COLUMN
59 1.3.8.2 tls #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
60 1.3.8.2 tls #endif
61 1.3.8.2 tls
62 1.3.8.2 tls /* ??? For the public function interfaces, we tend to gcc_assert that the
63 1.3.8.2 tls column numbers are in range. For the dwarf2 unwind info this does happen,
64 1.3.8.2 tls although so far in a case that doesn't actually matter.
65 1.3.8.2 tls
66 1.3.8.2 tls See PR49146, in which a call from x86_64 ms abi to x86_64 unix abi stores
67 1.3.8.2 tls the call-saved xmm registers and annotates them. We havn't bothered
68 1.3.8.2 tls providing support for the xmm registers for the x86_64 port primarily
69 1.3.8.2 tls because the 64-bit windows targets don't use dwarf2 unwind, using sjlj or
70 1.3.8.2 tls SEH instead. Adding the support for unix targets would generally be a
71 1.3.8.2 tls waste. However, some runtime libraries supplied with ICC do contain such
72 1.3.8.2 tls an unorthodox transition, as well as the unwind info to match. This loss
73 1.3.8.2 tls of register restoration doesn't matter in practice, because the exception
74 1.3.8.2 tls is caught in the native unix abi, where all of the xmm registers are
75 1.3.8.2 tls call clobbered.
76 1.3.8.2 tls
77 1.3.8.2 tls Ideally, we'd record some bit to notice when we're failing to restore some
78 1.3.8.2 tls register recorded in the unwind info, but to do that we need annotation on
79 1.3.8.2 tls the unix->ms abi edge, so that we know when the register data may be
80 1.3.8.2 tls discarded. And since this edge is also within the ICC library, we're
81 1.3.8.2 tls unlikely to be able to get the new annotation.
82 1.3.8.2 tls
83 1.3.8.2 tls Barring a magic solution to restore the ms abi defined 128-bit xmm registers
84 1.3.8.2 tls (as distictly opposed to the full runtime width) without causing extra
85 1.3.8.2 tls overhead for normal unix abis, the best solution seems to be to simply
86 1.3.8.2 tls ignore unwind data for unknown columns. */
87 1.3.8.2 tls
88 1.3.8.2 tls #define UNWIND_COLUMN_IN_RANGE(x) \
89 1.3.8.2 tls __builtin_expect((x) <= DWARF_FRAME_REGISTERS, 1)
90 1.3.8.2 tls
91 1.3.8.2 tls #ifdef REG_VALUE_IN_UNWIND_CONTEXT
92 1.3.8.2 tls typedef _Unwind_Word _Unwind_Context_Reg_Val;
93 1.3.8.2 tls
94 1.3.8.2 tls #ifndef ASSUME_EXTENDED_UNWIND_CONTEXT
95 1.3.8.2 tls #define ASSUME_EXTENDED_UNWIND_CONTEXT 1
96 1.3.8.2 tls #endif
97 1.3.8.2 tls
98 1.3.8.2 tls static inline _Unwind_Word
99 1.3.8.2 tls _Unwind_Get_Unwind_Word (_Unwind_Context_Reg_Val val)
100 1.3.8.2 tls {
101 1.3.8.2 tls return val;
102 1.3.8.2 tls }
103 1.3.8.2 tls
104 1.3.8.2 tls static inline _Unwind_Context_Reg_Val
105 1.3.8.2 tls _Unwind_Get_Unwind_Context_Reg_Val (_Unwind_Word val)
106 1.3.8.2 tls {
107 1.3.8.2 tls return val;
108 1.3.8.2 tls }
109 1.3.8.2 tls #else
110 1.3.8.2 tls typedef void *_Unwind_Context_Reg_Val;
111 1.3.8.2 tls
112 1.3.8.2 tls static inline _Unwind_Word
113 1.3.8.2 tls _Unwind_Get_Unwind_Word (_Unwind_Context_Reg_Val val)
114 1.3.8.2 tls {
115 1.3.8.2 tls return (_Unwind_Word) (_Unwind_Internal_Ptr) val;
116 1.3.8.2 tls }
117 1.3.8.2 tls
118 1.3.8.2 tls static inline _Unwind_Context_Reg_Val
119 1.3.8.2 tls _Unwind_Get_Unwind_Context_Reg_Val (_Unwind_Word val)
120 1.3.8.2 tls {
121 1.3.8.2 tls return (_Unwind_Context_Reg_Val) (_Unwind_Internal_Ptr) val;
122 1.3.8.2 tls }
123 1.3.8.2 tls #endif
124 1.3.8.2 tls
125 1.3.8.2 tls #ifndef ASSUME_EXTENDED_UNWIND_CONTEXT
126 1.3.8.2 tls #define ASSUME_EXTENDED_UNWIND_CONTEXT 0
127 1.3.8.2 tls #endif
128 1.3.8.2 tls
129 1.3.8.2 tls /* This is the register and unwind state for a particular frame. This
130 1.3.8.2 tls provides the information necessary to unwind up past a frame and return
131 1.3.8.2 tls to its caller. */
132 1.3.8.2 tls struct _Unwind_Context
133 1.3.8.2 tls {
134 1.3.8.2 tls _Unwind_Context_Reg_Val reg[DWARF_FRAME_REGISTERS+1];
135 1.3.8.2 tls void *cfa;
136 1.3.8.2 tls void *ra;
137 1.3.8.2 tls void *lsda;
138 1.3.8.2 tls struct dwarf_eh_bases bases;
139 1.3.8.2 tls /* Signal frame context. */
140 1.3.8.2 tls #define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
141 1.3.8.2 tls /* Context which has version/args_size/by_value fields. */
142 1.3.8.2 tls #define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
143 1.3.8.2 tls _Unwind_Word flags;
144 1.3.8.2 tls /* 0 for now, can be increased when further fields are added to
145 1.3.8.2 tls struct _Unwind_Context. */
146 1.3.8.2 tls _Unwind_Word version;
147 1.3.8.2 tls _Unwind_Word args_size;
148 1.3.8.2 tls char by_value[DWARF_FRAME_REGISTERS+1];
149 1.3.8.2 tls };
150 1.3.8.2 tls
151 1.3.8.2 tls /* Byte size of every register managed by these routines. */
152 1.3.8.2 tls static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS+1];
153 1.3.8.2 tls
154 1.3.8.2 tls
155 1.3.8.2 tls /* Read unaligned data from the instruction buffer. */
157 1.3.8.2 tls
158 1.3.8.2 tls union unaligned
159 1.3.8.2 tls {
160 1.3.8.2 tls void *p;
161 1.3.8.2 tls unsigned u2 __attribute__ ((mode (HI)));
162 1.3.8.2 tls unsigned u4 __attribute__ ((mode (SI)));
163 1.3.8.2 tls unsigned u8 __attribute__ ((mode (DI)));
164 1.3.8.2 tls signed s2 __attribute__ ((mode (HI)));
165 1.3.8.2 tls signed s4 __attribute__ ((mode (SI)));
166 1.3.8.2 tls signed s8 __attribute__ ((mode (DI)));
167 1.3.8.2 tls } __attribute__ ((packed));
168 1.3.8.2 tls
169 1.3.8.2 tls static void uw_update_context (struct _Unwind_Context *, _Unwind_FrameState *);
170 1.3.8.2 tls static _Unwind_Reason_Code uw_frame_state_for (struct _Unwind_Context *,
171 1.3.8.2 tls _Unwind_FrameState *);
172 1.3.8.2 tls
173 1.3.8.2 tls static inline void *
174 1.3.8.2 tls read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
175 1.3.8.2 tls
176 1.3.8.2 tls static inline int
177 1.3.8.2 tls read_1u (const void *p) { return *(const unsigned char *) p; }
178 1.3.8.2 tls
179 1.3.8.2 tls static inline int
180 1.3.8.2 tls read_1s (const void *p) { return *(const signed char *) p; }
181 1.3.8.2 tls
182 1.3.8.2 tls static inline int
183 1.3.8.2 tls read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
184 1.3.8.2 tls
185 1.3.8.2 tls static inline int
186 1.3.8.2 tls read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
187 1.3.8.2 tls
188 1.3.8.2 tls static inline unsigned int
189 1.3.8.2 tls read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
190 1.3.8.2 tls
191 1.3.8.2 tls static inline int
192 1.3.8.2 tls read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
193 1.3.8.2 tls
194 1.3.8.2 tls static inline unsigned long
195 1.3.8.2 tls read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
196 1.3.8.2 tls
197 1.3.8.2 tls static inline unsigned long
198 1.3.8.2 tls read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
199 1.3.8.2 tls
200 1.3.8.2 tls static inline _Unwind_Word
202 1.3.8.2 tls _Unwind_IsSignalFrame (struct _Unwind_Context *context)
203 1.3.8.2 tls {
204 1.3.8.2 tls return (context->flags & SIGNAL_FRAME_BIT) ? 1 : 0;
205 1.3.8.2 tls }
206 1.3.8.2 tls
207 1.3.8.2 tls static inline void
208 1.3.8.2 tls _Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
209 1.3.8.2 tls {
210 1.3.8.2 tls if (val)
211 1.3.8.2 tls context->flags |= SIGNAL_FRAME_BIT;
212 1.3.8.2 tls else
213 1.3.8.2 tls context->flags &= ~SIGNAL_FRAME_BIT;
214 1.3.8.2 tls }
215 1.3.8.2 tls
216 1.3.8.2 tls static inline _Unwind_Word
217 1.3.8.2 tls _Unwind_IsExtendedContext (struct _Unwind_Context *context)
218 1.3.8.2 tls {
219 1.3.8.2 tls return (ASSUME_EXTENDED_UNWIND_CONTEXT
220 1.3.8.2 tls || (context->flags & EXTENDED_CONTEXT_BIT));
221 1.3.8.2 tls }
222 1.3.8.2 tls
223 1.3.8.2 tls /* Get the value of register INDEX as saved in CONTEXT. */
225 1.3.8.2 tls
226 1.3.8.2 tls inline _Unwind_Word
227 1.3.8.2 tls _Unwind_GetGR (struct _Unwind_Context *context, int index)
228 1.3.8.2 tls {
229 1.3.8.2 tls int size;
230 1.3.8.2 tls _Unwind_Context_Reg_Val val;
231 1.3.8.2 tls
232 1.3.8.2 tls #ifdef DWARF_ZERO_REG
233 1.3.8.2 tls if (index == DWARF_ZERO_REG)
234 1.3.8.2 tls return 0;
235 1.3.8.2 tls #endif
236 1.3.8.2 tls
237 1.3.8.2 tls index = DWARF_REG_TO_UNWIND_COLUMN (index);
238 1.3.8.2 tls gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
239 1.3.8.2 tls size = dwarf_reg_size_table[index];
240 1.3.8.2 tls val = context->reg[index];
241 1.3.8.2 tls
242 1.3.8.2 tls if (_Unwind_IsExtendedContext (context) && context->by_value[index])
243 1.3.8.2 tls return _Unwind_Get_Unwind_Word (val);
244 1.3.8.2 tls
245 1.3.8.2 tls /* This will segfault if the register hasn't been saved. */
246 1.3.8.2 tls if (size == sizeof(_Unwind_Ptr))
247 1.3.8.2 tls return * (_Unwind_Ptr *) (_Unwind_Internal_Ptr) val;
248 1.3.8.2 tls else
249 1.3.8.2 tls {
250 1.3.8.2 tls gcc_assert (size == sizeof(_Unwind_Word));
251 1.3.8.2 tls return * (_Unwind_Word *) (_Unwind_Internal_Ptr) val;
252 1.3.8.2 tls }
253 1.3.8.2 tls }
254 1.3.8.2 tls
255 1.3.8.2 tls static inline void *
256 1.3.8.2 tls _Unwind_GetPtr (struct _Unwind_Context *context, int index)
257 1.3.8.2 tls {
258 1.3.8.2 tls return (void *)(_Unwind_Ptr) _Unwind_GetGR (context, index);
259 1.3.8.2 tls }
260 1.3.8.2 tls
261 1.3.8.2 tls /* Get the value of the CFA as saved in CONTEXT. */
262 1.3.8.2 tls
263 1.3.8.2 tls _Unwind_Word
264 1.3.8.2 tls _Unwind_GetCFA (struct _Unwind_Context *context)
265 1.3.8.2 tls {
266 1.3.8.2 tls return (_Unwind_Ptr) context->cfa;
267 1.3.8.2 tls }
268 1.3.8.2 tls
269 1.3.8.2 tls /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
270 1.3.8.2 tls
271 1.3.8.2 tls inline void
272 1.3.8.2 tls _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
273 1.3.8.2 tls {
274 1.3.8.2 tls int size;
275 1.3.8.2 tls void *ptr;
276 1.3.8.2 tls
277 1.3.8.2 tls index = DWARF_REG_TO_UNWIND_COLUMN (index);
278 1.3.8.2 tls gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
279 1.3.8.2 tls size = dwarf_reg_size_table[index];
280 1.3.8.2 tls
281 1.3.8.2 tls if (_Unwind_IsExtendedContext (context) && context->by_value[index])
282 1.3.8.2 tls {
283 1.3.8.2 tls context->reg[index] = _Unwind_Get_Unwind_Context_Reg_Val (val);
284 1.3.8.2 tls return;
285 1.3.8.2 tls }
286 1.3.8.2 tls
287 1.3.8.2 tls ptr = (void *) (_Unwind_Internal_Ptr) context->reg[index];
288 1.3.8.2 tls
289 1.3.8.2 tls if (size == sizeof(_Unwind_Ptr))
290 1.3.8.2 tls * (_Unwind_Ptr *) ptr = val;
291 1.3.8.2 tls else
292 1.3.8.2 tls {
293 1.3.8.2 tls gcc_assert (size == sizeof(_Unwind_Word));
294 1.3.8.2 tls * (_Unwind_Word *) ptr = val;
295 1.3.8.2 tls }
296 1.3.8.2 tls }
297 1.3.8.2 tls
298 1.3.8.2 tls /* Get the pointer to a register INDEX as saved in CONTEXT. */
299 1.3.8.2 tls
300 1.3.8.2 tls static inline void *
301 1.3.8.2 tls _Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
302 1.3.8.2 tls {
303 1.3.8.2 tls index = DWARF_REG_TO_UNWIND_COLUMN (index);
304 1.3.8.2 tls if (_Unwind_IsExtendedContext (context) && context->by_value[index])
305 1.3.8.2 tls return &context->reg[index];
306 1.3.8.2 tls return (void *) (_Unwind_Internal_Ptr) context->reg[index];
307 1.3.8.2 tls }
308 1.3.8.2 tls
309 1.3.8.2 tls /* Set the pointer to a register INDEX as saved in CONTEXT. */
310 1.3.8.2 tls
311 1.3.8.2 tls static inline void
312 1.3.8.2 tls _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
313 1.3.8.2 tls {
314 1.3.8.2 tls index = DWARF_REG_TO_UNWIND_COLUMN (index);
315 1.3.8.2 tls if (_Unwind_IsExtendedContext (context))
316 1.3.8.2 tls context->by_value[index] = 0;
317 1.3.8.2 tls context->reg[index] = (_Unwind_Context_Reg_Val) (_Unwind_Internal_Ptr) p;
318 1.3.8.2 tls }
319 1.3.8.2 tls
320 1.3.8.2 tls /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
321 1.3.8.2 tls
322 1.3.8.2 tls static inline void
323 1.3.8.2 tls _Unwind_SetGRValue (struct _Unwind_Context *context, int index,
324 1.3.8.2 tls _Unwind_Word val)
325 1.3.8.2 tls {
326 1.3.8.2 tls index = DWARF_REG_TO_UNWIND_COLUMN (index);
327 1.3.8.2 tls gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
328 1.3.8.2 tls /* Return column size may be smaller than _Unwind_Context_Reg_Val. */
329 1.3.8.2 tls gcc_assert (dwarf_reg_size_table[index] <= sizeof (_Unwind_Context_Reg_Val));
330 1.3.8.2 tls
331 1.3.8.2 tls context->by_value[index] = 1;
332 1.3.8.2 tls context->reg[index] = _Unwind_Get_Unwind_Context_Reg_Val (val);
333 1.3.8.2 tls }
334 1.3.8.2 tls
335 1.3.8.2 tls /* Return nonzero if register INDEX is stored by value rather than
336 1.3.8.2 tls by reference. */
337 1.3.8.2 tls
338 1.3.8.2 tls static inline int
339 1.3.8.2 tls _Unwind_GRByValue (struct _Unwind_Context *context, int index)
340 1.3.8.2 tls {
341 1.3.8.2 tls index = DWARF_REG_TO_UNWIND_COLUMN (index);
342 1.3.8.2 tls return context->by_value[index];
343 1.3.8.2 tls }
344 1.3.8.2 tls
345 1.3.8.2 tls /* Retrieve the return address for CONTEXT. */
346 1.3.8.2 tls
347 1.3.8.2 tls inline _Unwind_Ptr
348 1.3.8.2 tls _Unwind_GetIP (struct _Unwind_Context *context)
349 1.3.8.2 tls {
350 1.3.8.2 tls return (_Unwind_Ptr) context->ra;
351 1.3.8.2 tls }
352 1.3.8.2 tls
353 1.3.8.2 tls /* Retrieve the return address and flag whether that IP is before
354 1.3.8.2 tls or after first not yet fully executed instruction. */
355 1.3.8.2 tls
356 1.3.8.2 tls inline _Unwind_Ptr
357 1.3.8.2 tls _Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
358 1.3.8.2 tls {
359 1.3.8.2 tls *ip_before_insn = _Unwind_IsSignalFrame (context);
360 1.3.8.2 tls return (_Unwind_Ptr) context->ra;
361 1.3.8.2 tls }
362 1.3.8.2 tls
363 1.3.8.2 tls /* Overwrite the return address for CONTEXT with VAL. */
364 1.3.8.2 tls
365 1.3.8.2 tls inline void
366 1.3.8.2 tls _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
367 1.3.8.2 tls {
368 1.3.8.2 tls context->ra = (void *) val;
369 1.3.8.2 tls }
370 1.3.8.2 tls
371 1.3.8.2 tls _Unwind_Ptr
372 1.3.8.2 tls _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
373 1.3.8.2 tls {
374 1.3.8.2 tls return (_Unwind_Ptr) context->lsda;
375 1.3.8.2 tls }
376 1.3.8.2 tls
377 1.3.8.2 tls _Unwind_Ptr
378 1.3.8.2 tls _Unwind_GetRegionStart (struct _Unwind_Context *context)
379 1.3.8.2 tls {
380 1.3.8.2 tls return (_Unwind_Ptr) context->bases.func;
381 1.3.8.2 tls }
382 1.3.8.2 tls
383 1.3.8.2 tls void *
384 1.3.8.2 tls _Unwind_FindEnclosingFunction (void *pc)
385 1.3.8.2 tls {
386 1.3.8.2 tls struct dwarf_eh_bases bases;
387 1.3.8.2 tls const struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
388 1.3.8.2 tls if (fde)
389 1.3.8.2 tls return bases.func;
390 1.3.8.2 tls else
391 1.3.8.2 tls return NULL;
392 1.3.8.2 tls }
393 1.3.8.2 tls
394 1.3.8.2 tls #ifndef __ia64__
395 1.3.8.2 tls _Unwind_Ptr
396 1.3.8.2 tls _Unwind_GetDataRelBase (struct _Unwind_Context *context)
397 1.3.8.2 tls {
398 1.3.8.2 tls return (_Unwind_Ptr) context->bases.dbase;
399 1.3.8.2 tls }
400 1.3.8.2 tls
401 1.3.8.2 tls _Unwind_Ptr
402 1.3.8.2 tls _Unwind_GetTextRelBase (struct _Unwind_Context *context)
403 1.3.8.2 tls {
404 1.3.8.2 tls return (_Unwind_Ptr) context->bases.tbase;
405 1.3.8.2 tls }
406 1.3.8.2 tls #endif
407 1.3.8.2 tls
408 1.3.8.2 tls #include "md-unwind-support.h"
409 1.3.8.2 tls
410 1.3.8.2 tls /* Extract any interesting information from the CIE for the translation
412 1.3.8.2 tls unit F belongs to. Return a pointer to the byte after the augmentation,
413 1.3.8.2 tls or NULL if we encountered an undecipherable augmentation. */
414 1.3.8.2 tls
415 1.3.8.2 tls static const unsigned char *
416 1.3.8.2 tls extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
417 1.3.8.2 tls _Unwind_FrameState *fs)
418 1.3.8.2 tls {
419 1.3.8.2 tls const unsigned char *aug = cie->augmentation;
420 1.3.8.2 tls const unsigned char *p = aug + strlen ((const char *)aug) + 1;
421 1.3.8.2 tls const unsigned char *ret = NULL;
422 1.3.8.2 tls _uleb128_t utmp;
423 1.3.8.2 tls _sleb128_t stmp;
424 1.3.8.2 tls
425 1.3.8.2 tls /* g++ v2 "eh" has pointer immediately following augmentation string,
426 1.3.8.2 tls so it must be handled first. */
427 1.3.8.2 tls if (aug[0] == 'e' && aug[1] == 'h')
428 1.3.8.2 tls {
429 1.3.8.2 tls fs->eh_ptr = read_pointer (p);
430 1.3.8.2 tls p += sizeof (void *);
431 1.3.8.2 tls aug += 2;
432 1.3.8.2 tls }
433 1.3.8.2 tls
434 1.3.8.2 tls /* After the augmentation resp. pointer for "eh" augmentation
435 1.3.8.2 tls follows for CIE version >= 4 address size byte and
436 1.3.8.2 tls segment size byte. */
437 1.3.8.2 tls if (__builtin_expect (cie->version >= 4, 0))
438 1.3.8.2 tls {
439 1.3.8.2 tls if (p[0] != sizeof (void *) || p[1] != 0)
440 1.3.8.2 tls return NULL;
441 1.3.8.2 tls p += 2;
442 1.3.8.2 tls }
443 1.3.8.2 tls /* Immediately following this are the code and
444 1.3.8.2 tls data alignment and return address column. */
445 1.3.8.2 tls p = read_uleb128 (p, &utmp);
446 1.3.8.2 tls fs->code_align = (_Unwind_Word)utmp;
447 1.3.8.2 tls p = read_sleb128 (p, &stmp);
448 1.3.8.2 tls fs->data_align = (_Unwind_Sword)stmp;
449 1.3.8.2 tls if (cie->version == 1)
450 1.3.8.2 tls fs->retaddr_column = *p++;
451 1.3.8.2 tls else
452 1.3.8.2 tls {
453 1.3.8.2 tls p = read_uleb128 (p, &utmp);
454 1.3.8.2 tls fs->retaddr_column = (_Unwind_Word)utmp;
455 1.3.8.2 tls }
456 1.3.8.2 tls fs->lsda_encoding = DW_EH_PE_omit;
457 1.3.8.2 tls
458 1.3.8.2 tls /* If the augmentation starts with 'z', then a uleb128 immediately
459 1.3.8.2 tls follows containing the length of the augmentation field following
460 1.3.8.2 tls the size. */
461 1.3.8.2 tls if (*aug == 'z')
462 1.3.8.2 tls {
463 1.3.8.2 tls p = read_uleb128 (p, &utmp);
464 1.3.8.2 tls ret = p + utmp;
465 1.3.8.2 tls
466 1.3.8.2 tls fs->saw_z = 1;
467 1.3.8.2 tls ++aug;
468 1.3.8.2 tls }
469 1.3.8.2 tls
470 1.3.8.2 tls /* Iterate over recognized augmentation subsequences. */
471 1.3.8.2 tls while (*aug != '\0')
472 1.3.8.2 tls {
473 1.3.8.2 tls /* "L" indicates a byte showing how the LSDA pointer is encoded. */
474 1.3.8.2 tls if (aug[0] == 'L')
475 1.3.8.2 tls {
476 1.3.8.2 tls fs->lsda_encoding = *p++;
477 1.3.8.2 tls aug += 1;
478 1.3.8.2 tls }
479 1.3.8.2 tls
480 1.3.8.2 tls /* "R" indicates a byte indicating how FDE addresses are encoded. */
481 1.3.8.2 tls else if (aug[0] == 'R')
482 1.3.8.2 tls {
483 1.3.8.2 tls fs->fde_encoding = *p++;
484 1.3.8.2 tls aug += 1;
485 1.3.8.2 tls }
486 1.3.8.2 tls
487 1.3.8.2 tls /* "P" indicates a personality routine in the CIE augmentation. */
488 1.3.8.2 tls else if (aug[0] == 'P')
489 1.3.8.2 tls {
490 1.3.8.2 tls _Unwind_Ptr personality;
491 1.3.8.2 tls
492 1.3.8.2 tls p = read_encoded_value (context, *p, p + 1, &personality);
493 1.3.8.2 tls fs->personality = (_Unwind_Personality_Fn) personality;
494 1.3.8.2 tls aug += 1;
495 1.3.8.2 tls }
496 1.3.8.2 tls
497 1.3.8.2 tls /* "S" indicates a signal frame. */
498 1.3.8.2 tls else if (aug[0] == 'S')
499 1.3.8.2 tls {
500 1.3.8.2 tls fs->signal_frame = 1;
501 1.3.8.2 tls aug += 1;
502 1.3.8.2 tls }
503 1.3.8.2 tls
504 1.3.8.2 tls /* Otherwise we have an unknown augmentation string.
505 1.3.8.2 tls Bail unless we saw a 'z' prefix. */
506 1.3.8.2 tls else
507 1.3.8.2 tls return ret;
508 1.3.8.2 tls }
509 1.3.8.2 tls
510 1.3.8.2 tls return ret ? ret : p;
511 1.3.8.2 tls }
512 1.3.8.2 tls
513 1.3.8.2 tls
514 1.3.8.2 tls /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
515 1.3.8.2 tls onto the stack to start. */
516 1.3.8.2 tls
517 1.3.8.2 tls static _Unwind_Word
518 1.3.8.2 tls execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
519 1.3.8.2 tls struct _Unwind_Context *context, _Unwind_Word initial)
520 1.3.8.2 tls {
521 1.3.8.2 tls _Unwind_Word stack[64]; /* ??? Assume this is enough. */
522 1.3.8.2 tls int stack_elt;
523 1.3.8.2 tls
524 1.3.8.2 tls stack[0] = initial;
525 1.3.8.2 tls stack_elt = 1;
526 1.3.8.2 tls
527 1.3.8.2 tls while (op_ptr < op_end)
528 1.3.8.2 tls {
529 1.3.8.2 tls enum dwarf_location_atom op = *op_ptr++;
530 1.3.8.2 tls _Unwind_Word result;
531 1.3.8.2 tls _uleb128_t reg, utmp;
532 1.3.8.2 tls _sleb128_t offset, stmp;
533 1.3.8.2 tls
534 1.3.8.2 tls switch (op)
535 1.3.8.2 tls {
536 1.3.8.2 tls case DW_OP_lit0:
537 1.3.8.2 tls case DW_OP_lit1:
538 1.3.8.2 tls case DW_OP_lit2:
539 1.3.8.2 tls case DW_OP_lit3:
540 1.3.8.2 tls case DW_OP_lit4:
541 1.3.8.2 tls case DW_OP_lit5:
542 1.3.8.2 tls case DW_OP_lit6:
543 1.3.8.2 tls case DW_OP_lit7:
544 1.3.8.2 tls case DW_OP_lit8:
545 1.3.8.2 tls case DW_OP_lit9:
546 1.3.8.2 tls case DW_OP_lit10:
547 1.3.8.2 tls case DW_OP_lit11:
548 1.3.8.2 tls case DW_OP_lit12:
549 1.3.8.2 tls case DW_OP_lit13:
550 1.3.8.2 tls case DW_OP_lit14:
551 1.3.8.2 tls case DW_OP_lit15:
552 1.3.8.2 tls case DW_OP_lit16:
553 1.3.8.2 tls case DW_OP_lit17:
554 1.3.8.2 tls case DW_OP_lit18:
555 1.3.8.2 tls case DW_OP_lit19:
556 1.3.8.2 tls case DW_OP_lit20:
557 1.3.8.2 tls case DW_OP_lit21:
558 1.3.8.2 tls case DW_OP_lit22:
559 1.3.8.2 tls case DW_OP_lit23:
560 1.3.8.2 tls case DW_OP_lit24:
561 1.3.8.2 tls case DW_OP_lit25:
562 1.3.8.2 tls case DW_OP_lit26:
563 1.3.8.2 tls case DW_OP_lit27:
564 1.3.8.2 tls case DW_OP_lit28:
565 1.3.8.2 tls case DW_OP_lit29:
566 1.3.8.2 tls case DW_OP_lit30:
567 1.3.8.2 tls case DW_OP_lit31:
568 1.3.8.2 tls result = op - DW_OP_lit0;
569 1.3.8.2 tls break;
570 1.3.8.2 tls
571 1.3.8.2 tls case DW_OP_addr:
572 1.3.8.2 tls result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
573 1.3.8.2 tls op_ptr += sizeof (void *);
574 1.3.8.2 tls break;
575 1.3.8.2 tls
576 1.3.8.2 tls case DW_OP_GNU_encoded_addr:
577 1.3.8.2 tls {
578 1.3.8.2 tls _Unwind_Ptr presult;
579 1.3.8.2 tls op_ptr = read_encoded_value (context, *op_ptr, op_ptr+1, &presult);
580 1.3.8.2 tls result = presult;
581 1.3.8.2 tls }
582 1.3.8.2 tls break;
583 1.3.8.2 tls
584 1.3.8.2 tls case DW_OP_const1u:
585 1.3.8.2 tls result = read_1u (op_ptr);
586 1.3.8.2 tls op_ptr += 1;
587 1.3.8.2 tls break;
588 1.3.8.2 tls case DW_OP_const1s:
589 1.3.8.2 tls result = read_1s (op_ptr);
590 1.3.8.2 tls op_ptr += 1;
591 1.3.8.2 tls break;
592 1.3.8.2 tls case DW_OP_const2u:
593 1.3.8.2 tls result = read_2u (op_ptr);
594 1.3.8.2 tls op_ptr += 2;
595 1.3.8.2 tls break;
596 1.3.8.2 tls case DW_OP_const2s:
597 1.3.8.2 tls result = read_2s (op_ptr);
598 1.3.8.2 tls op_ptr += 2;
599 1.3.8.2 tls break;
600 1.3.8.2 tls case DW_OP_const4u:
601 1.3.8.2 tls result = read_4u (op_ptr);
602 1.3.8.2 tls op_ptr += 4;
603 1.3.8.2 tls break;
604 1.3.8.2 tls case DW_OP_const4s:
605 1.3.8.2 tls result = read_4s (op_ptr);
606 1.3.8.2 tls op_ptr += 4;
607 1.3.8.2 tls break;
608 1.3.8.2 tls case DW_OP_const8u:
609 1.3.8.2 tls result = read_8u (op_ptr);
610 1.3.8.2 tls op_ptr += 8;
611 1.3.8.2 tls break;
612 1.3.8.2 tls case DW_OP_const8s:
613 1.3.8.2 tls result = read_8s (op_ptr);
614 1.3.8.2 tls op_ptr += 8;
615 1.3.8.2 tls break;
616 1.3.8.2 tls case DW_OP_constu:
617 1.3.8.2 tls op_ptr = read_uleb128 (op_ptr, &utmp);
618 1.3.8.2 tls result = (_Unwind_Word)utmp;
619 1.3.8.2 tls break;
620 1.3.8.2 tls case DW_OP_consts:
621 1.3.8.2 tls op_ptr = read_sleb128 (op_ptr, &stmp);
622 1.3.8.2 tls result = (_Unwind_Sword)stmp;
623 1.3.8.2 tls break;
624 1.3.8.2 tls
625 1.3.8.2 tls case DW_OP_reg0:
626 1.3.8.2 tls case DW_OP_reg1:
627 1.3.8.2 tls case DW_OP_reg2:
628 1.3.8.2 tls case DW_OP_reg3:
629 1.3.8.2 tls case DW_OP_reg4:
630 1.3.8.2 tls case DW_OP_reg5:
631 1.3.8.2 tls case DW_OP_reg6:
632 1.3.8.2 tls case DW_OP_reg7:
633 1.3.8.2 tls case DW_OP_reg8:
634 1.3.8.2 tls case DW_OP_reg9:
635 1.3.8.2 tls case DW_OP_reg10:
636 1.3.8.2 tls case DW_OP_reg11:
637 1.3.8.2 tls case DW_OP_reg12:
638 1.3.8.2 tls case DW_OP_reg13:
639 1.3.8.2 tls case DW_OP_reg14:
640 1.3.8.2 tls case DW_OP_reg15:
641 1.3.8.2 tls case DW_OP_reg16:
642 1.3.8.2 tls case DW_OP_reg17:
643 1.3.8.2 tls case DW_OP_reg18:
644 1.3.8.2 tls case DW_OP_reg19:
645 1.3.8.2 tls case DW_OP_reg20:
646 1.3.8.2 tls case DW_OP_reg21:
647 1.3.8.2 tls case DW_OP_reg22:
648 1.3.8.2 tls case DW_OP_reg23:
649 1.3.8.2 tls case DW_OP_reg24:
650 1.3.8.2 tls case DW_OP_reg25:
651 1.3.8.2 tls case DW_OP_reg26:
652 1.3.8.2 tls case DW_OP_reg27:
653 1.3.8.2 tls case DW_OP_reg28:
654 1.3.8.2 tls case DW_OP_reg29:
655 1.3.8.2 tls case DW_OP_reg30:
656 1.3.8.2 tls case DW_OP_reg31:
657 1.3.8.2 tls result = _Unwind_GetGR (context, op - DW_OP_reg0);
658 1.3.8.2 tls break;
659 1.3.8.2 tls case DW_OP_regx:
660 1.3.8.2 tls op_ptr = read_uleb128 (op_ptr, ®);
661 1.3.8.2 tls result = _Unwind_GetGR (context, reg);
662 1.3.8.2 tls break;
663 1.3.8.2 tls
664 1.3.8.2 tls case DW_OP_breg0:
665 1.3.8.2 tls case DW_OP_breg1:
666 1.3.8.2 tls case DW_OP_breg2:
667 1.3.8.2 tls case DW_OP_breg3:
668 1.3.8.2 tls case DW_OP_breg4:
669 1.3.8.2 tls case DW_OP_breg5:
670 1.3.8.2 tls case DW_OP_breg6:
671 1.3.8.2 tls case DW_OP_breg7:
672 1.3.8.2 tls case DW_OP_breg8:
673 1.3.8.2 tls case DW_OP_breg9:
674 1.3.8.2 tls case DW_OP_breg10:
675 1.3.8.2 tls case DW_OP_breg11:
676 1.3.8.2 tls case DW_OP_breg12:
677 1.3.8.2 tls case DW_OP_breg13:
678 1.3.8.2 tls case DW_OP_breg14:
679 1.3.8.2 tls case DW_OP_breg15:
680 1.3.8.2 tls case DW_OP_breg16:
681 1.3.8.2 tls case DW_OP_breg17:
682 1.3.8.2 tls case DW_OP_breg18:
683 1.3.8.2 tls case DW_OP_breg19:
684 1.3.8.2 tls case DW_OP_breg20:
685 1.3.8.2 tls case DW_OP_breg21:
686 1.3.8.2 tls case DW_OP_breg22:
687 1.3.8.2 tls case DW_OP_breg23:
688 1.3.8.2 tls case DW_OP_breg24:
689 1.3.8.2 tls case DW_OP_breg25:
690 1.3.8.2 tls case DW_OP_breg26:
691 1.3.8.2 tls case DW_OP_breg27:
692 1.3.8.2 tls case DW_OP_breg28:
693 1.3.8.2 tls case DW_OP_breg29:
694 1.3.8.2 tls case DW_OP_breg30:
695 1.3.8.2 tls case DW_OP_breg31:
696 1.3.8.2 tls op_ptr = read_sleb128 (op_ptr, &offset);
697 1.3.8.2 tls result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
698 1.3.8.2 tls break;
699 1.3.8.2 tls case DW_OP_bregx:
700 1.3.8.2 tls op_ptr = read_uleb128 (op_ptr, ®);
701 1.3.8.2 tls op_ptr = read_sleb128 (op_ptr, &offset);
702 1.3.8.2 tls result = _Unwind_GetGR (context, reg) + (_Unwind_Word)offset;
703 1.3.8.2 tls break;
704 1.3.8.2 tls
705 1.3.8.2 tls case DW_OP_dup:
706 1.3.8.2 tls gcc_assert (stack_elt);
707 1.3.8.2 tls result = stack[stack_elt - 1];
708 1.3.8.2 tls break;
709 1.3.8.2 tls
710 1.3.8.2 tls case DW_OP_drop:
711 1.3.8.2 tls gcc_assert (stack_elt);
712 1.3.8.2 tls stack_elt -= 1;
713 1.3.8.2 tls goto no_push;
714 1.3.8.2 tls
715 1.3.8.2 tls case DW_OP_pick:
716 1.3.8.2 tls offset = *op_ptr++;
717 1.3.8.2 tls gcc_assert (offset < stack_elt - 1);
718 1.3.8.2 tls result = stack[stack_elt - 1 - offset];
719 1.3.8.2 tls break;
720 1.3.8.2 tls
721 1.3.8.2 tls case DW_OP_over:
722 1.3.8.2 tls gcc_assert (stack_elt >= 2);
723 1.3.8.2 tls result = stack[stack_elt - 2];
724 1.3.8.2 tls break;
725 1.3.8.2 tls
726 1.3.8.2 tls case DW_OP_swap:
727 1.3.8.2 tls {
728 1.3.8.2 tls _Unwind_Word t;
729 1.3.8.2 tls gcc_assert (stack_elt >= 2);
730 1.3.8.2 tls t = stack[stack_elt - 1];
731 1.3.8.2 tls stack[stack_elt - 1] = stack[stack_elt - 2];
732 1.3.8.2 tls stack[stack_elt - 2] = t;
733 1.3.8.2 tls goto no_push;
734 1.3.8.2 tls }
735 1.3.8.2 tls
736 1.3.8.2 tls case DW_OP_rot:
737 1.3.8.2 tls {
738 1.3.8.2 tls _Unwind_Word t1, t2, t3;
739 1.3.8.2 tls
740 1.3.8.2 tls gcc_assert (stack_elt >= 3);
741 1.3.8.2 tls t1 = stack[stack_elt - 1];
742 1.3.8.2 tls t2 = stack[stack_elt - 2];
743 1.3.8.2 tls t3 = stack[stack_elt - 3];
744 1.3.8.2 tls stack[stack_elt - 1] = t2;
745 1.3.8.2 tls stack[stack_elt - 2] = t3;
746 1.3.8.2 tls stack[stack_elt - 3] = t1;
747 1.3.8.2 tls goto no_push;
748 1.3.8.2 tls }
749 1.3.8.2 tls
750 1.3.8.2 tls case DW_OP_deref:
751 1.3.8.2 tls case DW_OP_deref_size:
752 1.3.8.2 tls case DW_OP_abs:
753 1.3.8.2 tls case DW_OP_neg:
754 1.3.8.2 tls case DW_OP_not:
755 1.3.8.2 tls case DW_OP_plus_uconst:
756 1.3.8.2 tls /* Unary operations. */
757 1.3.8.2 tls gcc_assert (stack_elt);
758 1.3.8.2 tls stack_elt -= 1;
759 1.3.8.2 tls
760 1.3.8.2 tls result = stack[stack_elt];
761 1.3.8.2 tls
762 1.3.8.2 tls switch (op)
763 1.3.8.2 tls {
764 1.3.8.2 tls case DW_OP_deref:
765 1.3.8.2 tls {
766 1.3.8.2 tls void *ptr = (void *) (_Unwind_Ptr) result;
767 1.3.8.2 tls result = (_Unwind_Ptr) read_pointer (ptr);
768 1.3.8.2 tls }
769 1.3.8.2 tls break;
770 1.3.8.2 tls
771 1.3.8.2 tls case DW_OP_deref_size:
772 1.3.8.2 tls {
773 1.3.8.2 tls void *ptr = (void *) (_Unwind_Ptr) result;
774 1.3.8.2 tls switch (*op_ptr++)
775 1.3.8.2 tls {
776 1.3.8.2 tls case 1:
777 1.3.8.2 tls result = read_1u (ptr);
778 1.3.8.2 tls break;
779 1.3.8.2 tls case 2:
780 1.3.8.2 tls result = read_2u (ptr);
781 1.3.8.2 tls break;
782 1.3.8.2 tls case 4:
783 1.3.8.2 tls result = read_4u (ptr);
784 1.3.8.2 tls break;
785 1.3.8.2 tls case 8:
786 1.3.8.2 tls result = read_8u (ptr);
787 1.3.8.2 tls break;
788 1.3.8.2 tls default:
789 1.3.8.2 tls gcc_unreachable ();
790 1.3.8.2 tls }
791 1.3.8.2 tls }
792 1.3.8.2 tls break;
793 1.3.8.2 tls
794 1.3.8.2 tls case DW_OP_abs:
795 1.3.8.2 tls if ((_Unwind_Sword) result < 0)
796 1.3.8.2 tls result = -result;
797 1.3.8.2 tls break;
798 1.3.8.2 tls case DW_OP_neg:
799 1.3.8.2 tls result = -result;
800 1.3.8.2 tls break;
801 1.3.8.2 tls case DW_OP_not:
802 1.3.8.2 tls result = ~result;
803 1.3.8.2 tls break;
804 1.3.8.2 tls case DW_OP_plus_uconst:
805 1.3.8.2 tls op_ptr = read_uleb128 (op_ptr, &utmp);
806 1.3.8.2 tls result += (_Unwind_Word)utmp;
807 1.3.8.2 tls break;
808 1.3.8.2 tls
809 1.3.8.2 tls default:
810 1.3.8.2 tls gcc_unreachable ();
811 1.3.8.2 tls }
812 1.3.8.2 tls break;
813 1.3.8.2 tls
814 1.3.8.2 tls case DW_OP_and:
815 1.3.8.2 tls case DW_OP_div:
816 1.3.8.2 tls case DW_OP_minus:
817 1.3.8.2 tls case DW_OP_mod:
818 1.3.8.2 tls case DW_OP_mul:
819 1.3.8.2 tls case DW_OP_or:
820 1.3.8.2 tls case DW_OP_plus:
821 1.3.8.2 tls case DW_OP_shl:
822 1.3.8.2 tls case DW_OP_shr:
823 1.3.8.2 tls case DW_OP_shra:
824 1.3.8.2 tls case DW_OP_xor:
825 1.3.8.2 tls case DW_OP_le:
826 1.3.8.2 tls case DW_OP_ge:
827 1.3.8.2 tls case DW_OP_eq:
828 1.3.8.2 tls case DW_OP_lt:
829 1.3.8.2 tls case DW_OP_gt:
830 1.3.8.2 tls case DW_OP_ne:
831 1.3.8.2 tls {
832 1.3.8.2 tls /* Binary operations. */
833 1.3.8.2 tls _Unwind_Word first, second;
834 1.3.8.2 tls gcc_assert (stack_elt >= 2);
835 1.3.8.2 tls stack_elt -= 2;
836 1.3.8.2 tls
837 1.3.8.2 tls second = stack[stack_elt];
838 1.3.8.2 tls first = stack[stack_elt + 1];
839 1.3.8.2 tls
840 1.3.8.2 tls switch (op)
841 1.3.8.2 tls {
842 1.3.8.2 tls case DW_OP_and:
843 1.3.8.2 tls result = second & first;
844 1.3.8.2 tls break;
845 1.3.8.2 tls case DW_OP_div:
846 1.3.8.2 tls result = (_Unwind_Sword) second / (_Unwind_Sword) first;
847 1.3.8.2 tls break;
848 1.3.8.2 tls case DW_OP_minus:
849 1.3.8.2 tls result = second - first;
850 1.3.8.2 tls break;
851 1.3.8.2 tls case DW_OP_mod:
852 1.3.8.2 tls result = second % first;
853 1.3.8.2 tls break;
854 1.3.8.2 tls case DW_OP_mul:
855 1.3.8.2 tls result = second * first;
856 1.3.8.2 tls break;
857 1.3.8.2 tls case DW_OP_or:
858 1.3.8.2 tls result = second | first;
859 1.3.8.2 tls break;
860 1.3.8.2 tls case DW_OP_plus:
861 1.3.8.2 tls result = second + first;
862 1.3.8.2 tls break;
863 1.3.8.2 tls case DW_OP_shl:
864 1.3.8.2 tls result = second << first;
865 1.3.8.2 tls break;
866 1.3.8.2 tls case DW_OP_shr:
867 1.3.8.2 tls result = second >> first;
868 1.3.8.2 tls break;
869 1.3.8.2 tls case DW_OP_shra:
870 1.3.8.2 tls result = (_Unwind_Sword) second >> first;
871 1.3.8.2 tls break;
872 1.3.8.2 tls case DW_OP_xor:
873 1.3.8.2 tls result = second ^ first;
874 1.3.8.2 tls break;
875 1.3.8.2 tls case DW_OP_le:
876 1.3.8.2 tls result = (_Unwind_Sword) second <= (_Unwind_Sword) first;
877 1.3.8.2 tls break;
878 1.3.8.2 tls case DW_OP_ge:
879 1.3.8.2 tls result = (_Unwind_Sword) second >= (_Unwind_Sword) first;
880 1.3.8.2 tls break;
881 1.3.8.2 tls case DW_OP_eq:
882 1.3.8.2 tls result = (_Unwind_Sword) second == (_Unwind_Sword) first;
883 1.3.8.2 tls break;
884 1.3.8.2 tls case DW_OP_lt:
885 1.3.8.2 tls result = (_Unwind_Sword) second < (_Unwind_Sword) first;
886 1.3.8.2 tls break;
887 1.3.8.2 tls case DW_OP_gt:
888 1.3.8.2 tls result = (_Unwind_Sword) second > (_Unwind_Sword) first;
889 1.3.8.2 tls break;
890 1.3.8.2 tls case DW_OP_ne:
891 1.3.8.2 tls result = (_Unwind_Sword) second != (_Unwind_Sword) first;
892 1.3.8.2 tls break;
893 1.3.8.2 tls
894 1.3.8.2 tls default:
895 1.3.8.2 tls gcc_unreachable ();
896 1.3.8.2 tls }
897 1.3.8.2 tls }
898 1.3.8.2 tls break;
899 1.3.8.2 tls
900 1.3.8.2 tls case DW_OP_skip:
901 1.3.8.2 tls offset = read_2s (op_ptr);
902 1.3.8.2 tls op_ptr += 2;
903 1.3.8.2 tls op_ptr += offset;
904 1.3.8.2 tls goto no_push;
905 1.3.8.2 tls
906 1.3.8.2 tls case DW_OP_bra:
907 1.3.8.2 tls gcc_assert (stack_elt);
908 1.3.8.2 tls stack_elt -= 1;
909 1.3.8.2 tls
910 1.3.8.2 tls offset = read_2s (op_ptr);
911 1.3.8.2 tls op_ptr += 2;
912 1.3.8.2 tls if (stack[stack_elt] != 0)
913 1.3.8.2 tls op_ptr += offset;
914 1.3.8.2 tls goto no_push;
915 1.3.8.2 tls
916 1.3.8.2 tls case DW_OP_nop:
917 1.3.8.2 tls goto no_push;
918 1.3.8.2 tls
919 1.3.8.2 tls default:
920 1.3.8.2 tls gcc_unreachable ();
921 1.3.8.2 tls }
922 1.3.8.2 tls
923 1.3.8.2 tls /* Most things push a result value. */
924 1.3.8.2 tls gcc_assert ((size_t) stack_elt < sizeof(stack)/sizeof(*stack));
925 1.3.8.2 tls stack[stack_elt++] = result;
926 1.3.8.2 tls no_push:;
927 1.3.8.2 tls }
928 1.3.8.2 tls
929 1.3.8.2 tls /* We were executing this program to get a value. It should be
930 1.3.8.2 tls at top of stack. */
931 1.3.8.2 tls gcc_assert (stack_elt);
932 1.3.8.2 tls stack_elt -= 1;
933 1.3.8.2 tls return stack[stack_elt];
934 1.3.8.2 tls }
935 1.3.8.2 tls
936 1.3.8.2 tls
937 1.3.8.2 tls /* Decode DWARF 2 call frame information. Takes pointers the
938 1.3.8.2 tls instruction sequence to decode, current register information and
939 1.3.8.2 tls CIE info, and the PC range to evaluate. */
940 1.3.8.2 tls
941 1.3.8.2 tls static void
942 1.3.8.2 tls execute_cfa_program (const unsigned char *insn_ptr,
943 1.3.8.2 tls const unsigned char *insn_end,
944 1.3.8.2 tls struct _Unwind_Context *context,
945 1.3.8.2 tls _Unwind_FrameState *fs)
946 1.3.8.2 tls {
947 1.3.8.2 tls struct frame_state_reg_info *unused_rs = NULL;
948 1.3.8.2 tls
949 1.3.8.2 tls /* Don't allow remember/restore between CIE and FDE programs. */
950 1.3.8.2 tls fs->regs.prev = NULL;
951 1.3.8.2 tls
952 1.3.8.2 tls /* The comparison with the return address uses < rather than <= because
953 1.3.8.2 tls we are only interested in the effects of code before the call; for a
954 1.3.8.2 tls noreturn function, the return address may point to unrelated code with
955 1.3.8.2 tls a different stack configuration that we are not interested in. We
956 1.3.8.2 tls assume that the call itself is unwind info-neutral; if not, or if
957 1.3.8.2 tls there are delay instructions that adjust the stack, these must be
958 1.3.8.2 tls reflected at the point immediately before the call insn.
959 1.3.8.2 tls In signal frames, return address is after last completed instruction,
960 1.3.8.2 tls so we add 1 to return address to make the comparison <=. */
961 1.3.8.2 tls while (insn_ptr < insn_end
962 1.3.8.2 tls && fs->pc < context->ra + _Unwind_IsSignalFrame (context))
963 1.3.8.2 tls {
964 1.3.8.2 tls unsigned char insn = *insn_ptr++;
965 1.3.8.2 tls _uleb128_t reg, utmp;
966 1.3.8.2 tls _sleb128_t offset, stmp;
967 1.3.8.2 tls
968 1.3.8.2 tls if ((insn & 0xc0) == DW_CFA_advance_loc)
969 1.3.8.2 tls fs->pc += (insn & 0x3f) * fs->code_align;
970 1.3.8.2 tls else if ((insn & 0xc0) == DW_CFA_offset)
971 1.3.8.2 tls {
972 1.3.8.2 tls reg = insn & 0x3f;
973 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, &utmp);
974 1.3.8.2 tls offset = (_Unwind_Sword) utmp * fs->data_align;
975 1.3.8.2 tls reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
976 1.3.8.2 tls if (UNWIND_COLUMN_IN_RANGE (reg))
977 1.3.8.2 tls {
978 1.3.8.2 tls fs->regs.reg[reg].how = REG_SAVED_OFFSET;
979 1.3.8.2 tls fs->regs.reg[reg].loc.offset = offset;
980 1.3.8.2 tls }
981 1.3.8.2 tls }
982 1.3.8.2 tls else if ((insn & 0xc0) == DW_CFA_restore)
983 1.3.8.2 tls {
984 1.3.8.2 tls reg = insn & 0x3f;
985 1.3.8.2 tls reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
986 1.3.8.2 tls if (UNWIND_COLUMN_IN_RANGE (reg))
987 1.3.8.2 tls fs->regs.reg[reg].how = REG_UNSAVED;
988 1.3.8.2 tls }
989 1.3.8.2 tls else switch (insn)
990 1.3.8.2 tls {
991 1.3.8.2 tls case DW_CFA_set_loc:
992 1.3.8.2 tls {
993 1.3.8.2 tls _Unwind_Ptr pc;
994 1.3.8.2 tls
995 1.3.8.2 tls insn_ptr = read_encoded_value (context, fs->fde_encoding,
996 1.3.8.2 tls insn_ptr, &pc);
997 1.3.8.2 tls fs->pc = (void *) pc;
998 1.3.8.2 tls }
999 1.3.8.2 tls break;
1000 1.3.8.2 tls
1001 1.3.8.2 tls case DW_CFA_advance_loc1:
1002 1.3.8.2 tls fs->pc += read_1u (insn_ptr) * fs->code_align;
1003 1.3.8.2 tls insn_ptr += 1;
1004 1.3.8.2 tls break;
1005 1.3.8.2 tls case DW_CFA_advance_loc2:
1006 1.3.8.2 tls fs->pc += read_2u (insn_ptr) * fs->code_align;
1007 1.3.8.2 tls insn_ptr += 2;
1008 1.3.8.2 tls break;
1009 1.3.8.2 tls case DW_CFA_advance_loc4:
1010 1.3.8.2 tls fs->pc += read_4u (insn_ptr) * fs->code_align;
1011 1.3.8.2 tls insn_ptr += 4;
1012 1.3.8.2 tls break;
1013 1.3.8.2 tls
1014 1.3.8.2 tls case DW_CFA_offset_extended:
1015 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, ®);
1016 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, &utmp);
1017 1.3.8.2 tls offset = (_Unwind_Sword) utmp * fs->data_align;
1018 1.3.8.2 tls reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1019 1.3.8.2 tls if (UNWIND_COLUMN_IN_RANGE (reg))
1020 1.3.8.2 tls {
1021 1.3.8.2 tls fs->regs.reg[reg].how = REG_SAVED_OFFSET;
1022 1.3.8.2 tls fs->regs.reg[reg].loc.offset = offset;
1023 1.3.8.2 tls }
1024 1.3.8.2 tls break;
1025 1.3.8.2 tls
1026 1.3.8.2 tls case DW_CFA_restore_extended:
1027 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, ®);
1028 1.3.8.2 tls /* FIXME, this is wrong; the CIE might have said that the
1029 1.3.8.2 tls register was saved somewhere. */
1030 1.3.8.2 tls reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1031 1.3.8.2 tls if (UNWIND_COLUMN_IN_RANGE (reg))
1032 1.3.8.2 tls fs->regs.reg[reg].how = REG_UNSAVED;
1033 1.3.8.2 tls break;
1034 1.3.8.2 tls
1035 1.3.8.2 tls case DW_CFA_same_value:
1036 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, ®);
1037 1.3.8.2 tls reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1038 1.3.8.2 tls if (UNWIND_COLUMN_IN_RANGE (reg))
1039 1.3.8.2 tls fs->regs.reg[reg].how = REG_UNSAVED;
1040 1.3.8.2 tls break;
1041 1.3.8.2 tls
1042 1.3.8.2 tls case DW_CFA_undefined:
1043 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, ®);
1044 1.3.8.2 tls reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1045 1.3.8.2 tls if (UNWIND_COLUMN_IN_RANGE (reg))
1046 1.3.8.2 tls fs->regs.reg[reg].how = REG_UNDEFINED;
1047 1.3.8.2 tls break;
1048 1.3.8.2 tls
1049 1.3.8.2 tls case DW_CFA_nop:
1050 1.3.8.2 tls break;
1051 1.3.8.2 tls
1052 1.3.8.2 tls case DW_CFA_register:
1053 1.3.8.2 tls {
1054 1.3.8.2 tls _uleb128_t reg2;
1055 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, ®);
1056 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, ®2);
1057 1.3.8.2 tls reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1058 1.3.8.2 tls if (UNWIND_COLUMN_IN_RANGE (reg))
1059 1.3.8.2 tls {
1060 1.3.8.2 tls fs->regs.reg[reg].how = REG_SAVED_REG;
1061 1.3.8.2 tls fs->regs.reg[reg].loc.reg = (_Unwind_Word)reg2;
1062 1.3.8.2 tls }
1063 1.3.8.2 tls }
1064 1.3.8.2 tls break;
1065 1.3.8.2 tls
1066 1.3.8.2 tls case DW_CFA_remember_state:
1067 1.3.8.2 tls {
1068 1.3.8.2 tls struct frame_state_reg_info *new_rs;
1069 1.3.8.2 tls if (unused_rs)
1070 1.3.8.2 tls {
1071 1.3.8.2 tls new_rs = unused_rs;
1072 1.3.8.2 tls unused_rs = unused_rs->prev;
1073 1.3.8.2 tls }
1074 1.3.8.2 tls else
1075 1.3.8.2 tls new_rs = alloca (sizeof (struct frame_state_reg_info));
1076 1.3.8.2 tls
1077 1.3.8.2 tls *new_rs = fs->regs;
1078 1.3.8.2 tls fs->regs.prev = new_rs;
1079 1.3.8.2 tls }
1080 1.3.8.2 tls break;
1081 1.3.8.2 tls
1082 1.3.8.2 tls case DW_CFA_restore_state:
1083 1.3.8.2 tls {
1084 1.3.8.2 tls struct frame_state_reg_info *old_rs = fs->regs.prev;
1085 1.3.8.2 tls fs->regs = *old_rs;
1086 1.3.8.2 tls old_rs->prev = unused_rs;
1087 1.3.8.2 tls unused_rs = old_rs;
1088 1.3.8.2 tls }
1089 1.3.8.2 tls break;
1090 1.3.8.2 tls
1091 1.3.8.2 tls case DW_CFA_def_cfa:
1092 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, &utmp);
1093 1.3.8.2 tls fs->regs.cfa_reg = (_Unwind_Word)utmp;
1094 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, &utmp);
1095 1.3.8.2 tls fs->regs.cfa_offset = (_Unwind_Word)utmp;
1096 1.3.8.2 tls fs->regs.cfa_how = CFA_REG_OFFSET;
1097 1.3.8.2 tls break;
1098 1.3.8.2 tls
1099 1.3.8.2 tls case DW_CFA_def_cfa_register:
1100 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, &utmp);
1101 1.3.8.2 tls fs->regs.cfa_reg = (_Unwind_Word)utmp;
1102 1.3.8.2 tls fs->regs.cfa_how = CFA_REG_OFFSET;
1103 1.3.8.2 tls break;
1104 1.3.8.2 tls
1105 1.3.8.2 tls case DW_CFA_def_cfa_offset:
1106 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, &utmp);
1107 1.3.8.2 tls fs->regs.cfa_offset = utmp;
1108 1.3.8.2 tls /* cfa_how deliberately not set. */
1109 1.3.8.2 tls break;
1110 1.3.8.2 tls
1111 1.3.8.2 tls case DW_CFA_def_cfa_expression:
1112 1.3.8.2 tls fs->regs.cfa_exp = insn_ptr;
1113 1.3.8.2 tls fs->regs.cfa_how = CFA_EXP;
1114 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, &utmp);
1115 1.3.8.2 tls insn_ptr += utmp;
1116 1.3.8.2 tls break;
1117 1.3.8.2 tls
1118 1.3.8.2 tls case DW_CFA_expression:
1119 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, ®);
1120 1.3.8.2 tls reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1121 1.3.8.2 tls if (UNWIND_COLUMN_IN_RANGE (reg))
1122 1.3.8.2 tls {
1123 1.3.8.2 tls fs->regs.reg[reg].how = REG_SAVED_EXP;
1124 1.3.8.2 tls fs->regs.reg[reg].loc.exp = insn_ptr;
1125 1.3.8.2 tls }
1126 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, &utmp);
1127 1.3.8.2 tls insn_ptr += utmp;
1128 1.3.8.2 tls break;
1129 1.3.8.2 tls
1130 1.3.8.2 tls /* Dwarf3. */
1131 1.3.8.2 tls case DW_CFA_offset_extended_sf:
1132 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, ®);
1133 1.3.8.2 tls insn_ptr = read_sleb128 (insn_ptr, &stmp);
1134 1.3.8.2 tls offset = stmp * fs->data_align;
1135 1.3.8.2 tls reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1136 1.3.8.2 tls if (UNWIND_COLUMN_IN_RANGE (reg))
1137 1.3.8.2 tls {
1138 1.3.8.2 tls fs->regs.reg[reg].how = REG_SAVED_OFFSET;
1139 1.3.8.2 tls fs->regs.reg[reg].loc.offset = offset;
1140 1.3.8.2 tls }
1141 1.3.8.2 tls break;
1142 1.3.8.2 tls
1143 1.3.8.2 tls case DW_CFA_def_cfa_sf:
1144 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, &utmp);
1145 1.3.8.2 tls fs->regs.cfa_reg = (_Unwind_Word)utmp;
1146 1.3.8.2 tls insn_ptr = read_sleb128 (insn_ptr, &stmp);
1147 1.3.8.2 tls fs->regs.cfa_offset = (_Unwind_Sword)stmp;
1148 1.3.8.2 tls fs->regs.cfa_how = CFA_REG_OFFSET;
1149 1.3.8.2 tls fs->regs.cfa_offset *= fs->data_align;
1150 1.3.8.2 tls break;
1151 1.3.8.2 tls
1152 1.3.8.2 tls case DW_CFA_def_cfa_offset_sf:
1153 1.3.8.2 tls insn_ptr = read_sleb128 (insn_ptr, &stmp);
1154 1.3.8.2 tls fs->regs.cfa_offset = (_Unwind_Sword)stmp;
1155 1.3.8.2 tls fs->regs.cfa_offset *= fs->data_align;
1156 1.3.8.2 tls /* cfa_how deliberately not set. */
1157 1.3.8.2 tls break;
1158 1.3.8.2 tls
1159 1.3.8.2 tls case DW_CFA_val_offset:
1160 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, ®);
1161 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, &utmp);
1162 1.3.8.2 tls offset = (_Unwind_Sword) utmp * fs->data_align;
1163 1.3.8.2 tls reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1164 1.3.8.2 tls if (UNWIND_COLUMN_IN_RANGE (reg))
1165 1.3.8.2 tls {
1166 1.3.8.2 tls fs->regs.reg[reg].how = REG_SAVED_VAL_OFFSET;
1167 1.3.8.2 tls fs->regs.reg[reg].loc.offset = offset;
1168 1.3.8.2 tls }
1169 1.3.8.2 tls break;
1170 1.3.8.2 tls
1171 1.3.8.2 tls case DW_CFA_val_offset_sf:
1172 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, ®);
1173 1.3.8.2 tls insn_ptr = read_sleb128 (insn_ptr, &stmp);
1174 1.3.8.2 tls offset = stmp * fs->data_align;
1175 1.3.8.2 tls reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1176 1.3.8.2 tls if (UNWIND_COLUMN_IN_RANGE (reg))
1177 1.3.8.2 tls {
1178 1.3.8.2 tls fs->regs.reg[reg].how = REG_SAVED_VAL_OFFSET;
1179 1.3.8.2 tls fs->regs.reg[reg].loc.offset = offset;
1180 1.3.8.2 tls }
1181 1.3.8.2 tls break;
1182 1.3.8.2 tls
1183 1.3.8.2 tls case DW_CFA_val_expression:
1184 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, ®);
1185 1.3.8.2 tls reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1186 1.3.8.2 tls if (UNWIND_COLUMN_IN_RANGE (reg))
1187 1.3.8.2 tls {
1188 1.3.8.2 tls fs->regs.reg[reg].how = REG_SAVED_VAL_EXP;
1189 1.3.8.2 tls fs->regs.reg[reg].loc.exp = insn_ptr;
1190 1.3.8.2 tls }
1191 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, &utmp);
1192 1.3.8.2 tls insn_ptr += utmp;
1193 1.3.8.2 tls break;
1194 1.3.8.2 tls
1195 1.3.8.2 tls case DW_CFA_GNU_window_save:
1196 1.3.8.2 tls /* ??? Hardcoded for SPARC register window configuration. */
1197 1.3.8.2 tls if (DWARF_FRAME_REGISTERS >= 32)
1198 1.3.8.2 tls for (reg = 16; reg < 32; ++reg)
1199 1.3.8.2 tls {
1200 1.3.8.2 tls fs->regs.reg[reg].how = REG_SAVED_OFFSET;
1201 1.3.8.2 tls fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
1202 1.3.8.2 tls }
1203 1.3.8.2 tls break;
1204 1.3.8.2 tls
1205 1.3.8.2 tls case DW_CFA_GNU_args_size:
1206 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, &utmp);
1207 1.3.8.2 tls context->args_size = (_Unwind_Word)utmp;
1208 1.3.8.2 tls break;
1209 1.3.8.2 tls
1210 1.3.8.2 tls case DW_CFA_GNU_negative_offset_extended:
1211 1.3.8.2 tls /* Obsoleted by DW_CFA_offset_extended_sf, but used by
1212 1.3.8.2 tls older PowerPC code. */
1213 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, ®);
1214 1.3.8.2 tls insn_ptr = read_uleb128 (insn_ptr, &utmp);
1215 1.3.8.2 tls offset = (_Unwind_Word) utmp * fs->data_align;
1216 1.3.8.2 tls reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
1217 1.3.8.2 tls if (UNWIND_COLUMN_IN_RANGE (reg))
1218 1.3.8.2 tls {
1219 1.3.8.2 tls fs->regs.reg[reg].how = REG_SAVED_OFFSET;
1220 1.3.8.2 tls fs->regs.reg[reg].loc.offset = -offset;
1221 1.3.8.2 tls }
1222 1.3.8.2 tls break;
1223 1.3.8.2 tls
1224 1.3.8.2 tls default:
1225 1.3.8.2 tls gcc_unreachable ();
1226 1.3.8.2 tls }
1227 1.3.8.2 tls }
1228 1.3.8.2 tls }
1229 1.3.8.2 tls
1230 1.3.8.2 tls /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
1232 1.3.8.2 tls its caller and decode it into FS. This function also sets the
1233 1.3.8.2 tls args_size and lsda members of CONTEXT, as they are really information
1234 1.3.8.2 tls about the caller's frame. */
1235 1.3.8.2 tls
1236 1.3.8.2 tls static _Unwind_Reason_Code
1237 1.3.8.2 tls uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1238 1.3.8.2 tls {
1239 1.3.8.2 tls const struct dwarf_fde *fde;
1240 1.3.8.2 tls const struct dwarf_cie *cie;
1241 1.3.8.2 tls const unsigned char *aug, *insn, *end;
1242 1.3.8.2 tls
1243 1.3.8.2 tls memset (fs, 0, sizeof (*fs));
1244 1.3.8.2 tls context->args_size = 0;
1245 1.3.8.2 tls context->lsda = 0;
1246 1.3.8.2 tls
1247 1.3.8.2 tls if (context->ra == 0)
1248 1.3.8.2 tls return _URC_END_OF_STACK;
1249 1.3.8.2 tls
1250 1.3.8.2 tls fde = _Unwind_Find_FDE (context->ra + _Unwind_IsSignalFrame (context) - 1,
1251 1.3.8.2 tls &context->bases);
1252 1.3.8.2 tls if (fde == NULL)
1253 1.3.8.2 tls {
1254 1.3.8.2 tls #ifdef MD_FALLBACK_FRAME_STATE_FOR
1255 1.3.8.2 tls /* Couldn't find frame unwind info for this function. Try a
1256 1.3.8.2 tls target-specific fallback mechanism. This will necessarily
1257 1.3.8.2 tls not provide a personality routine or LSDA. */
1258 1.3.8.2 tls return MD_FALLBACK_FRAME_STATE_FOR (context, fs);
1259 1.3.8.2 tls #else
1260 1.3.8.2 tls return _URC_END_OF_STACK;
1261 1.3.8.2 tls #endif
1262 1.3.8.2 tls }
1263 1.3.8.2 tls
1264 1.3.8.2 tls fs->pc = context->bases.func;
1265 1.3.8.2 tls
1266 1.3.8.2 tls cie = get_cie (fde);
1267 1.3.8.2 tls insn = extract_cie_info (cie, context, fs);
1268 1.3.8.2 tls if (insn == NULL)
1269 1.3.8.2 tls /* CIE contained unknown augmentation. */
1270 1.3.8.2 tls return _URC_FATAL_PHASE1_ERROR;
1271 1.3.8.2 tls
1272 1.3.8.2 tls /* First decode all the insns in the CIE. */
1273 1.3.8.2 tls end = (const unsigned char *) next_fde ((const struct dwarf_fde *) cie);
1274 1.3.8.2 tls execute_cfa_program (insn, end, context, fs);
1275 1.3.8.2 tls
1276 1.3.8.2 tls /* Locate augmentation for the fde. */
1277 1.3.8.2 tls aug = (const unsigned char *) fde + sizeof (*fde);
1278 1.3.8.2 tls aug += 2 * size_of_encoded_value (fs->fde_encoding);
1279 1.3.8.2 tls insn = NULL;
1280 1.3.8.2 tls if (fs->saw_z)
1281 1.3.8.2 tls {
1282 1.3.8.2 tls _uleb128_t i;
1283 1.3.8.2 tls aug = read_uleb128 (aug, &i);
1284 1.3.8.2 tls insn = aug + i;
1285 1.3.8.2 tls }
1286 1.3.8.2 tls if (fs->lsda_encoding != DW_EH_PE_omit)
1287 1.3.8.2 tls {
1288 1.3.8.2 tls _Unwind_Ptr lsda;
1289 1.3.8.2 tls
1290 1.3.8.2 tls aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
1291 1.3.8.2 tls context->lsda = (void *) lsda;
1292 1.3.8.2 tls }
1293 1.3.8.2 tls
1294 1.3.8.2 tls /* Then the insns in the FDE up to our target PC. */
1295 1.3.8.2 tls if (insn == NULL)
1296 1.3.8.2 tls insn = aug;
1297 1.3.8.2 tls end = (const unsigned char *) next_fde (fde);
1298 1.3.8.2 tls execute_cfa_program (insn, end, context, fs);
1299 1.3.8.2 tls
1300 1.3.8.2 tls return _URC_NO_REASON;
1301 1.3.8.2 tls }
1302 1.3.8.2 tls
1303 1.3.8.2 tls typedef struct frame_state
1305 1.3.8.2 tls {
1306 1.3.8.2 tls void *cfa;
1307 1.3.8.2 tls void *eh_ptr;
1308 1.3.8.2 tls long cfa_offset;
1309 1.3.8.2 tls long args_size;
1310 1.3.8.2 tls long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1311 1.3.8.2 tls unsigned short cfa_reg;
1312 1.3.8.2 tls unsigned short retaddr_column;
1313 1.3.8.2 tls char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1314 1.3.8.2 tls } frame_state;
1315 1.3.8.2 tls
1316 1.3.8.2 tls struct frame_state * __frame_state_for (void *, struct frame_state *);
1317 1.3.8.2 tls
1318 1.3.8.2 tls /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1319 1.3.8.2 tls a given PC_TARGET. The caller should allocate a local variable of
1320 1.3.8.2 tls `struct frame_state' and pass its address to STATE_IN. */
1321 1.3.8.2 tls
1322 1.3.8.2 tls struct frame_state *
1323 1.3.8.2 tls __frame_state_for (void *pc_target, struct frame_state *state_in)
1324 1.3.8.2 tls {
1325 1.3.8.2 tls struct _Unwind_Context context;
1326 1.3.8.2 tls _Unwind_FrameState fs;
1327 1.3.8.2 tls int reg;
1328 1.3.8.2 tls
1329 1.3.8.2 tls memset (&context, 0, sizeof (struct _Unwind_Context));
1330 1.3.8.2 tls if (!ASSUME_EXTENDED_UNWIND_CONTEXT)
1331 1.3.8.2 tls context.flags = EXTENDED_CONTEXT_BIT;
1332 1.3.8.2 tls context.ra = pc_target + 1;
1333 1.3.8.2 tls
1334 1.3.8.2 tls if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
1335 1.3.8.2 tls return 0;
1336 1.3.8.2 tls
1337 1.3.8.2 tls /* We have no way to pass a location expression for the CFA to our
1338 1.3.8.2 tls caller. It wouldn't understand it anyway. */
1339 1.3.8.2 tls if (fs.regs.cfa_how == CFA_EXP)
1340 1.3.8.2 tls return 0;
1341 1.3.8.2 tls
1342 1.3.8.2 tls for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1343 1.3.8.2 tls {
1344 1.3.8.2 tls state_in->saved[reg] = fs.regs.reg[reg].how;
1345 1.3.8.2 tls switch (state_in->saved[reg])
1346 1.3.8.2 tls {
1347 1.3.8.2 tls case REG_SAVED_REG:
1348 1.3.8.2 tls state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1349 1.3.8.2 tls break;
1350 1.3.8.2 tls case REG_SAVED_OFFSET:
1351 1.3.8.2 tls state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1352 1.3.8.2 tls break;
1353 1.3.8.2 tls default:
1354 1.3.8.2 tls state_in->reg_or_offset[reg] = 0;
1355 1.3.8.2 tls break;
1356 1.3.8.2 tls }
1357 1.3.8.2 tls }
1358 1.3.8.2 tls
1359 1.3.8.2 tls state_in->cfa_offset = fs.regs.cfa_offset;
1360 1.3.8.2 tls state_in->cfa_reg = fs.regs.cfa_reg;
1361 1.3.8.2 tls state_in->retaddr_column = fs.retaddr_column;
1362 1.3.8.2 tls state_in->args_size = context.args_size;
1363 1.3.8.2 tls state_in->eh_ptr = fs.eh_ptr;
1364 1.3.8.2 tls
1365 1.3.8.2 tls return state_in;
1366 1.3.8.2 tls }
1367 1.3.8.2 tls
1368 1.3.8.2 tls typedef union { _Unwind_Ptr ptr; _Unwind_Word word; } _Unwind_SpTmp;
1370 1.3.8.2 tls
1371 1.3.8.2 tls static inline void
1372 1.3.8.2 tls _Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
1373 1.3.8.2 tls _Unwind_SpTmp *tmp_sp)
1374 1.3.8.2 tls {
1375 1.3.8.2 tls int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
1376 1.3.8.2 tls
1377 1.3.8.2 tls if (size == sizeof(_Unwind_Ptr))
1378 1.3.8.2 tls tmp_sp->ptr = (_Unwind_Ptr) cfa;
1379 1.3.8.2 tls else
1380 1.3.8.2 tls {
1381 1.3.8.2 tls gcc_assert (size == sizeof(_Unwind_Word));
1382 1.3.8.2 tls tmp_sp->word = (_Unwind_Ptr) cfa;
1383 1.3.8.2 tls }
1384 1.3.8.2 tls _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), tmp_sp);
1385 1.3.8.2 tls }
1386 1.3.8.2 tls
1387 1.3.8.2 tls static void
1388 1.3.8.2 tls uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1389 1.3.8.2 tls {
1390 1.3.8.2 tls struct _Unwind_Context orig_context = *context;
1391 1.3.8.2 tls void *cfa;
1392 1.3.8.2 tls long i;
1393 1.3.8.2 tls
1394 1.3.8.2 tls #ifdef EH_RETURN_STACKADJ_RTX
1395 1.3.8.2 tls /* Special handling here: Many machines do not use a frame pointer,
1396 1.3.8.2 tls and track the CFA only through offsets from the stack pointer from
1397 1.3.8.2 tls one frame to the next. In this case, the stack pointer is never
1398 1.3.8.2 tls stored, so it has no saved address in the context. What we do
1399 1.3.8.2 tls have is the CFA from the previous stack frame.
1400 1.3.8.2 tls
1401 1.3.8.2 tls In very special situations (such as unwind info for signal return),
1402 1.3.8.2 tls there may be location expressions that use the stack pointer as well.
1403 1.3.8.2 tls
1404 1.3.8.2 tls Do this conditionally for one frame. This allows the unwind info
1405 1.3.8.2 tls for one frame to save a copy of the stack pointer from the previous
1406 1.3.8.2 tls frame, and be able to use much easier CFA mechanisms to do it.
1407 1.3.8.2 tls Always zap the saved stack pointer value for the next frame; carrying
1408 1.3.8.2 tls the value over from one frame to another doesn't make sense. */
1409 1.3.8.2 tls
1410 1.3.8.2 tls _Unwind_SpTmp tmp_sp;
1411 1.3.8.2 tls
1412 1.3.8.2 tls if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
1413 1.3.8.2 tls _Unwind_SetSpColumn (&orig_context, context->cfa, &tmp_sp);
1414 1.3.8.2 tls _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
1415 1.3.8.2 tls #endif
1416 1.3.8.2 tls
1417 1.3.8.2 tls /* Compute this frame's CFA. */
1418 1.3.8.2 tls switch (fs->regs.cfa_how)
1419 1.3.8.2 tls {
1420 1.3.8.2 tls case CFA_REG_OFFSET:
1421 1.3.8.2 tls cfa = _Unwind_GetPtr (&orig_context, fs->regs.cfa_reg);
1422 1.3.8.2 tls cfa += fs->regs.cfa_offset;
1423 1.3.8.2 tls break;
1424 1.3.8.2 tls
1425 1.3.8.2 tls case CFA_EXP:
1426 1.3.8.2 tls {
1427 1.3.8.2 tls const unsigned char *exp = fs->regs.cfa_exp;
1428 1.3.8.2 tls _uleb128_t len;
1429 1.3.8.2 tls
1430 1.3.8.2 tls exp = read_uleb128 (exp, &len);
1431 1.3.8.2 tls cfa = (void *) (_Unwind_Ptr)
1432 1.3.8.2 tls execute_stack_op (exp, exp + len, &orig_context, 0);
1433 1.3.8.2 tls break;
1434 1.3.8.2 tls }
1435 1.3.8.2 tls
1436 1.3.8.2 tls default:
1437 1.3.8.2 tls gcc_unreachable ();
1438 1.3.8.2 tls }
1439 1.3.8.2 tls context->cfa = cfa;
1440 1.3.8.2 tls
1441 1.3.8.2 tls /* Compute the addresses of all registers saved in this frame. */
1442 1.3.8.2 tls for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1443 1.3.8.2 tls switch (fs->regs.reg[i].how)
1444 1.3.8.2 tls {
1445 1.3.8.2 tls case REG_UNSAVED:
1446 1.3.8.2 tls case REG_UNDEFINED:
1447 1.3.8.2 tls break;
1448 1.3.8.2 tls
1449 1.3.8.2 tls case REG_SAVED_OFFSET:
1450 1.3.8.2 tls _Unwind_SetGRPtr (context, i,
1451 1.3.8.2 tls (void *) (cfa + fs->regs.reg[i].loc.offset));
1452 1.3.8.2 tls break;
1453 1.3.8.2 tls
1454 1.3.8.2 tls case REG_SAVED_REG:
1455 1.3.8.2 tls if (_Unwind_GRByValue (&orig_context, fs->regs.reg[i].loc.reg))
1456 1.3.8.2 tls _Unwind_SetGRValue (context, i,
1457 1.3.8.2 tls _Unwind_GetGR (&orig_context,
1458 1.3.8.2 tls fs->regs.reg[i].loc.reg));
1459 1.3.8.2 tls else
1460 1.3.8.2 tls _Unwind_SetGRPtr (context, i,
1461 1.3.8.2 tls _Unwind_GetGRPtr (&orig_context,
1462 1.3.8.2 tls fs->regs.reg[i].loc.reg));
1463 1.3.8.2 tls break;
1464 1.3.8.2 tls
1465 1.3.8.2 tls case REG_SAVED_EXP:
1466 1.3.8.2 tls {
1467 1.3.8.2 tls const unsigned char *exp = fs->regs.reg[i].loc.exp;
1468 1.3.8.2 tls _uleb128_t len;
1469 1.3.8.2 tls _Unwind_Ptr val;
1470 1.3.8.2 tls
1471 1.3.8.2 tls exp = read_uleb128 (exp, &len);
1472 1.3.8.2 tls val = execute_stack_op (exp, exp + len, &orig_context,
1473 1.3.8.2 tls (_Unwind_Ptr) cfa);
1474 1.3.8.2 tls _Unwind_SetGRPtr (context, i, (void *) val);
1475 1.3.8.2 tls }
1476 1.3.8.2 tls break;
1477 1.3.8.2 tls
1478 1.3.8.2 tls case REG_SAVED_VAL_OFFSET:
1479 1.3.8.2 tls _Unwind_SetGRValue (context, i,
1480 1.3.8.2 tls (_Unwind_Internal_Ptr)
1481 1.3.8.2 tls (cfa + fs->regs.reg[i].loc.offset));
1482 1.3.8.2 tls break;
1483 1.3.8.2 tls
1484 1.3.8.2 tls case REG_SAVED_VAL_EXP:
1485 1.3.8.2 tls {
1486 1.3.8.2 tls const unsigned char *exp = fs->regs.reg[i].loc.exp;
1487 1.3.8.2 tls _uleb128_t len;
1488 1.3.8.2 tls _Unwind_Ptr val;
1489 1.3.8.2 tls
1490 1.3.8.2 tls exp = read_uleb128 (exp, &len);
1491 1.3.8.2 tls val = execute_stack_op (exp, exp + len, &orig_context,
1492 1.3.8.2 tls (_Unwind_Ptr) cfa);
1493 1.3.8.2 tls _Unwind_SetGRValue (context, i, val);
1494 1.3.8.2 tls }
1495 1.3.8.2 tls break;
1496 1.3.8.2 tls }
1497 1.3.8.2 tls
1498 1.3.8.2 tls _Unwind_SetSignalFrame (context, fs->signal_frame);
1499 1.3.8.2 tls
1500 1.3.8.2 tls #ifdef MD_FROB_UPDATE_CONTEXT
1501 1.3.8.2 tls MD_FROB_UPDATE_CONTEXT (context, fs);
1502 1.3.8.2 tls #endif
1503 1.3.8.2 tls }
1504 1.3.8.2 tls
1505 1.3.8.2 tls /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1506 1.3.8.2 tls of its caller. Update CONTEXT to refer to the caller as well. Note
1507 1.3.8.2 tls that the args_size and lsda members are not updated here, but later in
1508 1.3.8.2 tls uw_frame_state_for. */
1509 1.3.8.2 tls
1510 1.3.8.2 tls static void
1511 1.3.8.2 tls uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1512 1.3.8.2 tls {
1513 1.3.8.2 tls uw_update_context_1 (context, fs);
1514 1.3.8.2 tls
1515 1.3.8.2 tls /* In general this unwinder doesn't make any distinction between
1516 1.3.8.2 tls undefined and same_value rule. Call-saved registers are assumed
1517 1.3.8.2 tls to have same_value rule by default and explicit undefined
1518 1.3.8.2 tls rule is handled like same_value. The only exception is
1519 1.3.8.2 tls DW_CFA_undefined on retaddr_column which is supposed to
1520 1.3.8.2 tls mark outermost frame in DWARF 3. */
1521 1.3.8.2 tls if (fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (fs->retaddr_column)].how
1522 1.3.8.2 tls == REG_UNDEFINED)
1523 1.3.8.2 tls /* uw_frame_state_for uses context->ra == 0 check to find outermost
1524 1.3.8.2 tls stack frame. */
1525 1.3.8.2 tls context->ra = 0;
1526 1.3.8.2 tls else
1527 1.3.8.2 tls /* Compute the return address now, since the return address column
1528 1.3.8.2 tls can change from frame to frame. */
1529 1.3.8.2 tls context->ra = __builtin_extract_return_addr
1530 1.3.8.2 tls (_Unwind_GetPtr (context, fs->retaddr_column));
1531 1.3.8.2 tls }
1532 1.3.8.2 tls
1533 1.3.8.2 tls static void
1534 1.3.8.2 tls uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1535 1.3.8.2 tls {
1536 1.3.8.2 tls uw_update_context (context, fs);
1537 1.3.8.2 tls }
1538 1.3.8.2 tls
1539 1.3.8.2 tls /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1541 1.3.8.2 tls level will be the return address and the CFA. */
1542 1.3.8.2 tls
1543 1.3.8.2 tls #define uw_init_context(CONTEXT) \
1544 1.3.8.2 tls do \
1545 1.3.8.2 tls { \
1546 1.3.8.2 tls /* Do any necessary initialization to access arbitrary stack frames. \
1547 1.3.8.2 tls On the SPARC, this means flushing the register windows. */ \
1548 1.3.8.2 tls __builtin_unwind_init (); \
1549 1.3.8.2 tls uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1550 1.3.8.2 tls __builtin_return_address (0)); \
1551 1.3.8.2 tls } \
1552 1.3.8.2 tls while (0)
1553 1.3.8.2 tls
1554 1.3.8.2 tls static inline void
1555 1.3.8.2 tls init_dwarf_reg_size_table (void)
1556 1.3.8.2 tls {
1557 1.3.8.2 tls __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1558 1.3.8.2 tls }
1559 1.3.8.2 tls
1560 1.3.8.2 tls static void __attribute__((noinline))
1561 1.3.8.2 tls uw_init_context_1 (struct _Unwind_Context *context,
1562 1.3.8.2 tls void *outer_cfa, void *outer_ra)
1563 1.3.8.2 tls {
1564 1.3.8.2 tls void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1565 1.3.8.2 tls _Unwind_FrameState fs;
1566 1.3.8.2 tls _Unwind_SpTmp sp_slot;
1567 1.3.8.2 tls _Unwind_Reason_Code code;
1568 1.3.8.2 tls
1569 1.3.8.2 tls memset (context, 0, sizeof (struct _Unwind_Context));
1570 1.3.8.2 tls context->ra = ra;
1571 1.3.8.2 tls if (!ASSUME_EXTENDED_UNWIND_CONTEXT)
1572 1.3.8.2 tls context->flags = EXTENDED_CONTEXT_BIT;
1573 1.3.8.2 tls
1574 1.3.8.2 tls code = uw_frame_state_for (context, &fs);
1575 1.3.8.2 tls gcc_assert (code == _URC_NO_REASON);
1576 1.3.8.2 tls
1577 1.3.8.2 tls #if __GTHREADS
1578 1.3.8.2 tls {
1579 1.3.8.2 tls static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1580 1.3.8.2 tls if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1581 1.3.8.2 tls && dwarf_reg_size_table[0] == 0)
1582 1.3.8.2 tls init_dwarf_reg_size_table ();
1583 1.3.8.2 tls }
1584 1.3.8.2 tls #else
1585 1.3.8.2 tls if (dwarf_reg_size_table[0] == 0)
1586 1.3.8.2 tls init_dwarf_reg_size_table ();
1587 1.3.8.2 tls #endif
1588 1.3.8.2 tls
1589 1.3.8.2 tls /* Force the frame state to use the known cfa value. */
1590 1.3.8.2 tls _Unwind_SetSpColumn (context, outer_cfa, &sp_slot);
1591 1.3.8.2 tls fs.regs.cfa_how = CFA_REG_OFFSET;
1592 1.3.8.2 tls fs.regs.cfa_reg = __builtin_dwarf_sp_column ();
1593 1.3.8.2 tls fs.regs.cfa_offset = 0;
1594 1.3.8.2 tls
1595 1.3.8.2 tls uw_update_context_1 (context, &fs);
1596 1.3.8.2 tls
1597 1.3.8.2 tls /* If the return address column was saved in a register in the
1598 1.3.8.2 tls initialization context, then we can't see it in the given
1599 1.3.8.2 tls call frame data. So have the initialization context tell us. */
1600 1.3.8.2 tls context->ra = __builtin_extract_return_addr (outer_ra);
1601 1.3.8.2 tls }
1602 1.3.8.2 tls
1603 1.3.8.2 tls static void _Unwind_DebugHook (void *, void *)
1604 1.3.8.2 tls __attribute__ ((__noinline__, __used__, __noclone__));
1605 1.3.8.2 tls
1606 1.3.8.2 tls /* This function is called during unwinding. It is intended as a hook
1607 1.3.8.2 tls for a debugger to intercept exceptions. CFA is the CFA of the
1608 1.3.8.2 tls target frame. HANDLER is the PC to which control will be
1609 1.3.8.2 tls transferred. */
1610 1.3.8.2 tls static void
1611 1.3.8.2 tls _Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
1612 1.3.8.2 tls void *handler __attribute__ ((__unused__)))
1613 1.3.8.2 tls {
1614 1.3.8.2 tls /* We only want to use stap probes starting with v3. Earlier
1615 1.3.8.2 tls versions added too much startup cost. */
1616 1.3.8.2 tls #if defined (HAVE_SYS_SDT_H) && defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3
1617 1.3.8.2 tls STAP_PROBE2 (libgcc, unwind, cfa, handler);
1618 1.3.8.2 tls #else
1619 1.3.8.2 tls asm ("");
1620 1.3.8.2 tls #endif
1621 1.3.8.2 tls }
1622 1.3.8.2 tls
1623 1.3.8.2 tls /* Install TARGET into CURRENT so that we can return to it. This is a
1624 1.3.8.2 tls macro because __builtin_eh_return must be invoked in the context of
1625 1.3.8.2 tls our caller. */
1626 1.3.8.2 tls
1627 1.3.8.2 tls #define uw_install_context(CURRENT, TARGET) \
1628 1.3.8.2 tls do \
1629 1.3.8.2 tls { \
1630 1.3.8.2 tls long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1631 1.3.8.2 tls void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1632 1.3.8.2 tls _Unwind_DebugHook ((TARGET)->cfa, handler); \
1633 1.3.8.2 tls __builtin_eh_return (offset, handler); \
1634 1.3.8.2 tls } \
1635 1.3.8.2 tls while (0)
1636 1.3.8.2 tls
1637 1.3.8.2 tls static long
1638 1.3.8.2 tls uw_install_context_1 (struct _Unwind_Context *current,
1639 1.3.8.2 tls struct _Unwind_Context *target)
1640 1.3.8.2 tls {
1641 1.3.8.2 tls long i;
1642 1.3.8.2 tls _Unwind_SpTmp sp_slot;
1643 1.3.8.2 tls
1644 1.3.8.2 tls /* If the target frame does not have a saved stack pointer,
1645 1.3.8.2 tls then set up the target's CFA. */
1646 1.3.8.2 tls if (!_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
1647 1.3.8.2 tls _Unwind_SetSpColumn (target, target->cfa, &sp_slot);
1648 1.3.8.2 tls
1649 1.3.8.2 tls for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1650 1.3.8.2 tls {
1651 1.3.8.2 tls void *c = (void *) (_Unwind_Internal_Ptr) current->reg[i];
1652 1.3.8.2 tls void *t = (void *) (_Unwind_Internal_Ptr)target->reg[i];
1653 1.3.8.2 tls
1654 1.3.8.2 tls gcc_assert (current->by_value[i] == 0);
1655 1.3.8.2 tls if (target->by_value[i] && c)
1656 1.3.8.2 tls {
1657 1.3.8.2 tls _Unwind_Word w;
1658 1.3.8.2 tls _Unwind_Ptr p;
1659 1.3.8.2 tls if (dwarf_reg_size_table[i] == sizeof (_Unwind_Word))
1660 1.3.8.2 tls {
1661 1.3.8.2 tls w = (_Unwind_Internal_Ptr) t;
1662 1.3.8.2 tls memcpy (c, &w, sizeof (_Unwind_Word));
1663 1.3.8.2 tls }
1664 1.3.8.2 tls else
1665 1.3.8.2 tls {
1666 1.3.8.2 tls gcc_assert (dwarf_reg_size_table[i] == sizeof (_Unwind_Ptr));
1667 1.3.8.2 tls p = (_Unwind_Internal_Ptr) t;
1668 1.3.8.2 tls memcpy (c, &p, sizeof (_Unwind_Ptr));
1669 1.3.8.2 tls }
1670 1.3.8.2 tls }
1671 1.3.8.2 tls else if (t && c && t != c)
1672 1.3.8.2 tls memcpy (c, t, dwarf_reg_size_table[i]);
1673 1.3.8.2 tls }
1674 1.3.8.2 tls
1675 1.3.8.2 tls /* If the current frame doesn't have a saved stack pointer, then we
1676 1.3.8.2 tls need to rely on EH_RETURN_STACKADJ_RTX to get our target stack
1677 1.3.8.2 tls pointer value reloaded. */
1678 1.3.8.2 tls if (!_Unwind_GetGRPtr (current, __builtin_dwarf_sp_column ()))
1679 1.3.8.2 tls {
1680 1.3.8.2 tls void *target_cfa;
1681 1.3.8.2 tls
1682 1.3.8.2 tls target_cfa = _Unwind_GetPtr (target, __builtin_dwarf_sp_column ());
1683 1.3.8.2 tls
1684 1.3.8.2 tls /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1685 1.3.8.2 tls if (STACK_GROWS_DOWNWARD)
1686 1.3.8.2 tls return target_cfa - current->cfa + target->args_size;
1687 1.3.8.2 tls else
1688 1.3.8.2 tls return current->cfa - target_cfa - target->args_size;
1689 1.3.8.2 tls }
1690 1.3.8.2 tls return 0;
1691 1.3.8.2 tls }
1692 1.3.8.2 tls
1693 1.3.8.2 tls static inline _Unwind_Ptr
1694 1.3.8.2 tls uw_identify_context (struct _Unwind_Context *context)
1695 1.3.8.2 tls {
1696 1.3.8.2 tls /* The CFA is not sufficient to disambiguate the context of a function
1697 1.3.8.2 tls interrupted by a signal before establishing its frame and the context
1698 1.3.8.2 tls of the signal itself. */
1699 1.3.8.2 tls if (STACK_GROWS_DOWNWARD)
1700 1.3.8.2 tls return _Unwind_GetCFA (context) - _Unwind_IsSignalFrame (context);
1701 1.3.8.2 tls else
1702 1.3.8.2 tls return _Unwind_GetCFA (context) + _Unwind_IsSignalFrame (context);
1703 1.3.8.2 tls }
1704 1.3.8.2 tls
1705 1.3.8.2 tls
1706 1.3.8.2 tls #include "unwind.inc"
1707 1.3.8.2 tls
1708 1.3.8.2 tls #if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
1709 1.3.8.2 tls alias (_Unwind_Backtrace);
1710 1.3.8.2 tls alias (_Unwind_DeleteException);
1711 1.3.8.2 tls alias (_Unwind_FindEnclosingFunction);
1712 1.3.8.2 tls alias (_Unwind_ForcedUnwind);
1713 1.3.8.2 tls alias (_Unwind_GetDataRelBase);
1714 1.3.8.2 tls alias (_Unwind_GetTextRelBase);
1715 1.3.8.2 tls alias (_Unwind_GetCFA);
1716 1.3.8.2 tls alias (_Unwind_GetGR);
1717 1.3.8.2 tls alias (_Unwind_GetIP);
1718 1.3.8.2 tls alias (_Unwind_GetLanguageSpecificData);
1719 1.3.8.2 tls alias (_Unwind_GetRegionStart);
1720 alias (_Unwind_RaiseException);
1721 alias (_Unwind_Resume);
1722 alias (_Unwind_Resume_or_Rethrow);
1723 alias (_Unwind_SetGR);
1724 alias (_Unwind_SetIP);
1725 #endif
1726
1727 #endif /* !USING_SJLJ_EXCEPTIONS */
1728