OSDN Git Service

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