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