OSDN Git Service

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