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
;
221 _Unwind_Word code_align
;
222 _Unwind_Sword data_align
;
224 /* Immediately following the augmentation are the code and
225 data alignment and return address column. */
226 p
= read_uleb128 (p
, &code_align
);
227 p
= read_sleb128 (p
, &data_align
);
228 fs
->code_align
= code_align
;
229 fs
->data_align
= data_align
;
230 fs
->retaddr_column
= *p
++;
231 fs
->lsda_encoding
= DW_EH_PE_omit
;
233 /* If the augmentation starts with 'z', then a uleb128 immediately
234 follows containing the length of the augmentation field following
239 p
= read_uleb128 (p
, &i
);
246 /* Iterate over recognized augmentation subsequences. */
249 /* "eh" was used by g++ v2; recognize and skip. */
250 if (aug
[0] == 'e' && aug
[1] == 'h')
252 p
+= sizeof (void *);
256 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
257 else if (aug
[0] == 'L')
259 fs
->lsda_encoding
= *p
++;
263 /* "R" indicates a byte indicating how FDE addresses are encoded. */
264 else if (aug
[0] == 'R')
266 fs
->fde_encoding
= *p
++;
270 /* "P" indicates a personality routine in the CIE augmentation. */
271 else if (aug
[0] == 'P')
273 p
= read_encoded_value (context
, *p
, p
+ 1,
274 (_Unwind_Ptr
*) &fs
->personality
);
278 /* Otherwise we have an unknown augmentation string.
279 Bail unless we saw a 'z' prefix. */
284 return ret
? ret
: p
;
288 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
289 onto the stack to start. */
292 execute_stack_op (const unsigned char *op_ptr
, const unsigned char *op_end
,
293 struct _Unwind_Context
*context
, _Unwind_Word initial
)
295 _Unwind_Word stack
[64]; /* ??? Assume this is enough. */
301 while (op_ptr
< op_end
)
303 enum dwarf_location_atom op
= *op_ptr
++;
304 _Unwind_Word result
, reg
;
305 _Unwind_Sword offset
;
341 result
= op
- DW_OP_lit0
;
345 result
= (_Unwind_Word
) (_Unwind_Ptr
) read_pointer (op_ptr
);
346 op_ptr
+= sizeof (void *);
350 result
= read_1u (op_ptr
);
354 result
= read_1s (op_ptr
);
358 result
= read_2u (op_ptr
);
362 result
= read_2s (op_ptr
);
366 result
= read_4u (op_ptr
);
370 result
= read_4s (op_ptr
);
374 result
= read_8u (op_ptr
);
378 result
= read_8s (op_ptr
);
382 op_ptr
= read_uleb128 (op_ptr
, &result
);
385 op_ptr
= read_sleb128 (op_ptr
, &offset
);
421 result
= _Unwind_GetGR (context
, op
- DW_OP_reg0
);
424 op_ptr
= read_uleb128 (op_ptr
, ®
);
425 result
= _Unwind_GetGR (context
, reg
);
460 op_ptr
= read_sleb128 (op_ptr
, &offset
);
461 result
= _Unwind_GetGR (context
, op
- DW_OP_breg0
) + offset
;
464 op_ptr
= read_uleb128 (op_ptr
, ®
);
465 op_ptr
= read_sleb128 (op_ptr
, &offset
);
466 result
= _Unwind_GetGR (context
, reg
) + offset
;
472 result
= stack
[stack_elt
- 1];
482 if (offset
>= stack_elt
- 1)
484 result
= stack
[stack_elt
- 1 - offset
];
490 result
= stack
[stack_elt
- 2];
495 _Unwind_Word t1
, t2
, t3
;
499 t1
= stack
[stack_elt
- 1];
500 t2
= stack
[stack_elt
- 2];
501 t3
= stack
[stack_elt
- 3];
502 stack
[stack_elt
- 1] = t2
;
503 stack
[stack_elt
- 2] = t3
;
504 stack
[stack_elt
- 3] = t1
;
509 case DW_OP_deref_size
:
513 case DW_OP_plus_uconst
:
514 /* Unary operations. */
517 result
= stack
[stack_elt
];
523 void *ptr
= (void *)(_Unwind_Ptr
) result
;
524 result
= (_Unwind_Ptr
) read_pointer (ptr
);
528 case DW_OP_deref_size
:
530 void *ptr
= (void *)(_Unwind_Ptr
) result
;
534 result
= read_1u (ptr
);
537 result
= read_2u (ptr
);
540 result
= read_4u (ptr
);
543 result
= read_8u (ptr
);
552 if ((_Unwind_Sword
) result
< 0)
561 case DW_OP_plus_uconst
:
562 op_ptr
= read_uleb128 (op_ptr
, ®
);
582 /* Binary operations. */
583 _Unwind_Word first
, second
;
584 if ((stack_elt
-= 2) < 0)
586 second
= stack
[stack_elt
];
587 first
= stack
[stack_elt
+ 1];
592 result
= second
& first
;
595 result
= (_Unwind_Sword
)second
/ (_Unwind_Sword
)first
;
598 result
= second
- first
;
601 result
= (_Unwind_Sword
)second
% (_Unwind_Sword
)first
;
604 result
= second
* first
;
607 result
= second
| first
;
610 result
= second
+ first
;
613 result
= second
<< first
;
616 result
= second
>> first
;
619 result
= (_Unwind_Sword
)second
>> first
;
622 result
= second
^ first
;
625 result
= (_Unwind_Sword
)first
<= (_Unwind_Sword
)second
;
628 result
= (_Unwind_Sword
)first
>= (_Unwind_Sword
)second
;
631 result
= (_Unwind_Sword
)first
== (_Unwind_Sword
)second
;
634 result
= (_Unwind_Sword
)first
< (_Unwind_Sword
)second
;
637 result
= (_Unwind_Sword
)first
> (_Unwind_Sword
)second
;
640 result
= (_Unwind_Sword
)first
!= (_Unwind_Sword
)second
;
647 offset
= read_2s (op_ptr
);
655 offset
= read_2s (op_ptr
);
657 if (stack
[stack_elt
] != 0)
668 /* Most things push a result value. */
669 if ((size_t) stack_elt
>= sizeof(stack
)/sizeof(*stack
))
671 stack
[++stack_elt
] = result
;
675 /* We were executing this program to get a value. It should be
679 return stack
[stack_elt
];
683 /* Decode DWARF 2 call frame information. Takes pointers the
684 instruction sequence to decode, current register information and
685 CIE info, and the PC range to evaluate. */
688 execute_cfa_program (const unsigned char *insn_ptr
,
689 const unsigned char *insn_end
,
690 struct _Unwind_Context
*context
,
691 _Unwind_FrameState
*fs
)
693 struct frame_state_reg_info
*unused_rs
= NULL
;
695 /* Don't allow remember/restore between CIE and FDE programs. */
696 fs
->regs
.prev
= NULL
;
698 while (insn_ptr
< insn_end
&& fs
->pc
< context
->ra
)
700 unsigned char insn
= *insn_ptr
++;
701 _Unwind_Word reg
, uoffset
;
702 _Unwind_Sword offset
;
704 if (insn
& DW_CFA_advance_loc
)
705 fs
->pc
+= (insn
& 0x3f) * fs
->code_align
;
706 else if (insn
& DW_CFA_offset
)
709 insn_ptr
= read_uleb128 (insn_ptr
, &uoffset
);
710 offset
= (_Unwind_Sword
)uoffset
* fs
->data_align
;
711 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
712 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
714 else if (insn
& DW_CFA_restore
)
717 fs
->regs
.reg
[reg
].how
= REG_UNSAVED
;
722 insn_ptr
= read_encoded_value (context
, fs
->fde_encoding
,
723 insn_ptr
, (_Unwind_Ptr
*) &fs
->pc
);
726 case DW_CFA_advance_loc1
:
727 fs
->pc
+= read_1u (insn_ptr
);
730 case DW_CFA_advance_loc2
:
731 fs
->pc
+= read_2u (insn_ptr
);
734 case DW_CFA_advance_loc4
:
735 fs
->pc
+= read_4u (insn_ptr
);
739 case DW_CFA_offset_extended
:
740 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
741 insn_ptr
= read_uleb128 (insn_ptr
, &uoffset
);
742 offset
= (_Unwind_Sword
)uoffset
* fs
->data_align
;
743 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
744 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
747 case DW_CFA_restore_extended
:
748 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
749 fs
->regs
.reg
[reg
].how
= REG_UNSAVED
;
752 case DW_CFA_undefined
:
753 case DW_CFA_same_value
:
757 case DW_CFA_register
:
760 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
761 insn_ptr
= read_uleb128 (insn_ptr
, ®2
);
762 fs
->regs
.reg
[reg
].how
= REG_SAVED_REG
;
763 fs
->regs
.reg
[reg
].loc
.reg
= reg2
;
767 case DW_CFA_remember_state
:
769 struct frame_state_reg_info
*new_rs
;
773 unused_rs
= unused_rs
->prev
;
776 new_rs
= alloca (sizeof (struct frame_state_reg_info
));
779 fs
->regs
.prev
= new_rs
;
783 case DW_CFA_restore_state
:
785 struct frame_state_reg_info
*old_rs
= fs
->regs
.prev
;
787 old_rs
->prev
= unused_rs
;
793 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
794 insn_ptr
= read_uleb128 (insn_ptr
, &uoffset
);
795 fs
->cfa_offset
= uoffset
;
796 fs
->cfa_how
= CFA_REG_OFFSET
;
799 case DW_CFA_def_cfa_register
:
800 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
801 fs
->cfa_how
= CFA_REG_OFFSET
;
804 case DW_CFA_def_cfa_offset
:
805 insn_ptr
= read_uleb128 (insn_ptr
, &uoffset
);
806 fs
->cfa_offset
= uoffset
;
807 /* cfa_how deliberately not set. */
810 case DW_CFA_def_cfa_expression
:
811 insn_ptr
= read_uleb128 (insn_ptr
, &uoffset
);
812 fs
->cfa_exp
= insn_ptr
;
813 fs
->cfa_how
= CFA_EXP
;
817 case DW_CFA_expression
:
818 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
819 insn_ptr
= read_uleb128 (insn_ptr
, &uoffset
);
820 fs
->regs
.reg
[reg
].how
= REG_SAVED_EXP
;
821 fs
->regs
.reg
[reg
].loc
.exp
= insn_ptr
;
825 /* From the 2.1 draft. */
826 case DW_CFA_offset_extended_sf
:
827 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
828 insn_ptr
= read_sleb128 (insn_ptr
, &offset
);
829 offset
*= fs
->data_align
;
830 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
831 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
834 case DW_CFA_def_cfa_sf
:
835 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
836 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
837 fs
->cfa_how
= CFA_REG_OFFSET
;
840 case DW_CFA_def_cfa_offset_sf
:
841 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_offset
);
842 /* cfa_how deliberately not set. */
845 case DW_CFA_GNU_window_save
:
846 /* ??? Hardcoded for SPARC register window configuration. */
847 for (reg
= 16; reg
< 32; ++reg
)
849 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
850 fs
->regs
.reg
[reg
].loc
.offset
= (reg
- 16) * sizeof (void *);
854 case DW_CFA_GNU_args_size
:
855 insn_ptr
= read_uleb128 (insn_ptr
, &context
->args_size
);
858 case DW_CFA_GNU_negative_offset_extended
:
859 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
860 older PowerPC code. */
861 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
862 insn_ptr
= read_uleb128 (insn_ptr
, &uoffset
);
863 offset
= (_Unwind_Sword
)uoffset
* fs
->data_align
;
864 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
865 fs
->regs
.reg
[reg
].loc
.offset
= -offset
;
874 static _Unwind_Reason_Code
875 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
877 struct dwarf_fde
*fde
;
878 struct dwarf_cie
*cie
;
879 const unsigned char *aug
, *insn
, *end
;
881 memset (fs
, 0, sizeof (*fs
));
882 context
->args_size
= 0;
885 fde
= _Unwind_Find_FDE (context
->ra
- 1, &context
->bases
);
888 /* Couldn't find frame unwind info for this function. Try a
889 target-specific fallback mechanism. This will necessarily
890 not profide a personality routine or LSDA. */
891 #ifdef MD_FALLBACK_FRAME_STATE_FOR
892 MD_FALLBACK_FRAME_STATE_FOR (context
, fs
, success
);
893 return _URC_END_OF_STACK
;
895 return _URC_NO_REASON
;
897 return _URC_END_OF_STACK
;
901 fs
->pc
= context
->bases
.func
;
904 insn
= extract_cie_info (cie
, context
, fs
);
906 /* CIE contained unknown augmentation. */
907 return _URC_FATAL_PHASE1_ERROR
;
909 /* First decode all the insns in the CIE. */
910 end
= (unsigned char *) next_fde ((struct dwarf_fde
*) cie
);
911 execute_cfa_program (insn
, end
, context
, fs
);
913 /* Locate augmentation for the fde. */
914 aug
= (unsigned char *)fde
+ sizeof (*fde
);
915 aug
+= 2 * size_of_encoded_value (fs
->fde_encoding
);
920 aug
= read_uleb128 (aug
, &i
);
923 if (fs
->lsda_encoding
!= DW_EH_PE_omit
)
924 aug
= read_encoded_value (context
, fs
->lsda_encoding
, aug
,
925 (_Unwind_Ptr
*) &context
->lsda
);
927 /* Then the insns in the FDE up to our target PC. */
930 end
= (unsigned char *) next_fde (fde
);
931 execute_cfa_program (insn
, end
, context
, fs
);
933 return _URC_NO_REASON
;
938 uw_update_context_1 (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
940 struct _Unwind_Context orig_context
= *context
;
944 /* Compute this frame's CFA. */
948 /* Special handling here: Many machines do not use a frame pointer,
949 and track the CFA only through offsets from the stack pointer from
950 one frame to the next. In this case, the stack pointer is never
951 stored, so it has no saved address in the context. What we do
952 have is the CFA from the previous stack frame. */
953 if (context
->reg
[fs
->cfa_reg
] == NULL
)
956 cfa
= (void *) (_Unwind_Ptr
) _Unwind_GetGR (context
, fs
->cfa_reg
);
957 cfa
+= fs
->cfa_offset
;
961 /* ??? No way of knowing what register number is the stack pointer
962 to do the same sort of handling as above. Assume that if the
963 CFA calculation is so complicated as to require a stack program
964 that this will not be a problem. */
966 const unsigned char *exp
= fs
->cfa_exp
;
969 exp
= read_uleb128 (exp
, &len
);
970 cfa
= (void *) (_Unwind_Ptr
)
971 execute_stack_op (exp
, exp
+ len
, context
, 0);
980 /* Compute the addresses of all registers saved in this frame. */
981 for (i
= 0; i
< DWARF_FRAME_REGISTERS
+ 1; ++i
)
982 switch (fs
->regs
.reg
[i
].how
)
986 case REG_SAVED_OFFSET
:
987 context
->reg
[i
] = cfa
+ fs
->regs
.reg
[i
].loc
.offset
;
990 context
->reg
[i
] = orig_context
.reg
[fs
->regs
.reg
[i
].loc
.reg
];
994 const unsigned char *exp
= fs
->regs
.reg
[i
].loc
.exp
;
998 exp
= read_uleb128 (exp
, &len
);
999 val
= execute_stack_op (exp
, exp
+ len
, &orig_context
,
1001 context
->reg
[i
] = (void *) val
;
1008 uw_update_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1010 uw_update_context_1 (context
, fs
);
1012 /* Compute the return address now, since the return address column
1013 can change from frame to frame. */
1014 context
->ra
= __builtin_extract_return_addr
1015 ((void *) (_Unwind_Ptr
) _Unwind_GetGR (context
, fs
->retaddr_column
));
1018 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1019 level will be the return address and the CFA. */
1021 #define uw_init_context(CONTEXT) \
1023 /* Do any necessary initialization to access arbitrary stack frames. \
1024 On the SPARC, this means flushing the register windows. */ \
1025 __builtin_unwind_init (); \
1026 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1027 __builtin_return_address (0)); \
1031 uw_init_context_1 (struct _Unwind_Context
*context
,
1032 void *outer_cfa
, void *outer_ra
)
1034 void *ra
= __builtin_extract_return_addr (__builtin_return_address (0));
1035 _Unwind_FrameState fs
;
1037 memset (context
, 0, sizeof (struct _Unwind_Context
));
1040 if (uw_frame_state_for (context
, &fs
) != _URC_NO_REASON
)
1043 /* Force the frame state to use the known cfa value. */
1044 context
->cfa
= outer_cfa
;
1045 fs
.cfa_how
= CFA_REG_OFFSET
;
1049 uw_update_context_1 (context
, &fs
);
1051 /* If the return address column was saved in a register in the
1052 initialization context, then we can't see it in the given
1053 call frame data. So have the initialization context tell us. */
1054 context
->ra
= __builtin_extract_return_addr (outer_ra
);
1058 /* Install TARGET into CURRENT so that we can return to it. This is a
1059 macro because __builtin_eh_return must be invoked in the context of
1062 #define uw_install_context(CURRENT, TARGET) \
1064 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1065 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1066 __builtin_eh_return (offset, handler); \
1070 init_dwarf_reg_size_table (void)
1072 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table
);
1076 uw_install_context_1 (struct _Unwind_Context
*current
,
1077 struct _Unwind_Context
*target
)
1083 static __gthread_once_t once_regsizes
= __GTHREAD_ONCE_INIT
;
1084 if (__gthread_once (&once_regsizes
, init_dwarf_reg_size_table
) != 0
1085 || dwarf_reg_size_table
[0] == 0)
1086 init_dwarf_reg_size_table ();
1089 if (dwarf_reg_size_table
[0] == 0)
1090 init_dwarf_reg_size_table ();
1093 for (i
= 0; i
< DWARF_FRAME_REGISTERS
; ++i
)
1095 void *c
= current
->reg
[i
];
1096 void *t
= target
->reg
[i
];
1097 if (t
&& c
&& t
!= c
)
1098 memcpy (c
, t
, dwarf_reg_size_table
[i
]);
1101 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1102 if (STACK_GROWS_DOWNWARD
)
1103 return target
->cfa
- current
->cfa
+ target
->args_size
;
1105 return current
->cfa
- target
->cfa
- target
->args_size
;
1108 static inline _Unwind_Ptr
1109 uw_identify_context (struct _Unwind_Context
*context
)
1111 return _Unwind_GetIP (context
);
1115 #include "unwind.inc"
1117 #endif /* !USING_SJLJ_EXCEPTIONS */