re PR c++/11357 ([DR 425] no conversion of build-in binary operator argument attempted)
[official-gcc.git] / gcc / unwind-dw2.c
blobf94eaf99da9ca9d3f5dca948dbe3ba0de4cd8a15
1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file into combinations with other programs,
15 and to distribute those combinations without any restriction coming
16 from the use of this file. (The General Public License restrictions
17 do apply in other respects; for example, they cover modification of
18 the file, and distribution when not linked into a combined
19 executable.)
21 GCC is distributed in the hope that it will be useful, but WITHOUT
22 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
24 License for more details.
26 You should have received a copy of the GNU General Public License
27 along with GCC; see the file COPYING. If not, write to the Free
28 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
29 02111-1307, USA. */
31 #include "tconfig.h"
32 #include "tsystem.h"
33 #include "coretypes.h"
34 #include "tm.h"
35 #include "dwarf2.h"
36 #include "unwind.h"
37 #include "unwind-pe.h"
38 #include "unwind-dw2-fde.h"
39 #include "gthr.h"
42 #ifndef __USING_SJLJ_EXCEPTIONS__
44 #ifndef STACK_GROWS_DOWNWARD
45 #define STACK_GROWS_DOWNWARD 0
46 #else
47 #undef STACK_GROWS_DOWNWARD
48 #define STACK_GROWS_DOWNWARD 1
49 #endif
51 /* A target can override (perhaps for backward compatibility) how
52 many dwarf2 columns are unwound. */
53 #ifndef DWARF_FRAME_REGISTERS
54 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
55 #endif
57 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
58 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
59 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
60 #endif
62 #ifndef DWARF_REG_TO_UNWIND_COLUMN
63 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
64 #endif
66 /* A target can do some update context frobbing. */
67 #ifndef MD_FROB_UPDATE_CONTEXT
68 #define MD_FROB_UPDATE_CONTEXT(CTX, FS) do { } while (0)
69 #endif
71 /* This is the register and unwind state for a particular frame. This
72 provides the information necessary to unwind up past a frame and return
73 to its caller. */
74 struct _Unwind_Context
76 void *reg[DWARF_FRAME_REGISTERS+1];
77 void *cfa;
78 void *ra;
79 void *lsda;
80 struct dwarf_eh_bases bases;
81 _Unwind_Word args_size;
84 /* Byte size of every register managed by these routines. */
85 static unsigned char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
88 /* The result of interpreting the frame unwind info for a frame.
89 This is all symbolic at this point, as none of the values can
90 be resolved until the target pc is located. */
91 typedef struct
93 /* Each register save state can be described in terms of a CFA slot,
94 another register, or a location expression. */
95 struct frame_state_reg_info
97 struct {
98 union {
99 _Unwind_Word reg;
100 _Unwind_Sword offset;
101 const unsigned char *exp;
102 } loc;
103 enum {
104 REG_UNSAVED,
105 REG_SAVED_OFFSET,
106 REG_SAVED_REG,
107 REG_SAVED_EXP,
108 } how;
109 } reg[DWARF_FRAME_REGISTERS+1];
111 /* Used to implement DW_CFA_remember_state. */
112 struct frame_state_reg_info *prev;
113 } regs;
115 /* The CFA can be described in terms of a reg+offset or a
116 location expression. */
117 _Unwind_Sword cfa_offset;
118 _Unwind_Word cfa_reg;
119 const unsigned char *cfa_exp;
120 enum {
121 CFA_UNSET,
122 CFA_REG_OFFSET,
123 CFA_EXP,
124 } cfa_how;
126 /* The PC described by the current frame state. */
127 void *pc;
129 /* The information we care about from the CIE/FDE. */
130 _Unwind_Personality_Fn personality;
131 _Unwind_Sword data_align;
132 _Unwind_Word code_align;
133 unsigned char retaddr_column;
134 unsigned char fde_encoding;
135 unsigned char lsda_encoding;
136 unsigned char saw_z;
137 void *eh_ptr;
138 } _Unwind_FrameState;
140 /* Read unaligned data from the instruction buffer. */
142 union unaligned
144 void *p;
145 unsigned u2 __attribute__ ((mode (HI)));
146 unsigned u4 __attribute__ ((mode (SI)));
147 unsigned u8 __attribute__ ((mode (DI)));
148 signed s2 __attribute__ ((mode (HI)));
149 signed s4 __attribute__ ((mode (SI)));
150 signed s8 __attribute__ ((mode (DI)));
151 } __attribute__ ((packed));
153 static inline void *
154 read_pointer (const void *p) { const union unaligned *up = p; return up->p; }
156 static inline int
157 read_1u (const void *p) { return *(const unsigned char *) p; }
159 static inline int
160 read_1s (const void *p) { return *(const signed char *) p; }
162 static inline int
163 read_2u (const void *p) { const union unaligned *up = p; return up->u2; }
165 static inline int
166 read_2s (const void *p) { const union unaligned *up = p; return up->s2; }
168 static inline unsigned int
169 read_4u (const void *p) { const union unaligned *up = p; return up->u4; }
171 static inline int
172 read_4s (const void *p) { const union unaligned *up = p; return up->s4; }
174 static inline unsigned long
175 read_8u (const void *p) { const union unaligned *up = p; return up->u8; }
177 static inline unsigned long
178 read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
180 /* Get the value of register REG as saved in CONTEXT. */
182 inline _Unwind_Word
183 _Unwind_GetGR (struct _Unwind_Context *context, int index)
185 int size;
186 void *ptr;
188 index = DWARF_REG_TO_UNWIND_COLUMN (index);
189 size = dwarf_reg_size_table[index];
190 ptr = context->reg[index];
192 /* This will segfault if the register hasn't been saved. */
193 if (size == sizeof(_Unwind_Ptr))
194 return * (_Unwind_Ptr *) ptr;
196 if (size == sizeof(_Unwind_Word))
197 return * (_Unwind_Word *) ptr;
199 abort ();
202 static inline void *
203 _Unwind_GetPtr (struct _Unwind_Context *context, int index)
205 return (void *)(_Unwind_Ptr) _Unwind_GetGR (context, index);
208 /* Get the value of the CFA as saved in CONTEXT. */
210 _Unwind_Word
211 _Unwind_GetCFA (struct _Unwind_Context *context)
213 return (_Unwind_Ptr) context->cfa;
216 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
218 inline void
219 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
221 int size;
222 void *ptr;
224 index = DWARF_REG_TO_UNWIND_COLUMN (index);
225 size = dwarf_reg_size_table[index];
226 ptr = context->reg[index];
228 if (size == sizeof(_Unwind_Ptr))
229 * (_Unwind_Ptr *) ptr = val;
230 else if (size == sizeof(_Unwind_Word))
231 * (_Unwind_Word *) ptr = val;
232 else
233 abort ();
236 /* Get the pointer to a register INDEX as saved in CONTEXT. */
238 static inline void *
239 _Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
241 index = DWARF_REG_TO_UNWIND_COLUMN (index);
242 return context->reg[index];
245 /* Set the pointer to a register INDEX as saved in CONTEXT. */
247 static inline void
248 _Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
250 index = DWARF_REG_TO_UNWIND_COLUMN (index);
251 context->reg[index] = p;
254 /* Retrieve the return address for CONTEXT. */
256 inline _Unwind_Ptr
257 _Unwind_GetIP (struct _Unwind_Context *context)
259 return (_Unwind_Ptr) context->ra;
262 /* Overwrite the return address for CONTEXT with VAL. */
264 inline void
265 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
267 context->ra = (void *) val;
270 void *
271 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
273 return context->lsda;
276 _Unwind_Ptr
277 _Unwind_GetRegionStart (struct _Unwind_Context *context)
279 return (_Unwind_Ptr) context->bases.func;
282 void *
283 _Unwind_FindEnclosingFunction (void *pc)
285 struct dwarf_eh_bases bases;
286 struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
287 if (fde)
288 return bases.func;
289 else
290 return NULL;
293 #ifndef __ia64__
294 _Unwind_Ptr
295 _Unwind_GetDataRelBase (struct _Unwind_Context *context)
297 return (_Unwind_Ptr) context->bases.dbase;
300 _Unwind_Ptr
301 _Unwind_GetTextRelBase (struct _Unwind_Context *context)
303 return (_Unwind_Ptr) context->bases.tbase;
305 #endif
307 /* Extract any interesting information from the CIE for the translation
308 unit F belongs to. Return a pointer to the byte after the augmentation,
309 or NULL if we encountered an undecipherable augmentation. */
311 static const unsigned char *
312 extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
313 _Unwind_FrameState *fs)
315 const unsigned char *aug = cie->augmentation;
316 const unsigned char *p = aug + strlen (aug) + 1;
317 const unsigned char *ret = NULL;
318 _Unwind_Word utmp;
320 /* g++ v2 "eh" has pointer immediately following augmentation string,
321 so it must be handled first. */
322 if (aug[0] == 'e' && aug[1] == 'h')
324 fs->eh_ptr = read_pointer (p);
325 p += sizeof (void *);
326 aug += 2;
329 /* Immediately following the augmentation are the code and
330 data alignment and return address column. */
331 p = read_uleb128 (p, &fs->code_align);
332 p = read_sleb128 (p, &fs->data_align);
333 fs->retaddr_column = *p++;
334 fs->lsda_encoding = DW_EH_PE_omit;
336 /* If the augmentation starts with 'z', then a uleb128 immediately
337 follows containing the length of the augmentation field following
338 the size. */
339 if (*aug == 'z')
341 p = read_uleb128 (p, &utmp);
342 ret = p + utmp;
344 fs->saw_z = 1;
345 ++aug;
348 /* Iterate over recognized augmentation subsequences. */
349 while (*aug != '\0')
351 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
352 if (aug[0] == 'L')
354 fs->lsda_encoding = *p++;
355 aug += 1;
358 /* "R" indicates a byte indicating how FDE addresses are encoded. */
359 else if (aug[0] == 'R')
361 fs->fde_encoding = *p++;
362 aug += 1;
365 /* "P" indicates a personality routine in the CIE augmentation. */
366 else if (aug[0] == 'P')
368 p = read_encoded_value (context, *p, p + 1,
369 (_Unwind_Ptr *) &fs->personality);
370 aug += 1;
373 /* Otherwise we have an unknown augmentation string.
374 Bail unless we saw a 'z' prefix. */
375 else
376 return ret;
379 return ret ? ret : p;
383 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
384 onto the stack to start. */
386 static _Unwind_Word
387 execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
388 struct _Unwind_Context *context, _Unwind_Word initial)
390 _Unwind_Word stack[64]; /* ??? Assume this is enough. */
391 int stack_elt;
393 stack[0] = initial;
394 stack_elt = 1;
396 while (op_ptr < op_end)
398 enum dwarf_location_atom op = *op_ptr++;
399 _Unwind_Word result, reg, utmp;
400 _Unwind_Sword offset, stmp;
402 switch (op)
404 case DW_OP_lit0:
405 case DW_OP_lit1:
406 case DW_OP_lit2:
407 case DW_OP_lit3:
408 case DW_OP_lit4:
409 case DW_OP_lit5:
410 case DW_OP_lit6:
411 case DW_OP_lit7:
412 case DW_OP_lit8:
413 case DW_OP_lit9:
414 case DW_OP_lit10:
415 case DW_OP_lit11:
416 case DW_OP_lit12:
417 case DW_OP_lit13:
418 case DW_OP_lit14:
419 case DW_OP_lit15:
420 case DW_OP_lit16:
421 case DW_OP_lit17:
422 case DW_OP_lit18:
423 case DW_OP_lit19:
424 case DW_OP_lit20:
425 case DW_OP_lit21:
426 case DW_OP_lit22:
427 case DW_OP_lit23:
428 case DW_OP_lit24:
429 case DW_OP_lit25:
430 case DW_OP_lit26:
431 case DW_OP_lit27:
432 case DW_OP_lit28:
433 case DW_OP_lit29:
434 case DW_OP_lit30:
435 case DW_OP_lit31:
436 result = op - DW_OP_lit0;
437 break;
439 case DW_OP_addr:
440 result = (_Unwind_Word) (_Unwind_Ptr) read_pointer (op_ptr);
441 op_ptr += sizeof (void *);
442 break;
444 case DW_OP_const1u:
445 result = read_1u (op_ptr);
446 op_ptr += 1;
447 break;
448 case DW_OP_const1s:
449 result = read_1s (op_ptr);
450 op_ptr += 1;
451 break;
452 case DW_OP_const2u:
453 result = read_2u (op_ptr);
454 op_ptr += 2;
455 break;
456 case DW_OP_const2s:
457 result = read_2s (op_ptr);
458 op_ptr += 2;
459 break;
460 case DW_OP_const4u:
461 result = read_4u (op_ptr);
462 op_ptr += 4;
463 break;
464 case DW_OP_const4s:
465 result = read_4s (op_ptr);
466 op_ptr += 4;
467 break;
468 case DW_OP_const8u:
469 result = read_8u (op_ptr);
470 op_ptr += 8;
471 break;
472 case DW_OP_const8s:
473 result = read_8s (op_ptr);
474 op_ptr += 8;
475 break;
476 case DW_OP_constu:
477 op_ptr = read_uleb128 (op_ptr, &result);
478 break;
479 case DW_OP_consts:
480 op_ptr = read_sleb128 (op_ptr, &stmp);
481 result = stmp;
482 break;
484 case DW_OP_reg0:
485 case DW_OP_reg1:
486 case DW_OP_reg2:
487 case DW_OP_reg3:
488 case DW_OP_reg4:
489 case DW_OP_reg5:
490 case DW_OP_reg6:
491 case DW_OP_reg7:
492 case DW_OP_reg8:
493 case DW_OP_reg9:
494 case DW_OP_reg10:
495 case DW_OP_reg11:
496 case DW_OP_reg12:
497 case DW_OP_reg13:
498 case DW_OP_reg14:
499 case DW_OP_reg15:
500 case DW_OP_reg16:
501 case DW_OP_reg17:
502 case DW_OP_reg18:
503 case DW_OP_reg19:
504 case DW_OP_reg20:
505 case DW_OP_reg21:
506 case DW_OP_reg22:
507 case DW_OP_reg23:
508 case DW_OP_reg24:
509 case DW_OP_reg25:
510 case DW_OP_reg26:
511 case DW_OP_reg27:
512 case DW_OP_reg28:
513 case DW_OP_reg29:
514 case DW_OP_reg30:
515 case DW_OP_reg31:
516 result = _Unwind_GetGR (context, op - DW_OP_reg0);
517 break;
518 case DW_OP_regx:
519 op_ptr = read_uleb128 (op_ptr, &reg);
520 result = _Unwind_GetGR (context, reg);
521 break;
523 case DW_OP_breg0:
524 case DW_OP_breg1:
525 case DW_OP_breg2:
526 case DW_OP_breg3:
527 case DW_OP_breg4:
528 case DW_OP_breg5:
529 case DW_OP_breg6:
530 case DW_OP_breg7:
531 case DW_OP_breg8:
532 case DW_OP_breg9:
533 case DW_OP_breg10:
534 case DW_OP_breg11:
535 case DW_OP_breg12:
536 case DW_OP_breg13:
537 case DW_OP_breg14:
538 case DW_OP_breg15:
539 case DW_OP_breg16:
540 case DW_OP_breg17:
541 case DW_OP_breg18:
542 case DW_OP_breg19:
543 case DW_OP_breg20:
544 case DW_OP_breg21:
545 case DW_OP_breg22:
546 case DW_OP_breg23:
547 case DW_OP_breg24:
548 case DW_OP_breg25:
549 case DW_OP_breg26:
550 case DW_OP_breg27:
551 case DW_OP_breg28:
552 case DW_OP_breg29:
553 case DW_OP_breg30:
554 case DW_OP_breg31:
555 op_ptr = read_sleb128 (op_ptr, &offset);
556 result = _Unwind_GetGR (context, op - DW_OP_breg0) + offset;
557 break;
558 case DW_OP_bregx:
559 op_ptr = read_uleb128 (op_ptr, &reg);
560 op_ptr = read_sleb128 (op_ptr, &offset);
561 result = _Unwind_GetGR (context, reg) + offset;
562 break;
564 case DW_OP_dup:
565 if (stack_elt < 1)
566 abort ();
567 result = stack[stack_elt - 1];
568 break;
570 case DW_OP_drop:
571 if (--stack_elt < 0)
572 abort ();
573 goto no_push;
575 case DW_OP_pick:
576 offset = *op_ptr++;
577 if (offset >= stack_elt - 1)
578 abort ();
579 result = stack[stack_elt - 1 - offset];
580 break;
582 case DW_OP_over:
583 if (stack_elt < 2)
584 abort ();
585 result = stack[stack_elt - 2];
586 break;
588 case DW_OP_rot:
590 _Unwind_Word t1, t2, t3;
592 if (stack_elt < 3)
593 abort ();
594 t1 = stack[stack_elt - 1];
595 t2 = stack[stack_elt - 2];
596 t3 = stack[stack_elt - 3];
597 stack[stack_elt - 1] = t2;
598 stack[stack_elt - 2] = t3;
599 stack[stack_elt - 3] = t1;
600 goto no_push;
603 case DW_OP_deref:
604 case DW_OP_deref_size:
605 case DW_OP_abs:
606 case DW_OP_neg:
607 case DW_OP_not:
608 case DW_OP_plus_uconst:
609 /* Unary operations. */
610 if (--stack_elt < 0)
611 abort ();
612 result = stack[stack_elt];
614 switch (op)
616 case DW_OP_deref:
618 void *ptr = (void *) (_Unwind_Ptr) result;
619 result = (_Unwind_Ptr) read_pointer (ptr);
621 break;
623 case DW_OP_deref_size:
625 void *ptr = (void *) (_Unwind_Ptr) result;
626 switch (*op_ptr++)
628 case 1:
629 result = read_1u (ptr);
630 break;
631 case 2:
632 result = read_2u (ptr);
633 break;
634 case 4:
635 result = read_4u (ptr);
636 break;
637 case 8:
638 result = read_8u (ptr);
639 break;
640 default:
641 abort ();
644 break;
646 case DW_OP_abs:
647 if ((_Unwind_Sword) result < 0)
648 result = -result;
649 break;
650 case DW_OP_neg:
651 result = -result;
652 break;
653 case DW_OP_not:
654 result = ~result;
655 break;
656 case DW_OP_plus_uconst:
657 op_ptr = read_uleb128 (op_ptr, &utmp);
658 result += utmp;
659 break;
661 default:
662 abort ();
664 break;
666 case DW_OP_and:
667 case DW_OP_div:
668 case DW_OP_minus:
669 case DW_OP_mod:
670 case DW_OP_mul:
671 case DW_OP_or:
672 case DW_OP_plus:
673 case DW_OP_le:
674 case DW_OP_ge:
675 case DW_OP_eq:
676 case DW_OP_lt:
677 case DW_OP_gt:
678 case DW_OP_ne:
680 /* Binary operations. */
681 _Unwind_Word first, second;
682 if ((stack_elt -= 2) < 0)
683 abort ();
684 second = stack[stack_elt];
685 first = stack[stack_elt + 1];
687 switch (op)
689 case DW_OP_and:
690 result = second & first;
691 break;
692 case DW_OP_div:
693 result = (_Unwind_Sword) second / (_Unwind_Sword) first;
694 break;
695 case DW_OP_minus:
696 result = second - first;
697 break;
698 case DW_OP_mod:
699 result = (_Unwind_Sword) second % (_Unwind_Sword) first;
700 break;
701 case DW_OP_mul:
702 result = second * first;
703 break;
704 case DW_OP_or:
705 result = second | first;
706 break;
707 case DW_OP_plus:
708 result = second + first;
709 break;
710 case DW_OP_shl:
711 result = second << first;
712 break;
713 case DW_OP_shr:
714 result = second >> first;
715 break;
716 case DW_OP_shra:
717 result = (_Unwind_Sword) second >> first;
718 break;
719 case DW_OP_xor:
720 result = second ^ first;
721 break;
722 case DW_OP_le:
723 result = (_Unwind_Sword) first <= (_Unwind_Sword) second;
724 break;
725 case DW_OP_ge:
726 result = (_Unwind_Sword) first >= (_Unwind_Sword) second;
727 break;
728 case DW_OP_eq:
729 result = (_Unwind_Sword) first == (_Unwind_Sword) second;
730 break;
731 case DW_OP_lt:
732 result = (_Unwind_Sword) first < (_Unwind_Sword) second;
733 break;
734 case DW_OP_gt:
735 result = (_Unwind_Sword) first > (_Unwind_Sword) second;
736 break;
737 case DW_OP_ne:
738 result = (_Unwind_Sword) first != (_Unwind_Sword) second;
739 break;
741 default:
742 abort ();
745 break;
747 case DW_OP_skip:
748 offset = read_2s (op_ptr);
749 op_ptr += 2;
750 op_ptr += offset;
751 goto no_push;
753 case DW_OP_bra:
754 if (--stack_elt < 0)
755 abort ();
756 offset = read_2s (op_ptr);
757 op_ptr += 2;
758 if (stack[stack_elt] != 0)
759 op_ptr += offset;
760 goto no_push;
762 case DW_OP_nop:
763 goto no_push;
765 default:
766 abort ();
769 /* Most things push a result value. */
770 if ((size_t) stack_elt >= sizeof(stack)/sizeof(*stack))
771 abort ();
772 stack[stack_elt++] = result;
773 no_push:;
776 /* We were executing this program to get a value. It should be
777 at top of stack. */
778 if (--stack_elt < 0)
779 abort ();
780 return stack[stack_elt];
784 /* Decode DWARF 2 call frame information. Takes pointers the
785 instruction sequence to decode, current register information and
786 CIE info, and the PC range to evaluate. */
788 static void
789 execute_cfa_program (const unsigned char *insn_ptr,
790 const unsigned char *insn_end,
791 struct _Unwind_Context *context,
792 _Unwind_FrameState *fs)
794 struct frame_state_reg_info *unused_rs = NULL;
796 /* Don't allow remember/restore between CIE and FDE programs. */
797 fs->regs.prev = NULL;
799 /* The comparison with the return address uses < rather than <= because
800 we are only interested in the effects of code before the call; for a
801 noreturn function, the return address may point to unrelated code with
802 a different stack configuration that we are not interested in. We
803 assume that the call itself is unwind info-neutral; if not, or if
804 there are delay instructions that adjust the stack, these must be
805 reflected at the point immediately before the call insn. */
806 while (insn_ptr < insn_end && fs->pc < context->ra)
808 unsigned char insn = *insn_ptr++;
809 _Unwind_Word reg, utmp;
810 _Unwind_Sword offset, stmp;
812 if ((insn & 0xc0) == DW_CFA_advance_loc)
813 fs->pc += (insn & 0x3f) * fs->code_align;
814 else if ((insn & 0xc0) == DW_CFA_offset)
816 reg = insn & 0x3f;
817 insn_ptr = read_uleb128 (insn_ptr, &utmp);
818 offset = (_Unwind_Sword) utmp * fs->data_align;
819 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
820 = REG_SAVED_OFFSET;
821 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
823 else if ((insn & 0xc0) == DW_CFA_restore)
825 reg = insn & 0x3f;
826 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_UNSAVED;
828 else switch (insn)
830 case DW_CFA_set_loc:
831 insn_ptr = read_encoded_value (context, fs->fde_encoding,
832 insn_ptr, (_Unwind_Ptr *) &fs->pc);
833 break;
835 case DW_CFA_advance_loc1:
836 fs->pc += read_1u (insn_ptr) * fs->code_align;
837 insn_ptr += 1;
838 break;
839 case DW_CFA_advance_loc2:
840 fs->pc += read_2u (insn_ptr) * fs->code_align;
841 insn_ptr += 2;
842 break;
843 case DW_CFA_advance_loc4:
844 fs->pc += read_4u (insn_ptr) * fs->code_align;
845 insn_ptr += 4;
846 break;
848 case DW_CFA_offset_extended:
849 insn_ptr = read_uleb128 (insn_ptr, &reg);
850 insn_ptr = read_uleb128 (insn_ptr, &utmp);
851 offset = (_Unwind_Sword) utmp * fs->data_align;
852 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
853 = REG_SAVED_OFFSET;
854 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
855 break;
857 case DW_CFA_restore_extended:
858 insn_ptr = read_uleb128 (insn_ptr, &reg);
859 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
860 break;
862 case DW_CFA_undefined:
863 case DW_CFA_same_value:
864 insn_ptr = read_uleb128 (insn_ptr, &reg);
865 break;
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[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
876 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (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 = __builtin_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, &utmp);
908 fs->cfa_offset = utmp;
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, &utmp);
919 fs->cfa_offset = utmp;
920 /* cfa_how deliberately not set. */
921 break;
923 case DW_CFA_def_cfa_expression:
924 fs->cfa_exp = insn_ptr;
925 fs->cfa_how = CFA_EXP;
926 insn_ptr = read_uleb128 (insn_ptr, &utmp);
927 insn_ptr += utmp;
928 break;
930 case DW_CFA_expression:
931 insn_ptr = read_uleb128 (insn_ptr, &reg);
932 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP;
933 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
934 insn_ptr = read_uleb128 (insn_ptr, &utmp);
935 insn_ptr += utmp;
936 break;
938 /* From the 2.1 draft. */
939 case DW_CFA_offset_extended_sf:
940 insn_ptr = read_uleb128 (insn_ptr, &reg);
941 insn_ptr = read_sleb128 (insn_ptr, &stmp);
942 offset = stmp * fs->data_align;
943 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
944 = REG_SAVED_OFFSET;
945 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
946 break;
948 case DW_CFA_def_cfa_sf:
949 insn_ptr = read_uleb128 (insn_ptr, &fs->cfa_reg);
950 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
951 fs->cfa_how = CFA_REG_OFFSET;
952 break;
954 case DW_CFA_def_cfa_offset_sf:
955 insn_ptr = read_sleb128 (insn_ptr, &fs->cfa_offset);
956 /* cfa_how deliberately not set. */
957 break;
959 case DW_CFA_GNU_window_save:
960 /* ??? Hardcoded for SPARC register window configuration. */
961 for (reg = 16; reg < 32; ++reg)
963 fs->regs.reg[reg].how = REG_SAVED_OFFSET;
964 fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
966 break;
968 case DW_CFA_GNU_args_size:
969 insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
970 break;
972 case DW_CFA_GNU_negative_offset_extended:
973 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
974 older PowerPC code. */
975 insn_ptr = read_uleb128 (insn_ptr, &reg);
976 insn_ptr = read_uleb128 (insn_ptr, &utmp);
977 offset = (_Unwind_Word) utmp * fs->data_align;
978 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
979 = REG_SAVED_OFFSET;
980 fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = -offset;
981 break;
983 default:
984 abort ();
989 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
990 its caller and decode it into FS. This function also sets the
991 args_size and lsda members of CONTEXT, as they are really information
992 about the caller's frame. */
994 static _Unwind_Reason_Code
995 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
997 struct dwarf_fde *fde;
998 struct dwarf_cie *cie;
999 const unsigned char *aug, *insn, *end;
1001 memset (fs, 0, sizeof (*fs));
1002 context->args_size = 0;
1003 context->lsda = 0;
1005 fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
1006 if (fde == NULL)
1008 /* Couldn't find frame unwind info for this function. Try a
1009 target-specific fallback mechanism. This will necessarily
1010 not provide a personality routine or LSDA. */
1011 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1012 MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
1013 return _URC_END_OF_STACK;
1014 success:
1015 return _URC_NO_REASON;
1016 #else
1017 return _URC_END_OF_STACK;
1018 #endif
1021 fs->pc = context->bases.func;
1023 cie = get_cie (fde);
1024 insn = extract_cie_info (cie, context, fs);
1025 if (insn == NULL)
1026 /* CIE contained unknown augmentation. */
1027 return _URC_FATAL_PHASE1_ERROR;
1029 /* First decode all the insns in the CIE. */
1030 end = (unsigned char *) next_fde ((struct dwarf_fde *) cie);
1031 execute_cfa_program (insn, end, context, fs);
1033 /* Locate augmentation for the fde. */
1034 aug = (unsigned char *) fde + sizeof (*fde);
1035 aug += 2 * size_of_encoded_value (fs->fde_encoding);
1036 insn = NULL;
1037 if (fs->saw_z)
1039 _Unwind_Word i;
1040 aug = read_uleb128 (aug, &i);
1041 insn = aug + i;
1043 if (fs->lsda_encoding != DW_EH_PE_omit)
1044 aug = read_encoded_value (context, fs->lsda_encoding, aug,
1045 (_Unwind_Ptr *) &context->lsda);
1047 /* Then the insns in the FDE up to our target PC. */
1048 if (insn == NULL)
1049 insn = aug;
1050 end = (unsigned char *) next_fde (fde);
1051 execute_cfa_program (insn, end, context, fs);
1053 return _URC_NO_REASON;
1056 typedef struct frame_state
1058 void *cfa;
1059 void *eh_ptr;
1060 long cfa_offset;
1061 long args_size;
1062 long reg_or_offset[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1063 unsigned short cfa_reg;
1064 unsigned short retaddr_column;
1065 char saved[PRE_GCC3_DWARF_FRAME_REGISTERS+1];
1066 } frame_state;
1068 struct frame_state * __frame_state_for (void *, struct frame_state *);
1070 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1071 a given PC_TARGET. The caller should allocate a local variable of
1072 `struct frame_state' and pass its address to STATE_IN. */
1074 struct frame_state *
1075 __frame_state_for (void *pc_target, struct frame_state *state_in)
1077 struct _Unwind_Context context;
1078 _Unwind_FrameState fs;
1079 int reg;
1081 memset (&context, 0, sizeof (struct _Unwind_Context));
1082 context.ra = pc_target + 1;
1084 if (uw_frame_state_for (&context, &fs) != _URC_NO_REASON)
1085 return 0;
1087 /* We have no way to pass a location expression for the CFA to our
1088 caller. It wouldn't understand it anyway. */
1089 if (fs.cfa_how == CFA_EXP)
1090 return 0;
1092 for (reg = 0; reg < PRE_GCC3_DWARF_FRAME_REGISTERS + 1; reg++)
1094 state_in->saved[reg] = fs.regs.reg[reg].how;
1095 switch (state_in->saved[reg])
1097 case REG_SAVED_REG:
1098 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.reg;
1099 break;
1100 case REG_SAVED_OFFSET:
1101 state_in->reg_or_offset[reg] = fs.regs.reg[reg].loc.offset;
1102 break;
1103 default:
1104 state_in->reg_or_offset[reg] = 0;
1105 break;
1109 state_in->cfa_offset = fs.cfa_offset;
1110 state_in->cfa_reg = fs.cfa_reg;
1111 state_in->retaddr_column = fs.retaddr_column;
1112 state_in->args_size = context.args_size;
1113 state_in->eh_ptr = fs.eh_ptr;
1115 return state_in;
1118 typedef union { _Unwind_Ptr ptr; _Unwind_Word word; } _Unwind_SpTmp;
1120 static inline void
1121 _Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
1122 _Unwind_SpTmp *tmp_sp)
1124 int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
1126 if (size == sizeof(_Unwind_Ptr))
1127 tmp_sp->ptr = (_Unwind_Ptr) cfa;
1128 else if (size == sizeof(_Unwind_Word))
1129 tmp_sp->word = (_Unwind_Ptr) cfa;
1130 else
1131 abort ();
1132 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), tmp_sp);
1135 static void
1136 uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1138 struct _Unwind_Context orig_context = *context;
1139 void *cfa;
1140 long i;
1142 #ifdef EH_RETURN_STACKADJ_RTX
1143 /* Special handling here: Many machines do not use a frame pointer,
1144 and track the CFA only through offsets from the stack pointer from
1145 one frame to the next. In this case, the stack pointer is never
1146 stored, so it has no saved address in the context. What we do
1147 have is the CFA from the previous stack frame.
1149 In very special situations (such as unwind info for signal return),
1150 there may be location expressions that use the stack pointer as well.
1152 Do this conditionally for one frame. This allows the unwind info
1153 for one frame to save a copy of the stack pointer from the previous
1154 frame, and be able to use much easier CFA mechanisms to do it.
1155 Always zap the saved stack pointer value for the next frame; carrying
1156 the value over from one frame to another doesn't make sense. */
1158 _Unwind_SpTmp tmp_sp;
1160 if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
1161 _Unwind_SetSpColumn (&orig_context, context->cfa, &tmp_sp);
1162 _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
1163 #endif
1165 /* Compute this frame's CFA. */
1166 switch (fs->cfa_how)
1168 case CFA_REG_OFFSET:
1169 cfa = _Unwind_GetPtr (&orig_context, fs->cfa_reg);
1170 cfa += fs->cfa_offset;
1171 break;
1173 case CFA_EXP:
1175 const unsigned char *exp = fs->cfa_exp;
1176 _Unwind_Word len;
1178 exp = read_uleb128 (exp, &len);
1179 cfa = (void *) (_Unwind_Ptr)
1180 execute_stack_op (exp, exp + len, &orig_context, 0);
1181 break;
1184 default:
1185 abort ();
1187 context->cfa = cfa;
1189 /* Compute the addresses of all registers saved in this frame. */
1190 for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
1191 switch (fs->regs.reg[i].how)
1193 case REG_UNSAVED:
1194 break;
1196 case REG_SAVED_OFFSET:
1197 _Unwind_SetGRPtr (context, i,
1198 (void *) (cfa + fs->regs.reg[i].loc.offset));
1199 break;
1201 case REG_SAVED_REG:
1202 _Unwind_SetGRPtr
1203 (context, i,
1204 _Unwind_GetGRPtr (&orig_context, fs->regs.reg[i].loc.reg));
1205 break;
1207 case REG_SAVED_EXP:
1209 const unsigned char *exp = fs->regs.reg[i].loc.exp;
1210 _Unwind_Word len;
1211 _Unwind_Ptr val;
1213 exp = read_uleb128 (exp, &len);
1214 val = execute_stack_op (exp, exp + len, &orig_context,
1215 (_Unwind_Ptr) cfa);
1216 _Unwind_SetGRPtr (context, i, (void *) val);
1218 break;
1221 MD_FROB_UPDATE_CONTEXT (context, fs);
1224 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1225 of its caller. Update CONTEXT to refer to the caller as well. Note
1226 that the args_size and lsda members are not updated here, but later in
1227 uw_frame_state_for. */
1229 static void
1230 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1232 uw_update_context_1 (context, fs);
1234 /* Compute the return address now, since the return address column
1235 can change from frame to frame. */
1236 context->ra = __builtin_extract_return_addr
1237 (_Unwind_GetPtr (context, fs->retaddr_column));
1240 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1241 level will be the return address and the CFA. */
1243 #define uw_init_context(CONTEXT) \
1244 do \
1246 /* Do any necessary initialization to access arbitrary stack frames. \
1247 On the SPARC, this means flushing the register windows. */ \
1248 __builtin_unwind_init (); \
1249 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1250 __builtin_return_address (0)); \
1252 while (0)
1254 static inline void
1255 init_dwarf_reg_size_table (void)
1257 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
1260 static void
1261 uw_init_context_1 (struct _Unwind_Context *context,
1262 void *outer_cfa, void *outer_ra)
1264 void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
1265 _Unwind_FrameState fs;
1266 _Unwind_SpTmp sp_slot;
1268 memset (context, 0, sizeof (struct _Unwind_Context));
1269 context->ra = ra;
1271 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
1272 abort ();
1274 #if __GTHREADS
1276 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
1277 if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
1278 || dwarf_reg_size_table[0] == 0)
1279 init_dwarf_reg_size_table ();
1281 #else
1282 if (dwarf_reg_size_table[0] == 0)
1283 init_dwarf_reg_size_table ();
1284 #endif
1286 /* Force the frame state to use the known cfa value. */
1287 _Unwind_SetSpColumn (context, outer_cfa, &sp_slot);
1288 fs.cfa_how = CFA_REG_OFFSET;
1289 fs.cfa_reg = __builtin_dwarf_sp_column ();
1290 fs.cfa_offset = 0;
1292 uw_update_context_1 (context, &fs);
1294 /* If the return address column was saved in a register in the
1295 initialization context, then we can't see it in the given
1296 call frame data. So have the initialization context tell us. */
1297 context->ra = __builtin_extract_return_addr (outer_ra);
1301 /* Install TARGET into CURRENT so that we can return to it. This is a
1302 macro because __builtin_eh_return must be invoked in the context of
1303 our caller. */
1305 #define uw_install_context(CURRENT, TARGET) \
1306 do \
1308 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1309 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1310 __builtin_eh_return (offset, handler); \
1312 while (0)
1314 static long
1315 uw_install_context_1 (struct _Unwind_Context *current,
1316 struct _Unwind_Context *target)
1318 long i;
1320 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
1322 void *c = current->reg[i];
1323 void *t = target->reg[i];
1325 if (t && c && t != c)
1326 memcpy (c, t, dwarf_reg_size_table[i]);
1329 #ifdef EH_RETURN_STACKADJ_RTX
1331 void *target_cfa;
1333 /* If the last frame records a saved stack pointer, use it. */
1334 if (_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
1335 target_cfa = _Unwind_GetPtr (target, __builtin_dwarf_sp_column ());
1336 else
1337 target_cfa = target->cfa;
1339 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1340 if (STACK_GROWS_DOWNWARD)
1341 return target_cfa - current->cfa + target->args_size;
1342 else
1343 return current->cfa - target_cfa - target->args_size;
1345 #else
1346 return 0;
1347 #endif
1350 static inline _Unwind_Ptr
1351 uw_identify_context (struct _Unwind_Context *context)
1353 return _Unwind_GetIP (context);
1357 #include "unwind.inc"
1359 #endif /* !USING_SJLJ_EXCEPTIONS */