1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
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)
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 #include "coretypes.h"
28 #include "unwind-pe.h"
29 #include "unwind-dw2-fde.h"
33 #ifndef __USING_SJLJ_EXCEPTIONS__
35 #ifndef STACK_GROWS_DOWNWARD
36 #define STACK_GROWS_DOWNWARD 0
38 #undef STACK_GROWS_DOWNWARD
39 #define STACK_GROWS_DOWNWARD 1
42 /* A target can override (perhaps for backward compatibility) how
43 many dwarf2 columns are unwound. */
44 #ifndef DWARF_FRAME_REGISTERS
45 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
48 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
49 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
50 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
53 /* This is the register and unwind state for a particular frame. This
54 provides the information necessary to unwind up past a frame and return
56 struct _Unwind_Context
58 void *reg
[DWARF_FRAME_REGISTERS
+1];
62 struct dwarf_eh_bases bases
;
63 _Unwind_Word args_size
;
66 /* Byte size of every register managed by these routines. */
67 static unsigned char dwarf_reg_size_table
[DWARF_FRAME_REGISTERS
];
70 /* The result of interpreting the frame unwind info for a frame.
71 This is all symbolic at this point, as none of the values can
72 be resolved until the target pc is located. */
75 /* Each register save state can be described in terms of a CFA slot,
76 another register, or a location expression. */
77 struct frame_state_reg_info
83 const unsigned char *exp
;
91 } reg
[DWARF_FRAME_REGISTERS
+1];
93 /* Used to implement DW_CFA_remember_state. */
94 struct frame_state_reg_info
*prev
;
97 /* The CFA can be described in terms of a reg+offset or a
98 location expression. */
99 _Unwind_Sword cfa_offset
;
100 _Unwind_Word cfa_reg
;
101 const unsigned char *cfa_exp
;
108 /* The PC described by the current frame state. */
111 /* The information we care about from the CIE/FDE. */
112 _Unwind_Personality_Fn personality
;
113 _Unwind_Sword data_align
;
114 _Unwind_Word code_align
;
115 unsigned char retaddr_column
;
116 unsigned char fde_encoding
;
117 unsigned char lsda_encoding
;
120 } _Unwind_FrameState
;
122 /* Read unaligned data from the instruction buffer. */
127 unsigned u2
__attribute__ ((mode (HI
)));
128 unsigned u4
__attribute__ ((mode (SI
)));
129 unsigned u8
__attribute__ ((mode (DI
)));
130 signed s2
__attribute__ ((mode (HI
)));
131 signed s4
__attribute__ ((mode (SI
)));
132 signed s8
__attribute__ ((mode (DI
)));
133 } __attribute__ ((packed
));
136 read_pointer (const void *p
) { const union unaligned
*up
= p
; return up
->p
; }
139 read_1u (const void *p
) { return *(const unsigned char *) p
; }
142 read_1s (const void *p
) { return *(const signed char *) p
; }
145 read_2u (const void *p
) { const union unaligned
*up
= p
; return up
->u2
; }
148 read_2s (const void *p
) { const union unaligned
*up
= p
; return up
->s2
; }
150 static inline unsigned int
151 read_4u (const void *p
) { const union unaligned
*up
= p
; return up
->u4
; }
154 read_4s (const void *p
) { const union unaligned
*up
= p
; return up
->s4
; }
156 static inline unsigned long
157 read_8u (const void *p
) { const union unaligned
*up
= p
; return up
->u8
; }
159 static inline unsigned long
160 read_8s (const void *p
) { const union unaligned
*up
= p
; return up
->s8
; }
162 /* Get the value of register REG as saved in CONTEXT. */
165 _Unwind_GetGR (struct _Unwind_Context
*context
, int index
)
167 /* This will segfault if the register hasn't been saved. */
168 return * (_Unwind_Word
*) context
->reg
[index
];
171 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
174 _Unwind_SetGR (struct _Unwind_Context
*context
, int index
, _Unwind_Word val
)
176 * (_Unwind_Word
*) context
->reg
[index
] = val
;
179 /* Retrieve the return address for CONTEXT. */
182 _Unwind_GetIP (struct _Unwind_Context
*context
)
184 return (_Unwind_Ptr
) context
->ra
;
187 /* Overwrite the return address for CONTEXT with VAL. */
190 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
192 context
->ra
= (void *) val
;
196 _Unwind_GetLanguageSpecificData (struct _Unwind_Context
*context
)
198 return context
->lsda
;
202 _Unwind_GetRegionStart (struct _Unwind_Context
*context
)
204 return (_Unwind_Ptr
) context
->bases
.func
;
208 _Unwind_FindEnclosingFunction (void *pc
)
210 struct dwarf_eh_bases bases
;
211 struct dwarf_fde
*fde
= _Unwind_Find_FDE (pc
-1, &bases
);
220 _Unwind_GetDataRelBase (struct _Unwind_Context
*context
)
222 return (_Unwind_Ptr
) context
->bases
.dbase
;
226 _Unwind_GetTextRelBase (struct _Unwind_Context
*context
)
228 return (_Unwind_Ptr
) context
->bases
.tbase
;
232 /* Extract any interesting information from the CIE for the translation
233 unit F belongs to. Return a pointer to the byte after the augmentation,
234 or NULL if we encountered an undecipherable augmentation. */
236 static const unsigned char *
237 extract_cie_info (struct dwarf_cie
*cie
, struct _Unwind_Context
*context
,
238 _Unwind_FrameState
*fs
)
240 const unsigned char *aug
= cie
->augmentation
;
241 const unsigned char *p
= aug
+ strlen (aug
) + 1;
242 const unsigned char *ret
= NULL
;
245 /* g++ v2 "eh" has pointer immediately following augmentation string,
246 so it must be handled first. */
247 if (aug
[0] == 'e' && aug
[1] == 'h')
249 fs
->eh_ptr
= read_pointer (p
);
250 p
+= sizeof (void *);
254 /* Immediately following the augmentation are the code and
255 data alignment and return address column. */
256 p
= read_uleb128 (p
, &fs
->code_align
);
257 p
= read_sleb128 (p
, &fs
->data_align
);
258 fs
->retaddr_column
= *p
++;
259 fs
->lsda_encoding
= DW_EH_PE_omit
;
261 /* If the augmentation starts with 'z', then a uleb128 immediately
262 follows containing the length of the augmentation field following
266 p
= read_uleb128 (p
, &utmp
);
273 /* Iterate over recognized augmentation subsequences. */
276 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
279 fs
->lsda_encoding
= *p
++;
283 /* "R" indicates a byte indicating how FDE addresses are encoded. */
284 else if (aug
[0] == 'R')
286 fs
->fde_encoding
= *p
++;
290 /* "P" indicates a personality routine in the CIE augmentation. */
291 else if (aug
[0] == 'P')
293 p
= read_encoded_value (context
, *p
, p
+ 1,
294 (_Unwind_Ptr
*) &fs
->personality
);
298 /* Otherwise we have an unknown augmentation string.
299 Bail unless we saw a 'z' prefix. */
304 return ret
? ret
: p
;
308 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
309 onto the stack to start. */
312 execute_stack_op (const unsigned char *op_ptr
, const unsigned char *op_end
,
313 struct _Unwind_Context
*context
, _Unwind_Word initial
)
315 _Unwind_Word stack
[64]; /* ??? Assume this is enough. */
321 while (op_ptr
< op_end
)
323 enum dwarf_location_atom op
= *op_ptr
++;
324 _Unwind_Word result
, reg
, utmp
;
325 _Unwind_Sword offset
, stmp
;
361 result
= op
- DW_OP_lit0
;
365 result
= (_Unwind_Word
) (_Unwind_Ptr
) read_pointer (op_ptr
);
366 op_ptr
+= sizeof (void *);
370 result
= read_1u (op_ptr
);
374 result
= read_1s (op_ptr
);
378 result
= read_2u (op_ptr
);
382 result
= read_2s (op_ptr
);
386 result
= read_4u (op_ptr
);
390 result
= read_4s (op_ptr
);
394 result
= read_8u (op_ptr
);
398 result
= read_8s (op_ptr
);
402 op_ptr
= read_uleb128 (op_ptr
, &result
);
405 op_ptr
= read_sleb128 (op_ptr
, &stmp
);
441 result
= _Unwind_GetGR (context
, op
- DW_OP_reg0
);
444 op_ptr
= read_uleb128 (op_ptr
, ®
);
445 result
= _Unwind_GetGR (context
, reg
);
480 op_ptr
= read_sleb128 (op_ptr
, &offset
);
481 result
= _Unwind_GetGR (context
, op
- DW_OP_breg0
) + offset
;
484 op_ptr
= read_uleb128 (op_ptr
, ®
);
485 op_ptr
= read_sleb128 (op_ptr
, &offset
);
486 result
= _Unwind_GetGR (context
, reg
) + offset
;
492 result
= stack
[stack_elt
- 1];
502 if (offset
>= stack_elt
- 1)
504 result
= stack
[stack_elt
- 1 - offset
];
510 result
= stack
[stack_elt
- 2];
515 _Unwind_Word t1
, t2
, t3
;
519 t1
= stack
[stack_elt
- 1];
520 t2
= stack
[stack_elt
- 2];
521 t3
= stack
[stack_elt
- 3];
522 stack
[stack_elt
- 1] = t2
;
523 stack
[stack_elt
- 2] = t3
;
524 stack
[stack_elt
- 3] = t1
;
529 case DW_OP_deref_size
:
533 case DW_OP_plus_uconst
:
534 /* Unary operations. */
537 result
= stack
[stack_elt
];
543 void *ptr
= (void *) (_Unwind_Ptr
) result
;
544 result
= (_Unwind_Ptr
) read_pointer (ptr
);
548 case DW_OP_deref_size
:
550 void *ptr
= (void *) (_Unwind_Ptr
) result
;
554 result
= read_1u (ptr
);
557 result
= read_2u (ptr
);
560 result
= read_4u (ptr
);
563 result
= read_8u (ptr
);
572 if ((_Unwind_Sword
) result
< 0)
581 case DW_OP_plus_uconst
:
582 op_ptr
= read_uleb128 (op_ptr
, &utmp
);
605 /* Binary operations. */
606 _Unwind_Word first
, second
;
607 if ((stack_elt
-= 2) < 0)
609 second
= stack
[stack_elt
];
610 first
= stack
[stack_elt
+ 1];
615 result
= second
& first
;
618 result
= (_Unwind_Sword
) second
/ (_Unwind_Sword
) first
;
621 result
= second
- first
;
624 result
= (_Unwind_Sword
) second
% (_Unwind_Sword
) first
;
627 result
= second
* first
;
630 result
= second
| first
;
633 result
= second
+ first
;
636 result
= second
<< first
;
639 result
= second
>> first
;
642 result
= (_Unwind_Sword
) second
>> first
;
645 result
= second
^ first
;
648 result
= (_Unwind_Sword
) first
<= (_Unwind_Sword
) second
;
651 result
= (_Unwind_Sword
) first
>= (_Unwind_Sword
) second
;
654 result
= (_Unwind_Sword
) first
== (_Unwind_Sword
) second
;
657 result
= (_Unwind_Sword
) first
< (_Unwind_Sword
) second
;
660 result
= (_Unwind_Sword
) first
> (_Unwind_Sword
) second
;
663 result
= (_Unwind_Sword
) first
!= (_Unwind_Sword
) second
;
673 offset
= read_2s (op_ptr
);
681 offset
= read_2s (op_ptr
);
683 if (stack
[stack_elt
] != 0)
694 /* Most things push a result value. */
695 if ((size_t) stack_elt
>= sizeof(stack
)/sizeof(*stack
))
697 stack
[++stack_elt
] = result
;
701 /* We were executing this program to get a value. It should be
705 return stack
[stack_elt
];
709 /* Decode DWARF 2 call frame information. Takes pointers the
710 instruction sequence to decode, current register information and
711 CIE info, and the PC range to evaluate. */
714 execute_cfa_program (const unsigned char *insn_ptr
,
715 const unsigned char *insn_end
,
716 struct _Unwind_Context
*context
,
717 _Unwind_FrameState
*fs
)
719 struct frame_state_reg_info
*unused_rs
= NULL
;
721 /* Don't allow remember/restore between CIE and FDE programs. */
722 fs
->regs
.prev
= NULL
;
724 /* The comparison with the return address uses < rather than <= because
725 we are only interested in the effects of code before the call; for a
726 noreturn function, the return address may point to unrelated code with
727 a different stack configuration that we are not interested in. We
728 assume that the call itself is unwind info-neutral; if not, or if
729 there are delay instructions that adjust the stack, these must be
730 reflected at the point immediately before the call insn. */
731 while (insn_ptr
< insn_end
&& fs
->pc
< context
->ra
)
733 unsigned char insn
= *insn_ptr
++;
734 _Unwind_Word reg
, utmp
;
735 _Unwind_Sword offset
, stmp
;
737 if ((insn
& 0xc0) == DW_CFA_advance_loc
)
738 fs
->pc
+= (insn
& 0x3f) * fs
->code_align
;
739 else if ((insn
& 0xc0) == DW_CFA_offset
)
742 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
743 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
744 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
745 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
747 else if ((insn
& 0xc0) == DW_CFA_restore
)
750 fs
->regs
.reg
[reg
].how
= REG_UNSAVED
;
755 insn_ptr
= read_encoded_value (context
, fs
->fde_encoding
,
756 insn_ptr
, (_Unwind_Ptr
*) &fs
->pc
);
759 case DW_CFA_advance_loc1
:
760 fs
->pc
+= read_1u (insn_ptr
) * fs
->code_align
;
763 case DW_CFA_advance_loc2
:
764 fs
->pc
+= read_2u (insn_ptr
) * fs
->code_align
;
767 case DW_CFA_advance_loc4
:
768 fs
->pc
+= read_4u (insn_ptr
) * fs
->code_align
;
772 case DW_CFA_offset_extended
:
773 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
774 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
775 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
776 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
777 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
780 case DW_CFA_restore_extended
:
781 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
782 fs
->regs
.reg
[reg
].how
= REG_UNSAVED
;
785 case DW_CFA_undefined
:
786 case DW_CFA_same_value
:
790 case DW_CFA_register
:
793 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
794 insn_ptr
= read_uleb128 (insn_ptr
, ®2
);
795 fs
->regs
.reg
[reg
].how
= REG_SAVED_REG
;
796 fs
->regs
.reg
[reg
].loc
.reg
= reg2
;
800 case DW_CFA_remember_state
:
802 struct frame_state_reg_info
*new_rs
;
806 unused_rs
= unused_rs
->prev
;
809 new_rs
= __builtin_alloca (sizeof (struct frame_state_reg_info
));
812 fs
->regs
.prev
= new_rs
;
816 case DW_CFA_restore_state
:
818 struct frame_state_reg_info
*old_rs
= fs
->regs
.prev
;
820 old_rs
->prev
= unused_rs
;
826 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
827 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
828 fs
->cfa_offset
= utmp
;
829 fs
->cfa_how
= CFA_REG_OFFSET
;
832 case DW_CFA_def_cfa_register
:
833 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
834 fs
->cfa_how
= CFA_REG_OFFSET
;
837 case DW_CFA_def_cfa_offset
:
838 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
839 fs
->cfa_offset
= utmp
;
840 /* cfa_how deliberately not set. */
843 case DW_CFA_def_cfa_expression
:
844 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
845 fs
->cfa_exp
= insn_ptr
;
846 fs
->cfa_how
= CFA_EXP
;
850 case DW_CFA_expression
:
851 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
852 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
853 fs
->regs
.reg
[reg
].how
= REG_SAVED_EXP
;
854 fs
->regs
.reg
[reg
].loc
.exp
= insn_ptr
;
858 /* From the 2.1 draft. */
859 case DW_CFA_offset_extended_sf
:
860 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
861 insn_ptr
= read_sleb128 (insn_ptr
, &stmp
);
862 offset
= stmp
* fs
->data_align
;
863 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
864 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
867 case DW_CFA_def_cfa_sf
:
868 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
869 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
870 fs
->cfa_how
= CFA_REG_OFFSET
;
873 case DW_CFA_def_cfa_offset_sf
:
874 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
875 /* cfa_how deliberately not set. */
878 case DW_CFA_GNU_window_save
:
879 /* ??? Hardcoded for SPARC register window configuration. */
880 for (reg
= 16; reg
< 32; ++reg
)
882 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
883 fs
->regs
.reg
[reg
].loc
.offset
= (reg
- 16) * sizeof (void *);
887 case DW_CFA_GNU_args_size
:
888 insn_ptr
= read_uleb128 (insn_ptr
, &context
->args_size
);
891 case DW_CFA_GNU_negative_offset_extended
:
892 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
893 older PowerPC code. */
894 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
895 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
896 offset
= (_Unwind_Word
) utmp
* fs
->data_align
;
897 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
898 fs
->regs
.reg
[reg
].loc
.offset
= -offset
;
907 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
908 its caller and decode it into FS. This function also sets the
909 args_size and lsda members of CONTEXT, as they are really information
910 about the caller's frame. */
912 static _Unwind_Reason_Code
913 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
915 struct dwarf_fde
*fde
;
916 struct dwarf_cie
*cie
;
917 const unsigned char *aug
, *insn
, *end
;
919 memset (fs
, 0, sizeof (*fs
));
920 context
->args_size
= 0;
923 fde
= _Unwind_Find_FDE (context
->ra
- 1, &context
->bases
);
926 /* Couldn't find frame unwind info for this function. Try a
927 target-specific fallback mechanism. This will necessarily
928 not provide a personality routine or LSDA. */
929 #ifdef MD_FALLBACK_FRAME_STATE_FOR
930 MD_FALLBACK_FRAME_STATE_FOR (context
, fs
, success
);
931 return _URC_END_OF_STACK
;
933 return _URC_NO_REASON
;
935 return _URC_END_OF_STACK
;
939 fs
->pc
= context
->bases
.func
;
942 insn
= extract_cie_info (cie
, context
, fs
);
944 /* CIE contained unknown augmentation. */
945 return _URC_FATAL_PHASE1_ERROR
;
947 /* First decode all the insns in the CIE. */
948 end
= (unsigned char *) next_fde ((struct dwarf_fde
*) cie
);
949 execute_cfa_program (insn
, end
, context
, fs
);
951 /* Locate augmentation for the fde. */
952 aug
= (unsigned char *) fde
+ sizeof (*fde
);
953 aug
+= 2 * size_of_encoded_value (fs
->fde_encoding
);
958 aug
= read_uleb128 (aug
, &i
);
961 if (fs
->lsda_encoding
!= DW_EH_PE_omit
)
962 aug
= read_encoded_value (context
, fs
->lsda_encoding
, aug
,
963 (_Unwind_Ptr
*) &context
->lsda
);
965 /* Then the insns in the FDE up to our target PC. */
968 end
= (unsigned char *) next_fde (fde
);
969 execute_cfa_program (insn
, end
, context
, fs
);
971 return _URC_NO_REASON
;
974 typedef struct frame_state
980 long reg_or_offset
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
981 unsigned short cfa_reg
;
982 unsigned short retaddr_column
;
983 char saved
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
986 struct frame_state
* __frame_state_for (void *, struct frame_state
*);
988 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
989 a given PC_TARGET. The caller should allocate a local variable of
990 `struct frame_state' and pass its address to STATE_IN. */
993 __frame_state_for (void *pc_target
, struct frame_state
*state_in
)
995 struct _Unwind_Context context
;
996 _Unwind_FrameState fs
;
999 memset (&context
, 0, sizeof (struct _Unwind_Context
));
1000 context
.ra
= pc_target
+ 1;
1002 if (uw_frame_state_for (&context
, &fs
) != _URC_NO_REASON
)
1005 /* We have no way to pass a location expression for the CFA to our
1006 caller. It wouldn't understand it anyway. */
1007 if (fs
.cfa_how
== CFA_EXP
)
1010 for (reg
= 0; reg
< PRE_GCC3_DWARF_FRAME_REGISTERS
+ 1; reg
++)
1012 state_in
->saved
[reg
] = fs
.regs
.reg
[reg
].how
;
1013 switch (state_in
->saved
[reg
])
1016 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.reg
;
1018 case REG_SAVED_OFFSET
:
1019 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.offset
;
1022 state_in
->reg_or_offset
[reg
] = 0;
1027 state_in
->cfa_offset
= fs
.cfa_offset
;
1028 state_in
->cfa_reg
= fs
.cfa_reg
;
1029 state_in
->retaddr_column
= fs
.retaddr_column
;
1030 state_in
->args_size
= context
.args_size
;
1031 state_in
->eh_ptr
= fs
.eh_ptr
;
1037 uw_update_context_1 (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1039 struct _Unwind_Context orig_context
= *context
;
1043 /* Compute this frame's CFA. */
1044 switch (fs
->cfa_how
)
1046 case CFA_REG_OFFSET
:
1047 /* Special handling here: Many machines do not use a frame pointer,
1048 and track the CFA only through offsets from the stack pointer from
1049 one frame to the next. In this case, the stack pointer is never
1050 stored, so it has no saved address in the context. What we do
1051 have is the CFA from the previous stack frame. */
1052 if (context
->reg
[fs
->cfa_reg
] == NULL
)
1055 cfa
= (void *) (_Unwind_Ptr
) _Unwind_GetGR (context
, fs
->cfa_reg
);
1056 cfa
+= fs
->cfa_offset
;
1060 /* ??? No way of knowing what register number is the stack pointer
1061 to do the same sort of handling as above. Assume that if the
1062 CFA calculation is so complicated as to require a stack program
1063 that this will not be a problem. */
1065 const unsigned char *exp
= fs
->cfa_exp
;
1068 exp
= read_uleb128 (exp
, &len
);
1069 cfa
= (void *) (_Unwind_Ptr
)
1070 execute_stack_op (exp
, exp
+ len
, context
, 0);
1079 /* Compute the addresses of all registers saved in this frame. */
1080 for (i
= 0; i
< DWARF_FRAME_REGISTERS
+ 1; ++i
)
1081 switch (fs
->regs
.reg
[i
].how
)
1085 case REG_SAVED_OFFSET
:
1086 context
->reg
[i
] = cfa
+ fs
->regs
.reg
[i
].loc
.offset
;
1089 context
->reg
[i
] = orig_context
.reg
[fs
->regs
.reg
[i
].loc
.reg
];
1093 const unsigned char *exp
= fs
->regs
.reg
[i
].loc
.exp
;
1097 exp
= read_uleb128 (exp
, &len
);
1098 val
= execute_stack_op (exp
, exp
+ len
, &orig_context
,
1100 context
->reg
[i
] = (void *) val
;
1106 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1107 of its caller. Update CONTEXT to refer to the caller as well. Note
1108 that the args_size and lsda members are not updated here, but later in
1109 uw_frame_state_for. */
1112 uw_update_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1114 uw_update_context_1 (context
, fs
);
1116 /* Compute the return address now, since the return address column
1117 can change from frame to frame. */
1118 context
->ra
= __builtin_extract_return_addr
1119 ((void *) (_Unwind_Ptr
) _Unwind_GetGR (context
, fs
->retaddr_column
));
1122 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1123 level will be the return address and the CFA. */
1125 #define uw_init_context(CONTEXT) \
1128 /* Do any necessary initialization to access arbitrary stack frames. \
1129 On the SPARC, this means flushing the register windows. */ \
1130 __builtin_unwind_init (); \
1131 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1132 __builtin_return_address (0)); \
1137 uw_init_context_1 (struct _Unwind_Context
*context
,
1138 void *outer_cfa
, void *outer_ra
)
1140 void *ra
= __builtin_extract_return_addr (__builtin_return_address (0));
1141 _Unwind_FrameState fs
;
1143 memset (context
, 0, sizeof (struct _Unwind_Context
));
1146 if (uw_frame_state_for (context
, &fs
) != _URC_NO_REASON
)
1149 /* Force the frame state to use the known cfa value. */
1150 context
->cfa
= outer_cfa
;
1151 fs
.cfa_how
= CFA_REG_OFFSET
;
1155 uw_update_context_1 (context
, &fs
);
1157 /* If the return address column was saved in a register in the
1158 initialization context, then we can't see it in the given
1159 call frame data. So have the initialization context tell us. */
1160 context
->ra
= __builtin_extract_return_addr (outer_ra
);
1164 /* Install TARGET into CURRENT so that we can return to it. This is a
1165 macro because __builtin_eh_return must be invoked in the context of
1168 #define uw_install_context(CURRENT, TARGET) \
1171 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1172 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1173 __builtin_eh_return (offset, handler); \
1178 init_dwarf_reg_size_table (void)
1180 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table
);
1184 uw_install_context_1 (struct _Unwind_Context
*current
,
1185 struct _Unwind_Context
*target
)
1191 static __gthread_once_t once_regsizes
= __GTHREAD_ONCE_INIT
;
1192 if (__gthread_once (&once_regsizes
, init_dwarf_reg_size_table
) != 0
1193 || dwarf_reg_size_table
[0] == 0)
1194 init_dwarf_reg_size_table ();
1197 if (dwarf_reg_size_table
[0] == 0)
1198 init_dwarf_reg_size_table ();
1201 for (i
= 0; i
< DWARF_FRAME_REGISTERS
; ++i
)
1203 void *c
= current
->reg
[i
];
1204 void *t
= target
->reg
[i
];
1205 if (t
&& c
&& t
!= c
)
1206 memcpy (c
, t
, dwarf_reg_size_table
[i
]);
1209 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1210 if (STACK_GROWS_DOWNWARD
)
1211 return target
->cfa
- current
->cfa
+ target
->args_size
;
1213 return current
->cfa
- target
->cfa
- target
->args_size
;
1216 static inline _Unwind_Ptr
1217 uw_identify_context (struct _Unwind_Context
*context
)
1219 return _Unwind_GetIP (context
);
1223 #include "unwind.inc"
1225 #endif /* !USING_SJLJ_EXCEPTIONS */