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