OSDN Git Service

* tree-ssa-operands.c: Cleanup whitespace.
[pf3gnuchains/gcc-fork.git] / gcc / unwind-dw2.c
1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
3    Free Software Foundation, Inc.
4
5    This file is part of GCC.
6
7    GCC is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2, or (at your option)
10    any later version.
11
12    In addition to the permissions in the GNU General Public License, the
13    Free Software Foundation gives you unlimited permission to link the
14    compiled version of this file into combinations with other programs,
15    and to distribute those combinations without any restriction coming
16    from the use of this file.  (The General Public License restrictions
17    do apply in other respects; for example, they cover modification of
18    the file, and distribution when not linked into a combined
19    executable.)
20
21    GCC is distributed in the hope that it will be useful, but WITHOUT
22    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
24    License for more details.
25
26    You should have received a copy of the GNU General Public License
27    along with GCC; see the file COPYING.  If not, write to the Free
28    Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
29    02110-1301, USA.  */
30
31 #include "tconfig.h"
32 #include "tsystem.h"
33 #include "coretypes.h"
34 #include "tm.h"
35 #include "dwarf2.h"
36 #include "unwind.h"
37 #ifdef __USING_SJLJ_EXCEPTIONS__
38 # define NO_SIZE_OF_ENCODED_VALUE
39 #endif
40 #include "unwind-pe.h"
41 #include "unwind-dw2-fde.h"
42 #include "gthr.h"
43 #include "unwind-dw2.h"
44
45 #ifndef __USING_SJLJ_EXCEPTIONS__
46
47 #ifndef STACK_GROWS_DOWNWARD
48 #define STACK_GROWS_DOWNWARD 0
49 #else
50 #undef STACK_GROWS_DOWNWARD
51 #define STACK_GROWS_DOWNWARD 1
52 #endif
53
54 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc.  */
55 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
56 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
57 #endif
58
59 #ifndef DWARF_REG_TO_UNWIND_COLUMN
60 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
61 #endif
62
63 /* This is the register and unwind state for a particular frame.  This
64    provides the information necessary to unwind up past a frame and return
65    to its caller.  */
66 struct _Unwind_Context
67 {
68   void *reg[DWARF_FRAME_REGISTERS+1];
69   void *cfa;
70   void *ra;
71   void *lsda;
72   struct dwarf_eh_bases bases;
73   _Unwind_Word args_size;
74   char signal_frame;
75 };
76
77 /* Byte size of every register managed by these routines.  */
78 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS+1];
79
80 \f
81 /* Read unaligned data from the instruction buffer.  */
82
83 union unaligned
84 {
85   void *p;
86   unsigned u2 __attribute__ ((mode (HI)));
87   unsigned u4 __attribute__ ((mode (SI)));
88   unsigned u8 __attribute__ ((mode (DI)));
89   signed s2 __attribute__ ((mode (HI)));
90   signed s4 __attribute__ ((mode (SI)));
91   signed s8 __attribute__ ((mode (DI)));
92 } __attribute__ ((packed));
93
94 static inline void *
95 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
96
97 static inline int
98 read_1u (const void *p) { return *(const unsigned char *) p; }
99
100 static inline int
101 read_1s (const void *p) { return *(const signed char *) p; }
102
103 static inline int
104 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
105
106 static inline int
107 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
108
109 static inline unsigned int
110 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
111
112 static inline int
113 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
114
115 static inline unsigned long
116 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
117
118 static inline unsigned long
119 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
120 \f
121 /* Get the value of register REG as saved in CONTEXT.  */
122
123 inline _Unwind_Word
124 _Unwind_GetGR (struct _Unwind_Context *context, int index)
125 {
126   int size;
127   void *ptr;
128
129 #ifdef DWARF_ZERO_REG
130   if (index == DWARF_ZERO_REG)
131     return 0;
132 #endif
133
134   index = DWARF_REG_TO_UNWIND_COLUMN (index);
135   gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
136   size = dwarf_reg_size_table[index];
137   ptr = context->reg[index];
138
139   /* This will segfault if the register hasn't been saved.  */
140   if (size == sizeof(_Unwind_Ptr))
141     return * (_Unwind_Ptr *) ptr;
142   else
143     {
144       gcc_assert (size == sizeof(_Unwind_Word));
145       return * (_Unwind_Word *) ptr;
146     }
147 }
148
149 static inline void *
150 _Unwind_GetPtr (struct _Unwind_Context *context, int index)
151 {
152   return (void *)(_Unwind_Ptr) _Unwind_GetGR (context, index);
153 }
154
155 /* Get the value of the CFA as saved in CONTEXT.  */
156
157 _Unwind_Word
158 _Unwind_GetCFA (struct _Unwind_Context *context)
159 {
160   return (_Unwind_Ptr) context->cfa;
161 }
162
163 /* Overwrite the saved value for register REG in CONTEXT with VAL.  */
164
165 inline void
166 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
167 {
168   int size;
169   void *ptr;
170
171   index = DWARF_REG_TO_UNWIND_COLUMN (index);
172   gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
173   size = dwarf_reg_size_table[index];
174   ptr = context->reg[index];
175
176   if (size == sizeof(_Unwind_Ptr))
177     * (_Unwind_Ptr *) ptr = val;
178   else
179     {
180       gcc_assert (size == sizeof(_Unwind_Word));
181       * (_Unwind_Word *) ptr = val;
182     }
183 }
184
185 /* Get the pointer to a register INDEX as saved in CONTEXT.  */
186
187 static inline void *
188 _Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
189 {
190   index = DWARF_REG_TO_UNWIND_COLUMN (index);
191   return context->reg[index];
192 }
193
194 /* Set the pointer to a register INDEX as saved in CONTEXT.  */
195
196 static inline void
197 _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
198 {
199   index = DWARF_REG_TO_UNWIND_COLUMN (index);
200   context->reg[index] = p;
201 }
202
203 /* Retrieve the return address for CONTEXT.  */
204
205 inline _Unwind_Ptr
206 _Unwind_GetIP (struct _Unwind_Context *context)
207 {
208   return (_Unwind_Ptr) context->ra;
209 }
210
211 /* Retrieve the return address and flag whether that IP is before
212    or after first not yet fully executed instruction.  */
213
214 inline _Unwind_Ptr
215 _Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
216 {
217   *ip_before_insn = context->signal_frame != 0;
218   return (_Unwind_Ptr) context->ra;
219 }
220
221 /* Overwrite the return address for CONTEXT with VAL.  */
222
223 inline void
224 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
225 {
226   context->ra = (void *) val;
227 }
228
229 void *
230 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
231 {
232   return context->lsda;
233 }
234
235 _Unwind_Ptr
236 _Unwind_GetRegionStart (struct _Unwind_Context *context)
237 {
238   return (_Unwind_Ptr) context->bases.func;
239 }
240
241 void *
242 _Unwind_FindEnclosingFunction (void *pc)
243 {
244   struct dwarf_eh_bases bases;
245   const struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
246   if (fde)
247     return bases.func;
248   else
249     return NULL;
250 }
251
252 #ifndef __ia64__
253 _Unwind_Ptr
254 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
255 {
256   return (_Unwind_Ptr) context->bases.dbase;
257 }
258
259 _Unwind_Ptr
260 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
261 {
262   return (_Unwind_Ptr) context->bases.tbase;
263 }
264 #endif
265
266 #ifdef MD_UNWIND_SUPPORT
267 #include MD_UNWIND_SUPPORT
268 #endif
269 \f
270 /* Extract any interesting information from the CIE for the translation
271    unit F belongs to.  Return a pointer to the byte after the augmentation,
272    or NULL if we encountered an undecipherable augmentation.  */
273
274 static const unsigned char *
275 extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
276                   _Unwind_FrameState *fs)
277 {
278   const unsigned char *aug = cie->augmentation;
279   const unsigned char *p = aug + strlen ((const char *)aug) + 1;
280   const unsigned char *ret = NULL;
281   _Unwind_Word utmp;
282
283   /* g++ v2 "eh" has pointer immediately following augmentation string,
284      so it must be handled first.  */
285   if (aug[0] == 'e' && aug[1] == 'h')
286     {
287       fs->eh_ptr = read_pointer (p);
288       p += sizeof (void *);
289       aug += 2;
290     }
291
292   /* Immediately following the augmentation are the code and
293      data alignment and return address column.  */
294   p = read_uleb128 (p, &fs->code_align);
295   p = read_sleb128 (p, &fs->data_align);
296   if (cie->version == 1)
297     fs->retaddr_column = *p++;
298   else
299     p = read_uleb128 (p, &fs->retaddr_column);
300   fs->lsda_encoding = DW_EH_PE_omit;
301
302   /* If the augmentation starts with 'z', then a uleb128 immediately
303      follows containing the length of the augmentation field following
304      the size.  */
305   if (*aug == 'z')
306     {
307       p = read_uleb128 (p, &utmp);
308       ret = p + utmp;
309
310       fs->saw_z = 1;
311       ++aug;
312     }
313
314   /* Iterate over recognized augmentation subsequences.  */
315   while (*aug != '\0')
316     {
317       /* "L" indicates a byte showing how the LSDA pointer is encoded.  */
318       if (aug[0] == 'L')
319         {
320           fs->lsda_encoding = *p++;
321           aug += 1;
322         }
323
324       /* "R" indicates a byte indicating how FDE addresses are encoded.  */
325       else if (aug[0] == 'R')
326         {
327           fs->fde_encoding = *p++;
328           aug += 1;
329         }
330
331       /* "P" indicates a personality routine in the CIE augmentation.  */
332       else if (aug[0] == 'P')
333         {
334           _Unwind_Ptr personality;
335           
336           p = read_encoded_value (context, *p, p + 1, &personality);
337           fs->personality = (_Unwind_Personality_Fn) personality;
338           aug += 1;
339         }
340
341       /* "S" indicates a signal frame.  */
342       else if (aug[0] == 'S')
343         {
344           fs->signal_frame = 1;
345           aug += 1;
346         }
347
348       /* Otherwise we have an unknown augmentation string.
349          Bail unless we saw a 'z' prefix.  */
350       else
351         return ret;
352     }
353
354   return ret ? ret : p;
355 }
356
357
358 /* Decode a DW_OP stack program.  Return the top of stack.  Push INITIAL
359    onto the stack to start.  */
360
361 static _Unwind_Word
362 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
363                   struct _Unwind_Context *context, _Unwind_Word initial)
364 {
365   _Unwind_Word stack[64];       /* ??? Assume this is enough.  */
366   int stack_elt;
367
368   stack[0] = initial;
369   stack_elt = 1;
370
371   while (op_ptr < op_end)
372     {
373       enum dwarf_location_atom op = *op_ptr++;
374       _Unwind_Word result, reg, utmp;
375       _Unwind_Sword offset, stmp;
376
377       switch (op)
378         {
379         case DW_OP_lit0:
380         case DW_OP_lit1:
381         case DW_OP_lit2:
382         case DW_OP_lit3:
383         case DW_OP_lit4:
384         case DW_OP_lit5:
385         case DW_OP_lit6:
386         case DW_OP_lit7:
387         case DW_OP_lit8:
388         case DW_OP_lit9:
389         case DW_OP_lit10:
390         case DW_OP_lit11:
391         case DW_OP_lit12:
392         case DW_OP_lit13:
393         case DW_OP_lit14:
394         case DW_OP_lit15:
395         case DW_OP_lit16:
396         case DW_OP_lit17:
397         case DW_OP_lit18:
398         case DW_OP_lit19:
399         case DW_OP_lit20:
400         case DW_OP_lit21:
401         case DW_OP_lit22:
402         case DW_OP_lit23:
403         case DW_OP_lit24:
404         case DW_OP_lit25:
405         case DW_OP_lit26:
406         case DW_OP_lit27:
407         case DW_OP_lit28:
408         case DW_OP_lit29:
409         case DW_OP_lit30:
410         case DW_OP_lit31:
411           result = op - DW_OP_lit0;
412           break;
413
414         case DW_OP_addr:
415           result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
416           op_ptr += sizeof (void *);
417           break;
418
419         case DW_OP_const1u:
420           result = read_1u (op_ptr);
421           op_ptr += 1;
422           break;
423         case DW_OP_const1s:
424           result = read_1s (op_ptr);
425           op_ptr += 1;
426           break;
427         case DW_OP_const2u:
428           result = read_2u (op_ptr);
429           op_ptr += 2;
430           break;
431         case DW_OP_const2s:
432           result = read_2s (op_ptr);
433           op_ptr += 2;
434           break;
435         case DW_OP_const4u:
436           result = read_4u (op_ptr);
437           op_ptr += 4;
438           break;
439         case DW_OP_const4s:
440           result = read_4s (op_ptr);
441           op_ptr += 4;
442           break;
443         case DW_OP_const8u:
444           result = read_8u (op_ptr);
445           op_ptr += 8;
446           break;
447         case DW_OP_const8s:
448           result = read_8s (op_ptr);
449           op_ptr += 8;
450           break;
451         case DW_OP_constu:
452           op_ptr = read_uleb128 (op_ptr, &result);
453           break;
454         case DW_OP_consts:
455           op_ptr = read_sleb128 (op_ptr, &stmp);
456           result = stmp;
457           break;
458
459         case DW_OP_reg0:
460         case DW_OP_reg1:
461         case DW_OP_reg2:
462         case DW_OP_reg3:
463         case DW_OP_reg4:
464         case DW_OP_reg5:
465         case DW_OP_reg6:
466         case DW_OP_reg7:
467         case DW_OP_reg8:
468         case DW_OP_reg9:
469         case DW_OP_reg10:
470         case DW_OP_reg11:
471         case DW_OP_reg12:
472         case DW_OP_reg13:
473         case DW_OP_reg14:
474         case DW_OP_reg15:
475         case DW_OP_reg16:
476         case DW_OP_reg17:
477         case DW_OP_reg18:
478         case DW_OP_reg19:
479         case DW_OP_reg20:
480         case DW_OP_reg21:
481         case DW_OP_reg22:
482         case DW_OP_reg23:
483         case DW_OP_reg24:
484         case DW_OP_reg25:
485         case DW_OP_reg26:
486         case DW_OP_reg27:
487         case DW_OP_reg28:
488         case DW_OP_reg29:
489         case DW_OP_reg30:
490         case DW_OP_reg31:
491           result = _Unwind_GetGR (context, op - DW_OP_reg0);
492           break;
493         case DW_OP_regx:
494           op_ptr = read_uleb128 (op_ptr, &reg);
495           result = _Unwind_GetGR (context, reg);
496           break;
497
498         case DW_OP_breg0:
499         case DW_OP_breg1:
500         case DW_OP_breg2:
501         case DW_OP_breg3:
502         case DW_OP_breg4:
503         case DW_OP_breg5:
504         case DW_OP_breg6:
505         case DW_OP_breg7:
506         case DW_OP_breg8:
507         case DW_OP_breg9:
508         case DW_OP_breg10:
509         case DW_OP_breg11:
510         case DW_OP_breg12:
511         case DW_OP_breg13:
512         case DW_OP_breg14:
513         case DW_OP_breg15:
514         case DW_OP_breg16:
515         case DW_OP_breg17:
516         case DW_OP_breg18:
517         case DW_OP_breg19:
518         case DW_OP_breg20:
519         case DW_OP_breg21:
520         case DW_OP_breg22:
521         case DW_OP_breg23:
522         case DW_OP_breg24:
523         case DW_OP_breg25:
524         case DW_OP_breg26:
525         case DW_OP_breg27:
526         case DW_OP_breg28:
527         case DW_OP_breg29:
528         case DW_OP_breg30:
529         case DW_OP_breg31:
530           op_ptr = read_sleb128 (op_ptr, &offset);
531           result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
532           break;
533         case DW_OP_bregx:
534           op_ptr = read_uleb128 (op_ptr, &reg);
535           op_ptr = read_sleb128 (op_ptr, &offset);
536           result = _Unwind_GetGR (context, reg) + offset;
537           break;
538
539         case DW_OP_dup:
540           gcc_assert (stack_elt);
541           result = stack[stack_elt - 1];
542           break;
543
544         case DW_OP_drop:
545           gcc_assert (stack_elt);
546           stack_elt -= 1;
547           goto no_push;
548
549         case DW_OP_pick:
550           offset = *op_ptr++;
551           gcc_assert (offset < stack_elt - 1);
552           result = stack[stack_elt - 1 - offset];
553           break;
554
555         case DW_OP_over:
556           gcc_assert (stack_elt >= 2);
557           result = stack[stack_elt - 2];
558           break;
559
560         case DW_OP_rot:
561           {
562             _Unwind_Word t1, t2, t3;
563
564             gcc_assert (stack_elt >= 3);
565             t1 = stack[stack_elt - 1];
566             t2 = stack[stack_elt - 2];
567             t3 = stack[stack_elt - 3];
568             stack[stack_elt - 1] = t2;
569             stack[stack_elt - 2] = t3;
570             stack[stack_elt - 3] = t1;
571             goto no_push;
572           }
573
574         case DW_OP_deref:
575         case DW_OP_deref_size:
576         case DW_OP_abs:
577         case DW_OP_neg:
578         case DW_OP_not:
579         case DW_OP_plus_uconst:
580           /* Unary operations.  */
581           gcc_assert (stack_elt);
582           stack_elt -= 1;
583           
584           result = stack[stack_elt];
585
586           switch (op)
587             {
588             case DW_OP_deref:
589               {
590                 void *ptr = (void *) (_Unwind_Ptr) result;
591                 result = (_Unwind_Ptr) read_pointer (ptr);
592               }
593               break;
594
595             case DW_OP_deref_size:
596               {
597                 void *ptr = (void *) (_Unwind_Ptr) result;
598                 switch (*op_ptr++)
599                   {
600                   case 1:
601                     result = read_1u (ptr);
602                     break;
603                   case 2:
604                     result = read_2u (ptr);
605                     break;
606                   case 4:
607                     result = read_4u (ptr);
608                     break;
609                   case 8:
610                     result = read_8u (ptr);
611                     break;
612                   default:
613                     gcc_unreachable ();
614                   }
615               }
616               break;
617
618             case DW_OP_abs:
619               if ((_Unwind_Sword) result < 0)
620                 result = -result;
621               break;
622             case DW_OP_neg:
623               result = -result;
624               break;
625             case DW_OP_not:
626               result = ~result;
627               break;
628             case DW_OP_plus_uconst:
629               op_ptr = read_uleb128 (op_ptr, &utmp);
630               result += utmp;
631               break;
632
633             default:
634               gcc_unreachable ();
635             }
636           break;
637
638         case DW_OP_and:
639         case DW_OP_div:
640         case DW_OP_minus:
641         case DW_OP_mod:
642         case DW_OP_mul:
643         case DW_OP_or:
644         case DW_OP_plus:
645         case DW_OP_shl:
646         case DW_OP_shr:
647         case DW_OP_shra:
648         case DW_OP_xor:
649         case DW_OP_le:
650         case DW_OP_ge:
651         case DW_OP_eq:
652         case DW_OP_lt:
653         case DW_OP_gt:
654         case DW_OP_ne:
655           {
656             /* Binary operations.  */
657             _Unwind_Word first, second;
658             gcc_assert (stack_elt >= 2);
659             stack_elt -= 2;
660             
661             second = stack[stack_elt];
662             first = stack[stack_elt + 1];
663
664             switch (op)
665               {
666               case DW_OP_and:
667                 result = second & first;
668                 break;
669               case DW_OP_div:
670                 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
671                 break;
672               case DW_OP_minus:
673                 result = second - first;
674                 break;
675               case DW_OP_mod:
676                 result = (_Unwind_Sword) second % (_Unwind_Sword) first;
677                 break;
678               case DW_OP_mul:
679                 result = second * first;
680                 break;
681               case DW_OP_or:
682                 result = second | first;
683                 break;
684               case DW_OP_plus:
685                 result = second + first;
686                 break;
687               case DW_OP_shl:
688                 result = second << first;
689                 break;
690               case DW_OP_shr:
691                 result = second >> first;
692                 break;
693               case DW_OP_shra:
694                 result = (_Unwind_Sword) second >> first;
695                 break;
696               case DW_OP_xor:
697                 result = second ^ first;
698                 break;
699               case DW_OP_le:
700                 result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
701                 break;
702               case DW_OP_ge:
703                 result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
704                 break;
705               case DW_OP_eq:
706                 result = (_Unwind_Sword) first == (_Unwind_Sword) second;
707                 break;
708               case DW_OP_lt:
709                 result = (_Unwind_Sword) first < (_Unwind_Sword) second;
710                 break;
711               case DW_OP_gt:
712                 result = (_Unwind_Sword) first > (_Unwind_Sword) second;
713                 break;
714               case DW_OP_ne:
715                 result = (_Unwind_Sword) first != (_Unwind_Sword) second;
716                 break;
717
718               default:
719                 gcc_unreachable ();
720               }
721           }
722           break;
723
724         case DW_OP_skip:
725           offset = read_2s (op_ptr);
726           op_ptr += 2;
727           op_ptr += offset;
728           goto no_push;
729
730         case DW_OP_bra:
731           gcc_assert (stack_elt);
732           stack_elt -= 1;
733           
734           offset = read_2s (op_ptr);
735           op_ptr += 2;
736           if (stack[stack_elt] != 0)
737             op_ptr += offset;
738           goto no_push;
739
740         case DW_OP_nop:
741           goto no_push;
742
743         default:
744           gcc_unreachable ();
745         }
746
747       /* Most things push a result value.  */
748       gcc_assert ((size_t) stack_elt < sizeof(stack)/sizeof(*stack));
749       stack[stack_elt++] = result;
750     no_push:;
751     }
752
753   /* We were executing this program to get a value.  It should be
754      at top of stack.  */
755   gcc_assert (stack_elt);
756   stack_elt -= 1;
757   return stack[stack_elt];
758 }
759
760
761 /* Decode DWARF 2 call frame information. Takes pointers the
762    instruction sequence to decode, current register information and
763    CIE info, and the PC range to evaluate.  */
764
765 static void
766 execute_cfa_program (const unsigned char *insn_ptr,
767                      const unsigned char *insn_end,
768                      struct _Unwind_Context *context,
769                      _Unwind_FrameState *fs)
770 {
771   struct frame_state_reg_info *unused_rs = NULL;
772
773   /* Don't allow remember/restore between CIE and FDE programs.  */
774   fs->regs.prev = NULL;
775
776   /* The comparison with the return address uses < rather than <= because
777      we are only interested in the effects of code before the call; for a
778      noreturn function, the return address may point to unrelated code with
779      a different stack configuration that we are not interested in.  We
780      assume that the call itself is unwind info-neutral; if not, or if
781      there are delay instructions that adjust the stack, these must be
782      reflected at the point immediately before the call insn.
783      In signal frames, return address is after last completed instruction,
784      so we add 1 to return address to make the comparison <=.  */
785   while (insn_ptr < insn_end && fs->pc < context->ra + context->signal_frame)
786     {
787       unsigned char insn = *insn_ptr++;
788       _Unwind_Word reg, utmp;
789       _Unwind_Sword offset, stmp;
790
791       if ((insn & 0xc0) == DW_CFA_advance_loc)
792         fs->pc += (insn & 0x3f) * fs->code_align;
793       else if ((insn & 0xc0) == DW_CFA_offset)
794         {
795           reg = insn & 0x3f;
796           insn_ptr = read_uleb128 (insn_ptr, &utmp);
797           offset = (_Unwind_Sword) utmp * fs->data_align;
798           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
799             = REG_SAVED_OFFSET;
800           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
801         }
802       else if ((insn & 0xc0) == DW_CFA_restore)
803         {
804           reg = insn & 0x3f;
805           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_UNSAVED;
806         }
807       else switch (insn)
808         {
809         case DW_CFA_set_loc:
810           {
811             _Unwind_Ptr pc;
812             
813             insn_ptr = read_encoded_value (context, fs->fde_encoding,
814                                            insn_ptr, &pc);
815             fs->pc = (void *) pc;
816           }
817           break;
818
819         case DW_CFA_advance_loc1:
820           fs->pc += read_1u (insn_ptr) * fs->code_align;
821           insn_ptr += 1;
822           break;
823         case DW_CFA_advance_loc2:
824           fs->pc += read_2u (insn_ptr) * fs->code_align;
825           insn_ptr += 2;
826           break;
827         case DW_CFA_advance_loc4:
828           fs->pc += read_4u (insn_ptr) * fs->code_align;
829           insn_ptr += 4;
830           break;
831
832         case DW_CFA_offset_extended:
833           insn_ptr = read_uleb128 (insn_ptr, &reg);
834           insn_ptr = read_uleb128 (insn_ptr, &utmp);
835           offset = (_Unwind_Sword) utmp * fs->data_align;
836           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
837             = REG_SAVED_OFFSET;
838           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
839           break;
840
841         case DW_CFA_restore_extended:
842           insn_ptr = read_uleb128 (insn_ptr, &reg);
843           /* FIXME, this is wrong; the CIE might have said that the
844              register was saved somewhere.  */
845           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
846           break;
847
848         case DW_CFA_undefined:
849         case DW_CFA_same_value:
850           insn_ptr = read_uleb128 (insn_ptr, &reg);
851           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
852           break;
853
854         case DW_CFA_nop:
855           break;
856
857         case DW_CFA_register:
858           {
859             _Unwind_Word reg2;
860             insn_ptr = read_uleb128 (insn_ptr, &reg);
861             insn_ptr = read_uleb128 (insn_ptr, &reg2);
862             fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
863             fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.reg = reg2;
864           }
865           break;
866
867         case DW_CFA_remember_state:
868           {
869             struct frame_state_reg_info *new_rs;
870             if (unused_rs)
871               {
872                 new_rs = unused_rs;
873                 unused_rs = unused_rs->prev;
874               }
875             else
876               new_rs = alloca (sizeof (struct frame_state_reg_info));
877
878             *new_rs = fs->regs;
879             fs->regs.prev = new_rs;
880           }
881           break;
882
883         case DW_CFA_restore_state:
884           {
885             struct frame_state_reg_info *old_rs = fs->regs.prev;
886             fs->regs = *old_rs;
887             old_rs->prev = unused_rs;
888             unused_rs = old_rs;
889           }
890           break;
891
892         case DW_CFA_def_cfa:
893           insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
894           insn_ptr = read_uleb128 (insn_ptr, &utmp);
895           fs->cfa_offset = utmp;
896           fs->cfa_how = CFA_REG_OFFSET;
897           break;
898
899         case DW_CFA_def_cfa_register:
900           insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
901           fs->cfa_how = CFA_REG_OFFSET;
902           break;
903
904         case DW_CFA_def_cfa_offset:
905           insn_ptr = read_uleb128 (insn_ptr, &utmp);
906           fs->cfa_offset = utmp;
907           /* cfa_how deliberately not set.  */
908           break;
909
910         case DW_CFA_def_cfa_expression:
911           fs->cfa_exp = insn_ptr;
912           fs->cfa_how = CFA_EXP;
913           insn_ptr = read_uleb128 (insn_ptr, &utmp);
914           insn_ptr += utmp;
915           break;
916
917         case DW_CFA_expression:
918           insn_ptr = read_uleb128 (insn_ptr, &reg);
919           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP;
920           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
921           insn_ptr = read_uleb128 (insn_ptr, &utmp);
922           insn_ptr += utmp;
923           break;
924
925           /* From the dwarf3 draft.  */
926         case DW_CFA_offset_extended_sf:
927           insn_ptr = read_uleb128 (insn_ptr, &reg);
928           insn_ptr = read_sleb128 (insn_ptr, &stmp);
929           offset = stmp * fs->data_align;
930           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
931             = REG_SAVED_OFFSET;
932           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
933           break;
934
935         case DW_CFA_def_cfa_sf:
936           insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
937           insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
938           fs->cfa_how = CFA_REG_OFFSET;
939           fs->cfa_offset *= fs->data_align;
940           break;
941
942         case DW_CFA_def_cfa_offset_sf:
943           insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
944           fs->cfa_offset *= fs->data_align;
945           /* cfa_how deliberately not set.  */
946           break;
947
948         case DW_CFA_GNU_window_save:
949           /* ??? Hardcoded for SPARC register window configuration.  */
950           for (reg = 16; reg < 32; ++reg)
951             {
952               fs->regs.reg[reg].how = REG_SAVED_OFFSET;
953               fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
954             }
955           break;
956
957         case DW_CFA_GNU_args_size:
958           insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
959           break;
960
961         case DW_CFA_GNU_negative_offset_extended:
962           /* Obsoleted by DW_CFA_offset_extended_sf, but used by
963              older PowerPC code.  */
964           insn_ptr = read_uleb128 (insn_ptr, &reg);
965           insn_ptr = read_uleb128 (insn_ptr, &utmp);
966           offset = (_Unwind_Word) utmp * fs->data_align;
967           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
968             = REG_SAVED_OFFSET;
969           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = -offset;
970           break;
971
972         default:
973           gcc_unreachable ();
974         }
975     }
976 }
977 \f
978 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
979    its caller and decode it into FS.  This function also sets the
980    args_size and lsda members of CONTEXT, as they are really information
981    about the caller's frame.  */
982
983 static _Unwind_Reason_Code
984 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
985 {
986   const struct dwarf_fde *fde;
987   const struct dwarf_cie *cie;
988   const unsigned char *aug, *insn, *end;
989
990   memset (fs, 0, sizeof (*fs));
991   context->args_size = 0;
992   context->lsda = 0;
993
994   if (context->ra == 0)
995     return _URC_END_OF_STACK;
996
997   fde = _Unwind_Find_FDE (context->ra + context->signal_frame - 1,
998                           &context->bases);
999   if (fde == NULL)
1000     {
1001 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1002       /* Couldn't find frame unwind info for this function.  Try a
1003          target-specific fallback mechanism.  This will necessarily
1004          not provide a personality routine or LSDA.  */
1005       return MD_FALLBACK_FRAME_STATE_FOR (context, fs);
1006 #else
1007       return _URC_END_OF_STACK;
1008 #endif
1009     }
1010
1011   fs->pc = context->bases.func;
1012
1013   cie = get_cie (fde);
1014   insn = extract_cie_info (cie, context, fs);
1015   if (insn == NULL)
1016     /* CIE contained unknown augmentation.  */
1017     return _URC_FATAL_PHASE1_ERROR;
1018
1019   /* First decode all the insns in the CIE.  */
1020   end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
1021   execute_cfa_program (insn, end, context, fs);
1022
1023   /* Locate augmentation for the fde.  */
1024   aug = (unsigned char *) fde + sizeof (*fde);
1025   aug += 2 * size_of_encoded_value (fs->fde_encoding);
1026   insn = NULL;
1027   if (fs->saw_z)
1028     {
1029       _Unwind_Word i;
1030       aug = read_uleb128 (aug, &i);
1031       insn = aug + i;
1032     }
1033   if (fs->lsda_encoding != DW_EH_PE_omit)
1034     {
1035       _Unwind_Ptr lsda;
1036       
1037       aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
1038       context->lsda = (void *) lsda;
1039     }
1040
1041   /* Then the insns in the FDE up to our target PC.  */
1042   if (insn == NULL)
1043     insn = aug;
1044   end = (unsigned char *) next_fde (fde);
1045   execute_cfa_program (insn, end, context, fs);
1046
1047   return _URC_NO_REASON;
1048 }
1049 \f
1050 typedef struct frame_state
1051 {
1052   void *cfa;
1053   void *eh_ptr;
1054   long cfa_offset;
1055   long args_size;
1056   long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1057   unsigned short cfa_reg;
1058   unsigned short retaddr_column;
1059   char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1060 } frame_state;
1061
1062 struct frame_state * __frame_state_for (void *, struct frame_state *);
1063
1064 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1065    a given PC_TARGET.  The caller should allocate a local variable of
1066    `struct frame_state' and pass its address to STATE_IN.  */
1067
1068 struct frame_state *
1069 __frame_state_for (void *pc_target, struct frame_state *state_in)
1070 {
1071   struct _Unwind_Context context;
1072   _Unwind_FrameState fs;
1073   int reg;
1074
1075   memset (&context, 0, sizeof (struct _Unwind_Context));
1076   context.ra = pc_target + 1;
1077
1078   if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
1079     return 0;
1080
1081   /* We have no way to pass a location expression for the CFA to our
1082      caller.  It wouldn't understand it anyway.  */
1083   if (fs.cfa_how == CFA_EXP)
1084     return 0;
1085
1086   for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1087     {
1088       state_in->saved[reg] = fs.regs.reg[reg].how;
1089       switch (state_in->saved[reg])
1090         {
1091         case REG_SAVED_REG:
1092           state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1093           break;
1094         case REG_SAVED_OFFSET:
1095           state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1096           break;
1097         default:
1098           state_in->reg_or_offset[reg] = 0;
1099           break;
1100         }
1101     }
1102
1103   state_in->cfa_offset = fs.cfa_offset;
1104   state_in->cfa_reg = fs.cfa_reg;
1105   state_in->retaddr_column = fs.retaddr_column;
1106   state_in->args_size = context.args_size;
1107   state_in->eh_ptr = fs.eh_ptr;
1108
1109   return state_in;
1110 }
1111 \f
1112 typedef union { _Unwind_Ptr ptr; _Unwind_Word word; } _Unwind_SpTmp;
1113
1114 static inline void
1115 _Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
1116                      _Unwind_SpTmp *tmp_sp)
1117 {
1118   int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
1119   
1120   if (size == sizeof(_Unwind_Ptr))
1121     tmp_sp->ptr = (_Unwind_Ptr) cfa;
1122   else
1123     {
1124       gcc_assert (size == sizeof(_Unwind_Word));
1125       tmp_sp->word = (_Unwind_Ptr) cfa;
1126     }
1127   _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), tmp_sp);
1128 }
1129
1130 static void
1131 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1132 {
1133   struct _Unwind_Context orig_context = *context;
1134   void *cfa;
1135   long i;
1136
1137 #ifdef EH_RETURN_STACKADJ_RTX
1138   /* Special handling here: Many machines do not use a frame pointer,
1139      and track the CFA only through offsets from the stack pointer from
1140      one frame to the next.  In this case, the stack pointer is never
1141      stored, so it has no saved address in the context.  What we do
1142      have is the CFA from the previous stack frame.
1143
1144      In very special situations (such as unwind info for signal return),
1145      there may be location expressions that use the stack pointer as well.
1146
1147      Do this conditionally for one frame.  This allows the unwind info
1148      for one frame to save a copy of the stack pointer from the previous
1149      frame, and be able to use much easier CFA mechanisms to do it.
1150      Always zap the saved stack pointer value for the next frame; carrying
1151      the value over from one frame to another doesn't make sense.  */
1152
1153   _Unwind_SpTmp tmp_sp;
1154
1155   if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
1156     _Unwind_SetSpColumn (&orig_context, context->cfa, &tmp_sp);
1157   _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
1158 #endif
1159
1160   /* Compute this frame's CFA.  */
1161   switch (fs->cfa_how)
1162     {
1163     case CFA_REG_OFFSET:
1164       cfa = _Unwind_GetPtr (&orig_context, fs->cfa_reg);
1165       cfa += fs->cfa_offset;
1166       break;
1167
1168     case CFA_EXP:
1169       {
1170         const unsigned char *exp = fs->cfa_exp;
1171         _Unwind_Word len;
1172
1173         exp = read_uleb128 (exp, &len);
1174         cfa = (void *) (_Unwind_Ptr)
1175           execute_stack_op (exp, exp + len, &orig_context, 0);
1176         break;
1177       }
1178
1179     default:
1180       gcc_unreachable ();
1181     }
1182   context->cfa = cfa;
1183
1184   /* Compute the addresses of all registers saved in this frame.  */
1185   for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1186     switch (fs->regs.reg[i].how)
1187       {
1188       case REG_UNSAVED:
1189         break;
1190
1191       case REG_SAVED_OFFSET:
1192         _Unwind_SetGRPtr (context, i,
1193                           (void *) (cfa + fs->regs.reg[i].loc.offset));
1194         break;
1195
1196       case REG_SAVED_REG:
1197         _Unwind_SetGRPtr
1198           (context, i,
1199            _Unwind_GetGRPtr (&orig_context, fs->regs.reg[i].loc.reg));
1200         break;
1201
1202       case REG_SAVED_EXP:
1203         {
1204           const unsigned char *exp = fs->regs.reg[i].loc.exp;
1205           _Unwind_Word len;
1206           _Unwind_Ptr val;
1207
1208           exp = read_uleb128 (exp, &len);
1209           val = execute_stack_op (exp, exp + len, &orig_context,
1210                                   (_Unwind_Ptr) cfa);
1211           _Unwind_SetGRPtr (context, i, (void *) val);
1212         }
1213         break;
1214       }
1215
1216   context->signal_frame = fs->signal_frame;
1217
1218 #ifdef MD_FROB_UPDATE_CONTEXT
1219   MD_FROB_UPDATE_CONTEXT (context, fs);
1220 #endif
1221 }
1222
1223 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1224    of its caller.  Update CONTEXT to refer to the caller as well.  Note
1225    that the args_size and lsda members are not updated here, but later in
1226    uw_frame_state_for.  */
1227
1228 static void
1229 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1230 {
1231   uw_update_context_1 (context, fs);
1232
1233   /* Compute the return address now, since the return address column
1234      can change from frame to frame.  */
1235   context->ra = __builtin_extract_return_addr
1236     (_Unwind_GetPtr (context, fs->retaddr_column));
1237 }
1238
1239 static void
1240 uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1241 {
1242   uw_update_context (context, fs);
1243 }
1244 \f
1245 /* Fill in CONTEXT for top-of-stack.  The only valid registers at this
1246    level will be the return address and the CFA.  */
1247
1248 #define uw_init_context(CONTEXT)                                           \
1249   do                                                                       \
1250     {                                                                      \
1251       /* Do any necessary initialization to access arbitrary stack frames. \
1252          On the SPARC, this means flushing the register windows.  */       \
1253       __builtin_unwind_init ();                                            \
1254       uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (),                  \
1255                          __builtin_return_address (0));                    \
1256     }                                                                      \
1257   while (0)
1258
1259 static inline void
1260 init_dwarf_reg_size_table (void)
1261 {
1262   __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1263 }
1264
1265 static void
1266 uw_init_context_1 (struct _Unwind_Context *context,
1267                    void *outer_cfa, void *outer_ra)
1268 {
1269   void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1270   _Unwind_FrameState fs;
1271   _Unwind_SpTmp sp_slot;
1272   _Unwind_Reason_Code code;
1273
1274   memset (context, 0, sizeof (struct _Unwind_Context));
1275   context->ra = ra;
1276
1277   code = uw_frame_state_for (context, &fs);
1278   gcc_assert (code == _URC_NO_REASON);
1279
1280 #if __GTHREADS
1281   {
1282     static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1283     if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1284         || dwarf_reg_size_table[0] == 0)
1285       init_dwarf_reg_size_table ();
1286   }
1287 #else
1288   if (dwarf_reg_size_table[0] == 0)
1289     init_dwarf_reg_size_table ();
1290 #endif
1291
1292   /* Force the frame state to use the known cfa value.  */
1293   _Unwind_SetSpColumn (context, outer_cfa, &sp_slot);
1294   fs.cfa_how = CFA_REG_OFFSET;
1295   fs.cfa_reg = __builtin_dwarf_sp_column ();
1296   fs.cfa_offset = 0;
1297
1298   uw_update_context_1 (context, &fs);
1299
1300   /* If the return address column was saved in a register in the
1301      initialization context, then we can't see it in the given
1302      call frame data.  So have the initialization context tell us.  */
1303   context->ra = __builtin_extract_return_addr (outer_ra);
1304 }
1305
1306
1307 /* Install TARGET into CURRENT so that we can return to it.  This is a
1308    macro because __builtin_eh_return must be invoked in the context of
1309    our caller.  */
1310
1311 #define uw_install_context(CURRENT, TARGET)                              \
1312   do                                                                     \
1313     {                                                                    \
1314       long offset = uw_install_context_1 ((CURRENT), (TARGET));          \
1315       void *handler = __builtin_frob_return_addr ((TARGET)->ra);         \
1316       __builtin_eh_return (offset, handler);                             \
1317     }                                                                    \
1318   while (0)
1319
1320 static long
1321 uw_install_context_1 (struct _Unwind_Context *current,
1322                       struct _Unwind_Context *target)
1323 {
1324   long i;
1325   _Unwind_SpTmp sp_slot;
1326
1327   /* If the target frame does not have a saved stack pointer,
1328      then set up the target's CFA.  */
1329   if (!_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
1330         _Unwind_SetSpColumn (target, target->cfa, &sp_slot);
1331
1332   for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1333     {
1334       void *c = current->reg[i];
1335       void *t = target->reg[i];
1336
1337       if (t && c && t != c)
1338         memcpy (c, t, dwarf_reg_size_table[i]);
1339     }
1340
1341   /* If the current frame doesn't have a saved stack pointer, then we
1342      need to rely on EH_RETURN_STACKADJ_RTX to get our target stack
1343      pointer value reloaded.  */
1344   if (!_Unwind_GetGRPtr (current, __builtin_dwarf_sp_column ()))
1345     {
1346       void *target_cfa;
1347
1348       target_cfa = _Unwind_GetPtr (target, __builtin_dwarf_sp_column ());
1349
1350       /* We adjust SP by the difference between CURRENT and TARGET's CFA.  */
1351       if (STACK_GROWS_DOWNWARD)
1352         return target_cfa - current->cfa + target->args_size;
1353       else
1354         return current->cfa - target_cfa - target->args_size;
1355     }
1356   return 0;
1357 }
1358
1359 static inline _Unwind_Ptr
1360 uw_identify_context (struct _Unwind_Context *context)
1361 {
1362   return _Unwind_GetIP (context);
1363 }
1364
1365
1366 #include "unwind.inc"
1367
1368 #if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
1369 alias (_Unwind_Backtrace);
1370 alias (_Unwind_DeleteException);
1371 alias (_Unwind_FindEnclosingFunction);
1372 alias (_Unwind_ForcedUnwind);
1373 alias (_Unwind_GetDataRelBase);
1374 alias (_Unwind_GetTextRelBase);
1375 alias (_Unwind_GetCFA);
1376 alias (_Unwind_GetGR);
1377 alias (_Unwind_GetIP);
1378 alias (_Unwind_GetLanguageSpecificData);
1379 alias (_Unwind_GetRegionStart);
1380 alias (_Unwind_RaiseException);
1381 alias (_Unwind_Resume);
1382 alias (_Unwind_Resume_or_Rethrow);
1383 alias (_Unwind_SetGR);
1384 alias (_Unwind_SetIP);
1385 #endif
1386
1387 #endif /* !USING_SJLJ_EXCEPTIONS */