* gcc.dg/c99-float-1.c: XFAIL portions on Solaris.
[official-gcc.git] / gcc / unwind-dw2.c
blob6eb163d904b94513dbad685427aa317668c28e3b
1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4 This file is part of GNU CC.
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.
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.
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. */
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"
29 #if !USING_SJLJ_EXCEPTIONS
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
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
44 /* This is the register and unwind state for a particular frame. */
45 struct _Unwind_Context
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;
55 /* Byte size of every register managed by these routines. */
56 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
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
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
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];
82 /* Used to implement DW_CFA_remember_state. */
83 struct frame_state_reg_info *prev;
84 } regs;
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;
97 /* The PC described by the current frame state. */
98 void *pc;
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;
110 /* Decode the unsigned LEB128 constant at BUF into the variable pointed to
111 by R, and return the new value of BUF. */
113 static unsigned char *
114 read_uleb128 (unsigned char *buf, _Unwind_Word *r)
116 unsigned shift = 0;
117 _Unwind_Word result = 0;
119 while (1)
121 unsigned char byte = *buf++;
122 result |= (byte & 0x7f) << shift;
123 if ((byte & 0x80) == 0)
124 break;
125 shift += 7;
127 *r = result;
128 return buf;
131 /* Decode the signed LEB128 constant at BUF into the variable pointed to
132 by R, and return the new value of BUF. */
134 static unsigned char *
135 read_sleb128 (unsigned char *buf, _Unwind_Sword *r)
137 unsigned shift = 0;
138 _Unwind_Sword result = 0;
139 unsigned char byte;
141 while (1)
143 byte = *buf++;
144 result |= (byte & 0x7f) << shift;
145 shift += 7;
146 if ((byte & 0x80) == 0)
147 break;
149 if (shift < (sizeof (*r) * 8) && (byte & 0x40) != 0)
150 result |= - (1 << shift);
152 *r = result;
153 return buf;
156 /* Read unaligned data from the instruction buffer. */
158 union unaligned
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));
169 static inline void *
170 read_pointer (void *p) { union unaligned *up = p; return up->p; }
172 static inline int
173 read_1u (void *p) { return *(unsigned char *)p; }
175 static inline int
176 read_1s (void *p) { return *(signed char *)p; }
178 static inline int
179 read_2u (void *p) { union unaligned *up = p; return up->u2; }
181 static inline int
182 read_2s (void *p) { union unaligned *up = p; return up->s2; }
184 static inline unsigned int
185 read_4u (void *p) { union unaligned *up = p; return up->u4; }
187 static inline int
188 read_4s (void *p) { union unaligned *up = p; return up->s4; }
190 static inline unsigned long
191 read_8u (void *p) { union unaligned *up = p; return up->u8; }
193 static inline unsigned long
194 read_8s (void *p) { union unaligned *up = p; return up->s8; }
196 static unsigned char *
197 read_encoded_pointer (unsigned char *p, unsigned char encoding,
198 struct dwarf_eh_bases *bases, void **pptr)
200 signed long val;
201 unsigned char *ret;
203 switch (encoding & 0x0f)
205 case DW_EH_PE_absptr:
206 val = (_Unwind_Ptr) read_pointer (p);
207 ret = p + sizeof (void *);
208 break;
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;
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;
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;
243 default:
244 abort ();
247 if (val != 0)
248 switch (encoding & 0xf0)
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 ();
268 *pptr = (void *) (_Unwind_Ptr) val;
269 return ret;
272 /* Get the value of register REG as saved in CONTEXT. */
274 inline _Unwind_Word
275 _Unwind_GetGR (struct _Unwind_Context *context, int index)
277 /* This will segfault if the register hasn't been saved. */
278 return * (_Unwind_Word *) context->reg[index];
281 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
283 inline void
284 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
286 * (_Unwind_Word *) context->reg[index] = val;
289 /* Retrieve the return address for CONTEXT. */
291 inline _Unwind_Ptr
292 _Unwind_GetIP (struct _Unwind_Context *context)
294 return (_Unwind_Ptr) context->ra;
297 /* Overwrite the return address for CONTEXT with VAL. */
299 inline void
300 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
302 context->ra = (void *) val;
305 void *
306 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
308 return context->lsda;
311 _Unwind_Ptr
312 _Unwind_GetRegionStart (struct _Unwind_Context *context)
314 return (_Unwind_Ptr) context->bases.func;
317 #ifndef __ia64__
318 _Unwind_Ptr
319 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
321 return (_Unwind_Ptr) context->bases.dbase;
324 _Unwind_Ptr
325 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
327 return (_Unwind_Ptr) context->bases.tbase;
329 #endif
331 /* Extract any interesting information from the CIE for the translation
332 unit F belongs to. Return a pointer to the byte after the augmentation,
333 or NULL if we encountered an undecipherable augmentation. */
335 static unsigned char *
336 extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
337 _Unwind_FrameState *fs)
339 unsigned char *aug = cie->augmentation;
340 unsigned char *p = aug + strlen (aug) + 1;
341 unsigned char *ret = NULL;
342 _Unwind_Word code_align;
343 _Unwind_Sword data_align;
345 /* Immediately following the augmentation are the code and
346 data alignment and return address column. */
347 p = read_uleb128 (p, &code_align);
348 p = read_sleb128 (p, &data_align);
349 fs->code_align = code_align;
350 fs->data_align = data_align;
351 fs->retaddr_column = *p++;
353 /* If the augmentation starts with 'z', then a uleb128 immediately
354 follows containing the length of the augmentation field following
355 the size. */
356 if (*aug == 'z')
358 _Unwind_Word i;
359 p = read_uleb128 (p, &i);
360 ret = p + i;
362 fs->saw_z = 1;
363 ++aug;
366 /* Iterate over recognized augmentation subsequences. */
367 while (*aug != '\0')
369 /* "eh" was used by g++ v2; recognize and skip. */
370 if (aug[0] == 'e' && aug[1] == 'h')
372 p += sizeof (void *);
373 aug += 2;
376 /* "R" indicates a byte indicating how addresses are encoded. */
377 else if (aug[0] == 'R')
379 fs->addr_encoding = *p++;
380 aug += 1;
383 /* "P" indicates a personality routine in the CIE augmentation
384 and an lsda pointer in the FDE augmentation. */
385 else if (aug[0] == 'P')
387 p = read_encoded_pointer (p, fs->addr_encoding, &context->bases,
388 (void **) &fs->personality);
389 fs->saw_lsda = 1;
390 aug += 1;
393 /* Otherwise we have an unknown augmentation string.
394 Bail unless we saw a 'z' prefix. */
395 else
396 return ret;
399 return ret ? ret : p;
403 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
404 onto the stack to start. */
406 static _Unwind_Word
407 execute_stack_op (unsigned char *op_ptr, unsigned char *op_end,
408 struct _Unwind_Context *context, _Unwind_Word initial)
410 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
411 int stack_elt;
413 stack[0] = initial;
414 stack_elt = 1;
416 while (op_ptr < op_end)
418 enum dwarf_location_atom op = *op_ptr++;
419 _Unwind_Word result, reg;
420 _Unwind_Sword offset;
422 switch (op)
424 case DW_OP_lit0:
425 case DW_OP_lit1:
426 case DW_OP_lit2:
427 case DW_OP_lit3:
428 case DW_OP_lit4:
429 case DW_OP_lit5:
430 case DW_OP_lit6:
431 case DW_OP_lit7:
432 case DW_OP_lit8:
433 case DW_OP_lit9:
434 case DW_OP_lit10:
435 case DW_OP_lit11:
436 case DW_OP_lit12:
437 case DW_OP_lit13:
438 case DW_OP_lit14:
439 case DW_OP_lit15:
440 case DW_OP_lit16:
441 case DW_OP_lit17:
442 case DW_OP_lit18:
443 case DW_OP_lit19:
444 case DW_OP_lit20:
445 case DW_OP_lit21:
446 case DW_OP_lit22:
447 case DW_OP_lit23:
448 case DW_OP_lit24:
449 case DW_OP_lit25:
450 case DW_OP_lit26:
451 case DW_OP_lit27:
452 case DW_OP_lit28:
453 case DW_OP_lit29:
454 case DW_OP_lit30:
455 case DW_OP_lit31:
456 result = op - DW_OP_lit0;
457 break;
459 case DW_OP_addr:
460 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
461 op_ptr += sizeof (void *);
462 break;
464 case DW_OP_const1u:
465 result = read_1u (op_ptr);
466 op_ptr += 1;
467 break;
468 case DW_OP_const1s:
469 result = read_1s (op_ptr);
470 op_ptr += 1;
471 break;
472 case DW_OP_const2u:
473 result = read_2u (op_ptr);
474 op_ptr += 2;
475 break;
476 case DW_OP_const2s:
477 result = read_2s (op_ptr);
478 op_ptr += 2;
479 break;
480 case DW_OP_const4u:
481 result = read_4u (op_ptr);
482 op_ptr += 4;
483 break;
484 case DW_OP_const4s:
485 result = read_4s (op_ptr);
486 op_ptr += 4;
487 break;
488 case DW_OP_const8u:
489 result = read_8u (op_ptr);
490 op_ptr += 8;
491 break;
492 case DW_OP_const8s:
493 result = read_8s (op_ptr);
494 op_ptr += 8;
495 break;
496 case DW_OP_constu:
497 op_ptr = read_uleb128 (op_ptr, &result);
498 break;
499 case DW_OP_consts:
500 op_ptr = read_sleb128 (op_ptr, &offset);
501 result = offset;
502 break;
504 case DW_OP_reg0:
505 case DW_OP_reg1:
506 case DW_OP_reg2:
507 case DW_OP_reg3:
508 case DW_OP_reg4:
509 case DW_OP_reg5:
510 case DW_OP_reg6:
511 case DW_OP_reg7:
512 case DW_OP_reg8:
513 case DW_OP_reg9:
514 case DW_OP_reg10:
515 case DW_OP_reg11:
516 case DW_OP_reg12:
517 case DW_OP_reg13:
518 case DW_OP_reg14:
519 case DW_OP_reg15:
520 case DW_OP_reg16:
521 case DW_OP_reg17:
522 case DW_OP_reg18:
523 case DW_OP_reg19:
524 case DW_OP_reg20:
525 case DW_OP_reg21:
526 case DW_OP_reg22:
527 case DW_OP_reg23:
528 case DW_OP_reg24:
529 case DW_OP_reg25:
530 case DW_OP_reg26:
531 case DW_OP_reg27:
532 case DW_OP_reg28:
533 case DW_OP_reg29:
534 case DW_OP_reg30:
535 case DW_OP_reg31:
536 result = _Unwind_GetGR (context, op - DW_OP_reg0);
537 break;
538 case DW_OP_regx:
539 op_ptr = read_uleb128 (op_ptr, &reg);
540 result = _Unwind_GetGR (context, reg);
541 break;
543 case DW_OP_breg0:
544 case DW_OP_breg1:
545 case DW_OP_breg2:
546 case DW_OP_breg3:
547 case DW_OP_breg4:
548 case DW_OP_breg5:
549 case DW_OP_breg6:
550 case DW_OP_breg7:
551 case DW_OP_breg8:
552 case DW_OP_breg9:
553 case DW_OP_breg10:
554 case DW_OP_breg11:
555 case DW_OP_breg12:
556 case DW_OP_breg13:
557 case DW_OP_breg14:
558 case DW_OP_breg15:
559 case DW_OP_breg16:
560 case DW_OP_breg17:
561 case DW_OP_breg18:
562 case DW_OP_breg19:
563 case DW_OP_breg20:
564 case DW_OP_breg21:
565 case DW_OP_breg22:
566 case DW_OP_breg23:
567 case DW_OP_breg24:
568 case DW_OP_breg25:
569 case DW_OP_breg26:
570 case DW_OP_breg27:
571 case DW_OP_breg28:
572 case DW_OP_breg29:
573 case DW_OP_breg30:
574 case DW_OP_breg31:
575 op_ptr = read_sleb128 (op_ptr, &offset);
576 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
577 break;
578 case DW_OP_bregx:
579 op_ptr = read_uleb128 (op_ptr, &reg);
580 op_ptr = read_sleb128 (op_ptr, &offset);
581 result = _Unwind_GetGR (context, reg) + offset;
582 break;
584 case DW_OP_dup:
585 if (stack_elt < 1)
586 abort ();
587 result = stack[stack_elt - 1];
588 break;
590 case DW_OP_drop:
591 if (--stack_elt < 0)
592 abort ();
593 goto no_push;
595 case DW_OP_pick:
596 offset = *op_ptr++;
597 if (offset >= stack_elt - 1)
598 abort ();
599 result = stack[stack_elt - 1 - offset];
600 break;
602 case DW_OP_over:
603 if (stack_elt < 2)
604 abort ();
605 result = stack[stack_elt - 2];
606 break;
608 case DW_OP_rot:
610 _Unwind_Word t1, t2, t3;
612 if (stack_elt < 3)
613 abort ();
614 t1 = stack[stack_elt - 1];
615 t2 = stack[stack_elt - 2];
616 t3 = stack[stack_elt - 3];
617 stack[stack_elt - 1] = t2;
618 stack[stack_elt - 2] = t3;
619 stack[stack_elt - 3] = t1;
620 goto no_push;
623 case DW_OP_deref:
624 case DW_OP_deref_size:
625 case DW_OP_abs:
626 case DW_OP_neg:
627 case DW_OP_not:
628 case DW_OP_plus_uconst:
629 /* Unary operations. */
630 if (--stack_elt < 0)
631 abort ();
632 result = stack[stack_elt];
634 switch (op)
636 case DW_OP_deref:
638 void *ptr = (void *)(_Unwind_Ptr) result;
639 result = (_Unwind_Ptr) read_pointer (ptr);
641 break;
643 case DW_OP_deref_size:
645 void *ptr = (void *)(_Unwind_Ptr) result;
646 switch (*op_ptr++)
648 case 1:
649 result = read_1u (ptr);
650 break;
651 case 2:
652 result = read_2u (ptr);
653 break;
654 case 4:
655 result = read_4u (ptr);
656 break;
657 case 8:
658 result = read_8u (ptr);
659 break;
660 default:
661 abort ();
664 break;
666 case DW_OP_abs:
667 if ((_Unwind_Sword) result < 0)
668 result = -result;
669 break;
670 case DW_OP_neg:
671 result = -result;
672 break;
673 case DW_OP_not:
674 result = ~result;
675 break;
676 case DW_OP_plus_uconst:
677 op_ptr = read_uleb128 (op_ptr, &reg);
678 result += reg;
679 break;
681 break;
683 case DW_OP_and:
684 case DW_OP_div:
685 case DW_OP_minus:
686 case DW_OP_mod:
687 case DW_OP_mul:
688 case DW_OP_or:
689 case DW_OP_plus:
690 case DW_OP_le:
691 case DW_OP_ge:
692 case DW_OP_eq:
693 case DW_OP_lt:
694 case DW_OP_gt:
695 case DW_OP_ne:
697 /* Binary operations. */
698 _Unwind_Word first, second;
699 if ((stack_elt -= 2) < 0)
700 abort ();
701 second = stack[stack_elt];
702 first = stack[stack_elt + 1];
704 switch (op)
706 case DW_OP_and:
707 result = second & first;
708 break;
709 case DW_OP_div:
710 result = (_Unwind_Sword)second / (_Unwind_Sword)first;
711 break;
712 case DW_OP_minus:
713 result = second - first;
714 break;
715 case DW_OP_mod:
716 result = (_Unwind_Sword)second % (_Unwind_Sword)first;
717 break;
718 case DW_OP_mul:
719 result = second * first;
720 break;
721 case DW_OP_or:
722 result = second | first;
723 break;
724 case DW_OP_plus:
725 result = second + first;
726 break;
727 case DW_OP_shl:
728 result = second << first;
729 break;
730 case DW_OP_shr:
731 result = second >> first;
732 break;
733 case DW_OP_shra:
734 result = (_Unwind_Sword)second >> first;
735 break;
736 case DW_OP_xor:
737 result = second ^ first;
738 break;
739 case DW_OP_le:
740 result = (_Unwind_Sword)first <= (_Unwind_Sword)second;
741 break;
742 case DW_OP_ge:
743 result = (_Unwind_Sword)first >= (_Unwind_Sword)second;
744 break;
745 case DW_OP_eq:
746 result = (_Unwind_Sword)first == (_Unwind_Sword)second;
747 break;
748 case DW_OP_lt:
749 result = (_Unwind_Sword)first < (_Unwind_Sword)second;
750 break;
751 case DW_OP_gt:
752 result = (_Unwind_Sword)first > (_Unwind_Sword)second;
753 break;
754 case DW_OP_ne:
755 result = (_Unwind_Sword)first != (_Unwind_Sword)second;
756 break;
759 break;
761 case DW_OP_skip:
762 offset = read_2s (op_ptr);
763 op_ptr += 2;
764 op_ptr += offset;
765 goto no_push;
767 case DW_OP_bra:
768 if (--stack_elt < 0)
769 abort ();
770 offset = read_2s (op_ptr);
771 op_ptr += 2;
772 if (stack[stack_elt] != 0)
773 op_ptr += offset;
774 goto no_push;
776 case DW_OP_nop:
777 goto no_push;
779 default:
780 abort ();
783 /* Most things push a result value. */
784 if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
785 abort ();
786 stack[++stack_elt] = result;
787 no_push:;
790 /* We were executing this program to get a value. It should be
791 at top of stack. */
792 if (--stack_elt < 0)
793 abort ();
794 return stack[stack_elt];
798 /* Decode DWARF 2 call frame information. Takes pointers the
799 instruction sequence to decode, current register information and
800 CIE info, and the PC range to evaluate. */
802 static void
803 execute_cfa_program (unsigned char *insn_ptr, unsigned char *insn_end,
804 struct _Unwind_Context *context, _Unwind_FrameState *fs)
806 struct frame_state_reg_info *unused_rs = NULL;
808 /* Don't allow remember/restore between CIE and FDE programs. */
809 fs->regs.prev = NULL;
811 while (insn_ptr < insn_end && fs->pc < context->ra)
813 unsigned char insn = *insn_ptr++;
814 _Unwind_Word reg, uoffset;
815 _Unwind_Sword offset;
817 if (insn & DW_CFA_advance_loc)
818 fs->pc += (insn & 0x3f) * fs->code_align;
819 else if (insn & DW_CFA_offset)
821 reg = insn & 0x3f;
822 insn_ptr = read_uleb128 (insn_ptr, &uoffset);
823 offset = (_Unwind_Sword)uoffset * fs->data_align;
824 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
825 fs->regs.reg[reg].loc.offset = offset;
827 else if (insn & DW_CFA_restore)
829 reg = insn & 0x3f;
830 fs->regs.reg[reg].how = REG_UNSAVED;
832 else switch (insn)
834 case DW_CFA_set_loc:
835 insn_ptr = read_encoded_pointer (insn_ptr, fs->addr_encoding,
836 &context->bases, &fs->pc);
837 break;
839 case DW_CFA_advance_loc1:
840 fs->pc += read_1u (insn_ptr);
841 insn_ptr += 1;
842 break;
843 case DW_CFA_advance_loc2:
844 fs->pc += read_2u (insn_ptr);
845 insn_ptr += 2;
846 break;
847 case DW_CFA_advance_loc4:
848 fs->pc += read_4u (insn_ptr);
849 insn_ptr += 4;
850 break;
852 case DW_CFA_offset_extended:
853 insn_ptr = read_uleb128 (insn_ptr, &reg);
854 insn_ptr = read_uleb128 (insn_ptr, &uoffset);
855 offset = (_Unwind_Sword)uoffset * fs->data_align;
856 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
857 fs->regs.reg[reg].loc.offset = offset;
858 break;
860 case DW_CFA_restore_extended:
861 insn_ptr = read_uleb128 (insn_ptr, &reg);
862 fs->regs.reg[reg].how = REG_UNSAVED;
863 break;
865 case DW_CFA_undefined:
866 case DW_CFA_same_value:
867 case DW_CFA_nop:
868 break;
870 case DW_CFA_register:
872 _Unwind_Word reg2;
873 insn_ptr = read_uleb128 (insn_ptr, &reg);
874 insn_ptr = read_uleb128 (insn_ptr, &reg2);
875 fs->regs.reg[reg].how = REG_SAVED_REG;
876 fs->regs.reg[reg].loc.reg = reg2;
878 break;
880 case DW_CFA_remember_state:
882 struct frame_state_reg_info *new_rs;
883 if (unused_rs)
885 new_rs = unused_rs;
886 unused_rs = unused_rs->prev;
888 else
889 new_rs = alloca (sizeof (struct frame_state_reg_info));
891 *new_rs = fs->regs;
892 fs->regs.prev = new_rs;
894 break;
896 case DW_CFA_restore_state:
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;
903 break;
905 case DW_CFA_def_cfa:
906 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
907 insn_ptr = read_uleb128 (insn_ptr, &uoffset);
908 fs->cfa_offset = uoffset;
909 fs->cfa_how = CFA_REG_OFFSET;
910 break;
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;
917 case DW_CFA_def_cfa_offset:
918 insn_ptr = read_uleb128 (insn_ptr, &uoffset);
919 fs->cfa_offset = uoffset;
920 /* cfa_how deliberately not set. */
921 break;
923 case DW_CFA_def_cfa_expression:
924 insn_ptr = read_uleb128 (insn_ptr, &uoffset);
925 fs->cfa_exp = insn_ptr;
926 fs->cfa_how = CFA_EXP;
927 insn_ptr += uoffset;
928 break;
930 case DW_CFA_expression:
931 insn_ptr = read_uleb128 (insn_ptr, &reg);
932 insn_ptr = read_uleb128 (insn_ptr, &uoffset);
933 fs->regs.reg[reg].how = REG_SAVED_EXP;
934 fs->regs.reg[reg].loc.exp = insn_ptr;
935 insn_ptr += uoffset;
936 break;
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, &offset);
942 offset *= fs->data_align;
943 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
944 fs->regs.reg[reg].loc.offset = offset;
945 break;
947 case DW_CFA_def_cfa_sf:
948 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
949 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
950 fs->cfa_how = CFA_REG_OFFSET;
951 break;
953 case DW_CFA_def_cfa_offset_sf:
954 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_offset);
955 /* cfa_how deliberately not set. */
956 break;
958 case DW_CFA_GNU_window_save:
959 /* ??? Hardcoded for SPARC register window configuration. */
960 for (reg = 16; reg < 32; ++reg)
962 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
963 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
965 break;
967 case DW_CFA_GNU_args_size:
968 insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
969 break;
971 case DW_CFA_GNU_negative_offset_extended:
972 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
973 older PowerPC code. */
974 insn_ptr = read_uleb128 (insn_ptr, &reg);
975 insn_ptr = read_uleb128 (insn_ptr, &uoffset);
976 offset = (_Unwind_Sword)uoffset * fs->data_align;
977 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
978 fs->regs.reg[reg].loc.offset = -offset;
979 break;
981 default:
982 abort ();
987 static _Unwind_Reason_Code
988 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
990 struct dwarf_fde *fde;
991 struct dwarf_cie *cie;
992 unsigned char *aug, *insn, *end;
994 memset (fs, 0, sizeof (*fs));
995 context->args_size = 0;
996 context->lsda = 0;
998 fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
999 if (fde == NULL)
1001 /* Couldn't find frame unwind info for this function. Try a
1002 target-specific fallback mechanism. This will necessarily
1003 not profide a personality routine or LSDA. */
1004 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1005 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
1006 return _URC_END_OF_STACK;
1007 success:
1008 return _URC_NO_REASON;
1009 #else
1010 return _URC_END_OF_STACK;
1011 #endif
1014 context->bases.func = fde->pc_begin;
1015 fs->pc = fde->pc_begin;
1017 cie = get_cie (fde);
1018 insn = extract_cie_info (cie, context, fs);
1019 if (insn == NULL)
1020 /* CIE contained unknown augmentation. */
1021 return _URC_FATAL_PHASE1_ERROR;
1023 /* First decode all the insns in the CIE. */
1024 end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
1025 execute_cfa_program (insn, end, context, fs);
1027 /* Locate augmentation for the fde. */
1028 aug = (unsigned char *)fde + sizeof (*fde);
1029 insn = NULL;
1030 if (fs->saw_z)
1032 _Unwind_Word i;
1033 aug = read_uleb128 (aug, &i);
1034 insn = aug + i;
1036 if (fs->saw_lsda)
1037 aug = read_encoded_pointer (aug, fs->addr_encoding,
1038 &context->bases, &context->lsda);
1040 /* Then the insns in the FDE up to our target PC. */
1041 if (insn == NULL)
1042 insn = aug;
1043 end = (unsigned char *) next_fde (fde);
1044 execute_cfa_program (insn, end, context, fs);
1046 return _URC_NO_REASON;
1050 static void
1051 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1053 struct _Unwind_Context orig_context = *context;
1054 void *cfa;
1055 long i;
1057 /* Compute this frame's CFA. */
1058 switch (fs->cfa_how)
1060 case CFA_REG_OFFSET:
1061 /* Special handling here: Many machines do not use a frame pointer,
1062 and track the CFA only through offsets from the stack pointer from
1063 one frame to the next. In this case, the stack pointer is never
1064 stored, so it has no saved address in the context. What we do
1065 have is the CFA from the previous stack frame. */
1066 if (context->reg[fs->cfa_reg] == NULL)
1067 cfa = context->cfa;
1068 else
1069 cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->cfa_reg);
1070 cfa += fs->cfa_offset;
1071 break;
1073 case CFA_EXP:
1074 /* ??? No way of knowing what register number is the stack pointer
1075 to do the same sort of handling as above. Assume that if the
1076 CFA calculation is so complicated as to require a stack program
1077 that this will not be a problem. */
1079 unsigned char *exp = fs->cfa_exp;
1080 _Unwind_Word len;
1082 exp = read_uleb128 (exp, &len);
1083 cfa = (void *) (_Unwind_Ptr)
1084 execute_stack_op (exp, exp + len, context, 0);
1085 break;
1088 default:
1089 abort ();
1091 context->cfa = cfa;
1093 /* Compute the addresses of all registers saved in this frame. */
1094 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1095 switch (fs->regs.reg[i].how)
1097 case REG_UNSAVED:
1098 break;
1099 case REG_SAVED_OFFSET:
1100 context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
1101 break;
1102 case REG_SAVED_REG:
1103 context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
1104 break;
1105 case REG_SAVED_EXP:
1107 unsigned char *exp = fs->regs.reg[i].loc.exp;
1108 _Unwind_Word len;
1109 _Unwind_Ptr val;
1111 exp = read_uleb128 (exp, &len);
1112 val = execute_stack_op (exp, exp + len, &orig_context,
1113 (_Unwind_Ptr) cfa);
1114 context->reg[i] = (void *) val;
1116 break;
1120 static void
1121 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1123 uw_update_context_1 (context, fs);
1125 /* Compute the return address now, since the return address column
1126 can change from frame to frame. */
1127 context->ra = __builtin_extract_return_addr
1128 ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
1131 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1132 level will be the return address and the CFA. */
1134 #define uw_init_context(CONTEXT) \
1135 do { \
1136 /* Do any necessary initialization to access arbitrary stack frames. \
1137 On the SPARC, this means flushing the register windows. */ \
1138 __builtin_unwind_init (); \
1139 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1140 __builtin_return_address (0)); \
1141 } while (0)
1143 static void
1144 uw_init_context_1 (struct _Unwind_Context *context,
1145 void *outer_cfa, void *outer_ra)
1147 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1148 _Unwind_FrameState fs;
1150 memset (context, 0, sizeof (struct _Unwind_Context));
1151 context->ra = ra;
1153 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1154 abort ();
1156 /* Force the frame state to use the known cfa value. */
1157 context->cfa = outer_cfa;
1158 fs.cfa_how = CFA_REG_OFFSET;
1159 fs.cfa_reg = 0;
1160 fs.cfa_offset = 0;
1162 uw_update_context_1 (context, &fs);
1164 /* If the return address column was saved in a register in the
1165 initialization context, then we can't see it in the given
1166 call frame data. So have the initialization context tell us. */
1167 context->ra = __builtin_extract_return_addr (outer_ra);
1171 /* Install TARGET into CURRENT so that we can return to it. This is a
1172 macro because __builtin_eh_return must be invoked in the context of
1173 our caller. */
1175 #define uw_install_context(CURRENT, TARGET) \
1176 do { \
1177 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1178 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1179 __builtin_eh_return (offset, handler); \
1180 } while (0)
1182 static inline void
1183 init_dwarf_reg_size_table (void)
1185 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1188 static long
1189 uw_install_context_1 (struct _Unwind_Context *current,
1190 struct _Unwind_Context *target)
1192 long i;
1194 #if __GTHREADS
1196 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1197 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1198 || dwarf_reg_size_table[0] == 0)
1199 init_dwarf_reg_size_table ();
1201 #else
1202 if (dwarf_reg_size_table[0] == 0)
1203 init_dwarf_reg_size_table ();
1204 #endif
1206 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1208 void *c = current->reg[i];
1209 void *t = target->reg[i];
1210 if (t && c && t != c)
1211 memcpy (c, t, dwarf_reg_size_table[i]);
1214 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1215 if (STACK_GROWS_DOWNWARD)
1216 return target->cfa - current->cfa + target->args_size;
1217 else
1218 return current->cfa - target->cfa - target->args_size;
1221 static inline _Unwind_Ptr
1222 uw_identify_context (struct _Unwind_Context *context)
1224 return _Unwind_GetIP (context);
1228 #include "unwind.inc"
1230 #endif /* !USING_SJLJ_EXCEPTIONS */