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
26 #include "unwind-pe.h"
27 #include "unwind-dw2-fde.h"
31 #ifndef __USING_SJLJ_EXCEPTIONS__
33 #ifndef STACK_GROWS_DOWNWARD
34 #define STACK_GROWS_DOWNWARD 0
36 #undef STACK_GROWS_DOWNWARD
37 #define STACK_GROWS_DOWNWARD 1
40 /* A target can override (perhaps for backward compatibility) how
41 many dwarf2 columns are unwound. */
42 #ifndef DWARF_FRAME_REGISTERS
43 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
46 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
47 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
48 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
51 /* This is the register and unwind state for a particular frame. This
52 provides the information necessary to unwind up past a frame and return
54 struct _Unwind_Context
56 void *reg
[DWARF_FRAME_REGISTERS
+1];
60 struct dwarf_eh_bases bases
;
61 _Unwind_Word args_size
;
64 /* Byte size of every register managed by these routines. */
65 static unsigned char dwarf_reg_size_table
[DWARF_FRAME_REGISTERS
];
68 /* The result of interpreting the frame unwind info for a frame.
69 This is all symbolic at this point, as none of the values can
70 be resolved until the target pc is located. */
73 /* Each register save state can be described in terms of a CFA slot,
74 another register, or a location expression. */
75 struct frame_state_reg_info
81 const unsigned char *exp
;
89 } reg
[DWARF_FRAME_REGISTERS
+1];
91 /* Used to implement DW_CFA_remember_state. */
92 struct frame_state_reg_info
*prev
;
95 /* The CFA can be described in terms of a reg+offset or a
96 location expression. */
97 _Unwind_Sword cfa_offset
;
99 const unsigned char *cfa_exp
;
106 /* The PC described by the current frame state. */
109 /* The information we care about from the CIE/FDE. */
110 _Unwind_Personality_Fn personality
;
111 _Unwind_Sword data_align
;
112 _Unwind_Word code_align
;
113 unsigned char retaddr_column
;
114 unsigned char fde_encoding
;
115 unsigned char lsda_encoding
;
118 } _Unwind_FrameState
;
120 /* Read unaligned data from the instruction buffer. */
125 unsigned u2
__attribute__ ((mode (HI
)));
126 unsigned u4
__attribute__ ((mode (SI
)));
127 unsigned u8
__attribute__ ((mode (DI
)));
128 signed s2
__attribute__ ((mode (HI
)));
129 signed s4
__attribute__ ((mode (SI
)));
130 signed s8
__attribute__ ((mode (DI
)));
131 } __attribute__ ((packed
));
134 read_pointer (const void *p
) { const union unaligned
*up
= p
; return up
->p
; }
137 read_1u (const void *p
) { return *(const unsigned char *) p
; }
140 read_1s (const void *p
) { return *(const signed char *) p
; }
143 read_2u (const void *p
) { const union unaligned
*up
= p
; return up
->u2
; }
146 read_2s (const void *p
) { const union unaligned
*up
= p
; return up
->s2
; }
148 static inline unsigned int
149 read_4u (const void *p
) { const union unaligned
*up
= p
; return up
->u4
; }
152 read_4s (const void *p
) { const union unaligned
*up
= p
; return up
->s4
; }
154 static inline unsigned long
155 read_8u (const void *p
) { const union unaligned
*up
= p
; return up
->u8
; }
157 static inline unsigned long
158 read_8s (const void *p
) { const union unaligned
*up
= p
; return up
->s8
; }
160 /* Get the value of register REG as saved in CONTEXT. */
163 _Unwind_GetGR (struct _Unwind_Context
*context
, int index
)
165 /* This will segfault if the register hasn't been saved. */
166 return * (_Unwind_Word
*) context
->reg
[index
];
169 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
172 _Unwind_SetGR (struct _Unwind_Context
*context
, int index
, _Unwind_Word val
)
174 * (_Unwind_Word
*) context
->reg
[index
] = val
;
177 /* Retrieve the return address for CONTEXT. */
180 _Unwind_GetIP (struct _Unwind_Context
*context
)
182 return (_Unwind_Ptr
) context
->ra
;
185 /* Overwrite the return address for CONTEXT with VAL. */
188 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
190 context
->ra
= (void *) val
;
194 _Unwind_GetLanguageSpecificData (struct _Unwind_Context
*context
)
196 return context
->lsda
;
200 _Unwind_GetRegionStart (struct _Unwind_Context
*context
)
202 return (_Unwind_Ptr
) context
->bases
.func
;
207 _Unwind_GetDataRelBase (struct _Unwind_Context
*context
)
209 return (_Unwind_Ptr
) context
->bases
.dbase
;
213 _Unwind_GetTextRelBase (struct _Unwind_Context
*context
)
215 return (_Unwind_Ptr
) context
->bases
.tbase
;
219 /* Extract any interesting information from the CIE for the translation
220 unit F belongs to. Return a pointer to the byte after the augmentation,
221 or NULL if we encountered an undecipherable augmentation. */
223 static const unsigned char *
224 extract_cie_info (struct dwarf_cie
*cie
, struct _Unwind_Context
*context
,
225 _Unwind_FrameState
*fs
)
227 const unsigned char *aug
= cie
->augmentation
;
228 const unsigned char *p
= aug
+ strlen (aug
) + 1;
229 const unsigned char *ret
= NULL
;
232 /* g++ v2 "eh" has pointer immediately following augmentation string,
233 so it must be handled first. */
234 if (aug
[0] == 'e' && aug
[1] == 'h')
236 fs
->eh_ptr
= read_pointer (p
);
237 p
+= sizeof (void *);
241 /* Immediately following the augmentation are the code and
242 data alignment and return address column. */
243 p
= read_uleb128 (p
, &fs
->code_align
);
244 p
= read_sleb128 (p
, &fs
->data_align
);
245 fs
->retaddr_column
= *p
++;
246 fs
->lsda_encoding
= DW_EH_PE_omit
;
248 /* If the augmentation starts with 'z', then a uleb128 immediately
249 follows containing the length of the augmentation field following
253 p
= read_uleb128 (p
, &utmp
);
260 /* Iterate over recognized augmentation subsequences. */
263 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
266 fs
->lsda_encoding
= *p
++;
270 /* "R" indicates a byte indicating how FDE addresses are encoded. */
271 else if (aug
[0] == 'R')
273 fs
->fde_encoding
= *p
++;
277 /* "P" indicates a personality routine in the CIE augmentation. */
278 else if (aug
[0] == 'P')
280 p
= read_encoded_value (context
, *p
, p
+ 1,
281 (_Unwind_Ptr
*) &fs
->personality
);
285 /* Otherwise we have an unknown augmentation string.
286 Bail unless we saw a 'z' prefix. */
291 return ret
? ret
: p
;
295 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
296 onto the stack to start. */
299 execute_stack_op (const unsigned char *op_ptr
, const unsigned char *op_end
,
300 struct _Unwind_Context
*context
, _Unwind_Word initial
)
302 _Unwind_Word stack
[64]; /* ??? Assume this is enough. */
308 while (op_ptr
< op_end
)
310 enum dwarf_location_atom op
= *op_ptr
++;
311 _Unwind_Word result
, reg
, utmp
;
312 _Unwind_Sword offset
, stmp
;
348 result
= op
- DW_OP_lit0
;
352 result
= (_Unwind_Word
) (_Unwind_Ptr
) read_pointer (op_ptr
);
353 op_ptr
+= sizeof (void *);
357 result
= read_1u (op_ptr
);
361 result
= read_1s (op_ptr
);
365 result
= read_2u (op_ptr
);
369 result
= read_2s (op_ptr
);
373 result
= read_4u (op_ptr
);
377 result
= read_4s (op_ptr
);
381 result
= read_8u (op_ptr
);
385 result
= read_8s (op_ptr
);
389 op_ptr
= read_uleb128 (op_ptr
, &result
);
392 op_ptr
= read_sleb128 (op_ptr
, &stmp
);
428 result
= _Unwind_GetGR (context
, op
- DW_OP_reg0
);
431 op_ptr
= read_uleb128 (op_ptr
, ®
);
432 result
= _Unwind_GetGR (context
, reg
);
467 op_ptr
= read_sleb128 (op_ptr
, &offset
);
468 result
= _Unwind_GetGR (context
, op
- DW_OP_breg0
) + offset
;
471 op_ptr
= read_uleb128 (op_ptr
, ®
);
472 op_ptr
= read_sleb128 (op_ptr
, &offset
);
473 result
= _Unwind_GetGR (context
, reg
) + offset
;
479 result
= stack
[stack_elt
- 1];
489 if (offset
>= stack_elt
- 1)
491 result
= stack
[stack_elt
- 1 - offset
];
497 result
= stack
[stack_elt
- 2];
502 _Unwind_Word t1
, t2
, t3
;
506 t1
= stack
[stack_elt
- 1];
507 t2
= stack
[stack_elt
- 2];
508 t3
= stack
[stack_elt
- 3];
509 stack
[stack_elt
- 1] = t2
;
510 stack
[stack_elt
- 2] = t3
;
511 stack
[stack_elt
- 3] = t1
;
516 case DW_OP_deref_size
:
520 case DW_OP_plus_uconst
:
521 /* Unary operations. */
524 result
= stack
[stack_elt
];
530 void *ptr
= (void *) (_Unwind_Ptr
) result
;
531 result
= (_Unwind_Ptr
) read_pointer (ptr
);
535 case DW_OP_deref_size
:
537 void *ptr
= (void *) (_Unwind_Ptr
) result
;
541 result
= read_1u (ptr
);
544 result
= read_2u (ptr
);
547 result
= read_4u (ptr
);
550 result
= read_8u (ptr
);
559 if ((_Unwind_Sword
) result
< 0)
568 case DW_OP_plus_uconst
:
569 op_ptr
= read_uleb128 (op_ptr
, &utmp
);
592 /* Binary operations. */
593 _Unwind_Word first
, second
;
594 if ((stack_elt
-= 2) < 0)
596 second
= stack
[stack_elt
];
597 first
= stack
[stack_elt
+ 1];
602 result
= second
& first
;
605 result
= (_Unwind_Sword
) second
/ (_Unwind_Sword
) first
;
608 result
= second
- first
;
611 result
= (_Unwind_Sword
) second
% (_Unwind_Sword
) first
;
614 result
= second
* first
;
617 result
= second
| first
;
620 result
= second
+ first
;
623 result
= second
<< first
;
626 result
= second
>> first
;
629 result
= (_Unwind_Sword
) second
>> first
;
632 result
= second
^ first
;
635 result
= (_Unwind_Sword
) first
<= (_Unwind_Sword
) second
;
638 result
= (_Unwind_Sword
) first
>= (_Unwind_Sword
) second
;
641 result
= (_Unwind_Sword
) first
== (_Unwind_Sword
) second
;
644 result
= (_Unwind_Sword
) first
< (_Unwind_Sword
) second
;
647 result
= (_Unwind_Sword
) first
> (_Unwind_Sword
) second
;
650 result
= (_Unwind_Sword
) first
!= (_Unwind_Sword
) second
;
660 offset
= read_2s (op_ptr
);
668 offset
= read_2s (op_ptr
);
670 if (stack
[stack_elt
] != 0)
681 /* Most things push a result value. */
682 if ((size_t) stack_elt
>= sizeof(stack
)/sizeof(*stack
))
684 stack
[++stack_elt
] = result
;
688 /* We were executing this program to get a value. It should be
692 return stack
[stack_elt
];
696 /* Decode DWARF 2 call frame information. Takes pointers the
697 instruction sequence to decode, current register information and
698 CIE info, and the PC range to evaluate. */
701 execute_cfa_program (const unsigned char *insn_ptr
,
702 const unsigned char *insn_end
,
703 struct _Unwind_Context
*context
,
704 _Unwind_FrameState
*fs
)
706 struct frame_state_reg_info
*unused_rs
= NULL
;
708 /* Don't allow remember/restore between CIE and FDE programs. */
709 fs
->regs
.prev
= NULL
;
711 /* The comparison with the return address uses < rather than <= because
712 we are only interested in the effects of code before the call; for a
713 noreturn function, the return address may point to unrelated code with
714 a different stack configuration that we are not interested in. We
715 assume that the call itself is unwind info-neutral; if not, or if
716 there are delay instructions that adjust the stack, these must be
717 reflected at the point immediately before the call insn. */
718 while (insn_ptr
< insn_end
&& fs
->pc
< context
->ra
)
720 unsigned char insn
= *insn_ptr
++;
721 _Unwind_Word reg
, utmp
;
722 _Unwind_Sword offset
, stmp
;
724 if ((insn
& 0xc0) == DW_CFA_advance_loc
)
725 fs
->pc
+= (insn
& 0x3f) * fs
->code_align
;
726 else if ((insn
& 0xc0) == DW_CFA_offset
)
729 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
730 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
731 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
732 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
734 else if ((insn
& 0xc0) == DW_CFA_restore
)
737 fs
->regs
.reg
[reg
].how
= REG_UNSAVED
;
742 insn_ptr
= read_encoded_value (context
, fs
->fde_encoding
,
743 insn_ptr
, (_Unwind_Ptr
*) &fs
->pc
);
746 case DW_CFA_advance_loc1
:
747 fs
->pc
+= read_1u (insn_ptr
) * fs
->code_align
;
750 case DW_CFA_advance_loc2
:
751 fs
->pc
+= read_2u (insn_ptr
) * fs
->code_align
;
754 case DW_CFA_advance_loc4
:
755 fs
->pc
+= read_4u (insn_ptr
) * fs
->code_align
;
759 case DW_CFA_offset_extended
:
760 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
761 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
762 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
763 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
764 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
767 case DW_CFA_restore_extended
:
768 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
769 fs
->regs
.reg
[reg
].how
= REG_UNSAVED
;
772 case DW_CFA_undefined
:
773 case DW_CFA_same_value
:
777 case DW_CFA_register
:
780 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
781 insn_ptr
= read_uleb128 (insn_ptr
, ®2
);
782 fs
->regs
.reg
[reg
].how
= REG_SAVED_REG
;
783 fs
->regs
.reg
[reg
].loc
.reg
= reg2
;
787 case DW_CFA_remember_state
:
789 struct frame_state_reg_info
*new_rs
;
793 unused_rs
= unused_rs
->prev
;
796 new_rs
= __builtin_alloca (sizeof (struct frame_state_reg_info
));
799 fs
->regs
.prev
= new_rs
;
803 case DW_CFA_restore_state
:
805 struct frame_state_reg_info
*old_rs
= fs
->regs
.prev
;
807 old_rs
->prev
= unused_rs
;
813 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
814 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
815 fs
->cfa_offset
= utmp
;
816 fs
->cfa_how
= CFA_REG_OFFSET
;
819 case DW_CFA_def_cfa_register
:
820 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
821 fs
->cfa_how
= CFA_REG_OFFSET
;
824 case DW_CFA_def_cfa_offset
:
825 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
826 fs
->cfa_offset
= utmp
;
827 /* cfa_how deliberately not set. */
830 case DW_CFA_def_cfa_expression
:
831 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
832 fs
->cfa_exp
= insn_ptr
;
833 fs
->cfa_how
= CFA_EXP
;
837 case DW_CFA_expression
:
838 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
839 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
840 fs
->regs
.reg
[reg
].how
= REG_SAVED_EXP
;
841 fs
->regs
.reg
[reg
].loc
.exp
= insn_ptr
;
845 /* From the 2.1 draft. */
846 case DW_CFA_offset_extended_sf
:
847 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
848 insn_ptr
= read_sleb128 (insn_ptr
, &stmp
);
849 offset
= stmp
* fs
->data_align
;
850 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
851 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
854 case DW_CFA_def_cfa_sf
:
855 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
856 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
857 fs
->cfa_how
= CFA_REG_OFFSET
;
860 case DW_CFA_def_cfa_offset_sf
:
861 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
862 /* cfa_how deliberately not set. */
865 case DW_CFA_GNU_window_save
:
866 /* ??? Hardcoded for SPARC register window configuration. */
867 for (reg
= 16; reg
< 32; ++reg
)
869 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
870 fs
->regs
.reg
[reg
].loc
.offset
= (reg
- 16) * sizeof (void *);
874 case DW_CFA_GNU_args_size
:
875 insn_ptr
= read_uleb128 (insn_ptr
, &context
->args_size
);
878 case DW_CFA_GNU_negative_offset_extended
:
879 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
880 older PowerPC code. */
881 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
882 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
883 offset
= (_Unwind_Word
) utmp
* fs
->data_align
;
884 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
885 fs
->regs
.reg
[reg
].loc
.offset
= -offset
;
894 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
895 its caller and decode it into FS. This function also sets the
896 args_size and lsda members of CONTEXT, as they are really information
897 about the caller's frame. */
899 static _Unwind_Reason_Code
900 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
902 struct dwarf_fde
*fde
;
903 struct dwarf_cie
*cie
;
904 const unsigned char *aug
, *insn
, *end
;
906 memset (fs
, 0, sizeof (*fs
));
907 context
->args_size
= 0;
910 fde
= _Unwind_Find_FDE (context
->ra
- 1, &context
->bases
);
913 /* Couldn't find frame unwind info for this function. Try a
914 target-specific fallback mechanism. This will necessarily
915 not provide a personality routine or LSDA. */
916 #ifdef MD_FALLBACK_FRAME_STATE_FOR
917 MD_FALLBACK_FRAME_STATE_FOR (context
, fs
, success
);
918 return _URC_END_OF_STACK
;
920 return _URC_NO_REASON
;
922 return _URC_END_OF_STACK
;
926 fs
->pc
= context
->bases
.func
;
929 insn
= extract_cie_info (cie
, context
, fs
);
931 /* CIE contained unknown augmentation. */
932 return _URC_FATAL_PHASE1_ERROR
;
934 /* First decode all the insns in the CIE. */
935 end
= (unsigned char *) next_fde ((struct dwarf_fde
*) cie
);
936 execute_cfa_program (insn
, end
, context
, fs
);
938 /* Locate augmentation for the fde. */
939 aug
= (unsigned char *) fde
+ sizeof (*fde
);
940 aug
+= 2 * size_of_encoded_value (fs
->fde_encoding
);
945 aug
= read_uleb128 (aug
, &i
);
948 if (fs
->lsda_encoding
!= DW_EH_PE_omit
)
949 aug
= read_encoded_value (context
, fs
->lsda_encoding
, aug
,
950 (_Unwind_Ptr
*) &context
->lsda
);
952 /* Then the insns in the FDE up to our target PC. */
955 end
= (unsigned char *) next_fde (fde
);
956 execute_cfa_program (insn
, end
, context
, fs
);
958 return _URC_NO_REASON
;
961 typedef struct frame_state
967 long reg_or_offset
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
968 unsigned short cfa_reg
;
969 unsigned short retaddr_column
;
970 char saved
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
973 struct frame_state
* __frame_state_for (void *, struct frame_state
*);
975 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
976 a given PC_TARGET. The caller should allocate a local variable of
977 `struct frame_state' and pass its address to STATE_IN. */
980 __frame_state_for (void *pc_target
, struct frame_state
*state_in
)
982 struct _Unwind_Context context
;
983 _Unwind_FrameState fs
;
986 memset (&context
, 0, sizeof (struct _Unwind_Context
));
987 context
.ra
= pc_target
+ 1;
989 if (uw_frame_state_for (&context
, &fs
) != _URC_NO_REASON
)
992 /* We have no way to pass a location expression for the CFA to our
993 caller. It wouldn't understand it anyway. */
994 if (fs
.cfa_how
== CFA_EXP
)
997 for (reg
= 0; reg
< PRE_GCC3_DWARF_FRAME_REGISTERS
+ 1; reg
++)
999 state_in
->saved
[reg
] = fs
.regs
.reg
[reg
].how
;
1000 switch (state_in
->saved
[reg
])
1003 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.reg
;
1005 case REG_SAVED_OFFSET
:
1006 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.offset
;
1009 state_in
->reg_or_offset
[reg
] = 0;
1014 state_in
->cfa_offset
= fs
.cfa_offset
;
1015 state_in
->cfa_reg
= fs
.cfa_reg
;
1016 state_in
->retaddr_column
= fs
.retaddr_column
;
1017 state_in
->args_size
= context
.args_size
;
1018 state_in
->eh_ptr
= fs
.eh_ptr
;
1024 uw_update_context_1 (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1026 struct _Unwind_Context orig_context
= *context
;
1030 /* Compute this frame's CFA. */
1031 switch (fs
->cfa_how
)
1033 case CFA_REG_OFFSET
:
1034 /* Special handling here: Many machines do not use a frame pointer,
1035 and track the CFA only through offsets from the stack pointer from
1036 one frame to the next. In this case, the stack pointer is never
1037 stored, so it has no saved address in the context. What we do
1038 have is the CFA from the previous stack frame. */
1039 if (context
->reg
[fs
->cfa_reg
] == NULL
)
1042 cfa
= (void *) (_Unwind_Ptr
) _Unwind_GetGR (context
, fs
->cfa_reg
);
1043 cfa
+= fs
->cfa_offset
;
1047 /* ??? No way of knowing what register number is the stack pointer
1048 to do the same sort of handling as above. Assume that if the
1049 CFA calculation is so complicated as to require a stack program
1050 that this will not be a problem. */
1052 const unsigned char *exp
= fs
->cfa_exp
;
1055 exp
= read_uleb128 (exp
, &len
);
1056 cfa
= (void *) (_Unwind_Ptr
)
1057 execute_stack_op (exp
, exp
+ len
, context
, 0);
1066 /* Compute the addresses of all registers saved in this frame. */
1067 for (i
= 0; i
< DWARF_FRAME_REGISTERS
+ 1; ++i
)
1068 switch (fs
->regs
.reg
[i
].how
)
1072 case REG_SAVED_OFFSET
:
1073 context
->reg
[i
] = cfa
+ fs
->regs
.reg
[i
].loc
.offset
;
1076 context
->reg
[i
] = orig_context
.reg
[fs
->regs
.reg
[i
].loc
.reg
];
1080 const unsigned char *exp
= fs
->regs
.reg
[i
].loc
.exp
;
1084 exp
= read_uleb128 (exp
, &len
);
1085 val
= execute_stack_op (exp
, exp
+ len
, &orig_context
,
1087 context
->reg
[i
] = (void *) val
;
1093 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1094 of its caller. Update CONTEXT to refer to the caller as well. Note
1095 that the args_size and lsda members are not updated here, but later in
1096 uw_frame_state_for. */
1099 uw_update_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1101 uw_update_context_1 (context
, fs
);
1103 /* Compute the return address now, since the return address column
1104 can change from frame to frame. */
1105 context
->ra
= __builtin_extract_return_addr
1106 ((void *) (_Unwind_Ptr
) _Unwind_GetGR (context
, fs
->retaddr_column
));
1109 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1110 level will be the return address and the CFA. */
1112 #define uw_init_context(CONTEXT) \
1115 /* Do any necessary initialization to access arbitrary stack frames. \
1116 On the SPARC, this means flushing the register windows. */ \
1117 __builtin_unwind_init (); \
1118 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1119 __builtin_return_address (0)); \
1124 uw_init_context_1 (struct _Unwind_Context
*context
,
1125 void *outer_cfa
, void *outer_ra
)
1127 void *ra
= __builtin_extract_return_addr (__builtin_return_address (0));
1128 _Unwind_FrameState fs
;
1130 memset (context
, 0, sizeof (struct _Unwind_Context
));
1133 if (uw_frame_state_for (context
, &fs
) != _URC_NO_REASON
)
1136 /* Force the frame state to use the known cfa value. */
1137 context
->cfa
= outer_cfa
;
1138 fs
.cfa_how
= CFA_REG_OFFSET
;
1142 uw_update_context_1 (context
, &fs
);
1144 /* If the return address column was saved in a register in the
1145 initialization context, then we can't see it in the given
1146 call frame data. So have the initialization context tell us. */
1147 context
->ra
= __builtin_extract_return_addr (outer_ra
);
1151 /* Install TARGET into CURRENT so that we can return to it. This is a
1152 macro because __builtin_eh_return must be invoked in the context of
1155 #define uw_install_context(CURRENT, TARGET) \
1158 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1159 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1160 __builtin_eh_return (offset, handler); \
1165 init_dwarf_reg_size_table (void)
1167 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table
);
1171 uw_install_context_1 (struct _Unwind_Context
*current
,
1172 struct _Unwind_Context
*target
)
1178 static __gthread_once_t once_regsizes
= __GTHREAD_ONCE_INIT
;
1179 if (__gthread_once (&once_regsizes
, init_dwarf_reg_size_table
) != 0
1180 || dwarf_reg_size_table
[0] == 0)
1181 init_dwarf_reg_size_table ();
1184 if (dwarf_reg_size_table
[0] == 0)
1185 init_dwarf_reg_size_table ();
1188 for (i
= 0; i
< DWARF_FRAME_REGISTERS
; ++i
)
1190 void *c
= current
->reg
[i
];
1191 void *t
= target
->reg
[i
];
1192 if (t
&& c
&& t
!= c
)
1193 memcpy (c
, t
, dwarf_reg_size_table
[i
]);
1196 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1197 if (STACK_GROWS_DOWNWARD
)
1198 return target
->cfa
- current
->cfa
+ target
->args_size
;
1200 return current
->cfa
- target
->cfa
- target
->args_size
;
1203 static inline _Unwind_Ptr
1204 uw_identify_context (struct _Unwind_Context
*context
)
1206 return _Unwind_GetIP (context
);
1210 #include "unwind.inc"
1212 #endif /* !USING_SJLJ_EXCEPTIONS */