unwind-dw2-xtensa.c revision 1.2.4.2 1 1.2.4.2 yamt /* DWARF2 exception handling and frame unwinding for Xtensa.
2 1.2.4.2 yamt Copyright (C) 1997-2013 Free Software Foundation, Inc.
3 1.2.4.2 yamt
4 1.2.4.2 yamt This file is part of GCC.
5 1.2.4.2 yamt
6 1.2.4.2 yamt GCC is free software; you can redistribute it and/or modify it
7 1.2.4.2 yamt under the terms of the GNU General Public License as published by
8 1.2.4.2 yamt the Free Software Foundation; either version 3, or (at your option)
9 1.2.4.2 yamt any later version.
10 1.2.4.2 yamt
11 1.2.4.2 yamt GCC is distributed in the hope that it will be useful, but WITHOUT
12 1.2.4.2 yamt ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 1.2.4.2 yamt or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 1.2.4.2 yamt License for more details.
15 1.2.4.2 yamt
16 1.2.4.2 yamt Under Section 7 of GPL version 3, you are granted additional
17 1.2.4.2 yamt permissions described in the GCC Runtime Library Exception, version
18 1.2.4.2 yamt 3.1, as published by the Free Software Foundation.
19 1.2.4.2 yamt
20 1.2.4.2 yamt You should have received a copy of the GNU General Public License and
21 1.2.4.2 yamt a copy of the GCC Runtime Library Exception along with this program;
22 1.2.4.2 yamt see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 1.2.4.2 yamt <http://www.gnu.org/licenses/>. */
24 1.2.4.2 yamt
25 1.2.4.2 yamt #include "tconfig.h"
26 1.2.4.2 yamt #include "tsystem.h"
27 1.2.4.2 yamt #include "coretypes.h"
28 1.2.4.2 yamt #include "tm.h"
29 1.2.4.2 yamt #include "libgcc_tm.h"
30 1.2.4.2 yamt #include "dwarf2.h"
31 1.2.4.2 yamt #include "unwind.h"
32 1.2.4.2 yamt #ifdef __USING_SJLJ_EXCEPTIONS__
33 1.2.4.2 yamt # define NO_SIZE_OF_ENCODED_VALUE
34 1.2.4.2 yamt #endif
35 1.2.4.2 yamt #include "unwind-pe.h"
36 1.2.4.2 yamt #include "unwind-dw2-fde.h"
37 1.2.4.2 yamt #include "unwind-dw2-xtensa.h"
38 1.2.4.2 yamt
39 1.2.4.2 yamt #ifndef __USING_SJLJ_EXCEPTIONS__
40 1.2.4.2 yamt
41 1.2.4.2 yamt /* The standard CIE and FDE structures work fine for Xtensa but the
42 1.2.4.2 yamt variable-size register window save areas are not a good fit for the rest
43 1.2.4.2 yamt of the standard DWARF unwinding mechanism. Nor is that mechanism
44 1.2.4.2 yamt necessary, since the register save areas are always in fixed locations
45 1.2.4.2 yamt in each stack frame. This file is a stripped down and customized version
46 1.2.4.2 yamt of the standard DWARF unwinding code. It needs to be customized to have
47 1.2.4.2 yamt builtin logic for finding the save areas and also to track the stack
48 1.2.4.2 yamt pointer value (besides the CFA) while unwinding since the primary save
49 1.2.4.2 yamt area is located below the stack pointer. It is stripped down to reduce
50 1.2.4.2 yamt code size and ease the maintenance burden of tracking changes in the
51 1.2.4.2 yamt standard version of the code. */
52 1.2.4.2 yamt
53 1.2.4.2 yamt #ifndef DWARF_REG_TO_UNWIND_COLUMN
54 1.2.4.2 yamt #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
55 1.2.4.2 yamt #endif
56 1.2.4.2 yamt
57 1.2.4.2 yamt #define XTENSA_RA_FIELD_MASK 0x3FFFFFFF
58 1.2.4.2 yamt
59 1.2.4.2 yamt /* This is the register and unwind state for a particular frame. This
60 1.2.4.2 yamt provides the information necessary to unwind up past a frame and return
61 1.2.4.2 yamt to its caller. */
62 1.2.4.2 yamt struct _Unwind_Context
63 1.2.4.2 yamt {
64 1.2.4.2 yamt /* Track register window save areas of 4 registers each, instead of
65 1.2.4.2 yamt keeping separate addresses for the individual registers. */
66 1.2.4.2 yamt _Unwind_Word *reg[4];
67 1.2.4.2 yamt
68 1.2.4.2 yamt void *cfa;
69 1.2.4.2 yamt void *sp;
70 1.2.4.2 yamt void *ra;
71 1.2.4.2 yamt
72 1.2.4.2 yamt /* Cache the 2 high bits to replace the window size in return addresses. */
73 1.2.4.2 yamt _Unwind_Word ra_high_bits;
74 1.2.4.2 yamt
75 1.2.4.2 yamt void *lsda;
76 1.2.4.2 yamt struct dwarf_eh_bases bases;
77 1.2.4.2 yamt /* Signal frame context. */
78 1.2.4.2 yamt #define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
79 1.2.4.2 yamt _Unwind_Word flags;
80 1.2.4.2 yamt /* 0 for now, can be increased when further fields are added to
81 1.2.4.2 yamt struct _Unwind_Context. */
82 1.2.4.2 yamt _Unwind_Word version;
83 1.2.4.2 yamt };
84 1.2.4.2 yamt
85 1.2.4.2 yamt
86 1.2.4.2 yamt /* Read unaligned data from the instruction buffer. */
88 1.2.4.2 yamt
89 1.2.4.2 yamt union unaligned
90 1.2.4.2 yamt {
91 1.2.4.2 yamt void *p;
92 1.2.4.2 yamt } __attribute__ ((packed));
93 1.2.4.2 yamt
94 1.2.4.2 yamt static void uw_update_context (struct _Unwind_Context *, _Unwind_FrameState *);
95 1.2.4.2 yamt static _Unwind_Reason_Code uw_frame_state_for (struct _Unwind_Context *,
96 1.2.4.2 yamt _Unwind_FrameState *);
97 1.2.4.2 yamt
98 1.2.4.2 yamt static inline void *
99 1.2.4.2 yamt read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
100 1.2.4.2 yamt
101 1.2.4.2 yamt static inline _Unwind_Word
103 1.2.4.2 yamt _Unwind_IsSignalFrame (struct _Unwind_Context *context)
104 1.2.4.2 yamt {
105 1.2.4.2 yamt return (context->flags & SIGNAL_FRAME_BIT) ? 1 : 0;
106 1.2.4.2 yamt }
107 1.2.4.2 yamt
108 1.2.4.2 yamt static inline void
109 1.2.4.2 yamt _Unwind_SetSignalFrame (struct _Unwind_Context *context, int val)
110 1.2.4.2 yamt {
111 1.2.4.2 yamt if (val)
112 1.2.4.2 yamt context->flags |= SIGNAL_FRAME_BIT;
113 1.2.4.2 yamt else
114 1.2.4.2 yamt context->flags &= ~SIGNAL_FRAME_BIT;
115 1.2.4.2 yamt }
116 1.2.4.2 yamt
117 1.2.4.2 yamt /* Get the value of register INDEX as saved in CONTEXT. */
119 1.2.4.2 yamt
120 1.2.4.2 yamt inline _Unwind_Word
121 1.2.4.2 yamt _Unwind_GetGR (struct _Unwind_Context *context, int index)
122 1.2.4.2 yamt {
123 1.2.4.2 yamt _Unwind_Word *ptr;
124 1.2.4.2 yamt
125 1.2.4.2 yamt index = DWARF_REG_TO_UNWIND_COLUMN (index);
126 1.2.4.2 yamt ptr = context->reg[index >> 2] + (index & 3);
127 1.2.4.2 yamt
128 1.2.4.2 yamt return *ptr;
129 1.2.4.2 yamt }
130 1.2.4.2 yamt
131 1.2.4.2 yamt /* Get the value of the CFA as saved in CONTEXT. */
132 1.2.4.2 yamt
133 1.2.4.2 yamt _Unwind_Word
134 1.2.4.2 yamt _Unwind_GetCFA (struct _Unwind_Context *context)
135 1.2.4.2 yamt {
136 1.2.4.2 yamt return (_Unwind_Ptr) context->cfa;
137 1.2.4.2 yamt }
138 1.2.4.2 yamt
139 1.2.4.2 yamt /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
140 1.2.4.2 yamt
141 1.2.4.2 yamt inline void
142 1.2.4.2 yamt _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
143 1.2.4.2 yamt {
144 1.2.4.2 yamt _Unwind_Word *ptr;
145 1.2.4.2 yamt
146 1.2.4.2 yamt index = DWARF_REG_TO_UNWIND_COLUMN (index);
147 1.2.4.2 yamt ptr = context->reg[index >> 2] + (index & 3);
148 1.2.4.2 yamt
149 1.2.4.2 yamt *ptr = val;
150 1.2.4.2 yamt }
151 1.2.4.2 yamt
152 1.2.4.2 yamt /* Retrieve the return address for CONTEXT. */
153 1.2.4.2 yamt
154 1.2.4.2 yamt inline _Unwind_Ptr
155 1.2.4.2 yamt _Unwind_GetIP (struct _Unwind_Context *context)
156 1.2.4.2 yamt {
157 1.2.4.2 yamt return (_Unwind_Ptr) context->ra;
158 1.2.4.2 yamt }
159 1.2.4.2 yamt
160 1.2.4.2 yamt /* Retrieve the return address and flag whether that IP is before
161 1.2.4.2 yamt or after first not yet fully executed instruction. */
162 1.2.4.2 yamt
163 1.2.4.2 yamt inline _Unwind_Ptr
164 1.2.4.2 yamt _Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
165 1.2.4.2 yamt {
166 1.2.4.2 yamt *ip_before_insn = _Unwind_IsSignalFrame (context);
167 1.2.4.2 yamt return (_Unwind_Ptr) context->ra;
168 1.2.4.2 yamt }
169 1.2.4.2 yamt
170 1.2.4.2 yamt /* Overwrite the return address for CONTEXT with VAL. */
171 1.2.4.2 yamt
172 1.2.4.2 yamt inline void
173 1.2.4.2 yamt _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
174 1.2.4.2 yamt {
175 1.2.4.2 yamt context->ra = (void *) val;
176 1.2.4.2 yamt }
177 1.2.4.2 yamt
178 1.2.4.2 yamt _Unwind_Ptr
179 1.2.4.2 yamt _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
180 1.2.4.2 yamt {
181 1.2.4.2 yamt return context->lsda;
182 1.2.4.2 yamt }
183 1.2.4.2 yamt
184 1.2.4.2 yamt _Unwind_Ptr
185 1.2.4.2 yamt _Unwind_GetRegionStart (struct _Unwind_Context *context)
186 1.2.4.2 yamt {
187 1.2.4.2 yamt return (_Unwind_Ptr) context->bases.func;
188 1.2.4.2 yamt }
189 1.2.4.2 yamt
190 1.2.4.2 yamt void *
191 1.2.4.2 yamt _Unwind_FindEnclosingFunction (void *pc)
192 1.2.4.2 yamt {
193 1.2.4.2 yamt struct dwarf_eh_bases bases;
194 1.2.4.2 yamt const struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
195 1.2.4.2 yamt if (fde)
196 1.2.4.2 yamt return bases.func;
197 1.2.4.2 yamt else
198 1.2.4.2 yamt return NULL;
199 1.2.4.2 yamt }
200 1.2.4.2 yamt
201 1.2.4.2 yamt _Unwind_Ptr
202 1.2.4.2 yamt _Unwind_GetDataRelBase (struct _Unwind_Context *context)
203 1.2.4.2 yamt {
204 1.2.4.2 yamt return (_Unwind_Ptr) context->bases.dbase;
205 1.2.4.2 yamt }
206 1.2.4.2 yamt
207 1.2.4.2 yamt _Unwind_Ptr
208 1.2.4.2 yamt _Unwind_GetTextRelBase (struct _Unwind_Context *context)
209 1.2.4.2 yamt {
210 1.2.4.2 yamt return (_Unwind_Ptr) context->bases.tbase;
211 1.2.4.2 yamt }
212 1.2.4.2 yamt
213 1.2.4.2 yamt #include "md-unwind-support.h"
214 1.2.4.2 yamt
215 1.2.4.2 yamt /* Extract any interesting information from the CIE for the translation
217 1.2.4.2 yamt unit F belongs to. Return a pointer to the byte after the augmentation,
218 1.2.4.2 yamt or NULL if we encountered an undecipherable augmentation. */
219 1.2.4.2 yamt
220 1.2.4.2 yamt static const unsigned char *
221 1.2.4.2 yamt extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
222 1.2.4.2 yamt _Unwind_FrameState *fs)
223 1.2.4.2 yamt {
224 1.2.4.2 yamt const unsigned char *aug = cie->augmentation;
225 1.2.4.2 yamt const unsigned char *p = aug + strlen ((const char *)aug) + 1;
226 1.2.4.2 yamt const unsigned char *ret = NULL;
227 1.2.4.2 yamt _uleb128_t utmp;
228 1.2.4.2 yamt _sleb128_t stmp;
229 1.2.4.2 yamt
230 1.2.4.2 yamt /* g++ v2 "eh" has pointer immediately following augmentation string,
231 1.2.4.2 yamt so it must be handled first. */
232 1.2.4.2 yamt if (aug[0] == 'e' && aug[1] == 'h')
233 1.2.4.2 yamt {
234 1.2.4.2 yamt fs->eh_ptr = read_pointer (p);
235 1.2.4.2 yamt p += sizeof (void *);
236 1.2.4.2 yamt aug += 2;
237 1.2.4.2 yamt }
238 1.2.4.2 yamt
239 1.2.4.2 yamt /* Immediately following the augmentation are the code and
240 1.2.4.2 yamt data alignment and return address column. */
241 1.2.4.2 yamt p = read_uleb128 (p, &utmp);
242 1.2.4.2 yamt p = read_sleb128 (p, &stmp);
243 1.2.4.2 yamt if (cie->version == 1)
244 1.2.4.2 yamt fs->retaddr_column = *p++;
245 1.2.4.2 yamt else
246 1.2.4.2 yamt {
247 1.2.4.2 yamt p = read_uleb128 (p, &utmp);
248 1.2.4.2 yamt fs->retaddr_column = (_Unwind_Word)utmp;
249 1.2.4.2 yamt }
250 1.2.4.2 yamt fs->lsda_encoding = DW_EH_PE_omit;
251 1.2.4.2 yamt
252 1.2.4.2 yamt /* If the augmentation starts with 'z', then a uleb128 immediately
253 1.2.4.2 yamt follows containing the length of the augmentation field following
254 1.2.4.2 yamt the size. */
255 1.2.4.2 yamt if (*aug == 'z')
256 1.2.4.2 yamt {
257 1.2.4.2 yamt p = read_uleb128 (p, &utmp);
258 1.2.4.2 yamt ret = p + utmp;
259 1.2.4.2 yamt
260 1.2.4.2 yamt fs->saw_z = 1;
261 1.2.4.2 yamt ++aug;
262 1.2.4.2 yamt }
263 1.2.4.2 yamt
264 1.2.4.2 yamt /* Iterate over recognized augmentation subsequences. */
265 1.2.4.2 yamt while (*aug != '\0')
266 1.2.4.2 yamt {
267 1.2.4.2 yamt /* "L" indicates a byte showing how the LSDA pointer is encoded. */
268 1.2.4.2 yamt if (aug[0] == 'L')
269 1.2.4.2 yamt {
270 1.2.4.2 yamt fs->lsda_encoding = *p++;
271 1.2.4.2 yamt aug += 1;
272 1.2.4.2 yamt }
273 1.2.4.2 yamt
274 1.2.4.2 yamt /* "R" indicates a byte indicating how FDE addresses are encoded. */
275 1.2.4.2 yamt else if (aug[0] == 'R')
276 1.2.4.2 yamt {
277 1.2.4.2 yamt fs->fde_encoding = *p++;
278 1.2.4.2 yamt aug += 1;
279 1.2.4.2 yamt }
280 1.2.4.2 yamt
281 1.2.4.2 yamt /* "P" indicates a personality routine in the CIE augmentation. */
282 1.2.4.2 yamt else if (aug[0] == 'P')
283 1.2.4.2 yamt {
284 1.2.4.2 yamt _Unwind_Ptr personality;
285 1.2.4.2 yamt
286 1.2.4.2 yamt p = read_encoded_value (context, *p, p + 1, &personality);
287 1.2.4.2 yamt fs->personality = (_Unwind_Personality_Fn) personality;
288 1.2.4.2 yamt aug += 1;
289 1.2.4.2 yamt }
290 1.2.4.2 yamt
291 1.2.4.2 yamt /* "S" indicates a signal frame. */
292 1.2.4.2 yamt else if (aug[0] == 'S')
293 1.2.4.2 yamt {
294 1.2.4.2 yamt fs->signal_frame = 1;
295 1.2.4.2 yamt aug += 1;
296 1.2.4.2 yamt }
297 1.2.4.2 yamt
298 1.2.4.2 yamt /* Otherwise we have an unknown augmentation string.
299 1.2.4.2 yamt Bail unless we saw a 'z' prefix. */
300 1.2.4.2 yamt else
301 1.2.4.2 yamt return ret;
302 1.2.4.2 yamt }
303 1.2.4.2 yamt
304 1.2.4.2 yamt return ret ? ret : p;
305 1.2.4.2 yamt }
306 1.2.4.2 yamt
307 1.2.4.2 yamt /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
309 1.2.4.2 yamt its caller and decode it into FS. This function also sets the
310 1.2.4.2 yamt lsda member of CONTEXT, as it is really information
311 1.2.4.2 yamt about the caller's frame. */
312 1.2.4.2 yamt
313 1.2.4.2 yamt static _Unwind_Reason_Code
314 1.2.4.2 yamt uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
315 1.2.4.2 yamt {
316 1.2.4.2 yamt const struct dwarf_fde *fde;
317 1.2.4.2 yamt const struct dwarf_cie *cie;
318 1.2.4.2 yamt const unsigned char *aug;
319 1.2.4.2 yamt int window_size;
320 1.2.4.2 yamt _Unwind_Word *ra_ptr;
321 1.2.4.2 yamt
322 1.2.4.2 yamt memset (fs, 0, sizeof (*fs));
323 1.2.4.2 yamt context->lsda = 0;
324 1.2.4.2 yamt
325 1.2.4.2 yamt fde = _Unwind_Find_FDE (context->ra + _Unwind_IsSignalFrame (context) - 1,
326 1.2.4.2 yamt &context->bases);
327 1.2.4.2 yamt if (fde == NULL)
328 1.2.4.2 yamt {
329 1.2.4.2 yamt #ifdef MD_FALLBACK_FRAME_STATE_FOR
330 1.2.4.2 yamt _Unwind_Reason_Code reason;
331 1.2.4.2 yamt /* Couldn't find frame unwind info for this function. Try a
332 1.2.4.2 yamt target-specific fallback mechanism. This will necessarily
333 1.2.4.2 yamt not provide a personality routine or LSDA. */
334 1.2.4.2 yamt reason = MD_FALLBACK_FRAME_STATE_FOR (context, fs);
335 1.2.4.2 yamt if (reason != _URC_END_OF_STACK)
336 1.2.4.2 yamt return reason;
337 1.2.4.2 yamt #endif
338 1.2.4.2 yamt /* The frame was not recognized and handled by the fallback function,
339 1.2.4.2 yamt but it is not really the end of the stack. Fall through here and
340 1.2.4.2 yamt unwind it anyway. */
341 1.2.4.2 yamt }
342 1.2.4.2 yamt else
343 1.2.4.2 yamt {
344 1.2.4.2 yamt cie = get_cie (fde);
345 1.2.4.2 yamt if (extract_cie_info (cie, context, fs) == NULL)
346 1.2.4.2 yamt /* CIE contained unknown augmentation. */
347 1.2.4.2 yamt return _URC_FATAL_PHASE1_ERROR;
348 1.2.4.2 yamt
349 1.2.4.2 yamt /* Locate augmentation for the fde. */
350 1.2.4.2 yamt aug = (const unsigned char *) fde + sizeof (*fde);
351 1.2.4.2 yamt aug += 2 * size_of_encoded_value (fs->fde_encoding);
352 1.2.4.2 yamt if (fs->saw_z)
353 1.2.4.2 yamt {
354 1.2.4.2 yamt _uleb128_t i;
355 1.2.4.2 yamt aug = read_uleb128 (aug, &i);
356 1.2.4.2 yamt }
357 1.2.4.2 yamt if (fs->lsda_encoding != DW_EH_PE_omit)
358 1.2.4.2 yamt {
359 1.2.4.2 yamt _Unwind_Ptr lsda;
360 1.2.4.2 yamt
361 1.2.4.2 yamt aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
362 1.2.4.2 yamt context->lsda = (void *) lsda;
363 1.2.4.2 yamt }
364 1.2.4.2 yamt }
365 1.2.4.2 yamt
366 1.2.4.2 yamt /* Check for the end of the stack. This needs to be checked after
367 1.2.4.2 yamt the MD_FALLBACK_FRAME_STATE_FOR check for signal frames because
368 1.2.4.2 yamt the contents of context->reg[0] are undefined at a signal frame,
369 1.2.4.2 yamt and register a0 may appear to be zero. (The return address in
370 1.2.4.2 yamt context->ra comes from register a4 or a8). */
371 1.2.4.2 yamt ra_ptr = context->reg[0];
372 1.2.4.2 yamt if (ra_ptr && *ra_ptr == 0)
373 1.2.4.2 yamt return _URC_END_OF_STACK;
374 1.2.4.2 yamt
375 1.2.4.2 yamt /* Find the window size from the high bits of the return address. */
376 1.2.4.2 yamt if (ra_ptr)
377 1.2.4.2 yamt window_size = (*ra_ptr >> 30) * 4;
378 1.2.4.2 yamt else
379 1.2.4.2 yamt window_size = 8;
380 1.2.4.2 yamt
381 1.2.4.2 yamt fs->retaddr_column = window_size;
382 1.2.4.2 yamt
383 1.2.4.2 yamt return _URC_NO_REASON;
384 1.2.4.2 yamt }
385 1.2.4.2 yamt
386 1.2.4.2 yamt static void
388 1.2.4.2 yamt uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
389 1.2.4.2 yamt {
390 1.2.4.2 yamt struct _Unwind_Context orig_context = *context;
391 1.2.4.2 yamt _Unwind_Word *sp, *cfa, *next_cfa;
392 1.2.4.2 yamt int i;
393 1.2.4.2 yamt
394 1.2.4.2 yamt if (fs->signal_regs)
395 1.2.4.2 yamt {
396 1.2.4.2 yamt cfa = (_Unwind_Word *) fs->signal_regs[1];
397 1.2.4.2 yamt next_cfa = (_Unwind_Word *) cfa[-3];
398 1.2.4.2 yamt
399 1.2.4.2 yamt for (i = 0; i < 4; i++)
400 1.2.4.2 yamt context->reg[i] = fs->signal_regs + (i << 2);
401 1.2.4.2 yamt }
402 1.2.4.2 yamt else
403 1.2.4.2 yamt {
404 1.2.4.2 yamt int window_size = fs->retaddr_column >> 2;
405 1.2.4.2 yamt
406 1.2.4.2 yamt sp = (_Unwind_Word *) orig_context.sp;
407 1.2.4.2 yamt cfa = (_Unwind_Word *) orig_context.cfa;
408 1.2.4.2 yamt next_cfa = (_Unwind_Word *) cfa[-3];
409 1.2.4.2 yamt
410 1.2.4.2 yamt /* Registers a0-a3 are in the save area below sp. */
411 1.2.4.2 yamt context->reg[0] = sp - 4;
412 1.2.4.2 yamt
413 1.2.4.2 yamt /* Find the extra save area below next_cfa. */
414 1.2.4.2 yamt for (i = 1; i < window_size; i++)
415 1.2.4.2 yamt context->reg[i] = next_cfa - 4 * (1 + window_size - i);
416 1.2.4.2 yamt
417 1.2.4.2 yamt /* Remaining registers rotate from previous save areas. */
418 1.2.4.2 yamt for (i = window_size; i < 4; i++)
419 1.2.4.2 yamt context->reg[i] = orig_context.reg[i - window_size];
420 1.2.4.2 yamt }
421 1.2.4.2 yamt
422 1.2.4.2 yamt context->sp = cfa;
423 1.2.4.2 yamt context->cfa = next_cfa;
424 1.2.4.2 yamt
425 1.2.4.2 yamt _Unwind_SetSignalFrame (context, fs->signal_frame);
426 1.2.4.2 yamt }
427 1.2.4.2 yamt
428 1.2.4.2 yamt /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
429 1.2.4.2 yamt of its caller. Update CONTEXT to refer to the caller as well. Note
430 1.2.4.2 yamt that the lsda member is not updated here, but later in
431 1.2.4.2 yamt uw_frame_state_for. */
432 1.2.4.2 yamt
433 1.2.4.2 yamt static void
434 1.2.4.2 yamt uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
435 1.2.4.2 yamt {
436 1.2.4.2 yamt uw_update_context_1 (context, fs);
437 1.2.4.2 yamt
438 1.2.4.2 yamt /* Compute the return address now, since the return address column
439 1.2.4.2 yamt can change from frame to frame. */
440 1.2.4.2 yamt if (fs->signal_ra != 0)
441 1.2.4.2 yamt context->ra = (void *) fs->signal_ra;
442 1.2.4.2 yamt else
443 1.2.4.2 yamt context->ra = (void *) ((_Unwind_GetGR (context, fs->retaddr_column)
444 1.2.4.2 yamt & XTENSA_RA_FIELD_MASK) | context->ra_high_bits);
445 1.2.4.2 yamt }
446 1.2.4.2 yamt
447 1.2.4.2 yamt static void
448 1.2.4.2 yamt uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
449 1.2.4.2 yamt {
450 1.2.4.2 yamt uw_update_context (context, fs);
451 1.2.4.2 yamt }
452 1.2.4.2 yamt
453 1.2.4.2 yamt /* Fill in CONTEXT for top-of-stack. The only valid registers at this
455 1.2.4.2 yamt level will be the return address and the CFA. */
456 1.2.4.2 yamt
457 1.2.4.2 yamt #define uw_init_context(CONTEXT) \
458 1.2.4.2 yamt do \
459 1.2.4.2 yamt { \
460 1.2.4.2 yamt __builtin_unwind_init (); \
461 1.2.4.2 yamt uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
462 1.2.4.2 yamt __builtin_return_address (0)); \
463 1.2.4.2 yamt } \
464 1.2.4.2 yamt while (0)
465 1.2.4.2 yamt
466 1.2.4.2 yamt static void __attribute__((noinline))
467 1.2.4.2 yamt uw_init_context_1 (struct _Unwind_Context *context, void *outer_cfa,
468 1.2.4.2 yamt void *outer_ra)
469 1.2.4.2 yamt {
470 1.2.4.2 yamt void *ra = __builtin_return_address (0);
471 1.2.4.2 yamt void *cfa = __builtin_dwarf_cfa ();
472 1.2.4.2 yamt _Unwind_FrameState fs;
473 1.2.4.2 yamt
474 1.2.4.2 yamt memset (context, 0, sizeof (struct _Unwind_Context));
475 1.2.4.2 yamt context->ra = ra;
476 1.2.4.2 yamt
477 1.2.4.2 yamt memset (&fs, 0, sizeof (fs));
478 1.2.4.2 yamt fs.retaddr_column = 8;
479 1.2.4.2 yamt context->sp = cfa;
480 1.2.4.2 yamt context->cfa = outer_cfa;
481 1.2.4.2 yamt context->ra_high_bits =
482 1.2.4.2 yamt ((_Unwind_Word) uw_init_context_1) & ~XTENSA_RA_FIELD_MASK;
483 1.2.4.2 yamt uw_update_context_1 (context, &fs);
484 1.2.4.2 yamt
485 1.2.4.2 yamt context->ra = outer_ra;
486 1.2.4.2 yamt }
487 1.2.4.2 yamt
488 1.2.4.2 yamt
489 1.2.4.2 yamt /* Install TARGET into CURRENT so that we can return to it. This is a
490 1.2.4.2 yamt macro because __builtin_eh_return must be invoked in the context of
491 1.2.4.2 yamt our caller. */
492 1.2.4.2 yamt
493 1.2.4.2 yamt #define uw_install_context(CURRENT, TARGET) \
494 1.2.4.2 yamt do \
495 1.2.4.2 yamt { \
496 1.2.4.2 yamt long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
497 1.2.4.2 yamt void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
498 1.2.4.2 yamt __builtin_eh_return (offset, handler); \
499 1.2.4.2 yamt } \
500 1.2.4.2 yamt while (0)
501 1.2.4.2 yamt
502 1.2.4.2 yamt static long
503 1.2.4.2 yamt uw_install_context_1 (struct _Unwind_Context *current,
504 1.2.4.2 yamt struct _Unwind_Context *target)
505 1.2.4.2 yamt {
506 1.2.4.2 yamt long i;
507 1.2.4.2 yamt
508 1.2.4.2 yamt /* The eh_return insn assumes a window size of 8, so don't bother copying
509 1.2.4.2 yamt the save areas for registers a8-a15 since they won't be reloaded. */
510 1.2.4.2 yamt for (i = 0; i < 2; ++i)
511 1.2.4.2 yamt {
512 1.2.4.2 yamt void *c = current->reg[i];
513 1.2.4.2 yamt void *t = target->reg[i];
514 1.2.4.2 yamt
515 1.2.4.2 yamt if (t && c && t != c)
516 1.2.4.2 yamt memcpy (c, t, 4 * sizeof (_Unwind_Word));
517 1.2.4.2 yamt }
518 1.2.4.2 yamt
519 1.2.4.2 yamt return 0;
520 1.2.4.2 yamt }
521 1.2.4.2 yamt
522 1.2.4.2 yamt static inline _Unwind_Ptr
523 1.2.4.2 yamt uw_identify_context (struct _Unwind_Context *context)
524 1.2.4.2 yamt {
525 1.2.4.2 yamt return _Unwind_GetCFA (context);
526 1.2.4.2 yamt }
527 1.2.4.2 yamt
528 1.2.4.2 yamt
529 1.2.4.2 yamt #include "unwind.inc"
530 1.2.4.2 yamt
531 1.2.4.2 yamt #if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
532 1.2.4.2 yamt alias (_Unwind_Backtrace);
533 1.2.4.2 yamt alias (_Unwind_DeleteException);
534 1.2.4.2 yamt alias (_Unwind_FindEnclosingFunction);
535 1.2.4.2 yamt alias (_Unwind_ForcedUnwind);
536 1.2.4.2 yamt alias (_Unwind_GetDataRelBase);
537 1.2.4.2 yamt alias (_Unwind_GetTextRelBase);
538 1.2.4.2 yamt alias (_Unwind_GetCFA);
539 1.2.4.2 yamt alias (_Unwind_GetGR);
540 1.2.4.2 yamt alias (_Unwind_GetIP);
541 1.2.4.2 yamt alias (_Unwind_GetLanguageSpecificData);
542 1.2.4.2 yamt alias (_Unwind_GetRegionStart);
543 1.2.4.2 yamt alias (_Unwind_RaiseException);
544 alias (_Unwind_Resume);
545 alias (_Unwind_Resume_or_Rethrow);
546 alias (_Unwind_SetGR);
547 alias (_Unwind_SetIP);
548 #endif
549
550 #endif /* !USING_SJLJ_EXCEPTIONS */
551