OSDN Git Service

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