OSDN Git Service

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