OSDN Git Service

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