OSDN Git Service

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