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)
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 #ifndef DWARF_REG_TO_UNWIND_COLUMN
54 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
57 /* This is the register and unwind state for a particular frame. This
58 provides the information necessary to unwind up past a frame and return
60 struct _Unwind_Context
62 void *reg
[DWARF_FRAME_REGISTERS
+1];
66 struct dwarf_eh_bases bases
;
67 _Unwind_Word args_size
;
70 /* Byte size of every register managed by these routines. */
71 static unsigned char dwarf_reg_size_table
[DWARF_FRAME_REGISTERS
];
74 /* The result of interpreting the frame unwind info for a frame.
75 This is all symbolic at this point, as none of the values can
76 be resolved until the target pc is located. */
79 /* Each register save state can be described in terms of a CFA slot,
80 another register, or a location expression. */
81 struct frame_state_reg_info
87 const unsigned char *exp
;
95 } reg
[DWARF_FRAME_REGISTERS
+1];
97 /* Used to implement DW_CFA_remember_state. */
98 struct frame_state_reg_info
*prev
;
101 /* The CFA can be described in terms of a reg+offset or a
102 location expression. */
103 _Unwind_Sword cfa_offset
;
104 _Unwind_Word cfa_reg
;
105 const unsigned char *cfa_exp
;
112 /* The PC described by the current frame state. */
115 /* The information we care about from the CIE/FDE. */
116 _Unwind_Personality_Fn personality
;
117 _Unwind_Sword data_align
;
118 _Unwind_Word code_align
;
119 unsigned char retaddr_column
;
120 unsigned char fde_encoding
;
121 unsigned char lsda_encoding
;
124 } _Unwind_FrameState
;
126 /* Read unaligned data from the instruction buffer. */
131 unsigned u2
__attribute__ ((mode (HI
)));
132 unsigned u4
__attribute__ ((mode (SI
)));
133 unsigned u8
__attribute__ ((mode (DI
)));
134 signed s2
__attribute__ ((mode (HI
)));
135 signed s4
__attribute__ ((mode (SI
)));
136 signed s8
__attribute__ ((mode (DI
)));
137 } __attribute__ ((packed
));
140 read_pointer (const void *p
) { const union unaligned
*up
= p
; return up
->p
; }
143 read_1u (const void *p
) { return *(const unsigned char *) p
; }
146 read_1s (const void *p
) { return *(const signed char *) p
; }
149 read_2u (const void *p
) { const union unaligned
*up
= p
; return up
->u2
; }
152 read_2s (const void *p
) { const union unaligned
*up
= p
; return up
->s2
; }
154 static inline unsigned int
155 read_4u (const void *p
) { const union unaligned
*up
= p
; return up
->u4
; }
158 read_4s (const void *p
) { const union unaligned
*up
= p
; return up
->s4
; }
160 static inline unsigned long
161 read_8u (const void *p
) { const union unaligned
*up
= p
; return up
->u8
; }
163 static inline unsigned long
164 read_8s (const void *p
) { const union unaligned
*up
= p
; return up
->s8
; }
166 /* Get the value of register REG as saved in CONTEXT. */
169 _Unwind_GetGR (struct _Unwind_Context
*context
, int index
)
171 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
172 /* This will segfault if the register hasn't been saved. */
173 return * (_Unwind_Word
*) context
->reg
[index
];
176 /* Get the value of the CFA as saved in CONTEXT. */
179 _Unwind_GetCFA (struct _Unwind_Context
*context
)
181 return (_Unwind_Ptr
) context
->cfa
;
184 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
187 _Unwind_SetGR (struct _Unwind_Context
*context
, int index
, _Unwind_Word val
)
189 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
190 * (_Unwind_Word
*) context
->reg
[index
] = val
;
193 /* Get the pointer to a register INDEX as saved in CONTEXT. */
196 _Unwind_GetGRPtr (struct _Unwind_Context
*context
, int index
)
198 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
199 return context
->reg
[index
];
202 /* Set the pointer to a register INDEX as saved in CONTEXT. */
205 _Unwind_SetGRPtr (struct _Unwind_Context
*context
, int index
, void *p
)
207 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
208 context
->reg
[index
] = p
;
211 /* Retrieve the return address for CONTEXT. */
214 _Unwind_GetIP (struct _Unwind_Context
*context
)
216 return (_Unwind_Ptr
) context
->ra
;
219 /* Overwrite the return address for CONTEXT with VAL. */
222 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
224 context
->ra
= (void *) val
;
228 _Unwind_GetLanguageSpecificData (struct _Unwind_Context
*context
)
230 return context
->lsda
;
234 _Unwind_GetRegionStart (struct _Unwind_Context
*context
)
236 return (_Unwind_Ptr
) context
->bases
.func
;
240 _Unwind_FindEnclosingFunction (void *pc
)
242 struct dwarf_eh_bases bases
;
243 struct dwarf_fde
*fde
= _Unwind_Find_FDE (pc
-1, &bases
);
252 _Unwind_GetDataRelBase (struct _Unwind_Context
*context
)
254 return (_Unwind_Ptr
) context
->bases
.dbase
;
258 _Unwind_GetTextRelBase (struct _Unwind_Context
*context
)
260 return (_Unwind_Ptr
) context
->bases
.tbase
;
264 /* Extract any interesting information from the CIE for the translation
265 unit F belongs to. Return a pointer to the byte after the augmentation,
266 or NULL if we encountered an undecipherable augmentation. */
268 static const unsigned char *
269 extract_cie_info (struct dwarf_cie
*cie
, struct _Unwind_Context
*context
,
270 _Unwind_FrameState
*fs
)
272 const unsigned char *aug
= cie
->augmentation
;
273 const unsigned char *p
= aug
+ strlen (aug
) + 1;
274 const unsigned char *ret
= NULL
;
277 /* g++ v2 "eh" has pointer immediately following augmentation string,
278 so it must be handled first. */
279 if (aug
[0] == 'e' && aug
[1] == 'h')
281 fs
->eh_ptr
= read_pointer (p
);
282 p
+= sizeof (void *);
286 /* Immediately following the augmentation are the code and
287 data alignment and return address column. */
288 p
= read_uleb128 (p
, &fs
->code_align
);
289 p
= read_sleb128 (p
, &fs
->data_align
);
290 fs
->retaddr_column
= *p
++;
291 fs
->lsda_encoding
= DW_EH_PE_omit
;
293 /* If the augmentation starts with 'z', then a uleb128 immediately
294 follows containing the length of the augmentation field following
298 p
= read_uleb128 (p
, &utmp
);
305 /* Iterate over recognized augmentation subsequences. */
308 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
311 fs
->lsda_encoding
= *p
++;
315 /* "R" indicates a byte indicating how FDE addresses are encoded. */
316 else if (aug
[0] == 'R')
318 fs
->fde_encoding
= *p
++;
322 /* "P" indicates a personality routine in the CIE augmentation. */
323 else if (aug
[0] == 'P')
325 p
= read_encoded_value (context
, *p
, p
+ 1,
326 (_Unwind_Ptr
*) &fs
->personality
);
330 /* Otherwise we have an unknown augmentation string.
331 Bail unless we saw a 'z' prefix. */
336 return ret
? ret
: p
;
340 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
341 onto the stack to start. */
344 execute_stack_op (const unsigned char *op_ptr
, const unsigned char *op_end
,
345 struct _Unwind_Context
*context
, _Unwind_Word initial
)
347 _Unwind_Word stack
[64]; /* ??? Assume this is enough. */
353 while (op_ptr
< op_end
)
355 enum dwarf_location_atom op
= *op_ptr
++;
356 _Unwind_Word result
, reg
, utmp
;
357 _Unwind_Sword offset
, stmp
;
393 result
= op
- DW_OP_lit0
;
397 result
= (_Unwind_Word
) (_Unwind_Ptr
) read_pointer (op_ptr
);
398 op_ptr
+= sizeof (void *);
402 result
= read_1u (op_ptr
);
406 result
= read_1s (op_ptr
);
410 result
= read_2u (op_ptr
);
414 result
= read_2s (op_ptr
);
418 result
= read_4u (op_ptr
);
422 result
= read_4s (op_ptr
);
426 result
= read_8u (op_ptr
);
430 result
= read_8s (op_ptr
);
434 op_ptr
= read_uleb128 (op_ptr
, &result
);
437 op_ptr
= read_sleb128 (op_ptr
, &stmp
);
473 result
= _Unwind_GetGR (context
, op
- DW_OP_reg0
);
476 op_ptr
= read_uleb128 (op_ptr
, ®
);
477 result
= _Unwind_GetGR (context
, reg
);
512 op_ptr
= read_sleb128 (op_ptr
, &offset
);
513 result
= _Unwind_GetGR (context
, op
- DW_OP_breg0
) + offset
;
516 op_ptr
= read_uleb128 (op_ptr
, ®
);
517 op_ptr
= read_sleb128 (op_ptr
, &offset
);
518 result
= _Unwind_GetGR (context
, reg
) + offset
;
524 result
= stack
[stack_elt
- 1];
534 if (offset
>= stack_elt
- 1)
536 result
= stack
[stack_elt
- 1 - offset
];
542 result
= stack
[stack_elt
- 2];
547 _Unwind_Word t1
, t2
, t3
;
551 t1
= stack
[stack_elt
- 1];
552 t2
= stack
[stack_elt
- 2];
553 t3
= stack
[stack_elt
- 3];
554 stack
[stack_elt
- 1] = t2
;
555 stack
[stack_elt
- 2] = t3
;
556 stack
[stack_elt
- 3] = t1
;
561 case DW_OP_deref_size
:
565 case DW_OP_plus_uconst
:
566 /* Unary operations. */
569 result
= stack
[stack_elt
];
575 void *ptr
= (void *) (_Unwind_Ptr
) result
;
576 result
= (_Unwind_Ptr
) read_pointer (ptr
);
580 case DW_OP_deref_size
:
582 void *ptr
= (void *) (_Unwind_Ptr
) result
;
586 result
= read_1u (ptr
);
589 result
= read_2u (ptr
);
592 result
= read_4u (ptr
);
595 result
= read_8u (ptr
);
604 if ((_Unwind_Sword
) result
< 0)
613 case DW_OP_plus_uconst
:
614 op_ptr
= read_uleb128 (op_ptr
, &utmp
);
637 /* Binary operations. */
638 _Unwind_Word first
, second
;
639 if ((stack_elt
-= 2) < 0)
641 second
= stack
[stack_elt
];
642 first
= stack
[stack_elt
+ 1];
647 result
= second
& first
;
650 result
= (_Unwind_Sword
) second
/ (_Unwind_Sword
) first
;
653 result
= second
- first
;
656 result
= (_Unwind_Sword
) second
% (_Unwind_Sword
) first
;
659 result
= second
* first
;
662 result
= second
| first
;
665 result
= second
+ first
;
668 result
= second
<< first
;
671 result
= second
>> first
;
674 result
= (_Unwind_Sword
) second
>> first
;
677 result
= second
^ first
;
680 result
= (_Unwind_Sword
) first
<= (_Unwind_Sword
) second
;
683 result
= (_Unwind_Sword
) first
>= (_Unwind_Sword
) second
;
686 result
= (_Unwind_Sword
) first
== (_Unwind_Sword
) second
;
689 result
= (_Unwind_Sword
) first
< (_Unwind_Sword
) second
;
692 result
= (_Unwind_Sword
) first
> (_Unwind_Sword
) second
;
695 result
= (_Unwind_Sword
) first
!= (_Unwind_Sword
) second
;
705 offset
= read_2s (op_ptr
);
713 offset
= read_2s (op_ptr
);
715 if (stack
[stack_elt
] != 0)
726 /* Most things push a result value. */
727 if ((size_t) stack_elt
>= sizeof(stack
)/sizeof(*stack
))
729 stack
[stack_elt
++] = result
;
733 /* We were executing this program to get a value. It should be
737 return stack
[stack_elt
];
741 /* Decode DWARF 2 call frame information. Takes pointers the
742 instruction sequence to decode, current register information and
743 CIE info, and the PC range to evaluate. */
746 execute_cfa_program (const unsigned char *insn_ptr
,
747 const unsigned char *insn_end
,
748 struct _Unwind_Context
*context
,
749 _Unwind_FrameState
*fs
)
751 struct frame_state_reg_info
*unused_rs
= NULL
;
753 /* Don't allow remember/restore between CIE and FDE programs. */
754 fs
->regs
.prev
= NULL
;
756 /* The comparison with the return address uses < rather than <= because
757 we are only interested in the effects of code before the call; for a
758 noreturn function, the return address may point to unrelated code with
759 a different stack configuration that we are not interested in. We
760 assume that the call itself is unwind info-neutral; if not, or if
761 there are delay instructions that adjust the stack, these must be
762 reflected at the point immediately before the call insn. */
763 while (insn_ptr
< insn_end
&& fs
->pc
< context
->ra
)
765 unsigned char insn
= *insn_ptr
++;
766 _Unwind_Word reg
, utmp
;
767 _Unwind_Sword offset
, stmp
;
769 if ((insn
& 0xc0) == DW_CFA_advance_loc
)
770 fs
->pc
+= (insn
& 0x3f) * fs
->code_align
;
771 else if ((insn
& 0xc0) == DW_CFA_offset
)
774 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
775 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
776 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
778 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
780 else if ((insn
& 0xc0) == DW_CFA_restore
)
783 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_UNSAVED
;
788 insn_ptr
= read_encoded_value (context
, fs
->fde_encoding
,
789 insn_ptr
, (_Unwind_Ptr
*) &fs
->pc
);
792 case DW_CFA_advance_loc1
:
793 fs
->pc
+= read_1u (insn_ptr
) * fs
->code_align
;
796 case DW_CFA_advance_loc2
:
797 fs
->pc
+= read_2u (insn_ptr
) * fs
->code_align
;
800 case DW_CFA_advance_loc4
:
801 fs
->pc
+= read_4u (insn_ptr
) * fs
->code_align
;
805 case DW_CFA_offset_extended
:
806 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
807 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
808 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
809 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
811 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
814 case DW_CFA_restore_extended
:
815 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
816 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN(reg
)].how
= REG_UNSAVED
;
819 case DW_CFA_undefined
:
820 case DW_CFA_same_value
:
821 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
827 case DW_CFA_register
:
830 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
831 insn_ptr
= read_uleb128 (insn_ptr
, ®2
);
832 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_SAVED_REG
;
833 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.reg
= reg2
;
837 case DW_CFA_remember_state
:
839 struct frame_state_reg_info
*new_rs
;
843 unused_rs
= unused_rs
->prev
;
846 new_rs
= __builtin_alloca (sizeof (struct frame_state_reg_info
));
849 fs
->regs
.prev
= new_rs
;
853 case DW_CFA_restore_state
:
855 struct frame_state_reg_info
*old_rs
= fs
->regs
.prev
;
857 old_rs
->prev
= unused_rs
;
863 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
864 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
865 fs
->cfa_offset
= utmp
;
866 fs
->cfa_how
= CFA_REG_OFFSET
;
869 case DW_CFA_def_cfa_register
:
870 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
871 fs
->cfa_how
= CFA_REG_OFFSET
;
874 case DW_CFA_def_cfa_offset
:
875 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
876 fs
->cfa_offset
= utmp
;
877 /* cfa_how deliberately not set. */
880 case DW_CFA_def_cfa_expression
:
881 fs
->cfa_exp
= insn_ptr
;
882 fs
->cfa_how
= CFA_EXP
;
883 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
887 case DW_CFA_expression
:
888 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
889 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_SAVED_EXP
;
890 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.exp
= insn_ptr
;
891 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
895 /* From the 2.1 draft. */
896 case DW_CFA_offset_extended_sf
:
897 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
898 insn_ptr
= read_sleb128 (insn_ptr
, &stmp
);
899 offset
= stmp
* fs
->data_align
;
900 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
902 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
905 case DW_CFA_def_cfa_sf
:
906 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
907 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
908 fs
->cfa_how
= CFA_REG_OFFSET
;
911 case DW_CFA_def_cfa_offset_sf
:
912 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
913 /* cfa_how deliberately not set. */
916 case DW_CFA_GNU_window_save
:
917 /* ??? Hardcoded for SPARC register window configuration. */
918 for (reg
= 16; reg
< 32; ++reg
)
920 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
921 fs
->regs
.reg
[reg
].loc
.offset
= (reg
- 16) * sizeof (void *);
925 case DW_CFA_GNU_args_size
:
926 insn_ptr
= read_uleb128 (insn_ptr
, &context
->args_size
);
929 case DW_CFA_GNU_negative_offset_extended
:
930 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
931 older PowerPC code. */
932 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
933 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
934 offset
= (_Unwind_Word
) utmp
* fs
->data_align
;
935 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
937 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= -offset
;
946 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
947 its caller and decode it into FS. This function also sets the
948 args_size and lsda members of CONTEXT, as they are really information
949 about the caller's frame. */
951 static _Unwind_Reason_Code
952 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
954 struct dwarf_fde
*fde
;
955 struct dwarf_cie
*cie
;
956 const unsigned char *aug
, *insn
, *end
;
958 memset (fs
, 0, sizeof (*fs
));
959 context
->args_size
= 0;
962 fde
= _Unwind_Find_FDE (context
->ra
- 1, &context
->bases
);
965 /* Couldn't find frame unwind info for this function. Try a
966 target-specific fallback mechanism. This will necessarily
967 not provide a personality routine or LSDA. */
968 #ifdef MD_FALLBACK_FRAME_STATE_FOR
969 MD_FALLBACK_FRAME_STATE_FOR (context
, fs
, success
);
970 return _URC_END_OF_STACK
;
972 return _URC_NO_REASON
;
974 return _URC_END_OF_STACK
;
978 fs
->pc
= context
->bases
.func
;
981 insn
= extract_cie_info (cie
, context
, fs
);
983 /* CIE contained unknown augmentation. */
984 return _URC_FATAL_PHASE1_ERROR
;
986 /* First decode all the insns in the CIE. */
987 end
= (unsigned char *) next_fde ((struct dwarf_fde
*) cie
);
988 execute_cfa_program (insn
, end
, context
, fs
);
990 /* Locate augmentation for the fde. */
991 aug
= (unsigned char *) fde
+ sizeof (*fde
);
992 aug
+= 2 * size_of_encoded_value (fs
->fde_encoding
);
997 aug
= read_uleb128 (aug
, &i
);
1000 if (fs
->lsda_encoding
!= DW_EH_PE_omit
)
1001 aug
= read_encoded_value (context
, fs
->lsda_encoding
, aug
,
1002 (_Unwind_Ptr
*) &context
->lsda
);
1004 /* Then the insns in the FDE up to our target PC. */
1007 end
= (unsigned char *) next_fde (fde
);
1008 execute_cfa_program (insn
, end
, context
, fs
);
1010 return _URC_NO_REASON
;
1013 typedef struct frame_state
1019 long reg_or_offset
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1020 unsigned short cfa_reg
;
1021 unsigned short retaddr_column
;
1022 char saved
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1025 struct frame_state
* __frame_state_for (void *, struct frame_state
*);
1027 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1028 a given PC_TARGET. The caller should allocate a local variable of
1029 `struct frame_state' and pass its address to STATE_IN. */
1031 struct frame_state
*
1032 __frame_state_for (void *pc_target
, struct frame_state
*state_in
)
1034 struct _Unwind_Context context
;
1035 _Unwind_FrameState fs
;
1038 memset (&context
, 0, sizeof (struct _Unwind_Context
));
1039 context
.ra
= pc_target
+ 1;
1041 if (uw_frame_state_for (&context
, &fs
) != _URC_NO_REASON
)
1044 /* We have no way to pass a location expression for the CFA to our
1045 caller. It wouldn't understand it anyway. */
1046 if (fs
.cfa_how
== CFA_EXP
)
1049 for (reg
= 0; reg
< PRE_GCC3_DWARF_FRAME_REGISTERS
+ 1; reg
++)
1051 state_in
->saved
[reg
] = fs
.regs
.reg
[reg
].how
;
1052 switch (state_in
->saved
[reg
])
1055 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.reg
;
1057 case REG_SAVED_OFFSET
:
1058 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.offset
;
1061 state_in
->reg_or_offset
[reg
] = 0;
1066 state_in
->cfa_offset
= fs
.cfa_offset
;
1067 state_in
->cfa_reg
= fs
.cfa_reg
;
1068 state_in
->retaddr_column
= fs
.retaddr_column
;
1069 state_in
->args_size
= context
.args_size
;
1070 state_in
->eh_ptr
= fs
.eh_ptr
;
1076 uw_update_context_1 (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1078 struct _Unwind_Context orig_context
= *context
;
1082 #ifdef EH_RETURN_STACKADJ_RTX
1083 /* Special handling here: Many machines do not use a frame pointer,
1084 and track the CFA only through offsets from the stack pointer from
1085 one frame to the next. In this case, the stack pointer is never
1086 stored, so it has no saved address in the context. What we do
1087 have is the CFA from the previous stack frame.
1089 In very special situations (such as unwind info for signal return),
1090 there may be location expressions that use the stack pointer as well.
1092 Do this conditionally for one frame. This allows the unwind info
1093 for one frame to save a copy of the stack pointer from the previous
1094 frame, and be able to use much easier CFA mechanisms to do it.
1095 Always zap the saved stack pointer value for the next frame; carrying
1096 the value over from one frame to another doesn't make sense. */
1098 _Unwind_Word tmp_sp
;
1100 if (!_Unwind_GetGRPtr (&orig_context
, __builtin_dwarf_sp_column ()))
1102 tmp_sp
= (_Unwind_Ptr
) context
->cfa
;
1103 _Unwind_SetGRPtr (&orig_context
, __builtin_dwarf_sp_column (), &tmp_sp
);
1105 _Unwind_SetGRPtr (context
, __builtin_dwarf_sp_column (), NULL
);
1108 /* Compute this frame's CFA. */
1109 switch (fs
->cfa_how
)
1111 case CFA_REG_OFFSET
:
1112 cfa
= (void *) (_Unwind_Ptr
) _Unwind_GetGR (&orig_context
, fs
->cfa_reg
);
1113 cfa
+= fs
->cfa_offset
;
1118 const unsigned char *exp
= fs
->cfa_exp
;
1121 exp
= read_uleb128 (exp
, &len
);
1122 cfa
= (void *) (_Unwind_Ptr
)
1123 execute_stack_op (exp
, exp
+ len
, &orig_context
, 0);
1132 /* Compute the addresses of all registers saved in this frame. */
1133 for (i
= 0; i
< DWARF_FRAME_REGISTERS
+ 1; ++i
)
1134 switch (fs
->regs
.reg
[i
].how
)
1139 case REG_SAVED_OFFSET
:
1140 _Unwind_SetGRPtr (context
, i
,
1141 (void *) (cfa
+ fs
->regs
.reg
[i
].loc
.offset
));
1147 _Unwind_GetGRPtr (&orig_context
, fs
->regs
.reg
[i
].loc
.reg
));
1152 const unsigned char *exp
= fs
->regs
.reg
[i
].loc
.exp
;
1156 exp
= read_uleb128 (exp
, &len
);
1157 val
= execute_stack_op (exp
, exp
+ len
, &orig_context
,
1159 _Unwind_SetGRPtr (context
, i
, (void *) val
);
1165 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1166 of its caller. Update CONTEXT to refer to the caller as well. Note
1167 that the args_size and lsda members are not updated here, but later in
1168 uw_frame_state_for. */
1171 uw_update_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1173 uw_update_context_1 (context
, fs
);
1175 /* Compute the return address now, since the return address column
1176 can change from frame to frame. */
1177 context
->ra
= __builtin_extract_return_addr
1178 ((void *) (_Unwind_Ptr
) _Unwind_GetGR (context
, fs
->retaddr_column
));
1181 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1182 level will be the return address and the CFA. */
1184 #define uw_init_context(CONTEXT) \
1187 /* Do any necessary initialization to access arbitrary stack frames. \
1188 On the SPARC, this means flushing the register windows. */ \
1189 __builtin_unwind_init (); \
1190 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1191 __builtin_return_address (0)); \
1196 uw_init_context_1 (struct _Unwind_Context
*context
,
1197 void *outer_cfa
, void *outer_ra
)
1199 void *ra
= __builtin_extract_return_addr (__builtin_return_address (0));
1200 _Unwind_FrameState fs
;
1201 _Unwind_Word sp_slot
;
1203 memset (context
, 0, sizeof (struct _Unwind_Context
));
1206 if (uw_frame_state_for (context
, &fs
) != _URC_NO_REASON
)
1209 /* Force the frame state to use the known cfa value. */
1210 sp_slot
= (_Unwind_Ptr
) outer_cfa
;
1211 _Unwind_SetGRPtr (context
, __builtin_dwarf_sp_column (), &sp_slot
);
1212 fs
.cfa_how
= CFA_REG_OFFSET
;
1213 fs
.cfa_reg
= __builtin_dwarf_sp_column ();
1216 uw_update_context_1 (context
, &fs
);
1218 /* If the return address column was saved in a register in the
1219 initialization context, then we can't see it in the given
1220 call frame data. So have the initialization context tell us. */
1221 context
->ra
= __builtin_extract_return_addr (outer_ra
);
1225 /* Install TARGET into CURRENT so that we can return to it. This is a
1226 macro because __builtin_eh_return must be invoked in the context of
1229 #define uw_install_context(CURRENT, TARGET) \
1232 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1233 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1234 __builtin_eh_return (offset, handler); \
1239 init_dwarf_reg_size_table (void)
1241 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table
);
1245 uw_install_context_1 (struct _Unwind_Context
*current
,
1246 struct _Unwind_Context
*target
)
1252 static __gthread_once_t once_regsizes
= __GTHREAD_ONCE_INIT
;
1253 if (__gthread_once (&once_regsizes
, init_dwarf_reg_size_table
) != 0
1254 || dwarf_reg_size_table
[0] == 0)
1255 init_dwarf_reg_size_table ();
1258 if (dwarf_reg_size_table
[0] == 0)
1259 init_dwarf_reg_size_table ();
1262 for (i
= 0; i
< DWARF_FRAME_REGISTERS
; ++i
)
1264 void *c
= current
->reg
[i
];
1265 void *t
= target
->reg
[i
];
1267 if (t
&& c
&& t
!= c
)
1268 memcpy (c
, t
, dwarf_reg_size_table
[i
]);
1271 #ifdef EH_RETURN_STACKADJ_RTX
1275 /* If the last frame records a saved stack pointer, use it. */
1276 if (_Unwind_GetGRPtr (target
, __builtin_dwarf_sp_column ()))
1277 target_cfa
= (void *)(_Unwind_Ptr
)
1278 _Unwind_GetGR (target
, __builtin_dwarf_sp_column ());
1280 target_cfa
= target
->cfa
;
1282 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1283 if (STACK_GROWS_DOWNWARD
)
1284 return target_cfa
- current
->cfa
+ target
->args_size
;
1286 return current
->cfa
- target_cfa
- target
->args_size
;
1293 static inline _Unwind_Ptr
1294 uw_identify_context (struct _Unwind_Context
*context
)
1296 return _Unwind_GetIP (context
);
1300 #include "unwind.inc"
1302 #endif /* !USING_SJLJ_EXCEPTIONS */