OSDN Git Service

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