1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997,1998,1999,2000,2001,2002,2003,2005,2006,2007
3 Free Software Foundation, Inc.
5 This file is part of the GNU C Library.
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with the GNU C Library; if not, write to the Free
19 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
30 #include <unwind-pe.h>
31 #include <unwind-dw2-fde.h>
37 #include "unwind-pe.h"
38 #include "unwind-dw2-fde.h"
44 #ifndef STACK_GROWS_DOWNWARD
45 #define STACK_GROWS_DOWNWARD 0
47 #undef STACK_GROWS_DOWNWARD
48 #define STACK_GROWS_DOWNWARD 1
51 /* A target can override (perhaps for backward compatibility) how
52 many dwarf2 columns are unwound. */
53 #ifndef DWARF_FRAME_REGISTERS
54 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
57 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
58 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
59 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
62 /* This is the register and unwind state for a particular frame. This
63 provides the information necessary to unwind up past a frame and return
65 struct _Unwind_Context
67 void *reg
[DWARF_FRAME_REGISTERS
+1];
71 struct dwarf_eh_bases bases
;
72 _Unwind_Word args_size
;
76 /* Byte size of every register managed by these routines. */
77 static unsigned char dwarf_reg_size_table
[DWARF_FRAME_REGISTERS
];
81 /* The result of interpreting the frame unwind info for a frame.
82 This is all symbolic at this point, as none of the values can
83 be resolved until the target pc is located. */
86 /* Each register save state can be described in terms of a CFA slot,
87 another register, or a location expression. */
88 struct frame_state_reg_info
94 const unsigned char *exp
;
102 } reg
[DWARF_FRAME_REGISTERS
+1];
104 /* Used to implement DW_CFA_remember_state. */
105 struct frame_state_reg_info
*prev
;
108 /* The CFA can be described in terms of a reg+offset or a
109 location expression. */
110 _Unwind_Sword cfa_offset
;
111 _Unwind_Word cfa_reg
;
112 const unsigned char *cfa_exp
;
119 /* The PC described by the current frame state. */
122 /* The information we care about from the CIE/FDE. */
123 _Unwind_Personality_Fn personality
;
124 _Unwind_Sword data_align
;
125 _Unwind_Word code_align
;
126 unsigned char retaddr_column
;
127 unsigned char fde_encoding
;
128 unsigned char lsda_encoding
;
131 } _Unwind_FrameState
;
133 /* Read unaligned data from the instruction buffer. */
138 unsigned u2
__attribute__ ((mode (HI
)));
139 unsigned u4
__attribute__ ((mode (SI
)));
140 unsigned u8
__attribute__ ((mode (DI
)));
141 signed s2
__attribute__ ((mode (HI
)));
142 signed s4
__attribute__ ((mode (SI
)));
143 signed s8
__attribute__ ((mode (DI
)));
144 } __attribute__ ((packed
));
147 read_pointer (const void *p
) { const union unaligned
*up
= p
; return up
->p
; }
150 read_1u (const void *p
) { return *(const unsigned char *) p
; }
153 read_1s (const void *p
) { return *(const signed char *) p
; }
156 read_2u (const void *p
) { const union unaligned
*up
= p
; return up
->u2
; }
159 read_2s (const void *p
) { const union unaligned
*up
= p
; return up
->s2
; }
161 static inline unsigned int
162 read_4u (const void *p
) { const union unaligned
*up
= p
; return up
->u4
; }
165 read_4s (const void *p
) { const union unaligned
*up
= p
; return up
->s4
; }
167 static inline unsigned long
168 read_8u (const void *p
) { const union unaligned
*up
= p
; return up
->u8
; }
170 static inline unsigned long
171 read_8s (const void *p
) { const union unaligned
*up
= p
; return up
->s8
; }
173 /* Get the value of register REG as saved in CONTEXT. */
176 _Unwind_GetGR (struct _Unwind_Context
*context
, int index
)
178 /* This will segfault if the register hasn't been saved. */
179 return * (_Unwind_Word
*) context
->reg
[index
];
182 /* Get the value of the CFA as saved in CONTEXT. */
185 _Unwind_GetCFA (struct _Unwind_Context
*context
)
187 return (_Unwind_Ptr
) context
->cfa
;
190 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
193 _Unwind_SetGR (struct _Unwind_Context
*context
, int index
, _Unwind_Word val
)
195 * (_Unwind_Word
*) context
->reg
[index
] = val
;
198 /* Retrieve the return address for CONTEXT. */
201 _Unwind_GetIP (struct _Unwind_Context
*context
)
203 return (_Unwind_Ptr
) context
->ra
;
206 /* Overwrite the return address for CONTEXT with VAL. */
209 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
211 context
->ra
= (void *) val
;
215 _Unwind_GetLanguageSpecificData (struct _Unwind_Context
*context
)
217 return context
->lsda
;
221 _Unwind_GetRegionStart (struct _Unwind_Context
*context
)
223 return (_Unwind_Ptr
) context
->bases
.func
;
227 _Unwind_FindEnclosingFunction (void *pc
)
229 struct dwarf_eh_bases bases
;
230 struct dwarf_fde
*fde
= _Unwind_Find_FDE (pc
-1, &bases
);
239 _Unwind_GetDataRelBase (struct _Unwind_Context
*context
)
241 return (_Unwind_Ptr
) context
->bases
.dbase
;
245 _Unwind_GetTextRelBase (struct _Unwind_Context
*context
)
247 return (_Unwind_Ptr
) context
->bases
.tbase
;
251 /* Extract any interesting information from the CIE for the translation
252 unit F belongs to. Return a pointer to the byte after the augmentation,
253 or NULL if we encountered an undecipherable augmentation. */
255 static const unsigned char *
256 extract_cie_info (struct dwarf_cie
*cie
, struct _Unwind_Context
*context
,
257 _Unwind_FrameState
*fs
)
259 const unsigned char *aug
= cie
->augmentation
;
260 const unsigned char *p
= aug
+ strlen ((const char *) aug
) + 1;
261 const unsigned char *ret
= NULL
;
264 /* g++ v2 "eh" has pointer immediately following augmentation string,
265 so it must be handled first. */
266 if (aug
[0] == 'e' && aug
[1] == 'h')
268 fs
->eh_ptr
= read_pointer (p
);
269 p
+= sizeof (void *);
273 /* Immediately following the augmentation are the code and
274 data alignment and return address column. */
275 p
= read_uleb128 (p
, &fs
->code_align
);
276 p
= read_sleb128 (p
, &fs
->data_align
);
277 fs
->retaddr_column
= *p
++;
278 fs
->lsda_encoding
= DW_EH_PE_omit
;
280 /* If the augmentation starts with 'z', then a uleb128 immediately
281 follows containing the length of the augmentation field following
285 p
= read_uleb128 (p
, &utmp
);
292 /* Iterate over recognized augmentation subsequences. */
295 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
298 fs
->lsda_encoding
= *p
++;
302 /* "R" indicates a byte indicating how FDE addresses are encoded. */
303 else if (aug
[0] == 'R')
305 fs
->fde_encoding
= *p
++;
309 /* "P" indicates a personality routine in the CIE augmentation. */
310 else if (aug
[0] == 'P')
312 _Unwind_Ptr personality
;
313 p
= read_encoded_value (context
, *p
, p
+ 1, &personality
);
314 fs
->personality
= (_Unwind_Personality_Fn
) personality
;
318 /* Otherwise we have an unknown augmentation string.
319 Bail unless we saw a 'z' prefix. */
324 return ret
? ret
: p
;
328 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
329 onto the stack to start. */
332 execute_stack_op (const unsigned char *op_ptr
, const unsigned char *op_end
,
333 struct _Unwind_Context
*context
, _Unwind_Word initial
)
335 _Unwind_Word stack
[64]; /* ??? Assume this is enough. */
341 while (op_ptr
< op_end
)
343 enum dwarf_location_atom op
= *op_ptr
++;
344 _Unwind_Word result
, reg
, utmp
;
345 _Unwind_Sword offset
, stmp
;
381 result
= op
- DW_OP_lit0
;
385 result
= (_Unwind_Word
) (_Unwind_Ptr
) read_pointer (op_ptr
);
386 op_ptr
+= sizeof (void *);
390 result
= read_1u (op_ptr
);
394 result
= read_1s (op_ptr
);
398 result
= read_2u (op_ptr
);
402 result
= read_2s (op_ptr
);
406 result
= read_4u (op_ptr
);
410 result
= read_4s (op_ptr
);
414 result
= read_8u (op_ptr
);
418 result
= read_8s (op_ptr
);
422 op_ptr
= read_uleb128 (op_ptr
, &result
);
425 op_ptr
= read_sleb128 (op_ptr
, &stmp
);
461 result
= _Unwind_GetGR (context
, op
- DW_OP_reg0
);
464 op_ptr
= read_uleb128 (op_ptr
, ®
);
465 result
= _Unwind_GetGR (context
, reg
);
500 op_ptr
= read_sleb128 (op_ptr
, &offset
);
501 result
= _Unwind_GetGR (context
, op
- DW_OP_breg0
) + offset
;
504 op_ptr
= read_uleb128 (op_ptr
, ®
);
505 op_ptr
= read_sleb128 (op_ptr
, &offset
);
506 result
= _Unwind_GetGR (context
, reg
) + offset
;
512 result
= stack
[stack_elt
- 1];
522 if (offset
>= stack_elt
- 1)
524 result
= stack
[stack_elt
- 1 - offset
];
530 result
= stack
[stack_elt
- 2];
535 _Unwind_Word t1
, t2
, t3
;
539 t1
= stack
[stack_elt
- 1];
540 t2
= stack
[stack_elt
- 2];
541 t3
= stack
[stack_elt
- 3];
542 stack
[stack_elt
- 1] = t2
;
543 stack
[stack_elt
- 2] = t3
;
544 stack
[stack_elt
- 3] = t1
;
549 case DW_OP_deref_size
:
553 case DW_OP_plus_uconst
:
554 /* Unary operations. */
557 result
= stack
[stack_elt
];
563 void *ptr
= (void *) (_Unwind_Ptr
) result
;
564 result
= (_Unwind_Ptr
) read_pointer (ptr
);
568 case DW_OP_deref_size
:
570 void *ptr
= (void *) (_Unwind_Ptr
) result
;
574 result
= read_1u (ptr
);
577 result
= read_2u (ptr
);
580 result
= read_4u (ptr
);
583 result
= read_8u (ptr
);
592 if ((_Unwind_Sword
) result
< 0)
601 case DW_OP_plus_uconst
:
602 op_ptr
= read_uleb128 (op_ptr
, &utmp
);
625 /* Binary operations. */
626 _Unwind_Word first
, second
;
627 if ((stack_elt
-= 2) < 0)
629 second
= stack
[stack_elt
];
630 first
= stack
[stack_elt
+ 1];
635 result
= second
& first
;
638 result
= (_Unwind_Sword
) second
/ (_Unwind_Sword
) first
;
641 result
= second
- first
;
644 result
= (_Unwind_Sword
) second
% (_Unwind_Sword
) first
;
647 result
= second
* first
;
650 result
= second
| first
;
653 result
= second
+ first
;
656 result
= second
<< first
;
659 result
= second
>> first
;
662 result
= (_Unwind_Sword
) second
>> first
;
665 result
= second
^ first
;
668 result
= (_Unwind_Sword
) first
<= (_Unwind_Sword
) second
;
671 result
= (_Unwind_Sword
) first
>= (_Unwind_Sword
) second
;
674 result
= (_Unwind_Sword
) first
== (_Unwind_Sword
) second
;
677 result
= (_Unwind_Sword
) first
< (_Unwind_Sword
) second
;
680 result
= (_Unwind_Sword
) first
> (_Unwind_Sword
) second
;
683 result
= (_Unwind_Sword
) first
!= (_Unwind_Sword
) second
;
693 offset
= read_2s (op_ptr
);
701 offset
= read_2s (op_ptr
);
703 if (stack
[stack_elt
] != 0)
714 /* Most things push a result value. */
715 if ((size_t) stack_elt
>= sizeof(stack
)/sizeof(*stack
))
717 stack
[stack_elt
++] = result
;
721 /* We were executing this program to get a value. It should be
725 return stack
[stack_elt
];
729 /* Decode DWARF 2 call frame information. Takes pointers the
730 instruction sequence to decode, current register information and
731 CIE info, and the PC range to evaluate. */
734 execute_cfa_program (const unsigned char *insn_ptr
,
735 const unsigned char *insn_end
,
736 struct _Unwind_Context
*context
,
737 _Unwind_FrameState
*fs
)
739 struct frame_state_reg_info
*unused_rs
= NULL
;
741 /* Don't allow remember/restore between CIE and FDE programs. */
742 fs
->regs
.prev
= NULL
;
744 /* The comparison with the return address uses < rather than <= because
745 we are only interested in the effects of code before the call; for a
746 noreturn function, the return address may point to unrelated code with
747 a different stack configuration that we are not interested in. We
748 assume that the call itself is unwind info-neutral; if not, or if
749 there are delay instructions that adjust the stack, these must be
750 reflected at the point immediately before the call insn. */
751 while (insn_ptr
< insn_end
&& fs
->pc
< context
->ra
)
753 unsigned char insn
= *insn_ptr
++;
754 _Unwind_Word reg
, utmp
;
755 _Unwind_Sword offset
, stmp
;
757 if ((insn
& 0xc0) == DW_CFA_advance_loc
)
758 fs
->pc
+= (insn
& 0x3f) * fs
->code_align
;
759 else if ((insn
& 0xc0) == DW_CFA_offset
)
762 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
763 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
764 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
765 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
767 else if ((insn
& 0xc0) == DW_CFA_restore
)
770 fs
->regs
.reg
[reg
].how
= REG_UNSAVED
;
777 insn_ptr
= read_encoded_value (context
, fs
->fde_encoding
,
779 fs
->pc
= (void *) pc
;
783 case DW_CFA_advance_loc1
:
784 fs
->pc
+= read_1u (insn_ptr
) * fs
->code_align
;
787 case DW_CFA_advance_loc2
:
788 fs
->pc
+= read_2u (insn_ptr
) * fs
->code_align
;
791 case DW_CFA_advance_loc4
:
792 fs
->pc
+= read_4u (insn_ptr
) * fs
->code_align
;
796 case DW_CFA_offset_extended
:
797 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
798 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
799 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
800 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
801 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
804 case DW_CFA_restore_extended
:
805 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
806 fs
->regs
.reg
[reg
].how
= REG_UNSAVED
;
809 case DW_CFA_undefined
:
810 case DW_CFA_same_value
:
811 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
817 case DW_CFA_register
:
820 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
821 insn_ptr
= read_uleb128 (insn_ptr
, ®2
);
822 fs
->regs
.reg
[reg
].how
= REG_SAVED_REG
;
823 fs
->regs
.reg
[reg
].loc
.reg
= reg2
;
827 case DW_CFA_remember_state
:
829 struct frame_state_reg_info
*new_rs
;
833 unused_rs
= unused_rs
->prev
;
836 new_rs
= __builtin_alloca (sizeof (struct frame_state_reg_info
));
839 fs
->regs
.prev
= new_rs
;
843 case DW_CFA_restore_state
:
845 struct frame_state_reg_info
*old_rs
= fs
->regs
.prev
;
848 __libc_fatal ("invalid DWARF unwind data");
853 old_rs
->prev
= unused_rs
;
860 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
861 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
862 fs
->cfa_offset
= utmp
;
863 fs
->cfa_how
= CFA_REG_OFFSET
;
866 case DW_CFA_def_cfa_register
:
867 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
868 fs
->cfa_how
= CFA_REG_OFFSET
;
871 case DW_CFA_def_cfa_offset
:
872 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
873 fs
->cfa_offset
= utmp
;
874 /* cfa_how deliberately not set. */
877 case DW_CFA_def_cfa_expression
:
878 fs
->cfa_exp
= insn_ptr
;
879 fs
->cfa_how
= CFA_EXP
;
880 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
884 case DW_CFA_expression
:
885 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
886 fs
->regs
.reg
[reg
].how
= REG_SAVED_EXP
;
887 fs
->regs
.reg
[reg
].loc
.exp
= insn_ptr
;
888 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
892 /* From the 2.1 draft. */
893 case DW_CFA_offset_extended_sf
:
894 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
895 insn_ptr
= read_sleb128 (insn_ptr
, &stmp
);
896 offset
= stmp
* fs
->data_align
;
897 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
898 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
901 case DW_CFA_def_cfa_sf
:
902 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
903 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
904 fs
->cfa_how
= CFA_REG_OFFSET
;
907 case DW_CFA_def_cfa_offset_sf
:
908 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
909 /* cfa_how deliberately not set. */
912 case DW_CFA_GNU_window_save
:
913 /* ??? Hardcoded for SPARC register window configuration.
914 At least do not do anything for archs which explicitly
915 define a lower register number. */
916 #if DWARF_FRAME_REGISTERS >= 32
917 for (reg
= 16; reg
< 32; ++reg
)
919 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
920 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
[reg
].how
= REG_SAVED_OFFSET
;
936 fs
->regs
.reg
[reg
].loc
.offset
= -offset
;
945 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
946 its caller and decode it into FS. This function also sets the
947 args_size and lsda members of CONTEXT, as they are really information
948 about the caller's frame. */
950 static _Unwind_Reason_Code
951 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
953 struct dwarf_fde
*fde
;
954 struct dwarf_cie
*cie
;
955 const unsigned char *aug
, *insn
, *end
;
957 memset (fs
, 0, sizeof (*fs
));
958 context
->args_size
= 0;
961 fde
= _Unwind_Find_FDE (context
->ra
- 1, &context
->bases
);
964 /* Couldn't find frame unwind info for this function. Try a
965 target-specific fallback mechanism. This will necessarily
966 not provide a personality routine or LSDA. */
967 #ifdef MD_FALLBACK_FRAME_STATE_FOR
968 MD_FALLBACK_FRAME_STATE_FOR (context
, fs
, success
);
969 return _URC_END_OF_STACK
;
971 return _URC_NO_REASON
;
973 return _URC_END_OF_STACK
;
977 fs
->pc
= context
->bases
.func
;
980 insn
= extract_cie_info (cie
, context
, fs
);
982 /* CIE contained unknown augmentation. */
983 return _URC_FATAL_PHASE1_ERROR
;
985 /* First decode all the insns in the CIE. */
986 end
= (unsigned char *) next_fde ((struct dwarf_fde
*) cie
);
987 execute_cfa_program (insn
, end
, context
, fs
);
989 /* Locate augmentation for the fde. */
990 aug
= (unsigned char *) fde
+ sizeof (*fde
);
991 aug
+= 2 * size_of_encoded_value (fs
->fde_encoding
);
996 aug
= read_uleb128 (aug
, &i
);
999 if (fs
->lsda_encoding
!= DW_EH_PE_omit
)
1002 aug
= read_encoded_value (context
, fs
->lsda_encoding
, aug
, &lsda
);
1003 context
->lsda
= (void *) lsda
;
1006 /* Then the insns in the FDE up to our target PC. */
1009 end
= (unsigned char *) next_fde (fde
);
1010 execute_cfa_program (insn
, end
, context
, fs
);
1012 return _URC_NO_REASON
;
1015 typedef struct frame_state
1021 long reg_or_offset
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1022 unsigned short cfa_reg
;
1023 unsigned short retaddr_column
;
1024 char saved
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1032 struct frame_state
* __frame_state_for (void *, struct frame_state
*);
1034 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1035 a given PC_TARGET. The caller should allocate a local variable of
1036 `struct frame_state' and pass its address to STATE_IN. */
1039 struct frame_state
*
1040 __frame_state_for (void *pc_target
, struct frame_state
*state_in
)
1042 struct _Unwind_Context context
;
1043 _Unwind_FrameState fs
;
1046 memset (&context
, 0, sizeof (struct _Unwind_Context
));
1047 context
.ra
= pc_target
+ 1;
1049 if (uw_frame_state_for (&context
, &fs
) != _URC_NO_REASON
)
1052 /* We have no way to pass a location expression for the CFA to our
1053 caller. It wouldn't understand it anyway. */
1054 if (fs
.cfa_how
== CFA_EXP
)
1057 for (reg
= 0; reg
< PRE_GCC3_DWARF_FRAME_REGISTERS
+ 1; reg
++)
1059 state_in
->saved
[reg
] = fs
.regs
.reg
[reg
].how
;
1060 switch (state_in
->saved
[reg
])
1063 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.reg
;
1065 case REG_SAVED_OFFSET
:
1066 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.offset
;
1069 state_in
->reg_or_offset
[reg
] = 0;
1074 state_in
->cfa_offset
= fs
.cfa_offset
;
1075 state_in
->cfa_reg
= fs
.cfa_reg
;
1076 state_in
->retaddr_column
= fs
.retaddr_column
;
1077 state_in
->args_size
= context
.args_size
;
1078 state_in
->eh_ptr
= fs
.eh_ptr
;
1086 uw_update_context_1 (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1088 struct _Unwind_Context orig_context
= *context
;
1092 #ifdef EH_RETURN_STACKADJ_RTX
1093 /* Special handling here: Many machines do not use a frame pointer,
1094 and track the CFA only through offsets from the stack pointer from
1095 one frame to the next. In this case, the stack pointer is never
1096 stored, so it has no saved address in the context. What we do
1097 have is the CFA from the previous stack frame.
1099 In very special situations (such as unwind info for signal return),
1100 there may be location expressions that use the stack pointer as well.
1102 Do this conditionally for one frame. This allows the unwind info
1103 for one frame to save a copy of the stack pointer from the previous
1104 frame, and be able to use much easier CFA mechanisms to do it.
1105 Always zap the saved stack pointer value for the next frame; carrying
1106 the value over from one frame to another doesn't make sense. */
1108 _Unwind_Word tmp_sp
;
1110 if (!orig_context
.reg
[__builtin_dwarf_sp_column ()])
1112 tmp_sp
= (_Unwind_Ptr
) context
->cfa
;
1113 orig_context
.reg
[__builtin_dwarf_sp_column ()] = &tmp_sp
;
1115 context
->reg
[__builtin_dwarf_sp_column ()] = NULL
;
1118 /* Compute this frame's CFA. */
1119 switch (fs
->cfa_how
)
1121 case CFA_REG_OFFSET
:
1122 cfa
= (void *) (_Unwind_Ptr
) _Unwind_GetGR (&orig_context
, fs
->cfa_reg
);
1123 cfa
+= fs
->cfa_offset
;
1128 const unsigned char *exp
= fs
->cfa_exp
;
1131 exp
= read_uleb128 (exp
, &len
);
1132 cfa
= (void *) (_Unwind_Ptr
)
1133 execute_stack_op (exp
, exp
+ len
, &orig_context
, 0);
1142 /* Compute the addresses of all registers saved in this frame. */
1143 for (i
= 0; i
< DWARF_FRAME_REGISTERS
+ 1; ++i
)
1144 switch (fs
->regs
.reg
[i
].how
)
1149 case REG_SAVED_OFFSET
:
1150 context
->reg
[i
] = cfa
+ fs
->regs
.reg
[i
].loc
.offset
;
1154 context
->reg
[i
] = orig_context
.reg
[fs
->regs
.reg
[i
].loc
.reg
];
1159 const unsigned char *exp
= fs
->regs
.reg
[i
].loc
.exp
;
1163 exp
= read_uleb128 (exp
, &len
);
1164 val
= execute_stack_op (exp
, exp
+ len
, &orig_context
,
1166 context
->reg
[i
] = (void *) val
;
1172 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1173 of its caller. Update CONTEXT to refer to the caller as well. Note
1174 that the args_size and lsda members are not updated here, but later in
1175 uw_frame_state_for. */
1178 uw_update_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1180 uw_update_context_1 (context
, fs
);
1182 /* Compute the return address now, since the return address column
1183 can change from frame to frame. */
1184 context
->ra
= __builtin_extract_return_addr
1185 ((void *) (_Unwind_Ptr
) _Unwind_GetGR (context
, fs
->retaddr_column
));
1188 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1189 level will be the return address and the CFA. */
1191 #define uw_init_context(CONTEXT) \
1194 /* Do any necessary initialization to access arbitrary stack frames. \
1195 On the SPARC, this means flushing the register windows. */ \
1196 __builtin_unwind_init (); \
1197 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1198 __builtin_return_address (0)); \
1203 uw_init_context_1 (struct _Unwind_Context
*context
,
1204 void *outer_cfa
, void *outer_ra
)
1206 void *ra
= __builtin_extract_return_addr (__builtin_return_address (0));
1207 _Unwind_FrameState fs
;
1208 _Unwind_Word sp_slot
;
1210 memset (context
, 0, sizeof (struct _Unwind_Context
));
1213 if (uw_frame_state_for (context
, &fs
) != _URC_NO_REASON
)
1216 /* Force the frame state to use the known cfa value. */
1217 sp_slot
= (_Unwind_Ptr
) outer_cfa
;
1218 context
->reg
[__builtin_dwarf_sp_column ()] = &sp_slot
;
1219 fs
.cfa_how
= CFA_REG_OFFSET
;
1220 fs
.cfa_reg
= __builtin_dwarf_sp_column ();
1223 uw_update_context_1 (context
, &fs
);
1225 /* If the return address column was saved in a register in the
1226 initialization context, then we can't see it in the given
1227 call frame data. So have the initialization context tell us. */
1228 context
->ra
= __builtin_extract_return_addr (outer_ra
);
1232 /* Install TARGET into CURRENT so that we can return to it. This is a
1233 macro because __builtin_eh_return must be invoked in the context of
1236 #define uw_install_context(CURRENT, TARGET) \
1239 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1240 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1241 __builtin_eh_return (offset, handler); \
1246 init_dwarf_reg_size_table (void)
1248 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table
);
1252 uw_install_context_1 (struct _Unwind_Context
*current
,
1253 struct _Unwind_Context
*target
)
1259 static __gthread_once_t once_regsizes
= __GTHREAD_ONCE_INIT
;
1260 if (__gthread_once (&once_regsizes
, init_dwarf_reg_size_table
) != 0
1261 || dwarf_reg_size_table
[0] == 0)
1262 init_dwarf_reg_size_table ();
1265 if (dwarf_reg_size_table
[0] == 0)
1266 init_dwarf_reg_size_table ();
1269 for (i
= 0; i
< DWARF_FRAME_REGISTERS
; ++i
)
1271 void *c
= current
->reg
[i
];
1272 void *t
= target
->reg
[i
];
1273 if (t
&& c
&& t
!= c
)
1274 memcpy (c
, t
, dwarf_reg_size_table
[i
]);
1277 #ifdef EH_RETURN_STACKADJ_RTX
1281 /* If the last frame records a saved stack pointer, use it. */
1282 if (target
->reg
[__builtin_dwarf_sp_column ()])
1283 target_cfa
= (void *)(_Unwind_Ptr
)
1284 _Unwind_GetGR (target
, __builtin_dwarf_sp_column ());
1286 target_cfa
= target
->cfa
;
1288 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1289 if (STACK_GROWS_DOWNWARD
)
1290 return target_cfa
- current
->cfa
+ target
->args_size
;
1292 return current
->cfa
- target_cfa
- target
->args_size
;
1299 static inline _Unwind_Ptr
1300 uw_identify_context (struct _Unwind_Context
*context
)
1302 return _Unwind_GetIP (context
);
1306 #include "unwind.inc"