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)
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. */
25 #include "unwind-pe.h"
26 #include "unwind-dw2-fde.h"
30 #if !USING_SJLJ_EXCEPTIONS
32 #ifndef STACK_GROWS_DOWNWARD
33 #define STACK_GROWS_DOWNWARD 0
35 #undef STACK_GROWS_DOWNWARD
36 #define STACK_GROWS_DOWNWARD 1
39 /* A target can override (perhaps for backward compatibility) how
40 many dwarf2 columns are unwound. */
41 #ifndef DWARF_FRAME_REGISTERS
42 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
45 /* This is the register and unwind state for a particular frame. */
46 struct _Unwind_Context
48 void *reg
[DWARF_FRAME_REGISTERS
+1];
52 struct dwarf_eh_bases bases
;
53 _Unwind_Word args_size
;
56 /* Byte size of every register managed by these routines. */
57 static unsigned char dwarf_reg_size_table
[DWARF_FRAME_REGISTERS
];
60 /* The result of interpreting the frame unwind info for a frame.
61 This is all symbolic at this point, as none of the values can
62 be resolved until the target pc is located. */
65 /* Each register save state can be described in terms of a CFA slot,
66 another register, or a location expression. */
67 struct frame_state_reg_info
73 const unsigned char *exp
;
81 } reg
[DWARF_FRAME_REGISTERS
+1];
83 /* Used to implement DW_CFA_remember_state. */
84 struct frame_state_reg_info
*prev
;
87 /* The CFA can be described in terms of a reg+offset or a
88 location expression. */
89 _Unwind_Sword cfa_offset
;
91 const unsigned char *cfa_exp
;
98 /* The PC described by the current frame state. */
101 /* The information we care about from the CIE/FDE. */
102 _Unwind_Personality_Fn personality
;
103 signed int data_align
;
104 unsigned int code_align
;
105 unsigned char retaddr_column
;
106 unsigned char fde_encoding
;
107 unsigned char lsda_encoding
;
109 } _Unwind_FrameState
;
111 /* Read unaligned data from the instruction buffer. */
116 unsigned u2
__attribute__ ((mode (HI
)));
117 unsigned u4
__attribute__ ((mode (SI
)));
118 unsigned u8
__attribute__ ((mode (DI
)));
119 signed s2
__attribute__ ((mode (HI
)));
120 signed s4
__attribute__ ((mode (SI
)));
121 signed s8
__attribute__ ((mode (DI
)));
122 } __attribute__ ((packed
));
125 read_pointer (const void *p
) { const union unaligned
*up
= p
; return up
->p
; }
128 read_1u (const void *p
) { return *(const unsigned char *)p
; }
131 read_1s (const void *p
) { return *(const signed char *)p
; }
134 read_2u (const void *p
) { const union unaligned
*up
= p
; return up
->u2
; }
137 read_2s (const void *p
) { const union unaligned
*up
= p
; return up
->s2
; }
139 static inline unsigned int
140 read_4u (const void *p
) { const union unaligned
*up
= p
; return up
->u4
; }
143 read_4s (const void *p
) { const union unaligned
*up
= p
; return up
->s4
; }
145 static inline unsigned long
146 read_8u (const void *p
) { const union unaligned
*up
= p
; return up
->u8
; }
148 static inline unsigned long
149 read_8s (const void *p
) { const union unaligned
*up
= p
; return up
->s8
; }
151 /* Get the value of register REG as saved in CONTEXT. */
154 _Unwind_GetGR (struct _Unwind_Context
*context
, int index
)
156 /* This will segfault if the register hasn't been saved. */
157 return * (_Unwind_Word
*) context
->reg
[index
];
160 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
163 _Unwind_SetGR (struct _Unwind_Context
*context
, int index
, _Unwind_Word val
)
165 * (_Unwind_Word
*) context
->reg
[index
] = val
;
168 /* Retrieve the return address for CONTEXT. */
171 _Unwind_GetIP (struct _Unwind_Context
*context
)
173 return (_Unwind_Ptr
) context
->ra
;
176 /* Overwrite the return address for CONTEXT with VAL. */
179 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
181 context
->ra
= (void *) val
;
185 _Unwind_GetLanguageSpecificData (struct _Unwind_Context
*context
)
187 return context
->lsda
;
191 _Unwind_GetRegionStart (struct _Unwind_Context
*context
)
193 return (_Unwind_Ptr
) context
->bases
.func
;
198 _Unwind_GetDataRelBase (struct _Unwind_Context
*context
)
200 return (_Unwind_Ptr
) context
->bases
.dbase
;
204 _Unwind_GetTextRelBase (struct _Unwind_Context
*context
)
206 return (_Unwind_Ptr
) context
->bases
.tbase
;
210 /* Extract any interesting information from the CIE for the translation
211 unit F belongs to. Return a pointer to the byte after the augmentation,
212 or NULL if we encountered an undecipherable augmentation. */
214 static const unsigned char *
215 extract_cie_info (struct dwarf_cie
*cie
, struct _Unwind_Context
*context
,
216 _Unwind_FrameState
*fs
)
218 const unsigned char *aug
= cie
->augmentation
;
219 const unsigned char *p
= aug
+ strlen (aug
) + 1;
220 const unsigned char *ret
= NULL
;
223 /* Immediately following the augmentation are the code and
224 data alignment and return address column. */
225 p
= read_uleb128 (p
, &tmp
); fs
->code_align
= tmp
;
226 p
= read_sleb128 (p
, &tmp
); fs
->data_align
= (saddr
) tmp
;
227 fs
->retaddr_column
= *p
++;
228 fs
->lsda_encoding
= DW_EH_PE_omit
;
230 /* If the augmentation starts with 'z', then a uleb128 immediately
231 follows containing the length of the augmentation field following
235 p
= read_uleb128 (p
, &tmp
);
242 /* Iterate over recognized augmentation subsequences. */
245 /* "eh" was used by g++ v2; recognize and skip. */
246 if (aug
[0] == 'e' && aug
[1] == 'h')
248 p
+= sizeof (void *);
252 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
253 else if (aug
[0] == 'L')
255 fs
->lsda_encoding
= *p
++;
259 /* "R" indicates a byte indicating how FDE addresses are encoded. */
260 else if (aug
[0] == 'R')
262 fs
->fde_encoding
= *p
++;
266 /* "P" indicates a personality routine in the CIE augmentation. */
267 else if (aug
[0] == 'P')
269 p
= read_encoded_value (context
, *p
, p
+ 1,
270 (_Unwind_Ptr
*) &fs
->personality
);
274 /* Otherwise we have an unknown augmentation string.
275 Bail unless we saw a 'z' prefix. */
280 return ret
? ret
: p
;
284 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
285 onto the stack to start. */
288 execute_stack_op (const unsigned char *op_ptr
, const unsigned char *op_end
,
289 struct _Unwind_Context
*context
, _Unwind_Word initial
)
291 _Unwind_Word stack
[64]; /* ??? Assume this is enough. */
297 while (op_ptr
< op_end
)
299 enum dwarf_location_atom op
= *op_ptr
++;
300 _Unwind_Word result
, reg
;
301 _Unwind_Sword offset
;
338 result
= op
- DW_OP_lit0
;
342 result
= (_Unwind_Word
) (_Unwind_Ptr
) read_pointer (op_ptr
);
343 op_ptr
+= sizeof (void *);
347 result
= read_1u (op_ptr
);
351 result
= read_1s (op_ptr
);
355 result
= read_2u (op_ptr
);
359 result
= read_2s (op_ptr
);
363 result
= read_4u (op_ptr
);
367 result
= read_4s (op_ptr
);
371 result
= read_8u (op_ptr
);
375 result
= read_8s (op_ptr
);
379 op_ptr
= read_uleb128 (op_ptr
, &ptrtmp
);
383 op_ptr
= read_sleb128 (op_ptr
, &ptrtmp
);
384 result
= (saddr
)ptrtmp
;
419 result
= _Unwind_GetGR (context
, op
- DW_OP_reg0
);
422 op_ptr
= read_uleb128 (op_ptr
, &ptrtmp
); reg
= ptrtmp
;
423 result
= _Unwind_GetGR (context
, reg
);
458 op_ptr
= read_sleb128 (op_ptr
, &ptrtmp
); offset
= (saddr
)ptrtmp
;
459 result
= _Unwind_GetGR (context
, op
- DW_OP_breg0
) + offset
;
462 op_ptr
= read_uleb128 (op_ptr
, &ptrtmp
); reg
= ptrtmp
;
463 op_ptr
= read_sleb128 (op_ptr
, &ptrtmp
); offset
= (saddr
)ptrtmp
;
464 result
= _Unwind_GetGR (context
, reg
) + offset
;
470 result
= stack
[stack_elt
- 1];
480 if (offset
>= stack_elt
- 1)
482 result
= stack
[stack_elt
- 1 - offset
];
488 result
= stack
[stack_elt
- 2];
493 _Unwind_Word t1
, t2
, t3
;
497 t1
= stack
[stack_elt
- 1];
498 t2
= stack
[stack_elt
- 2];
499 t3
= stack
[stack_elt
- 3];
500 stack
[stack_elt
- 1] = t2
;
501 stack
[stack_elt
- 2] = t3
;
502 stack
[stack_elt
- 3] = t1
;
507 case DW_OP_deref_size
:
511 case DW_OP_plus_uconst
:
512 /* Unary operations. */
515 result
= stack
[stack_elt
];
521 void *ptr
= (void *)(_Unwind_Ptr
) result
;
522 result
= (_Unwind_Ptr
) read_pointer (ptr
);
526 case DW_OP_deref_size
:
528 void *ptr
= (void *)(_Unwind_Ptr
) result
;
532 result
= read_1u (ptr
);
535 result
= read_2u (ptr
);
538 result
= read_4u (ptr
);
541 result
= read_8u (ptr
);
550 if ((_Unwind_Sword
) result
< 0)
559 case DW_OP_plus_uconst
:
560 op_ptr
= read_uleb128 (op_ptr
, &ptrtmp
); reg
= ptrtmp
;
580 /* Binary operations. */
581 _Unwind_Word first
, second
;
582 if ((stack_elt
-= 2) < 0)
584 second
= stack
[stack_elt
];
585 first
= stack
[stack_elt
+ 1];
590 result
= second
& first
;
593 result
= (_Unwind_Sword
)second
/ (_Unwind_Sword
)first
;
596 result
= second
- first
;
599 result
= (_Unwind_Sword
)second
% (_Unwind_Sword
)first
;
602 result
= second
* first
;
605 result
= second
| first
;
608 result
= second
+ first
;
611 result
= second
<< first
;
614 result
= second
>> first
;
617 result
= (_Unwind_Sword
)second
>> first
;
620 result
= second
^ first
;
623 result
= (_Unwind_Sword
)first
<= (_Unwind_Sword
)second
;
626 result
= (_Unwind_Sword
)first
>= (_Unwind_Sword
)second
;
629 result
= (_Unwind_Sword
)first
== (_Unwind_Sword
)second
;
632 result
= (_Unwind_Sword
)first
< (_Unwind_Sword
)second
;
635 result
= (_Unwind_Sword
)first
> (_Unwind_Sword
)second
;
638 result
= (_Unwind_Sword
)first
!= (_Unwind_Sword
)second
;
645 offset
= read_2s (op_ptr
);
653 offset
= read_2s (op_ptr
);
655 if (stack
[stack_elt
] != 0)
666 /* Most things push a result value. */
667 if ((size_t) stack_elt
>= sizeof(stack
)/sizeof(*stack
))
669 stack
[++stack_elt
] = result
;
673 /* We were executing this program to get a value. It should be
677 return stack
[stack_elt
];
681 /* Decode DWARF 2 call frame information. Takes pointers the
682 instruction sequence to decode, current register information and
683 CIE info, and the PC range to evaluate. */
686 execute_cfa_program (const unsigned char *insn_ptr
,
687 const unsigned char *insn_end
,
688 struct _Unwind_Context
*context
,
689 _Unwind_FrameState
*fs
)
691 struct frame_state_reg_info
*unused_rs
= NULL
;
693 /* Don't allow remember/restore between CIE and FDE programs. */
694 fs
->regs
.prev
= NULL
;
696 while (insn_ptr
< insn_end
&& fs
->pc
< context
->ra
)
698 unsigned char insn
= *insn_ptr
++;
700 _Unwind_Sword offset
;
703 if (insn
& DW_CFA_advance_loc
)
704 fs
->pc
+= (insn
& 0x3f) * fs
->code_align
;
705 else if (insn
& DW_CFA_offset
)
708 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
);
709 offset
= ptrtmp
* fs
->data_align
;
710 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
711 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
713 else if (insn
& DW_CFA_restore
)
716 fs
->regs
.reg
[reg
].how
= REG_UNSAVED
;
721 insn_ptr
= read_encoded_value (context
, fs
->fde_encoding
,
722 insn_ptr
, (_Unwind_Ptr
*) &fs
->pc
);
725 case DW_CFA_advance_loc1
:
726 fs
->pc
+= read_1u (insn_ptr
) * fs
->code_align
;
729 case DW_CFA_advance_loc2
:
730 fs
->pc
+= read_2u (insn_ptr
) * fs
->code_align
;
733 case DW_CFA_advance_loc4
:
734 fs
->pc
+= read_4u (insn_ptr
) * fs
->code_align
;
738 case DW_CFA_offset_extended
:
739 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
); reg
= ptrtmp
;
740 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
);
741 offset
= ptrtmp
* fs
->data_align
;
742 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
743 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
746 case DW_CFA_restore_extended
:
747 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
); reg
= ptrtmp
;
748 fs
->regs
.reg
[reg
].how
= REG_UNSAVED
;
751 case DW_CFA_undefined
:
752 case DW_CFA_same_value
:
756 case DW_CFA_register
:
759 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
); reg
= ptrtmp
;
760 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
); reg2
= ptrtmp
;
761 fs
->regs
.reg
[reg
].how
= REG_SAVED_REG
;
762 fs
->regs
.reg
[reg
].loc
.reg
= reg2
;
766 case DW_CFA_remember_state
:
768 struct frame_state_reg_info
*new_rs
;
772 unused_rs
= unused_rs
->prev
;
775 new_rs
= alloca (sizeof (struct frame_state_reg_info
));
778 fs
->regs
.prev
= new_rs
;
782 case DW_CFA_restore_state
:
784 struct frame_state_reg_info
*old_rs
= fs
->regs
.prev
;
786 old_rs
->prev
= unused_rs
;
792 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
);
793 fs
->cfa_reg
= ptrtmp
;
794 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
);
795 fs
->cfa_offset
= ptrtmp
;
796 fs
->cfa_how
= CFA_REG_OFFSET
;
799 case DW_CFA_def_cfa_register
:
800 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
);
801 fs
->cfa_reg
= ptrtmp
;
802 fs
->cfa_how
= CFA_REG_OFFSET
;
805 case DW_CFA_def_cfa_offset
:
806 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
);
807 fs
->cfa_offset
= ptrtmp
;
808 /* cfa_how deliberately not set. */
811 case DW_CFA_def_cfa_expression
:
812 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
);
813 fs
->cfa_exp
= insn_ptr
;
814 fs
->cfa_how
= CFA_EXP
;
818 case DW_CFA_expression
:
819 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
); reg
= ptrtmp
;
820 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
);
821 fs
->regs
.reg
[reg
].how
= REG_SAVED_EXP
;
822 fs
->regs
.reg
[reg
].loc
.exp
= insn_ptr
;
826 /* From the 2.1 draft. */
827 case DW_CFA_offset_extended_sf
:
828 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
); reg
= ptrtmp
;
829 insn_ptr
= read_sleb128 (insn_ptr
, &ptrtmp
);
830 offset
= (saddr
)ptrtmp
* fs
->data_align
;
831 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
832 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
835 case DW_CFA_def_cfa_sf
:
836 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
);
837 fs
->cfa_reg
= ptrtmp
;
838 insn_ptr
= read_sleb128 (insn_ptr
, &ptrtmp
);
839 fs
->cfa_offset
= (saddr
)ptrtmp
;
840 fs
->cfa_how
= CFA_REG_OFFSET
;
843 case DW_CFA_def_cfa_offset_sf
:
844 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
);
845 fs
->cfa_offset
= ptrtmp
;
846 /* cfa_how deliberately not set. */
849 case DW_CFA_GNU_window_save
:
850 /* ??? Hardcoded for SPARC register window configuration. */
851 for (reg
= 16; reg
< 32; ++reg
)
853 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
854 fs
->regs
.reg
[reg
].loc
.offset
= (reg
- 16) * sizeof (void *);
858 case DW_CFA_GNU_args_size
:
859 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
);
860 context
->args_size
= ptrtmp
;
863 case DW_CFA_GNU_negative_offset_extended
:
864 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
865 older PowerPC code. */
866 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
); reg
= ptrtmp
;
867 insn_ptr
= read_uleb128 (insn_ptr
, &ptrtmp
);
868 offset
= ptrtmp
* fs
->data_align
;
869 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
870 fs
->regs
.reg
[reg
].loc
.offset
= -offset
;
879 static _Unwind_Reason_Code
880 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
882 struct dwarf_fde
*fde
;
883 struct dwarf_cie
*cie
;
884 const unsigned char *aug
, *insn
, *end
;
886 memset (fs
, 0, sizeof (*fs
));
887 context
->args_size
= 0;
890 fde
= _Unwind_Find_FDE (context
->ra
- 1, &context
->bases
);
893 /* Couldn't find frame unwind info for this function. Try a
894 target-specific fallback mechanism. This will necessarily
895 not profide a personality routine or LSDA. */
896 #ifdef MD_FALLBACK_FRAME_STATE_FOR
897 MD_FALLBACK_FRAME_STATE_FOR (context
, fs
, success
);
898 return _URC_END_OF_STACK
;
900 return _URC_NO_REASON
;
902 return _URC_END_OF_STACK
;
906 fs
->pc
= context
->bases
.func
;
909 insn
= extract_cie_info (cie
, context
, fs
);
911 /* CIE contained unknown augmentation. */
912 return _URC_FATAL_PHASE1_ERROR
;
914 /* First decode all the insns in the CIE. */
915 end
= (unsigned char *) next_fde ((struct dwarf_fde
*) cie
);
916 execute_cfa_program (insn
, end
, context
, fs
);
918 /* Locate augmentation for the fde. */
919 aug
= (unsigned char *)fde
+ sizeof (*fde
);
920 aug
+= 2 * size_of_encoded_value (fs
->fde_encoding
);
925 aug
= read_uleb128 (aug
, &i
);
928 if (fs
->lsda_encoding
!= DW_EH_PE_omit
)
929 aug
= read_encoded_value (context
, fs
->lsda_encoding
, aug
,
930 (_Unwind_Ptr
*) &context
->lsda
);
932 /* Then the insns in the FDE up to our target PC. */
935 end
= (unsigned char *) next_fde (fde
);
936 execute_cfa_program (insn
, end
, context
, fs
);
938 return _URC_NO_REASON
;
943 uw_update_context_1 (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
945 struct _Unwind_Context orig_context
= *context
;
949 /* Compute this frame's CFA. */
953 /* Special handling here: Many machines do not use a frame pointer,
954 and track the CFA only through offsets from the stack pointer from
955 one frame to the next. In this case, the stack pointer is never
956 stored, so it has no saved address in the context. What we do
957 have is the CFA from the previous stack frame. */
958 if (context
->reg
[fs
->cfa_reg
] == NULL
)
961 cfa
= (void *) (_Unwind_Ptr
) _Unwind_GetGR (context
, fs
->cfa_reg
);
962 cfa
+= fs
->cfa_offset
;
966 /* ??? No way of knowing what register number is the stack pointer
967 to do the same sort of handling as above. Assume that if the
968 CFA calculation is so complicated as to require a stack program
969 that this will not be a problem. */
971 const unsigned char *exp
= fs
->cfa_exp
;
974 exp
= read_uleb128 (exp
, &len
);
975 cfa
= (void *) (_Unwind_Ptr
)
976 execute_stack_op (exp
, exp
+ len
, context
, 0);
985 /* Compute the addresses of all registers saved in this frame. */
986 for (i
= 0; i
< DWARF_FRAME_REGISTERS
+ 1; ++i
)
987 switch (fs
->regs
.reg
[i
].how
)
991 case REG_SAVED_OFFSET
:
992 context
->reg
[i
] = cfa
+ fs
->regs
.reg
[i
].loc
.offset
;
995 context
->reg
[i
] = orig_context
.reg
[fs
->regs
.reg
[i
].loc
.reg
];
999 const unsigned char *exp
= fs
->regs
.reg
[i
].loc
.exp
;
1003 exp
= read_uleb128 (exp
, &len
);
1004 val
= execute_stack_op (exp
, exp
+ len
, &orig_context
,
1006 context
->reg
[i
] = (void *) val
;
1013 uw_update_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1015 uw_update_context_1 (context
, fs
);
1017 /* Compute the return address now, since the return address column
1018 can change from frame to frame. */
1019 context
->ra
= __builtin_extract_return_addr
1020 ((void *) (_Unwind_Ptr
) _Unwind_GetGR (context
, fs
->retaddr_column
));
1023 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1024 level will be the return address and the CFA. */
1026 #define uw_init_context(CONTEXT) \
1028 /* Do any necessary initialization to access arbitrary stack frames. \
1029 On the SPARC, this means flushing the register windows. */ \
1030 __builtin_unwind_init (); \
1031 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1032 __builtin_return_address (0)); \
1036 uw_init_context_1 (struct _Unwind_Context
*context
,
1037 void *outer_cfa
, void *outer_ra
)
1039 void *ra
= __builtin_extract_return_addr (__builtin_return_address (0));
1040 _Unwind_FrameState fs
;
1042 memset (context
, 0, sizeof (struct _Unwind_Context
));
1045 if (uw_frame_state_for (context
, &fs
) != _URC_NO_REASON
)
1048 /* Force the frame state to use the known cfa value. */
1049 context
->cfa
= outer_cfa
;
1050 fs
.cfa_how
= CFA_REG_OFFSET
;
1054 uw_update_context_1 (context
, &fs
);
1056 /* If the return address column was saved in a register in the
1057 initialization context, then we can't see it in the given
1058 call frame data. So have the initialization context tell us. */
1059 context
->ra
= __builtin_extract_return_addr (outer_ra
);
1063 /* Install TARGET into CURRENT so that we can return to it. This is a
1064 macro because __builtin_eh_return must be invoked in the context of
1067 #define uw_install_context(CURRENT, TARGET) \
1069 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1070 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1071 __builtin_eh_return (offset, handler); \
1075 init_dwarf_reg_size_table (void)
1077 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table
);
1081 uw_install_context_1 (struct _Unwind_Context
*current
,
1082 struct _Unwind_Context
*target
)
1088 static __gthread_once_t once_regsizes
= __GTHREAD_ONCE_INIT
;
1089 if (__gthread_once (&once_regsizes
, init_dwarf_reg_size_table
) != 0
1090 || dwarf_reg_size_table
[0] == 0)
1091 init_dwarf_reg_size_table ();
1094 if (dwarf_reg_size_table
[0] == 0)
1095 init_dwarf_reg_size_table ();
1098 for (i
= 0; i
< DWARF_FRAME_REGISTERS
; ++i
)
1100 void *c
= current
->reg
[i
];
1101 void *t
= target
->reg
[i
];
1102 if (t
&& c
&& t
!= c
)
1103 memcpy (c
, t
, dwarf_reg_size_table
[i
]);
1106 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1107 if (STACK_GROWS_DOWNWARD
)
1108 return target
->cfa
- current
->cfa
+ target
->args_size
;
1110 return current
->cfa
- target
->cfa
- target
->args_size
;
1113 static inline _Unwind_Ptr
1114 uw_identify_context (struct _Unwind_Context
*context
)
1116 return _Unwind_GetIP (context
);
1120 #include "unwind.inc"
1122 #endif /* !USING_SJLJ_EXCEPTIONS */