OSDN Git Service

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