OSDN Git Service

gcc/
[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   /* 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_rot:
632           {
633             _Unwind_Word t1, t2, t3;
634
635             gcc_assert (stack_elt >= 3);
636             t1 = stack[stack_elt - 1];
637             t2 = stack[stack_elt - 2];
638             t3 = stack[stack_elt - 3];
639             stack[stack_elt - 1] = t2;
640             stack[stack_elt - 2] = t3;
641             stack[stack_elt - 3] = t1;
642             goto no_push;
643           }
644
645         case DW_OP_deref:
646         case DW_OP_deref_size:
647         case DW_OP_abs:
648         case DW_OP_neg:
649         case DW_OP_not:
650         case DW_OP_plus_uconst:
651           /* Unary operations.  */
652           gcc_assert (stack_elt);
653           stack_elt -= 1;
654           
655           result = stack[stack_elt];
656
657           switch (op)
658             {
659             case DW_OP_deref:
660               {
661                 void *ptr = (void *) (_Unwind_Ptr) result;
662                 result = (_Unwind_Ptr) read_pointer (ptr);
663               }
664               break;
665
666             case DW_OP_deref_size:
667               {
668                 void *ptr = (void *) (_Unwind_Ptr) result;
669                 switch (*op_ptr++)
670                   {
671                   case 1:
672                     result = read_1u (ptr);
673                     break;
674                   case 2:
675                     result = read_2u (ptr);
676                     break;
677                   case 4:
678                     result = read_4u (ptr);
679                     break;
680                   case 8:
681                     result = read_8u (ptr);
682                     break;
683                   default:
684                     gcc_unreachable ();
685                   }
686               }
687               break;
688
689             case DW_OP_abs:
690               if ((_Unwind_Sword) result < 0)
691                 result = -result;
692               break;
693             case DW_OP_neg:
694               result = -result;
695               break;
696             case DW_OP_not:
697               result = ~result;
698               break;
699             case DW_OP_plus_uconst:
700               op_ptr = read_uleb128 (op_ptr, &utmp);
701               result += utmp;
702               break;
703
704             default:
705               gcc_unreachable ();
706             }
707           break;
708
709         case DW_OP_and:
710         case DW_OP_div:
711         case DW_OP_minus:
712         case DW_OP_mod:
713         case DW_OP_mul:
714         case DW_OP_or:
715         case DW_OP_plus:
716         case DW_OP_shl:
717         case DW_OP_shr:
718         case DW_OP_shra:
719         case DW_OP_xor:
720         case DW_OP_le:
721         case DW_OP_ge:
722         case DW_OP_eq:
723         case DW_OP_lt:
724         case DW_OP_gt:
725         case DW_OP_ne:
726           {
727             /* Binary operations.  */
728             _Unwind_Word first, second;
729             gcc_assert (stack_elt >= 2);
730             stack_elt -= 2;
731             
732             second = stack[stack_elt];
733             first = stack[stack_elt + 1];
734
735             switch (op)
736               {
737               case DW_OP_and:
738                 result = second & first;
739                 break;
740               case DW_OP_div:
741                 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
742                 break;
743               case DW_OP_minus:
744                 result = second - first;
745                 break;
746               case DW_OP_mod:
747                 result = (_Unwind_Sword) second % (_Unwind_Sword) first;
748                 break;
749               case DW_OP_mul:
750                 result = second * first;
751                 break;
752               case DW_OP_or:
753                 result = second | first;
754                 break;
755               case DW_OP_plus:
756                 result = second + first;
757                 break;
758               case DW_OP_shl:
759                 result = second << first;
760                 break;
761               case DW_OP_shr:
762                 result = second >> first;
763                 break;
764               case DW_OP_shra:
765                 result = (_Unwind_Sword) second >> first;
766                 break;
767               case DW_OP_xor:
768                 result = second ^ first;
769                 break;
770               case DW_OP_le:
771                 result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
772                 break;
773               case DW_OP_ge:
774                 result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
775                 break;
776               case DW_OP_eq:
777                 result = (_Unwind_Sword) first == (_Unwind_Sword) second;
778                 break;
779               case DW_OP_lt:
780                 result = (_Unwind_Sword) first < (_Unwind_Sword) second;
781                 break;
782               case DW_OP_gt:
783                 result = (_Unwind_Sword) first > (_Unwind_Sword) second;
784                 break;
785               case DW_OP_ne:
786                 result = (_Unwind_Sword) first != (_Unwind_Sword) second;
787                 break;
788
789               default:
790                 gcc_unreachable ();
791               }
792           }
793           break;
794
795         case DW_OP_skip:
796           offset = read_2s (op_ptr);
797           op_ptr += 2;
798           op_ptr += offset;
799           goto no_push;
800
801         case DW_OP_bra:
802           gcc_assert (stack_elt);
803           stack_elt -= 1;
804           
805           offset = read_2s (op_ptr);
806           op_ptr += 2;
807           if (stack[stack_elt] != 0)
808             op_ptr += offset;
809           goto no_push;
810
811         case DW_OP_nop:
812           goto no_push;
813
814         default:
815           gcc_unreachable ();
816         }
817
818       /* Most things push a result value.  */
819       gcc_assert ((size_t) stack_elt < sizeof(stack)/sizeof(*stack));
820       stack[stack_elt++] = result;
821     no_push:;
822     }
823
824   /* We were executing this program to get a value.  It should be
825      at top of stack.  */
826   gcc_assert (stack_elt);
827   stack_elt -= 1;
828   return stack[stack_elt];
829 }
830
831
832 /* Decode DWARF 2 call frame information. Takes pointers the
833    instruction sequence to decode, current register information and
834    CIE info, and the PC range to evaluate.  */
835
836 static void
837 execute_cfa_program (const unsigned char *insn_ptr,
838                      const unsigned char *insn_end,
839                      struct _Unwind_Context *context,
840                      _Unwind_FrameState *fs)
841 {
842   struct frame_state_reg_info *unused_rs = NULL;
843
844   /* Don't allow remember/restore between CIE and FDE programs.  */
845   fs->regs.prev = NULL;
846
847   /* The comparison with the return address uses < rather than <= because
848      we are only interested in the effects of code before the call; for a
849      noreturn function, the return address may point to unrelated code with
850      a different stack configuration that we are not interested in.  We
851      assume that the call itself is unwind info-neutral; if not, or if
852      there are delay instructions that adjust the stack, these must be
853      reflected at the point immediately before the call insn.
854      In signal frames, return address is after last completed instruction,
855      so we add 1 to return address to make the comparison <=.  */
856   while (insn_ptr < insn_end
857          && fs->pc < context->ra + _Unwind_IsSignalFrame (context))
858     {
859       unsigned char insn = *insn_ptr++;
860       _Unwind_Word reg, utmp;
861       _Unwind_Sword offset, stmp;
862
863       if ((insn & 0xc0) == DW_CFA_advance_loc)
864         fs->pc += (insn & 0x3f) * fs->code_align;
865       else if ((insn & 0xc0) == DW_CFA_offset)
866         {
867           reg = insn & 0x3f;
868           insn_ptr = read_uleb128 (insn_ptr, &utmp);
869           offset = (_Unwind_Sword) utmp * fs->data_align;
870           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
871             = REG_SAVED_OFFSET;
872           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
873         }
874       else if ((insn & 0xc0) == DW_CFA_restore)
875         {
876           reg = insn & 0x3f;
877           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_UNSAVED;
878         }
879       else switch (insn)
880         {
881         case DW_CFA_set_loc:
882           {
883             _Unwind_Ptr pc;
884             
885             insn_ptr = read_encoded_value (context, fs->fde_encoding,
886                                            insn_ptr, &pc);
887             fs->pc = (void *) pc;
888           }
889           break;
890
891         case DW_CFA_advance_loc1:
892           fs->pc += read_1u (insn_ptr) * fs->code_align;
893           insn_ptr += 1;
894           break;
895         case DW_CFA_advance_loc2:
896           fs->pc += read_2u (insn_ptr) * fs->code_align;
897           insn_ptr += 2;
898           break;
899         case DW_CFA_advance_loc4:
900           fs->pc += read_4u (insn_ptr) * fs->code_align;
901           insn_ptr += 4;
902           break;
903
904         case DW_CFA_offset_extended:
905           insn_ptr = read_uleb128 (insn_ptr, &reg);
906           insn_ptr = read_uleb128 (insn_ptr, &utmp);
907           offset = (_Unwind_Sword) utmp * fs->data_align;
908           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
909             = REG_SAVED_OFFSET;
910           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
911           break;
912
913         case DW_CFA_restore_extended:
914           insn_ptr = read_uleb128 (insn_ptr, &reg);
915           /* FIXME, this is wrong; the CIE might have said that the
916              register was saved somewhere.  */
917           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
918           break;
919
920         case DW_CFA_undefined:
921         case DW_CFA_same_value:
922           insn_ptr = read_uleb128 (insn_ptr, &reg);
923           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
924           break;
925
926         case DW_CFA_nop:
927           break;
928
929         case DW_CFA_register:
930           {
931             _Unwind_Word reg2;
932             insn_ptr = read_uleb128 (insn_ptr, &reg);
933             insn_ptr = read_uleb128 (insn_ptr, &reg2);
934             fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
935             fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.reg = reg2;
936           }
937           break;
938
939         case DW_CFA_remember_state:
940           {
941             struct frame_state_reg_info *new_rs;
942             if (unused_rs)
943               {
944                 new_rs = unused_rs;
945                 unused_rs = unused_rs->prev;
946               }
947             else
948               new_rs = alloca (sizeof (struct frame_state_reg_info));
949
950             *new_rs = fs->regs;
951             fs->regs.prev = new_rs;
952           }
953           break;
954
955         case DW_CFA_restore_state:
956           {
957             struct frame_state_reg_info *old_rs = fs->regs.prev;
958             fs->regs = *old_rs;
959             old_rs->prev = unused_rs;
960             unused_rs = old_rs;
961           }
962           break;
963
964         case DW_CFA_def_cfa:
965           insn_ptr = read_uleb128 (insn_ptr, &fs->regs.cfa_reg);
966           insn_ptr = read_uleb128 (insn_ptr, &utmp);
967           fs->regs.cfa_offset = utmp;
968           fs->regs.cfa_how = CFA_REG_OFFSET;
969           break;
970
971         case DW_CFA_def_cfa_register:
972           insn_ptr = read_uleb128 (insn_ptr, &fs->regs.cfa_reg);
973           fs->regs.cfa_how = CFA_REG_OFFSET;
974           break;
975
976         case DW_CFA_def_cfa_offset:
977           insn_ptr = read_uleb128 (insn_ptr, &utmp);
978           fs->regs.cfa_offset = utmp;
979           /* cfa_how deliberately not set.  */
980           break;
981
982         case DW_CFA_def_cfa_expression:
983           fs->regs.cfa_exp = insn_ptr;
984           fs->regs.cfa_how = CFA_EXP;
985           insn_ptr = read_uleb128 (insn_ptr, &utmp);
986           insn_ptr += utmp;
987           break;
988
989         case DW_CFA_expression:
990           insn_ptr = read_uleb128 (insn_ptr, &reg);
991           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP;
992           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
993           insn_ptr = read_uleb128 (insn_ptr, &utmp);
994           insn_ptr += utmp;
995           break;
996
997           /* Dwarf3.  */
998         case DW_CFA_offset_extended_sf:
999           insn_ptr = read_uleb128 (insn_ptr, &reg);
1000           insn_ptr = read_sleb128 (insn_ptr, &stmp);
1001           offset = stmp * fs->data_align;
1002           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1003             = REG_SAVED_OFFSET;
1004           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
1005           break;
1006
1007         case DW_CFA_def_cfa_sf:
1008           insn_ptr = read_uleb128 (insn_ptr, &fs->regs.cfa_reg);
1009           insn_ptr = read_sleb128 (insn_ptr, &fs->regs.cfa_offset);
1010           fs->regs.cfa_how = CFA_REG_OFFSET;
1011           fs->regs.cfa_offset *= fs->data_align;
1012           break;
1013
1014         case DW_CFA_def_cfa_offset_sf:
1015           insn_ptr = read_sleb128 (insn_ptr, &fs->regs.cfa_offset);
1016           fs->regs.cfa_offset *= fs->data_align;
1017           /* cfa_how deliberately not set.  */
1018           break;
1019
1020         case DW_CFA_val_offset:
1021           insn_ptr = read_uleb128 (insn_ptr, &reg);
1022           insn_ptr = read_uleb128 (insn_ptr, &utmp);
1023           offset = (_Unwind_Sword) utmp * fs->data_align;
1024           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1025             = REG_SAVED_VAL_OFFSET;
1026           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
1027           break;
1028
1029         case DW_CFA_val_offset_sf:
1030           insn_ptr = read_uleb128 (insn_ptr, &reg);
1031           insn_ptr = read_sleb128 (insn_ptr, &stmp);
1032           offset = stmp * fs->data_align;
1033           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1034             = REG_SAVED_VAL_OFFSET;
1035           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
1036           break;
1037
1038         case DW_CFA_val_expression:
1039           insn_ptr = read_uleb128 (insn_ptr, &reg);
1040           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1041             = REG_SAVED_VAL_EXP;
1042           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
1043           insn_ptr = read_uleb128 (insn_ptr, &utmp);
1044           insn_ptr += utmp;
1045           break;
1046
1047         case DW_CFA_GNU_window_save:
1048           /* ??? Hardcoded for SPARC register window configuration.  */
1049           for (reg = 16; reg < 32; ++reg)
1050             {
1051               fs->regs.reg[reg].how = REG_SAVED_OFFSET;
1052               fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
1053             }
1054           break;
1055
1056         case DW_CFA_GNU_args_size:
1057           insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
1058           break;
1059
1060         case DW_CFA_GNU_negative_offset_extended:
1061           /* Obsoleted by DW_CFA_offset_extended_sf, but used by
1062              older PowerPC code.  */
1063           insn_ptr = read_uleb128 (insn_ptr, &reg);
1064           insn_ptr = read_uleb128 (insn_ptr, &utmp);
1065           offset = (_Unwind_Word) utmp * fs->data_align;
1066           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
1067             = REG_SAVED_OFFSET;
1068           fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = -offset;
1069           break;
1070
1071         default:
1072           gcc_unreachable ();
1073         }
1074     }
1075 }
1076 \f
1077 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
1078    its caller and decode it into FS.  This function also sets the
1079    args_size and lsda members of CONTEXT, as they are really information
1080    about the caller's frame.  */
1081
1082 static _Unwind_Reason_Code
1083 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1084 {
1085   const struct dwarf_fde *fde;
1086   const struct dwarf_cie *cie;
1087   const unsigned char *aug, *insn, *end;
1088
1089   memset (fs, 0, sizeof (*fs));
1090   context->args_size = 0;
1091   context->lsda = 0;
1092
1093   if (context->ra == 0)
1094     return _URC_END_OF_STACK;
1095
1096   fde = _Unwind_Find_FDE (context->ra + _Unwind_IsSignalFrame (context) - 1,
1097                           &context->bases);
1098   if (fde == NULL)
1099     {
1100 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1101       /* Couldn't find frame unwind info for this function.  Try a
1102          target-specific fallback mechanism.  This will necessarily
1103          not provide a personality routine or LSDA.  */
1104       return MD_FALLBACK_FRAME_STATE_FOR (context, fs);
1105 #else
1106       return _URC_END_OF_STACK;
1107 #endif
1108     }
1109
1110   fs->pc = context->bases.func;
1111
1112   cie = get_cie (fde);
1113   insn = extract_cie_info (cie, context, fs);
1114   if (insn == NULL)
1115     /* CIE contained unknown augmentation.  */
1116     return _URC_FATAL_PHASE1_ERROR;
1117
1118   /* First decode all the insns in the CIE.  */
1119   end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
1120   execute_cfa_program (insn, end, context, fs);
1121
1122   /* Locate augmentation for the fde.  */
1123   aug = (unsigned char *) fde + sizeof (*fde);
1124   aug += 2 * size_of_encoded_value (fs->fde_encoding);
1125   insn = NULL;
1126   if (fs->saw_z)
1127     {
1128       _Unwind_Word i;
1129       aug = read_uleb128 (aug, &i);
1130       insn = aug + i;
1131     }
1132   if (fs->lsda_encoding != DW_EH_PE_omit)
1133     {
1134       _Unwind_Ptr lsda;
1135       
1136       aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
1137       context->lsda = (void *) lsda;
1138     }
1139
1140   /* Then the insns in the FDE up to our target PC.  */
1141   if (insn == NULL)
1142     insn = aug;
1143   end = (unsigned char *) next_fde (fde);
1144   execute_cfa_program (insn, end, context, fs);
1145
1146   return _URC_NO_REASON;
1147 }
1148 \f
1149 typedef struct frame_state
1150 {
1151   void *cfa;
1152   void *eh_ptr;
1153   long cfa_offset;
1154   long args_size;
1155   long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1156   unsigned short cfa_reg;
1157   unsigned short retaddr_column;
1158   char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1159 } frame_state;
1160
1161 struct frame_state * __frame_state_for (void *, struct frame_state *);
1162
1163 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1164    a given PC_TARGET.  The caller should allocate a local variable of
1165    `struct frame_state' and pass its address to STATE_IN.  */
1166
1167 struct frame_state *
1168 __frame_state_for (void *pc_target, struct frame_state *state_in)
1169 {
1170   struct _Unwind_Context context;
1171   _Unwind_FrameState fs;
1172   int reg;
1173
1174   memset (&context, 0, sizeof (struct _Unwind_Context));
1175   context.flags = EXTENDED_CONTEXT_BIT;
1176   context.ra = pc_target + 1;
1177
1178   if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
1179     return 0;
1180
1181   /* We have no way to pass a location expression for the CFA to our
1182      caller.  It wouldn't understand it anyway.  */
1183   if (fs.regs.cfa_how == CFA_EXP)
1184     return 0;
1185
1186   for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1187     {
1188       state_in->saved[reg] = fs.regs.reg[reg].how;
1189       switch (state_in->saved[reg])
1190         {
1191         case REG_SAVED_REG:
1192           state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1193           break;
1194         case REG_SAVED_OFFSET:
1195           state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1196           break;
1197         default:
1198           state_in->reg_or_offset[reg] = 0;
1199           break;
1200         }
1201     }
1202
1203   state_in->cfa_offset = fs.regs.cfa_offset;
1204   state_in->cfa_reg = fs.regs.cfa_reg;
1205   state_in->retaddr_column = fs.retaddr_column;
1206   state_in->args_size = context.args_size;
1207   state_in->eh_ptr = fs.eh_ptr;
1208
1209   return state_in;
1210 }
1211 \f
1212 typedef union { _Unwind_Ptr ptr; _Unwind_Word word; } _Unwind_SpTmp;
1213
1214 static inline void
1215 _Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
1216                      _Unwind_SpTmp *tmp_sp)
1217 {
1218   int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
1219   
1220   if (size == sizeof(_Unwind_Ptr))
1221     tmp_sp->ptr = (_Unwind_Ptr) cfa;
1222   else
1223     {
1224       gcc_assert (size == sizeof(_Unwind_Word));
1225       tmp_sp->word = (_Unwind_Ptr) cfa;
1226     }
1227   _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), tmp_sp);
1228 }
1229
1230 static void
1231 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1232 {
1233   struct _Unwind_Context orig_context = *context;
1234   void *cfa;
1235   long i;
1236
1237 #ifdef EH_RETURN_STACKADJ_RTX
1238   /* Special handling here: Many machines do not use a frame pointer,
1239      and track the CFA only through offsets from the stack pointer from
1240      one frame to the next.  In this case, the stack pointer is never
1241      stored, so it has no saved address in the context.  What we do
1242      have is the CFA from the previous stack frame.
1243
1244      In very special situations (such as unwind info for signal return),
1245      there may be location expressions that use the stack pointer as well.
1246
1247      Do this conditionally for one frame.  This allows the unwind info
1248      for one frame to save a copy of the stack pointer from the previous
1249      frame, and be able to use much easier CFA mechanisms to do it.
1250      Always zap the saved stack pointer value for the next frame; carrying
1251      the value over from one frame to another doesn't make sense.  */
1252
1253   _Unwind_SpTmp tmp_sp;
1254
1255   if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
1256     _Unwind_SetSpColumn (&orig_context, context->cfa, &tmp_sp);
1257   _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
1258 #endif
1259
1260   /* Compute this frame's CFA.  */
1261   switch (fs->regs.cfa_how)
1262     {
1263     case CFA_REG_OFFSET:
1264       cfa = _Unwind_GetPtr (&orig_context, fs->regs.cfa_reg);
1265       cfa += fs->regs.cfa_offset;
1266       break;
1267
1268     case CFA_EXP:
1269       {
1270         const unsigned char *exp = fs->regs.cfa_exp;
1271         _Unwind_Word len;
1272
1273         exp = read_uleb128 (exp, &len);
1274         cfa = (void *) (_Unwind_Ptr)
1275           execute_stack_op (exp, exp + len, &orig_context, 0);
1276         break;
1277       }
1278
1279     default:
1280       gcc_unreachable ();
1281     }
1282   context->cfa = cfa;
1283
1284   /* Compute the addresses of all registers saved in this frame.  */
1285   for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1286     switch (fs->regs.reg[i].how)
1287       {
1288       case REG_UNSAVED:
1289         break;
1290
1291       case REG_SAVED_OFFSET:
1292         _Unwind_SetGRPtr (context, i,
1293                           (void *) (cfa + fs->regs.reg[i].loc.offset));
1294         break;
1295
1296       case REG_SAVED_REG:
1297         if (_Unwind_GRByValue (&orig_context, fs->regs.reg[i].loc.reg))
1298           _Unwind_SetGRValue (context, i,
1299                               _Unwind_GetGR (&orig_context,
1300                                              fs->regs.reg[i].loc.reg));
1301         else
1302           _Unwind_SetGRPtr (context, i,
1303                             _Unwind_GetGRPtr (&orig_context,
1304                                               fs->regs.reg[i].loc.reg));
1305         break;
1306
1307       case REG_SAVED_EXP:
1308         {
1309           const unsigned char *exp = fs->regs.reg[i].loc.exp;
1310           _Unwind_Word len;
1311           _Unwind_Ptr val;
1312
1313           exp = read_uleb128 (exp, &len);
1314           val = execute_stack_op (exp, exp + len, &orig_context,
1315                                   (_Unwind_Ptr) cfa);
1316           _Unwind_SetGRPtr (context, i, (void *) val);
1317         }
1318         break;
1319
1320       case REG_SAVED_VAL_OFFSET:
1321         _Unwind_SetGRValue (context, i,
1322                             (_Unwind_Internal_Ptr)
1323                             (cfa + fs->regs.reg[i].loc.offset));
1324         break;
1325
1326       case REG_SAVED_VAL_EXP:
1327         {
1328           const unsigned char *exp = fs->regs.reg[i].loc.exp;
1329           _Unwind_Word len;
1330           _Unwind_Ptr val;
1331
1332           exp = read_uleb128 (exp, &len);
1333           val = execute_stack_op (exp, exp + len, &orig_context,
1334                                   (_Unwind_Ptr) cfa);
1335           _Unwind_SetGRValue (context, i, val);
1336         }
1337         break;
1338       }
1339
1340   _Unwind_SetSignalFrame (context, fs->signal_frame);
1341
1342 #ifdef MD_FROB_UPDATE_CONTEXT
1343   MD_FROB_UPDATE_CONTEXT (context, fs);
1344 #endif
1345 }
1346
1347 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1348    of its caller.  Update CONTEXT to refer to the caller as well.  Note
1349    that the args_size and lsda members are not updated here, but later in
1350    uw_frame_state_for.  */
1351
1352 static void
1353 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1354 {
1355   uw_update_context_1 (context, fs);
1356
1357   /* Compute the return address now, since the return address column
1358      can change from frame to frame.  */
1359   context->ra = __builtin_extract_return_addr
1360     (_Unwind_GetPtr (context, fs->retaddr_column));
1361 }
1362
1363 static void
1364 uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1365 {
1366   uw_update_context (context, fs);
1367 }
1368 \f
1369 /* Fill in CONTEXT for top-of-stack.  The only valid registers at this
1370    level will be the return address and the CFA.  */
1371
1372 #define uw_init_context(CONTEXT)                                           \
1373   do                                                                       \
1374     {                                                                      \
1375       /* Do any necessary initialization to access arbitrary stack frames. \
1376          On the SPARC, this means flushing the register windows.  */       \
1377       __builtin_unwind_init ();                                            \
1378       uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (),                  \
1379                          __builtin_return_address (0));                    \
1380     }                                                                      \
1381   while (0)
1382
1383 static inline void
1384 init_dwarf_reg_size_table (void)
1385 {
1386   __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1387 }
1388
1389 static void
1390 uw_init_context_1 (struct _Unwind_Context *context,
1391                    void *outer_cfa, void *outer_ra)
1392 {
1393   void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1394   _Unwind_FrameState fs;
1395   _Unwind_SpTmp sp_slot;
1396   _Unwind_Reason_Code code;
1397
1398   memset (context, 0, sizeof (struct _Unwind_Context));
1399   context->ra = ra;
1400   context->flags = EXTENDED_CONTEXT_BIT;
1401
1402   code = uw_frame_state_for (context, &fs);
1403   gcc_assert (code == _URC_NO_REASON);
1404
1405 #if __GTHREADS
1406   {
1407     static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1408     if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1409         && dwarf_reg_size_table[0] == 0)
1410       init_dwarf_reg_size_table ();
1411   }
1412 #else
1413   if (dwarf_reg_size_table[0] == 0)
1414     init_dwarf_reg_size_table ();
1415 #endif
1416
1417   /* Force the frame state to use the known cfa value.  */
1418   _Unwind_SetSpColumn (context, outer_cfa, &sp_slot);
1419   fs.regs.cfa_how = CFA_REG_OFFSET;
1420   fs.regs.cfa_reg = __builtin_dwarf_sp_column ();
1421   fs.regs.cfa_offset = 0;
1422
1423   uw_update_context_1 (context, &fs);
1424
1425   /* If the return address column was saved in a register in the
1426      initialization context, then we can't see it in the given
1427      call frame data.  So have the initialization context tell us.  */
1428   context->ra = __builtin_extract_return_addr (outer_ra);
1429 }
1430
1431
1432 /* Install TARGET into CURRENT so that we can return to it.  This is a
1433    macro because __builtin_eh_return must be invoked in the context of
1434    our caller.  */
1435
1436 #define uw_install_context(CURRENT, TARGET)                              \
1437   do                                                                     \
1438     {                                                                    \
1439       long offset = uw_install_context_1 ((CURRENT), (TARGET));          \
1440       void *handler = __builtin_frob_return_addr ((TARGET)->ra);         \
1441       __builtin_eh_return (offset, handler);                             \
1442     }                                                                    \
1443   while (0)
1444
1445 static long
1446 uw_install_context_1 (struct _Unwind_Context *current,
1447                       struct _Unwind_Context *target)
1448 {
1449   long i;
1450   _Unwind_SpTmp sp_slot;
1451
1452   /* If the target frame does not have a saved stack pointer,
1453      then set up the target's CFA.  */
1454   if (!_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
1455     _Unwind_SetSpColumn (target, target->cfa, &sp_slot);
1456
1457   for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1458     {
1459       void *c = current->reg[i];
1460       void *t = target->reg[i];
1461
1462       gcc_assert (current->by_value[i] == 0);
1463       if (target->by_value[i] && c)
1464         {
1465           _Unwind_Word w;
1466           _Unwind_Ptr p;
1467           if (dwarf_reg_size_table[i] == sizeof (_Unwind_Word))
1468             {
1469               w = (_Unwind_Internal_Ptr) t;
1470               memcpy (c, &w, sizeof (_Unwind_Word));
1471             }
1472           else
1473             {
1474               gcc_assert (dwarf_reg_size_table[i] == sizeof (_Unwind_Ptr));
1475               p = (_Unwind_Internal_Ptr) t;
1476               memcpy (c, &p, sizeof (_Unwind_Ptr));
1477             }
1478         }
1479       else if (t && c && t != c)
1480         memcpy (c, t, dwarf_reg_size_table[i]);
1481     }
1482
1483   /* If the current frame doesn't have a saved stack pointer, then we
1484      need to rely on EH_RETURN_STACKADJ_RTX to get our target stack
1485      pointer value reloaded.  */
1486   if (!_Unwind_GetGRPtr (current, __builtin_dwarf_sp_column ()))
1487     {
1488       void *target_cfa;
1489
1490       target_cfa = _Unwind_GetPtr (target, __builtin_dwarf_sp_column ());
1491
1492       /* We adjust SP by the difference between CURRENT and TARGET's CFA.  */
1493       if (STACK_GROWS_DOWNWARD)
1494         return target_cfa - current->cfa + target->args_size;
1495       else
1496         return current->cfa - target_cfa - target->args_size;
1497     }
1498   return 0;
1499 }
1500
1501 static inline _Unwind_Ptr
1502 uw_identify_context (struct _Unwind_Context *context)
1503 {
1504   return _Unwind_GetIP (context);
1505 }
1506
1507
1508 #include "unwind.inc"
1509
1510 #if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
1511 alias (_Unwind_Backtrace);
1512 alias (_Unwind_DeleteException);
1513 alias (_Unwind_FindEnclosingFunction);
1514 alias (_Unwind_ForcedUnwind);
1515 alias (_Unwind_GetDataRelBase);
1516 alias (_Unwind_GetTextRelBase);
1517 alias (_Unwind_GetCFA);
1518 alias (_Unwind_GetGR);
1519 alias (_Unwind_GetIP);
1520 alias (_Unwind_GetLanguageSpecificData);
1521 alias (_Unwind_GetRegionStart);
1522 alias (_Unwind_RaiseException);
1523 alias (_Unwind_Resume);
1524 alias (_Unwind_Resume_or_Rethrow);
1525 alias (_Unwind_SetGR);
1526 alias (_Unwind_SetIP);
1527 #endif
1528
1529 #endif /* !USING_SJLJ_EXCEPTIONS */