OSDN Git Service

* config/stormy16/stormy16.h: Remove DEFAULT_VTABLE_THUNKS.
[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 Free Software Foundation, Inc.
3
4    This file is part of GCC.
5
6    GCC is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10
11    GCC is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14    License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GCC; see the file COPYING.  If not, write to the Free
18    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19    02111-1307, USA.  */
20
21 #include "tconfig.h"
22 #include "tsystem.h"
23 #include "dwarf2.h"
24 #include "unwind.h"
25 #include "unwind-pe.h"
26 #include "unwind-dw2-fde.h"
27 #include "gthr.h"
28
29
30 #if !USING_SJLJ_EXCEPTIONS
31
32 #ifndef STACK_GROWS_DOWNWARD
33 #define STACK_GROWS_DOWNWARD 0
34 #else
35 #undef STACK_GROWS_DOWNWARD
36 #define STACK_GROWS_DOWNWARD 1
37 #endif
38
39 /* A target can override (perhaps for backward compatibility) how
40    many dwarf2 columns are unwound.  */
41 #ifndef DWARF_FRAME_REGISTERS
42 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
43 #endif
44
45 /* This is the register and unwind state for a particular frame.  */
46 struct _Unwind_Context
47 {
48   void *reg[DWARF_FRAME_REGISTERS+1];
49   void *cfa;
50   void *ra;
51   void *lsda;
52   struct dwarf_eh_bases bases;
53   _Unwind_Word args_size;
54 };
55
56 /* Byte size of every register managed by these routines.  */
57 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
58
59 \f
60 /* The result of interpreting the frame unwind info for a frame.
61    This is all symbolic at this point, as none of the values can
62    be resolved until the target pc is located.  */
63 typedef struct
64 {
65   /* Each register save state can be described in terms of a CFA slot,
66      another register, or a location expression.  */
67   struct frame_state_reg_info
68   {
69     struct {
70       union {
71         _Unwind_Word reg;
72         _Unwind_Sword offset;
73         const unsigned char *exp;
74       } loc;
75       enum {
76         REG_UNSAVED,
77         REG_SAVED_OFFSET,
78         REG_SAVED_REG,
79         REG_SAVED_EXP,
80       } how;
81     } reg[DWARF_FRAME_REGISTERS+1];
82
83     /* Used to implement DW_CFA_remember_state.  */
84     struct frame_state_reg_info *prev;
85   } regs;
86
87   /* The CFA can be described in terms of a reg+offset or a
88      location expression.  */
89   _Unwind_Sword cfa_offset;
90   _Unwind_Word cfa_reg;
91   const unsigned char *cfa_exp;
92   enum {
93     CFA_UNSET,
94     CFA_REG_OFFSET,
95     CFA_EXP,
96   } cfa_how;
97
98   /* The PC described by the current frame state.  */
99   void *pc;
100
101   /* The information we care about from the CIE/FDE.  */
102   _Unwind_Personality_Fn personality;
103   _Unwind_Sword data_align;
104   _Unwind_Word code_align;
105   unsigned char retaddr_column;
106   unsigned char fde_encoding;
107   unsigned char lsda_encoding;
108   unsigned char saw_z;
109   void *eh_ptr;
110 } _Unwind_FrameState;
111 \f
112 /* Read unaligned data from the instruction buffer.  */
113
114 union unaligned
115 {
116   void *p;
117   unsigned u2 __attribute__ ((mode (HI)));
118   unsigned u4 __attribute__ ((mode (SI)));
119   unsigned u8 __attribute__ ((mode (DI)));
120   signed s2 __attribute__ ((mode (HI)));
121   signed s4 __attribute__ ((mode (SI)));
122   signed s8 __attribute__ ((mode (DI)));
123 } __attribute__ ((packed));
124
125 static inline void *
126 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
127
128 static inline int
129 read_1u (const void *p) { return *(const unsigned char *)p; }
130
131 static inline int
132 read_1s (const void *p) { return *(const signed char *)p; }
133
134 static inline int
135 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
136
137 static inline int
138 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
139
140 static inline unsigned int
141 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
142
143 static inline int
144 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
145
146 static inline unsigned long
147 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
148
149 static inline unsigned long
150 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
151 \f
152 /* Get the value of register REG as saved in CONTEXT.  */
153
154 inline _Unwind_Word
155 _Unwind_GetGR (struct _Unwind_Context *context, int index)
156 {
157   /* This will segfault if the register hasn't been saved.  */
158   return * (_Unwind_Word *) context->reg[index];
159 }
160
161 /* Overwrite the saved value for register REG in CONTEXT with VAL.  */
162
163 inline void
164 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
165 {
166   * (_Unwind_Word *) context->reg[index] = val;
167 }
168
169 /* Retrieve the return address for CONTEXT.  */
170
171 inline _Unwind_Ptr
172 _Unwind_GetIP (struct _Unwind_Context *context)
173 {
174   return (_Unwind_Ptr) context->ra;
175 }
176
177 /* Overwrite the return address for CONTEXT with VAL.  */
178
179 inline void
180 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
181 {
182   context->ra = (void *) val;
183 }
184
185 void *
186 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
187 {
188   return context->lsda;
189 }
190
191 _Unwind_Ptr
192 _Unwind_GetRegionStart (struct _Unwind_Context *context)
193 {
194   return (_Unwind_Ptr) context->bases.func;
195 }
196
197 #ifndef __ia64__
198 _Unwind_Ptr
199 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
200 {
201   return (_Unwind_Ptr) context->bases.dbase;
202 }
203
204 _Unwind_Ptr
205 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
206 {
207   return (_Unwind_Ptr) context->bases.tbase;
208 }
209 #endif
210 \f
211 /* Extract any interesting information from the CIE for the translation
212    unit F belongs to.  Return a pointer to the byte after the augmentation,
213    or NULL if we encountered an undecipherable augmentation.  */
214
215 static const unsigned char *
216 extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
217                   _Unwind_FrameState *fs)
218 {
219   const unsigned char *aug = cie->augmentation;
220   const unsigned char *p = aug + strlen (aug) + 1;
221   const unsigned char *ret = NULL;
222   _Unwind_Word utmp;
223
224   /* g++ v2 "eh" has pointer immediately following augmentation string,
225      so it must be handled first.  */
226   if (aug[0] == 'e' && aug[1] == 'h')
227     {
228       fs->eh_ptr = read_pointer (p);
229       p += sizeof (void *);
230       aug += 2;
231     }
232
233   /* Immediately following the augmentation are the code and
234      data alignment and return address column.  */
235   p = read_uleb128 (p, &fs->code_align);
236   p = read_sleb128 (p, &fs->data_align);
237   fs->retaddr_column = *p++;
238   fs->lsda_encoding = DW_EH_PE_omit;
239
240   /* If the augmentation starts with 'z', then a uleb128 immediately
241      follows containing the length of the augmentation field following
242      the size.  */
243   if (*aug == 'z')
244     {
245       p = read_uleb128 (p, &utmp);
246       ret = p + utmp;
247
248       fs->saw_z = 1;
249       ++aug;
250     }
251
252   /* Iterate over recognized augmentation subsequences.  */
253   while (*aug != '\0')
254     {
255       /* "L" indicates a byte showing how the LSDA pointer is encoded.  */
256       if (aug[0] == 'L')
257         {
258           fs->lsda_encoding = *p++;
259           aug += 1;
260         }
261
262       /* "R" indicates a byte indicating how FDE addresses are encoded.  */
263       else if (aug[0] == 'R')
264         {
265           fs->fde_encoding = *p++;
266           aug += 1;
267         }
268
269       /* "P" indicates a personality routine in the CIE augmentation.  */
270       else if (aug[0] == 'P')
271         {
272           p = read_encoded_value (context, *p, p + 1,
273                                   (_Unwind_Ptr *) &fs->personality);
274           aug += 1;
275         }
276
277       /* Otherwise we have an unknown augmentation string.
278          Bail unless we saw a 'z' prefix.  */
279       else
280         return ret;
281     }
282
283   return ret ? ret : p;
284 }
285
286
287 /* Decode a DW_OP stack program.  Return the top of stack.  Push INITIAL
288    onto the stack to start.  */
289
290 static _Unwind_Word
291 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
292                   struct _Unwind_Context *context, _Unwind_Word initial)
293 {
294   _Unwind_Word stack[64];       /* ??? Assume this is enough.  */
295   int stack_elt;
296
297   stack[0] = initial;
298   stack_elt = 1;
299
300   while (op_ptr < op_end)
301     {
302       enum dwarf_location_atom op = *op_ptr++;
303       _Unwind_Word result, reg, utmp;
304       _Unwind_Sword offset, stmp;
305
306       switch (op)
307         {
308         case DW_OP_lit0:
309         case DW_OP_lit1:
310         case DW_OP_lit2:
311         case DW_OP_lit3:
312         case DW_OP_lit4:
313         case DW_OP_lit5:
314         case DW_OP_lit6:
315         case DW_OP_lit7:
316         case DW_OP_lit8:
317         case DW_OP_lit9:
318         case DW_OP_lit10:
319         case DW_OP_lit11:
320         case DW_OP_lit12:
321         case DW_OP_lit13:
322         case DW_OP_lit14:
323         case DW_OP_lit15:
324         case DW_OP_lit16:
325         case DW_OP_lit17:
326         case DW_OP_lit18:
327         case DW_OP_lit19:
328         case DW_OP_lit20:
329         case DW_OP_lit21:
330         case DW_OP_lit22:
331         case DW_OP_lit23:
332         case DW_OP_lit24:
333         case DW_OP_lit25:
334         case DW_OP_lit26:
335         case DW_OP_lit27:
336         case DW_OP_lit28:
337         case DW_OP_lit29:
338         case DW_OP_lit30:
339         case DW_OP_lit31:
340           result = op - DW_OP_lit0;
341           break;
342
343         case DW_OP_addr:
344           result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
345           op_ptr += sizeof (void *);
346           break;
347
348         case DW_OP_const1u:
349           result = read_1u (op_ptr);
350           op_ptr += 1;
351           break;
352         case DW_OP_const1s:
353           result = read_1s (op_ptr);
354           op_ptr += 1;
355           break;
356         case DW_OP_const2u:
357           result = read_2u (op_ptr);
358           op_ptr += 2;
359           break;
360         case DW_OP_const2s:
361           result = read_2s (op_ptr);
362           op_ptr += 2;
363           break;
364         case DW_OP_const4u:
365           result = read_4u (op_ptr);
366           op_ptr += 4;
367           break;
368         case DW_OP_const4s:
369           result = read_4s (op_ptr);
370           op_ptr += 4;
371           break;
372         case DW_OP_const8u:
373           result = read_8u (op_ptr);
374           op_ptr += 8;
375           break;
376         case DW_OP_const8s:
377           result = read_8s (op_ptr);
378           op_ptr += 8;
379           break;
380         case DW_OP_constu:
381           op_ptr = read_uleb128 (op_ptr, &result);
382           break;
383         case DW_OP_consts:
384           op_ptr = read_sleb128 (op_ptr, &stmp);
385           result = stmp;
386           break;
387
388         case DW_OP_reg0:
389         case DW_OP_reg1:
390         case DW_OP_reg2:
391         case DW_OP_reg3:
392         case DW_OP_reg4:
393         case DW_OP_reg5:
394         case DW_OP_reg6:
395         case DW_OP_reg7:
396         case DW_OP_reg8:
397         case DW_OP_reg9:
398         case DW_OP_reg10:
399         case DW_OP_reg11:
400         case DW_OP_reg12:
401         case DW_OP_reg13:
402         case DW_OP_reg14:
403         case DW_OP_reg15:
404         case DW_OP_reg16:
405         case DW_OP_reg17:
406         case DW_OP_reg18:
407         case DW_OP_reg19:
408         case DW_OP_reg20:
409         case DW_OP_reg21:
410         case DW_OP_reg22:
411         case DW_OP_reg23:
412         case DW_OP_reg24:
413         case DW_OP_reg25:
414         case DW_OP_reg26:
415         case DW_OP_reg27:
416         case DW_OP_reg28:
417         case DW_OP_reg29:
418         case DW_OP_reg30:
419         case DW_OP_reg31:
420           result = _Unwind_GetGR (context, op - DW_OP_reg0);
421           break;
422         case DW_OP_regx:
423           op_ptr = read_uleb128 (op_ptr, &reg);
424           result = _Unwind_GetGR (context, reg);
425           break;
426
427         case DW_OP_breg0:
428         case DW_OP_breg1:
429         case DW_OP_breg2:
430         case DW_OP_breg3:
431         case DW_OP_breg4:
432         case DW_OP_breg5:
433         case DW_OP_breg6:
434         case DW_OP_breg7:
435         case DW_OP_breg8:
436         case DW_OP_breg9:
437         case DW_OP_breg10:
438         case DW_OP_breg11:
439         case DW_OP_breg12:
440         case DW_OP_breg13:
441         case DW_OP_breg14:
442         case DW_OP_breg15:
443         case DW_OP_breg16:
444         case DW_OP_breg17:
445         case DW_OP_breg18:
446         case DW_OP_breg19:
447         case DW_OP_breg20:
448         case DW_OP_breg21:
449         case DW_OP_breg22:
450         case DW_OP_breg23:
451         case DW_OP_breg24:
452         case DW_OP_breg25:
453         case DW_OP_breg26:
454         case DW_OP_breg27:
455         case DW_OP_breg28:
456         case DW_OP_breg29:
457         case DW_OP_breg30:
458         case DW_OP_breg31:
459           op_ptr = read_sleb128 (op_ptr, &offset);
460           result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
461           break;
462         case DW_OP_bregx:
463           op_ptr = read_uleb128 (op_ptr, &reg);
464           op_ptr = read_sleb128 (op_ptr, &offset);
465           result = _Unwind_GetGR (context, reg) + offset;
466           break;
467
468         case DW_OP_dup:
469           if (stack_elt < 1)
470             abort ();
471           result = stack[stack_elt - 1];
472           break;
473
474         case DW_OP_drop:
475           if (--stack_elt < 0)
476             abort ();
477           goto no_push;
478
479         case DW_OP_pick:
480           offset = *op_ptr++;
481           if (offset >= stack_elt - 1)
482             abort ();
483           result = stack[stack_elt - 1 - offset];
484           break;
485
486         case DW_OP_over:
487           if (stack_elt < 2)
488             abort ();
489           result = stack[stack_elt - 2];
490           break;
491
492         case DW_OP_rot:
493           {
494             _Unwind_Word t1, t2, t3;
495
496             if (stack_elt < 3)
497               abort ();
498             t1 = stack[stack_elt - 1];
499             t2 = stack[stack_elt - 2];
500             t3 = stack[stack_elt - 3];
501             stack[stack_elt - 1] = t2;
502             stack[stack_elt - 2] = t3;
503             stack[stack_elt - 3] = t1;
504             goto no_push;
505           }
506
507         case DW_OP_deref:
508         case DW_OP_deref_size:
509         case DW_OP_abs:
510         case DW_OP_neg:
511         case DW_OP_not:
512         case DW_OP_plus_uconst:
513           /* Unary operations.  */
514           if (--stack_elt < 0)
515             abort ();
516           result = stack[stack_elt];
517
518           switch (op)
519             {
520             case DW_OP_deref:
521               {
522                 void *ptr = (void *)(_Unwind_Ptr) result;
523                 result = (_Unwind_Ptr) read_pointer (ptr);
524               }
525               break;
526
527             case DW_OP_deref_size:
528               {
529                 void *ptr = (void *)(_Unwind_Ptr) result;
530                 switch (*op_ptr++)
531                   {
532                   case 1:
533                     result = read_1u (ptr);
534                     break;
535                   case 2:
536                     result = read_2u (ptr);
537                     break;
538                   case 4:
539                     result = read_4u (ptr);
540                     break;
541                   case 8:
542                     result = read_8u (ptr);
543                     break;
544                   default:
545                     abort ();
546                   }
547               }
548               break;
549
550             case DW_OP_abs:
551               if ((_Unwind_Sword) result < 0)
552                 result = -result;
553               break;
554             case DW_OP_neg:
555               result = -result;
556               break;
557             case DW_OP_not:
558               result = ~result;
559               break;
560             case DW_OP_plus_uconst:
561               op_ptr = read_uleb128 (op_ptr, &utmp);
562               result += utmp;
563               break;
564
565             default:
566               abort ();
567             }
568           break;
569
570         case DW_OP_and:
571         case DW_OP_div:
572         case DW_OP_minus:
573         case DW_OP_mod:
574         case DW_OP_mul:
575         case DW_OP_or:
576         case DW_OP_plus:
577         case DW_OP_le:
578         case DW_OP_ge:
579         case DW_OP_eq:
580         case DW_OP_lt:
581         case DW_OP_gt:
582         case DW_OP_ne:
583           {
584             /* Binary operations.  */
585             _Unwind_Word first, second;
586           if ((stack_elt -= 2) < 0)
587             abort ();
588           second = stack[stack_elt];
589           first = stack[stack_elt + 1];
590
591           switch (op)
592             {
593             case DW_OP_and:
594               result = second & first;
595               break;
596             case DW_OP_div:
597               result = (_Unwind_Sword)second / (_Unwind_Sword)first;
598               break;
599             case DW_OP_minus:
600               result = second - first;
601               break;
602             case DW_OP_mod:
603               result = (_Unwind_Sword)second % (_Unwind_Sword)first;
604               break;
605             case DW_OP_mul:
606               result = second * first;
607               break;
608             case DW_OP_or:
609               result = second | first;
610               break;
611             case DW_OP_plus:
612               result = second + first;
613               break;
614             case DW_OP_shl:
615               result = second << first;
616               break;
617             case DW_OP_shr:
618               result = second >> first;
619               break;
620             case DW_OP_shra:
621               result = (_Unwind_Sword)second >> first;
622               break;
623             case DW_OP_xor:
624               result = second ^ first;
625               break;
626             case DW_OP_le:
627               result = (_Unwind_Sword)first <= (_Unwind_Sword)second;
628               break;
629             case DW_OP_ge:
630               result = (_Unwind_Sword)first >= (_Unwind_Sword)second;
631               break;
632             case DW_OP_eq:
633               result = (_Unwind_Sword)first == (_Unwind_Sword)second;
634               break;
635             case DW_OP_lt:
636               result = (_Unwind_Sword)first < (_Unwind_Sword)second;
637               break;
638             case DW_OP_gt:
639               result = (_Unwind_Sword)first > (_Unwind_Sword)second;
640               break;
641             case DW_OP_ne:
642               result = (_Unwind_Sword)first != (_Unwind_Sword)second;
643               break;
644
645             default:
646               abort ();
647             }
648           }
649           break;
650
651         case DW_OP_skip:
652           offset = read_2s (op_ptr);
653           op_ptr += 2;
654           op_ptr += offset;
655           goto no_push;
656
657         case DW_OP_bra:
658           if (--stack_elt < 0)
659             abort ();
660           offset = read_2s (op_ptr);
661           op_ptr += 2;
662           if (stack[stack_elt] != 0)
663             op_ptr += offset;
664           goto no_push;
665
666         case DW_OP_nop:
667           goto no_push;
668
669         default:
670           abort ();
671         }
672
673       /* Most things push a result value.  */
674       if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
675         abort ();
676       stack[++stack_elt] = result;
677     no_push:;
678     }
679
680   /* We were executing this program to get a value.  It should be
681      at top of stack.  */
682   if (--stack_elt < 0)
683     abort ();
684   return stack[stack_elt];
685 }
686
687
688 /* Decode DWARF 2 call frame information. Takes pointers the
689    instruction sequence to decode, current register information and
690    CIE info, and the PC range to evaluate.  */
691
692 static void
693 execute_cfa_program (const unsigned char *insn_ptr,
694                      const unsigned char *insn_end,
695                      struct _Unwind_Context *context,
696                      _Unwind_FrameState *fs)
697 {
698   struct frame_state_reg_info *unused_rs = NULL;
699
700   /* Don't allow remember/restore between CIE and FDE programs.  */
701   fs->regs.prev = NULL;
702
703   while (insn_ptr < insn_end && fs->pc <= context->ra)
704     {
705       unsigned char insn = *insn_ptr++;
706       _Unwind_Word reg, utmp;
707       _Unwind_Sword offset, stmp;
708
709       if (insn & DW_CFA_advance_loc)
710         fs->pc += (insn & 0x3f) * fs->code_align;
711       else if (insn & DW_CFA_offset)
712         {
713           reg = insn & 0x3f;
714           insn_ptr = read_uleb128 (insn_ptr, &utmp);
715           offset = (_Unwind_Sword)utmp * fs->data_align;
716           fs->regs.reg[reg].how = REG_SAVED_OFFSET;
717           fs->regs.reg[reg].loc.offset = offset;
718         }
719       else if (insn & DW_CFA_restore)
720         {
721           reg = insn & 0x3f;
722           fs->regs.reg[reg].how = REG_UNSAVED;
723         }
724       else switch (insn)
725         {
726         case DW_CFA_set_loc:
727           insn_ptr = read_encoded_value (context, fs->fde_encoding,
728                                          insn_ptr, (_Unwind_Ptr *) &fs->pc);
729           break;
730
731         case DW_CFA_advance_loc1:
732           fs->pc += read_1u (insn_ptr) * fs->code_align;
733           insn_ptr += 1;
734           break;
735         case DW_CFA_advance_loc2:
736           fs->pc += read_2u (insn_ptr) * fs->code_align;
737           insn_ptr += 2;
738           break;
739         case DW_CFA_advance_loc4:
740           fs->pc += read_4u (insn_ptr) * fs->code_align;
741           insn_ptr += 4;
742           break;
743
744         case DW_CFA_offset_extended:
745           insn_ptr = read_uleb128 (insn_ptr, &reg);
746           insn_ptr = read_uleb128 (insn_ptr, &utmp);
747           offset = (_Unwind_Sword)utmp * fs->data_align;
748           fs->regs.reg[reg].how = REG_SAVED_OFFSET;
749           fs->regs.reg[reg].loc.offset = offset;
750           break;
751
752         case DW_CFA_restore_extended:
753           insn_ptr = read_uleb128 (insn_ptr, &reg);
754           fs->regs.reg[reg].how = REG_UNSAVED;
755           break;
756
757         case DW_CFA_undefined:
758         case DW_CFA_same_value:
759         case DW_CFA_nop:
760           break;
761
762         case DW_CFA_register:
763           {
764             _Unwind_Word reg2;
765             insn_ptr = read_uleb128 (insn_ptr, &reg);
766             insn_ptr = read_uleb128 (insn_ptr, &reg2);
767             fs->regs.reg[reg].how = REG_SAVED_REG;
768             fs->regs.reg[reg].loc.reg = reg2;
769           }
770           break;
771       
772         case DW_CFA_remember_state:
773           {
774             struct frame_state_reg_info *new_rs;
775             if (unused_rs)
776               {
777                 new_rs = unused_rs;
778                 unused_rs = unused_rs->prev;
779               }
780             else
781               new_rs = __builtin_alloca (sizeof (struct frame_state_reg_info));
782
783             *new_rs = fs->regs;
784             fs->regs.prev = new_rs;
785           }
786           break;
787
788         case DW_CFA_restore_state:
789           {
790             struct frame_state_reg_info *old_rs = fs->regs.prev;
791             fs->regs = *old_rs;
792             old_rs->prev = unused_rs;
793             unused_rs = old_rs;
794           }
795           break;
796
797         case DW_CFA_def_cfa:
798           insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
799           insn_ptr = read_uleb128 (insn_ptr, &utmp);
800           fs->cfa_offset = utmp;
801           fs->cfa_how = CFA_REG_OFFSET;
802           break;
803
804         case DW_CFA_def_cfa_register:
805           insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
806           fs->cfa_how = CFA_REG_OFFSET;
807           break;
808
809         case DW_CFA_def_cfa_offset:
810           insn_ptr = read_uleb128 (insn_ptr, &utmp);
811           fs->cfa_offset = utmp;
812           /* cfa_how deliberately not set.  */
813           break;
814
815         case DW_CFA_def_cfa_expression:
816           insn_ptr = read_uleb128 (insn_ptr, &utmp);
817           fs->cfa_exp = insn_ptr;
818           fs->cfa_how = CFA_EXP;
819           insn_ptr += utmp;
820           break;
821
822         case DW_CFA_expression:
823           insn_ptr = read_uleb128 (insn_ptr, &reg);
824           insn_ptr = read_uleb128 (insn_ptr, &utmp);
825           fs->regs.reg[reg].how = REG_SAVED_EXP;
826           fs->regs.reg[reg].loc.exp = insn_ptr;
827           insn_ptr += utmp;
828           break;
829
830           /* From the 2.1 draft.  */
831         case DW_CFA_offset_extended_sf:
832           insn_ptr = read_uleb128 (insn_ptr, &reg);
833           insn_ptr = read_sleb128 (insn_ptr, &stmp);
834           offset = stmp * fs->data_align;
835           fs->regs.reg[reg].how = REG_SAVED_OFFSET;
836           fs->regs.reg[reg].loc.offset = offset;
837           break;
838           
839         case DW_CFA_def_cfa_sf:
840           insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
841           insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
842           fs->cfa_how = CFA_REG_OFFSET;
843           break;
844
845         case DW_CFA_def_cfa_offset_sf:
846           insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
847           /* cfa_how deliberately not set.  */
848           break;
849
850         case DW_CFA_GNU_window_save:
851           /* ??? Hardcoded for SPARC register window configuration.  */
852           for (reg = 16; reg < 32; ++reg)
853             {
854               fs->regs.reg[reg].how = REG_SAVED_OFFSET;
855               fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
856             }
857           break;
858
859         case DW_CFA_GNU_args_size:
860           insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
861           break;
862
863         case DW_CFA_GNU_negative_offset_extended:
864           /* Obsoleted by DW_CFA_offset_extended_sf, but used by
865              older PowerPC code.  */
866           insn_ptr = read_uleb128 (insn_ptr, &reg);
867           insn_ptr = read_uleb128 (insn_ptr, &utmp);
868           offset = (_Unwind_Word)utmp * fs->data_align;
869           fs->regs.reg[reg].how = REG_SAVED_OFFSET;
870           fs->regs.reg[reg].loc.offset = -offset;
871           break;
872
873         default:
874           abort ();
875         }
876     }
877 }
878 \f
879 static _Unwind_Reason_Code
880 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
881 {
882   struct dwarf_fde *fde;
883   struct dwarf_cie *cie;
884   const unsigned char *aug, *insn, *end;
885
886   memset (fs, 0, sizeof (*fs));
887   context->args_size = 0;
888   context->lsda = 0;
889
890   fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
891   if (fde == NULL)
892     {
893       /* Couldn't find frame unwind info for this function.  Try a
894          target-specific fallback mechanism.  This will necessarily
895          not provide a personality routine or LSDA.  */
896 #ifdef MD_FALLBACK_FRAME_STATE_FOR
897       MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
898       return _URC_END_OF_STACK;
899     success:
900       return _URC_NO_REASON;
901 #else
902       return _URC_END_OF_STACK;
903 #endif
904     }
905
906   fs->pc = context->bases.func;
907
908   cie = get_cie (fde);
909   insn = extract_cie_info (cie, context, fs);
910   if (insn == NULL)
911     /* CIE contained unknown augmentation.  */
912     return _URC_FATAL_PHASE1_ERROR;
913
914   /* First decode all the insns in the CIE.  */
915   end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
916   execute_cfa_program (insn, end, context, fs);
917
918   /* Locate augmentation for the fde.  */
919   aug = (unsigned char *)fde + sizeof (*fde);
920   aug += 2 * size_of_encoded_value (fs->fde_encoding);
921   insn = NULL;
922   if (fs->saw_z)
923     {
924       _Unwind_Word i;
925       aug = read_uleb128 (aug, &i);
926       insn = aug + i;
927     }
928   if (fs->lsda_encoding != DW_EH_PE_omit)
929     aug = read_encoded_value (context, fs->lsda_encoding, aug,
930                               (_Unwind_Ptr *) &context->lsda);
931
932   /* Then the insns in the FDE up to our target PC.  */
933   if (insn == NULL)
934     insn = aug;
935   end = (unsigned char *) next_fde (fde);
936   execute_cfa_program (insn, end, context, fs);
937
938   return _URC_NO_REASON;
939 }
940 \f
941 typedef struct frame_state
942 {
943   void *cfa;
944   void *eh_ptr;
945   long cfa_offset;
946   long args_size;
947   long reg_or_offset[DWARF_FRAME_REGISTERS+1];
948   unsigned short cfa_reg;
949   unsigned short retaddr_column;
950   char saved[DWARF_FRAME_REGISTERS+1];
951 } frame_state;
952
953 struct frame_state * __frame_state_for (void *, struct frame_state *);
954
955 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
956    a given PC_TARGET.  The caller should allocate a local variable of
957    `struct frame_state' and pass its address to STATE_IN.  */
958
959 struct frame_state *
960 __frame_state_for (void *pc_target, struct frame_state *state_in)
961 {
962   struct _Unwind_Context context;
963   _Unwind_FrameState fs;
964   int reg;
965
966   memset (&context, 0, sizeof (struct _Unwind_Context));
967   context.ra = pc_target + 1;
968
969   if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
970     return 0;
971
972   /* We have no way to pass a location expression for the CFA to our
973      caller.  It wouldn't understand it anyway.  */
974   if (fs.cfa_how == CFA_EXP)
975     return 0;
976
977   for (reg = 0; reg < DWARF_FRAME_REGISTERS + 1; reg++)
978     {
979       state_in->saved[reg] = fs.regs.reg[reg].how;
980       switch (state_in->saved[reg])
981         {
982         case REG_SAVED_REG:
983           state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
984           break;
985         case REG_SAVED_OFFSET:
986           state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
987           break;
988         default:
989           state_in->reg_or_offset[reg] = 0;
990           break;
991         }
992     }
993
994   state_in->cfa_offset = fs.cfa_offset;
995   state_in->cfa_reg = fs.cfa_reg;
996   state_in->retaddr_column = fs.retaddr_column;
997   state_in->args_size = context.args_size;
998   state_in->eh_ptr = fs.eh_ptr;
999
1000   return state_in;
1001 }
1002 \f
1003 static void
1004 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1005 {
1006   struct _Unwind_Context orig_context = *context;
1007   void *cfa;
1008   long i;
1009
1010   /* Compute this frame's CFA.  */
1011   switch (fs->cfa_how)
1012     {
1013     case CFA_REG_OFFSET:
1014       /* Special handling here: Many machines do not use a frame pointer,
1015          and track the CFA only through offsets from the stack pointer from
1016          one frame to the next.  In this case, the stack pointer is never
1017          stored, so it has no saved address in the context.  What we do 
1018          have is the CFA from the previous stack frame.  */
1019       if (context->reg[fs->cfa_reg] == NULL)
1020         cfa = context->cfa;
1021       else
1022         cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->cfa_reg);
1023       cfa += fs->cfa_offset;
1024       break;
1025
1026     case CFA_EXP:
1027       /* ??? No way of knowing what register number is the stack pointer
1028          to do the same sort of handling as above.  Assume that if the
1029          CFA calculation is so complicated as to require a stack program
1030          that this will not be a problem.  */
1031       {
1032         const unsigned char *exp = fs->cfa_exp;
1033         _Unwind_Word len;
1034
1035         exp = read_uleb128 (exp, &len);
1036         cfa = (void *) (_Unwind_Ptr)
1037           execute_stack_op (exp, exp + len, context, 0);
1038         break;
1039       }
1040
1041     default:
1042       abort ();
1043     }
1044   context->cfa = cfa;
1045
1046   /* Compute the addresses of all registers saved in this frame.  */
1047   for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1048     switch (fs->regs.reg[i].how)
1049       {
1050       case REG_UNSAVED:
1051         break;
1052       case REG_SAVED_OFFSET:
1053         context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
1054         break;
1055       case REG_SAVED_REG:
1056         context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
1057         break;
1058       case REG_SAVED_EXP:
1059         {
1060           const unsigned char *exp = fs->regs.reg[i].loc.exp;
1061           _Unwind_Word len;
1062           _Unwind_Ptr val;
1063
1064           exp = read_uleb128 (exp, &len);
1065           val = execute_stack_op (exp, exp + len, &orig_context,
1066                                   (_Unwind_Ptr) cfa);
1067           context->reg[i] = (void *) val;
1068         }
1069         break;
1070       }
1071 }
1072
1073 static void
1074 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1075 {
1076   uw_update_context_1 (context, fs);
1077
1078   /* Compute the return address now, since the return address column
1079      can change from frame to frame.  */
1080   context->ra = __builtin_extract_return_addr
1081     ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
1082 }
1083 \f
1084 /* Fill in CONTEXT for top-of-stack.  The only valid registers at this
1085    level will be the return address and the CFA.  */
1086    
1087 #define uw_init_context(CONTEXT)                                        \
1088 do {                                                                    \
1089   /* Do any necessary initialization to access arbitrary stack frames.  \
1090      On the SPARC, this means flushing the register windows.  */        \
1091   __builtin_unwind_init ();                                             \
1092   uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (),                   \
1093                      __builtin_return_address (0));                     \
1094 } while (0)
1095
1096 static void
1097 uw_init_context_1 (struct _Unwind_Context *context,
1098                    void *outer_cfa, void *outer_ra)
1099 {
1100   void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1101   _Unwind_FrameState fs;
1102
1103   memset (context, 0, sizeof (struct _Unwind_Context));
1104   context->ra = ra;
1105
1106   if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1107     abort ();
1108
1109   /* Force the frame state to use the known cfa value.  */
1110   context->cfa = outer_cfa;
1111   fs.cfa_how = CFA_REG_OFFSET;
1112   fs.cfa_reg = 0;
1113   fs.cfa_offset = 0;
1114
1115   uw_update_context_1 (context, &fs);
1116
1117   /* If the return address column was saved in a register in the
1118      initialization context, then we can't see it in the given
1119      call frame data.  So have the initialization context tell us.  */
1120   context->ra = __builtin_extract_return_addr (outer_ra);
1121 }
1122
1123
1124 /* Install TARGET into CURRENT so that we can return to it.  This is a
1125    macro because __builtin_eh_return must be invoked in the context of
1126    our caller.  */
1127
1128 #define uw_install_context(CURRENT, TARGET)                             \
1129 do {                                                                    \
1130   long offset = uw_install_context_1 ((CURRENT), (TARGET));             \
1131   void *handler = __builtin_frob_return_addr ((TARGET)->ra);            \
1132   __builtin_eh_return (offset, handler);                                \
1133 } while (0)
1134
1135 static inline void
1136 init_dwarf_reg_size_table (void)
1137 {
1138   __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1139 }
1140
1141 static long
1142 uw_install_context_1 (struct _Unwind_Context *current,
1143                       struct _Unwind_Context *target)
1144 {
1145   long i;
1146
1147 #if __GTHREADS
1148   {
1149     static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1150     if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1151         || dwarf_reg_size_table[0] == 0)
1152       init_dwarf_reg_size_table ();
1153   }
1154 #else
1155   if (dwarf_reg_size_table[0] == 0)
1156     init_dwarf_reg_size_table ();
1157 #endif
1158
1159   for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1160     {
1161       void *c = current->reg[i];
1162       void *t = target->reg[i];
1163       if (t && c && t != c)
1164         memcpy (c, t, dwarf_reg_size_table[i]);
1165     }
1166
1167   /* We adjust SP by the difference between CURRENT and TARGET's CFA.  */
1168   if (STACK_GROWS_DOWNWARD)
1169     return target->cfa - current->cfa + target->args_size;
1170   else
1171     return current->cfa - target->cfa - target->args_size;
1172 }
1173
1174 static inline _Unwind_Ptr
1175 uw_identify_context (struct _Unwind_Context *context)
1176 {
1177   return _Unwind_GetIP (context);
1178 }
1179
1180
1181 #include "unwind.inc"
1182
1183 #endif /* !USING_SJLJ_EXCEPTIONS */