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 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
179 _Unwind_SetGR (struct _Unwind_Context
*context
, int index
, _Unwind_Word val
)
181 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
182 * (_Unwind_Word
*) context
->reg
[index
] = val
;
185 /* Get the pointer to a register INDEX as saved in CONTEXT. */
188 _Unwind_GetGRPtr (struct _Unwind_Context
*context
, int index
)
190 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
191 return context
->reg
[index
];
194 /* Set the pointer to a register INDEX as saved in CONTEXT. */
197 _Unwind_SetGRPtr (struct _Unwind_Context
*context
, int index
, void *p
)
199 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
200 context
->reg
[index
] = p
;
203 /* Retrieve the return address for CONTEXT. */
206 _Unwind_GetIP (struct _Unwind_Context
*context
)
208 return (_Unwind_Ptr
) context
->ra
;
211 /* Overwrite the return address for CONTEXT with VAL. */
214 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
216 context
->ra
= (void *) val
;
220 _Unwind_GetLanguageSpecificData (struct _Unwind_Context
*context
)
222 return context
->lsda
;
226 _Unwind_GetRegionStart (struct _Unwind_Context
*context
)
228 return (_Unwind_Ptr
) context
->bases
.func
;
232 _Unwind_FindEnclosingFunction (void *pc
)
234 struct dwarf_eh_bases bases
;
235 struct dwarf_fde
*fde
= _Unwind_Find_FDE (pc
-1, &bases
);
244 _Unwind_GetDataRelBase (struct _Unwind_Context
*context
)
246 return (_Unwind_Ptr
) context
->bases
.dbase
;
250 _Unwind_GetTextRelBase (struct _Unwind_Context
*context
)
252 return (_Unwind_Ptr
) context
->bases
.tbase
;
256 /* Extract any interesting information from the CIE for the translation
257 unit F belongs to. Return a pointer to the byte after the augmentation,
258 or NULL if we encountered an undecipherable augmentation. */
260 static const unsigned char *
261 extract_cie_info (struct dwarf_cie
*cie
, struct _Unwind_Context
*context
,
262 _Unwind_FrameState
*fs
)
264 const unsigned char *aug
= cie
->augmentation
;
265 const unsigned char *p
= aug
+ strlen (aug
) + 1;
266 const unsigned char *ret
= NULL
;
269 /* g++ v2 "eh" has pointer immediately following augmentation string,
270 so it must be handled first. */
271 if (aug
[0] == 'e' && aug
[1] == 'h')
273 fs
->eh_ptr
= read_pointer (p
);
274 p
+= sizeof (void *);
278 /* Immediately following the augmentation are the code and
279 data alignment and return address column. */
280 p
= read_uleb128 (p
, &fs
->code_align
);
281 p
= read_sleb128 (p
, &fs
->data_align
);
282 fs
->retaddr_column
= *p
++;
283 fs
->lsda_encoding
= DW_EH_PE_omit
;
285 /* If the augmentation starts with 'z', then a uleb128 immediately
286 follows containing the length of the augmentation field following
290 p
= read_uleb128 (p
, &utmp
);
297 /* Iterate over recognized augmentation subsequences. */
300 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
303 fs
->lsda_encoding
= *p
++;
307 /* "R" indicates a byte indicating how FDE addresses are encoded. */
308 else if (aug
[0] == 'R')
310 fs
->fde_encoding
= *p
++;
314 /* "P" indicates a personality routine in the CIE augmentation. */
315 else if (aug
[0] == 'P')
317 p
= read_encoded_value (context
, *p
, p
+ 1,
318 (_Unwind_Ptr
*) &fs
->personality
);
322 /* Otherwise we have an unknown augmentation string.
323 Bail unless we saw a 'z' prefix. */
328 return ret
? ret
: p
;
332 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
333 onto the stack to start. */
336 execute_stack_op (const unsigned char *op_ptr
, const unsigned char *op_end
,
337 struct _Unwind_Context
*context
, _Unwind_Word initial
)
339 _Unwind_Word stack
[64]; /* ??? Assume this is enough. */
345 while (op_ptr
< op_end
)
347 enum dwarf_location_atom op
= *op_ptr
++;
348 _Unwind_Word result
, reg
, utmp
;
349 _Unwind_Sword offset
, stmp
;
385 result
= op
- DW_OP_lit0
;
389 result
= (_Unwind_Word
) (_Unwind_Ptr
) read_pointer (op_ptr
);
390 op_ptr
+= sizeof (void *);
394 result
= read_1u (op_ptr
);
398 result
= read_1s (op_ptr
);
402 result
= read_2u (op_ptr
);
406 result
= read_2s (op_ptr
);
410 result
= read_4u (op_ptr
);
414 result
= read_4s (op_ptr
);
418 result
= read_8u (op_ptr
);
422 result
= read_8s (op_ptr
);
426 op_ptr
= read_uleb128 (op_ptr
, &result
);
429 op_ptr
= read_sleb128 (op_ptr
, &stmp
);
465 result
= _Unwind_GetGR (context
, op
- DW_OP_reg0
);
468 op_ptr
= read_uleb128 (op_ptr
, ®
);
469 result
= _Unwind_GetGR (context
, reg
);
504 op_ptr
= read_sleb128 (op_ptr
, &offset
);
505 result
= _Unwind_GetGR (context
, op
- DW_OP_breg0
) + offset
;
508 op_ptr
= read_uleb128 (op_ptr
, ®
);
509 op_ptr
= read_sleb128 (op_ptr
, &offset
);
510 result
= _Unwind_GetGR (context
, reg
) + offset
;
516 result
= stack
[stack_elt
- 1];
526 if (offset
>= stack_elt
- 1)
528 result
= stack
[stack_elt
- 1 - offset
];
534 result
= stack
[stack_elt
- 2];
539 _Unwind_Word t1
, t2
, t3
;
543 t1
= stack
[stack_elt
- 1];
544 t2
= stack
[stack_elt
- 2];
545 t3
= stack
[stack_elt
- 3];
546 stack
[stack_elt
- 1] = t2
;
547 stack
[stack_elt
- 2] = t3
;
548 stack
[stack_elt
- 3] = t1
;
553 case DW_OP_deref_size
:
557 case DW_OP_plus_uconst
:
558 /* Unary operations. */
561 result
= stack
[stack_elt
];
567 void *ptr
= (void *) (_Unwind_Ptr
) result
;
568 result
= (_Unwind_Ptr
) read_pointer (ptr
);
572 case DW_OP_deref_size
:
574 void *ptr
= (void *) (_Unwind_Ptr
) result
;
578 result
= read_1u (ptr
);
581 result
= read_2u (ptr
);
584 result
= read_4u (ptr
);
587 result
= read_8u (ptr
);
596 if ((_Unwind_Sword
) result
< 0)
605 case DW_OP_plus_uconst
:
606 op_ptr
= read_uleb128 (op_ptr
, &utmp
);
629 /* Binary operations. */
630 _Unwind_Word first
, second
;
631 if ((stack_elt
-= 2) < 0)
633 second
= stack
[stack_elt
];
634 first
= stack
[stack_elt
+ 1];
639 result
= second
& first
;
642 result
= (_Unwind_Sword
) second
/ (_Unwind_Sword
) first
;
645 result
= second
- first
;
648 result
= (_Unwind_Sword
) second
% (_Unwind_Sword
) first
;
651 result
= second
* first
;
654 result
= second
| first
;
657 result
= second
+ first
;
660 result
= second
<< first
;
663 result
= second
>> first
;
666 result
= (_Unwind_Sword
) second
>> first
;
669 result
= second
^ first
;
672 result
= (_Unwind_Sword
) first
<= (_Unwind_Sword
) second
;
675 result
= (_Unwind_Sword
) first
>= (_Unwind_Sword
) second
;
678 result
= (_Unwind_Sword
) first
== (_Unwind_Sword
) second
;
681 result
= (_Unwind_Sword
) first
< (_Unwind_Sword
) second
;
684 result
= (_Unwind_Sword
) first
> (_Unwind_Sword
) second
;
687 result
= (_Unwind_Sword
) first
!= (_Unwind_Sword
) second
;
697 offset
= read_2s (op_ptr
);
705 offset
= read_2s (op_ptr
);
707 if (stack
[stack_elt
] != 0)
718 /* Most things push a result value. */
719 if ((size_t) stack_elt
>= sizeof(stack
)/sizeof(*stack
))
721 stack
[++stack_elt
] = result
;
725 /* We were executing this program to get a value. It should be
729 return stack
[stack_elt
];
733 /* Decode DWARF 2 call frame information. Takes pointers the
734 instruction sequence to decode, current register information and
735 CIE info, and the PC range to evaluate. */
738 execute_cfa_program (const unsigned char *insn_ptr
,
739 const unsigned char *insn_end
,
740 struct _Unwind_Context
*context
,
741 _Unwind_FrameState
*fs
)
743 struct frame_state_reg_info
*unused_rs
= NULL
;
745 /* Don't allow remember/restore between CIE and FDE programs. */
746 fs
->regs
.prev
= NULL
;
748 /* The comparison with the return address uses < rather than <= because
749 we are only interested in the effects of code before the call; for a
750 noreturn function, the return address may point to unrelated code with
751 a different stack configuration that we are not interested in. We
752 assume that the call itself is unwind info-neutral; if not, or if
753 there are delay instructions that adjust the stack, these must be
754 reflected at the point immediately before the call insn. */
755 while (insn_ptr
< insn_end
&& fs
->pc
< context
->ra
)
757 unsigned char insn
= *insn_ptr
++;
758 _Unwind_Word reg
, utmp
;
759 _Unwind_Sword offset
, stmp
;
761 if ((insn
& 0xc0) == DW_CFA_advance_loc
)
762 fs
->pc
+= (insn
& 0x3f) * fs
->code_align
;
763 else if ((insn
& 0xc0) == DW_CFA_offset
)
766 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
767 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
768 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
770 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
772 else if ((insn
& 0xc0) == DW_CFA_restore
)
775 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_UNSAVED
;
780 insn_ptr
= read_encoded_value (context
, fs
->fde_encoding
,
781 insn_ptr
, (_Unwind_Ptr
*) &fs
->pc
);
784 case DW_CFA_advance_loc1
:
785 fs
->pc
+= read_1u (insn_ptr
) * fs
->code_align
;
788 case DW_CFA_advance_loc2
:
789 fs
->pc
+= read_2u (insn_ptr
) * fs
->code_align
;
792 case DW_CFA_advance_loc4
:
793 fs
->pc
+= read_4u (insn_ptr
) * fs
->code_align
;
797 case DW_CFA_offset_extended
:
798 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
799 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
800 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
801 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
803 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
806 case DW_CFA_restore_extended
:
807 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
808 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN(reg
)].how
= REG_UNSAVED
;
811 case DW_CFA_undefined
:
812 case DW_CFA_same_value
:
813 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
819 case DW_CFA_register
:
822 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
823 insn_ptr
= read_uleb128 (insn_ptr
, ®2
);
824 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_SAVED_REG
;
825 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.reg
= reg2
;
829 case DW_CFA_remember_state
:
831 struct frame_state_reg_info
*new_rs
;
835 unused_rs
= unused_rs
->prev
;
838 new_rs
= __builtin_alloca (sizeof (struct frame_state_reg_info
));
841 fs
->regs
.prev
= new_rs
;
845 case DW_CFA_restore_state
:
847 struct frame_state_reg_info
*old_rs
= fs
->regs
.prev
;
849 old_rs
->prev
= unused_rs
;
855 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
856 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
857 fs
->cfa_offset
= utmp
;
858 fs
->cfa_how
= CFA_REG_OFFSET
;
861 case DW_CFA_def_cfa_register
:
862 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
863 fs
->cfa_how
= CFA_REG_OFFSET
;
866 case DW_CFA_def_cfa_offset
:
867 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
868 fs
->cfa_offset
= utmp
;
869 /* cfa_how deliberately not set. */
872 case DW_CFA_def_cfa_expression
:
873 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
874 fs
->cfa_exp
= insn_ptr
;
875 fs
->cfa_how
= CFA_EXP
;
879 case DW_CFA_expression
:
880 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
881 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
882 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_SAVED_EXP
;
883 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.exp
= insn_ptr
;
887 /* From the 2.1 draft. */
888 case DW_CFA_offset_extended_sf
:
889 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
890 insn_ptr
= read_sleb128 (insn_ptr
, &stmp
);
891 offset
= stmp
* fs
->data_align
;
892 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
894 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
897 case DW_CFA_def_cfa_sf
:
898 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
899 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
900 fs
->cfa_how
= CFA_REG_OFFSET
;
903 case DW_CFA_def_cfa_offset_sf
:
904 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
905 /* cfa_how deliberately not set. */
908 case DW_CFA_GNU_window_save
:
909 /* ??? Hardcoded for SPARC register window configuration. */
910 for (reg
= 16; reg
< 32; ++reg
)
912 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
913 fs
->regs
.reg
[reg
].loc
.offset
= (reg
- 16) * sizeof (void *);
917 case DW_CFA_GNU_args_size
:
918 insn_ptr
= read_uleb128 (insn_ptr
, &context
->args_size
);
921 case DW_CFA_GNU_negative_offset_extended
:
922 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
923 older PowerPC code. */
924 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
925 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
926 offset
= (_Unwind_Word
) utmp
* fs
->data_align
;
927 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
929 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= -offset
;
938 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
939 its caller and decode it into FS. This function also sets the
940 args_size and lsda members of CONTEXT, as they are really information
941 about the caller's frame. */
943 static _Unwind_Reason_Code
944 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
946 struct dwarf_fde
*fde
;
947 struct dwarf_cie
*cie
;
948 const unsigned char *aug
, *insn
, *end
;
950 memset (fs
, 0, sizeof (*fs
));
951 context
->args_size
= 0;
954 fde
= _Unwind_Find_FDE (context
->ra
- 1, &context
->bases
);
957 /* Couldn't find frame unwind info for this function. Try a
958 target-specific fallback mechanism. This will necessarily
959 not provide a personality routine or LSDA. */
960 #ifdef MD_FALLBACK_FRAME_STATE_FOR
961 MD_FALLBACK_FRAME_STATE_FOR (context
, fs
, success
);
962 return _URC_END_OF_STACK
;
964 return _URC_NO_REASON
;
966 return _URC_END_OF_STACK
;
970 fs
->pc
= context
->bases
.func
;
973 insn
= extract_cie_info (cie
, context
, fs
);
975 /* CIE contained unknown augmentation. */
976 return _URC_FATAL_PHASE1_ERROR
;
978 /* First decode all the insns in the CIE. */
979 end
= (unsigned char *) next_fde ((struct dwarf_fde
*) cie
);
980 execute_cfa_program (insn
, end
, context
, fs
);
982 /* Locate augmentation for the fde. */
983 aug
= (unsigned char *) fde
+ sizeof (*fde
);
984 aug
+= 2 * size_of_encoded_value (fs
->fde_encoding
);
989 aug
= read_uleb128 (aug
, &i
);
992 if (fs
->lsda_encoding
!= DW_EH_PE_omit
)
993 aug
= read_encoded_value (context
, fs
->lsda_encoding
, aug
,
994 (_Unwind_Ptr
*) &context
->lsda
);
996 /* Then the insns in the FDE up to our target PC. */
999 end
= (unsigned char *) next_fde (fde
);
1000 execute_cfa_program (insn
, end
, context
, fs
);
1002 return _URC_NO_REASON
;
1005 typedef struct frame_state
1011 long reg_or_offset
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1012 unsigned short cfa_reg
;
1013 unsigned short retaddr_column
;
1014 char saved
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1017 struct frame_state
* __frame_state_for (void *, struct frame_state
*);
1019 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1020 a given PC_TARGET. The caller should allocate a local variable of
1021 `struct frame_state' and pass its address to STATE_IN. */
1023 struct frame_state
*
1024 __frame_state_for (void *pc_target
, struct frame_state
*state_in
)
1026 struct _Unwind_Context context
;
1027 _Unwind_FrameState fs
;
1030 memset (&context
, 0, sizeof (struct _Unwind_Context
));
1031 context
.ra
= pc_target
+ 1;
1033 if (uw_frame_state_for (&context
, &fs
) != _URC_NO_REASON
)
1036 /* We have no way to pass a location expression for the CFA to our
1037 caller. It wouldn't understand it anyway. */
1038 if (fs
.cfa_how
== CFA_EXP
)
1041 for (reg
= 0; reg
< PRE_GCC3_DWARF_FRAME_REGISTERS
+ 1; reg
++)
1043 state_in
->saved
[reg
] = fs
.regs
.reg
[reg
].how
;
1044 switch (state_in
->saved
[reg
])
1047 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.reg
;
1049 case REG_SAVED_OFFSET
:
1050 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.offset
;
1053 state_in
->reg_or_offset
[reg
] = 0;
1058 state_in
->cfa_offset
= fs
.cfa_offset
;
1059 state_in
->cfa_reg
= fs
.cfa_reg
;
1060 state_in
->retaddr_column
= fs
.retaddr_column
;
1061 state_in
->args_size
= context
.args_size
;
1062 state_in
->eh_ptr
= fs
.eh_ptr
;
1068 uw_update_context_1 (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1070 struct _Unwind_Context orig_context
= *context
;
1074 /* Compute this frame's CFA. */
1075 switch (fs
->cfa_how
)
1077 case CFA_REG_OFFSET
:
1078 /* Special handling here: Many machines do not use a frame pointer,
1079 and track the CFA only through offsets from the stack pointer from
1080 one frame to the next. In this case, the stack pointer is never
1081 stored, so it has no saved address in the context. What we do
1082 have is the CFA from the previous stack frame. */
1083 if (_Unwind_GetGRPtr (context
, fs
->cfa_reg
) == NULL
)
1086 cfa
= (void *) (_Unwind_Ptr
) _Unwind_GetGR (context
, fs
->cfa_reg
);
1087 cfa
+= fs
->cfa_offset
;
1091 /* ??? No way of knowing what register number is the stack pointer
1092 to do the same sort of handling as above. Assume that if the
1093 CFA calculation is so complicated as to require a stack program
1094 that this will not be a problem. */
1096 const unsigned char *exp
= fs
->cfa_exp
;
1099 exp
= read_uleb128 (exp
, &len
);
1100 cfa
= (void *) (_Unwind_Ptr
)
1101 execute_stack_op (exp
, exp
+ len
, context
, 0);
1110 /* Compute the addresses of all registers saved in this frame. */
1111 for (i
= 0; i
< DWARF_FRAME_REGISTERS
+ 1; ++i
)
1112 switch (fs
->regs
.reg
[i
].how
)
1116 case REG_SAVED_OFFSET
:
1117 _Unwind_SetGRPtr (context
, i
, (void *) (cfa
+ fs
->regs
.reg
[i
].loc
.offset
));
1122 _Unwind_GetGRPtr (&orig_context
, fs
->regs
.reg
[i
].loc
.reg
));
1126 const unsigned char *exp
= fs
->regs
.reg
[i
].loc
.exp
;
1130 exp
= read_uleb128 (exp
, &len
);
1131 val
= execute_stack_op (exp
, exp
+ len
, &orig_context
,
1133 _Unwind_SetGRPtr (context
, i
, (void *) val
);
1139 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1140 of its caller. Update CONTEXT to refer to the caller as well. Note
1141 that the args_size and lsda members are not updated here, but later in
1142 uw_frame_state_for. */
1145 uw_update_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1147 uw_update_context_1 (context
, fs
);
1149 /* Compute the return address now, since the return address column
1150 can change from frame to frame. */
1151 context
->ra
= __builtin_extract_return_addr
1152 ((void *) (_Unwind_Ptr
) _Unwind_GetGR (context
, fs
->retaddr_column
));
1155 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1156 level will be the return address and the CFA. */
1158 #define uw_init_context(CONTEXT) \
1161 /* Do any necessary initialization to access arbitrary stack frames. \
1162 On the SPARC, this means flushing the register windows. */ \
1163 __builtin_unwind_init (); \
1164 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1165 __builtin_return_address (0)); \
1170 uw_init_context_1 (struct _Unwind_Context
*context
,
1171 void *outer_cfa
, void *outer_ra
)
1173 void *ra
= __builtin_extract_return_addr (__builtin_return_address (0));
1174 _Unwind_FrameState fs
;
1176 memset (context
, 0, sizeof (struct _Unwind_Context
));
1179 if (uw_frame_state_for (context
, &fs
) != _URC_NO_REASON
)
1182 /* Force the frame state to use the known cfa value. */
1183 context
->cfa
= outer_cfa
;
1184 fs
.cfa_how
= CFA_REG_OFFSET
;
1188 uw_update_context_1 (context
, &fs
);
1190 /* If the return address column was saved in a register in the
1191 initialization context, then we can't see it in the given
1192 call frame data. So have the initialization context tell us. */
1193 context
->ra
= __builtin_extract_return_addr (outer_ra
);
1197 /* Install TARGET into CURRENT so that we can return to it. This is a
1198 macro because __builtin_eh_return must be invoked in the context of
1201 #define uw_install_context(CURRENT, TARGET) \
1204 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1205 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1206 __builtin_eh_return (offset, handler); \
1211 init_dwarf_reg_size_table (void)
1213 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table
);
1217 uw_install_context_1 (struct _Unwind_Context
*current
,
1218 struct _Unwind_Context
*target
)
1224 static __gthread_once_t once_regsizes
= __GTHREAD_ONCE_INIT
;
1225 if (__gthread_once (&once_regsizes
, init_dwarf_reg_size_table
) != 0
1226 || dwarf_reg_size_table
[0] == 0)
1227 init_dwarf_reg_size_table ();
1230 if (dwarf_reg_size_table
[0] == 0)
1231 init_dwarf_reg_size_table ();
1234 for (i
= 0; i
< DWARF_FRAME_REGISTERS
; ++i
)
1236 void *c
= current
->reg
[i
];
1237 void *t
= target
->reg
[i
];
1239 if (t
&& c
&& t
!= c
)
1240 memcpy (c
, t
, dwarf_reg_size_table
[i
]);
1243 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1244 if (STACK_GROWS_DOWNWARD
)
1245 return target
->cfa
- current
->cfa
+ target
->args_size
;
1247 return current
->cfa
- target
->cfa
- target
->args_size
;
1250 static inline _Unwind_Ptr
1251 uw_identify_context (struct _Unwind_Context
*context
)
1253 return _Unwind_GetIP (context
);
1257 #include "unwind.inc"
1259 #endif /* !USING_SJLJ_EXCEPTIONS */