1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997,1998,1999,2000,2001,2002,2003,2005,2006
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 p
= read_encoded_value (context
, *p
, p
+ 1,
313 (_Unwind_Ptr
*) &fs
->personality
);
317 /* Otherwise we have an unknown augmentation string.
318 Bail unless we saw a 'z' prefix. */
323 return ret
? ret
: p
;
327 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
328 onto the stack to start. */
331 execute_stack_op (const unsigned char *op_ptr
, const unsigned char *op_end
,
332 struct _Unwind_Context
*context
, _Unwind_Word initial
)
334 _Unwind_Word stack
[64]; /* ??? Assume this is enough. */
340 while (op_ptr
< op_end
)
342 enum dwarf_location_atom op
= *op_ptr
++;
343 _Unwind_Word result
, reg
, utmp
;
344 _Unwind_Sword offset
, stmp
;
380 result
= op
- DW_OP_lit0
;
384 result
= (_Unwind_Word
) (_Unwind_Ptr
) read_pointer (op_ptr
);
385 op_ptr
+= sizeof (void *);
389 result
= read_1u (op_ptr
);
393 result
= read_1s (op_ptr
);
397 result
= read_2u (op_ptr
);
401 result
= read_2s (op_ptr
);
405 result
= read_4u (op_ptr
);
409 result
= read_4s (op_ptr
);
413 result
= read_8u (op_ptr
);
417 result
= read_8s (op_ptr
);
421 op_ptr
= read_uleb128 (op_ptr
, &result
);
424 op_ptr
= read_sleb128 (op_ptr
, &stmp
);
460 result
= _Unwind_GetGR (context
, op
- DW_OP_reg0
);
463 op_ptr
= read_uleb128 (op_ptr
, ®
);
464 result
= _Unwind_GetGR (context
, reg
);
499 op_ptr
= read_sleb128 (op_ptr
, &offset
);
500 result
= _Unwind_GetGR (context
, op
- DW_OP_breg0
) + offset
;
503 op_ptr
= read_uleb128 (op_ptr
, ®
);
504 op_ptr
= read_sleb128 (op_ptr
, &offset
);
505 result
= _Unwind_GetGR (context
, reg
) + offset
;
511 result
= stack
[stack_elt
- 1];
521 if (offset
>= stack_elt
- 1)
523 result
= stack
[stack_elt
- 1 - offset
];
529 result
= stack
[stack_elt
- 2];
534 _Unwind_Word t1
, t2
, t3
;
538 t1
= stack
[stack_elt
- 1];
539 t2
= stack
[stack_elt
- 2];
540 t3
= stack
[stack_elt
- 3];
541 stack
[stack_elt
- 1] = t2
;
542 stack
[stack_elt
- 2] = t3
;
543 stack
[stack_elt
- 3] = t1
;
548 case DW_OP_deref_size
:
552 case DW_OP_plus_uconst
:
553 /* Unary operations. */
556 result
= stack
[stack_elt
];
562 void *ptr
= (void *) (_Unwind_Ptr
) result
;
563 result
= (_Unwind_Ptr
) read_pointer (ptr
);
567 case DW_OP_deref_size
:
569 void *ptr
= (void *) (_Unwind_Ptr
) result
;
573 result
= read_1u (ptr
);
576 result
= read_2u (ptr
);
579 result
= read_4u (ptr
);
582 result
= read_8u (ptr
);
591 if ((_Unwind_Sword
) result
< 0)
600 case DW_OP_plus_uconst
:
601 op_ptr
= read_uleb128 (op_ptr
, &utmp
);
624 /* Binary operations. */
625 _Unwind_Word first
, second
;
626 if ((stack_elt
-= 2) < 0)
628 second
= stack
[stack_elt
];
629 first
= stack
[stack_elt
+ 1];
634 result
= second
& first
;
637 result
= (_Unwind_Sword
) second
/ (_Unwind_Sword
) first
;
640 result
= second
- first
;
643 result
= (_Unwind_Sword
) second
% (_Unwind_Sword
) first
;
646 result
= second
* first
;
649 result
= second
| first
;
652 result
= second
+ first
;
655 result
= second
<< first
;
658 result
= second
>> first
;
661 result
= (_Unwind_Sword
) second
>> first
;
664 result
= second
^ first
;
667 result
= (_Unwind_Sword
) first
<= (_Unwind_Sword
) second
;
670 result
= (_Unwind_Sword
) first
>= (_Unwind_Sword
) second
;
673 result
= (_Unwind_Sword
) first
== (_Unwind_Sword
) second
;
676 result
= (_Unwind_Sword
) first
< (_Unwind_Sword
) second
;
679 result
= (_Unwind_Sword
) first
> (_Unwind_Sword
) second
;
682 result
= (_Unwind_Sword
) first
!= (_Unwind_Sword
) second
;
692 offset
= read_2s (op_ptr
);
700 offset
= read_2s (op_ptr
);
702 if (stack
[stack_elt
] != 0)
713 /* Most things push a result value. */
714 if ((size_t) stack_elt
>= sizeof(stack
)/sizeof(*stack
))
716 stack
[stack_elt
++] = result
;
720 /* We were executing this program to get a value. It should be
724 return stack
[stack_elt
];
728 /* Decode DWARF 2 call frame information. Takes pointers the
729 instruction sequence to decode, current register information and
730 CIE info, and the PC range to evaluate. */
733 execute_cfa_program (const unsigned char *insn_ptr
,
734 const unsigned char *insn_end
,
735 struct _Unwind_Context
*context
,
736 _Unwind_FrameState
*fs
)
738 struct frame_state_reg_info
*unused_rs
= NULL
;
740 /* Don't allow remember/restore between CIE and FDE programs. */
741 fs
->regs
.prev
= NULL
;
743 /* The comparison with the return address uses < rather than <= because
744 we are only interested in the effects of code before the call; for a
745 noreturn function, the return address may point to unrelated code with
746 a different stack configuration that we are not interested in. We
747 assume that the call itself is unwind info-neutral; if not, or if
748 there are delay instructions that adjust the stack, these must be
749 reflected at the point immediately before the call insn. */
750 while (insn_ptr
< insn_end
&& fs
->pc
< context
->ra
)
752 unsigned char insn
= *insn_ptr
++;
753 _Unwind_Word reg
, utmp
;
754 _Unwind_Sword offset
, stmp
;
756 if ((insn
& 0xc0) == DW_CFA_advance_loc
)
757 fs
->pc
+= (insn
& 0x3f) * fs
->code_align
;
758 else if ((insn
& 0xc0) == DW_CFA_offset
)
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
;
766 else if ((insn
& 0xc0) == DW_CFA_restore
)
769 fs
->regs
.reg
[reg
].how
= REG_UNSAVED
;
774 insn_ptr
= read_encoded_value (context
, fs
->fde_encoding
,
775 insn_ptr
, (_Unwind_Ptr
*) &fs
->pc
);
778 case DW_CFA_advance_loc1
:
779 fs
->pc
+= read_1u (insn_ptr
) * fs
->code_align
;
782 case DW_CFA_advance_loc2
:
783 fs
->pc
+= read_2u (insn_ptr
) * fs
->code_align
;
786 case DW_CFA_advance_loc4
:
787 fs
->pc
+= read_4u (insn_ptr
) * fs
->code_align
;
791 case DW_CFA_offset_extended
:
792 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
793 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
794 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
795 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
796 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
799 case DW_CFA_restore_extended
:
800 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
801 fs
->regs
.reg
[reg
].how
= REG_UNSAVED
;
804 case DW_CFA_undefined
:
805 case DW_CFA_same_value
:
806 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
812 case DW_CFA_register
:
815 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
816 insn_ptr
= read_uleb128 (insn_ptr
, ®2
);
817 fs
->regs
.reg
[reg
].how
= REG_SAVED_REG
;
818 fs
->regs
.reg
[reg
].loc
.reg
= reg2
;
822 case DW_CFA_remember_state
:
824 struct frame_state_reg_info
*new_rs
;
828 unused_rs
= unused_rs
->prev
;
831 new_rs
= __builtin_alloca (sizeof (struct frame_state_reg_info
));
834 fs
->regs
.prev
= new_rs
;
838 case DW_CFA_restore_state
:
840 struct frame_state_reg_info
*old_rs
= fs
->regs
.prev
;
843 __libc_fatal ("invalid DWARF unwind data");
848 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 fs
->cfa_exp
= insn_ptr
;
874 fs
->cfa_how
= CFA_EXP
;
875 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
879 case DW_CFA_expression
:
880 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
881 fs
->regs
.reg
[reg
].how
= REG_SAVED_EXP
;
882 fs
->regs
.reg
[reg
].loc
.exp
= insn_ptr
;
883 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
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
[reg
].how
= REG_SAVED_OFFSET
;
893 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
896 case DW_CFA_def_cfa_sf
:
897 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
898 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
899 fs
->cfa_how
= CFA_REG_OFFSET
;
902 case DW_CFA_def_cfa_offset_sf
:
903 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
904 /* cfa_how deliberately not set. */
907 case DW_CFA_GNU_window_save
:
908 /* ??? Hardcoded for SPARC register window configuration.
909 At least do not do anything for archs which explicitly
910 define a lower register number. */
911 #if DWARF_FRAME_REGISTERS >= 32
912 for (reg
= 16; reg
< 32; ++reg
)
914 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
915 fs
->regs
.reg
[reg
].loc
.offset
= (reg
- 16) * sizeof (void *);
920 case DW_CFA_GNU_args_size
:
921 insn_ptr
= read_uleb128 (insn_ptr
, &context
->args_size
);
924 case DW_CFA_GNU_negative_offset_extended
:
925 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
926 older PowerPC code. */
927 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
928 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
929 offset
= (_Unwind_Word
) utmp
* fs
->data_align
;
930 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
931 fs
->regs
.reg
[reg
].loc
.offset
= -offset
;
940 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
941 its caller and decode it into FS. This function also sets the
942 args_size and lsda members of CONTEXT, as they are really information
943 about the caller's frame. */
945 static _Unwind_Reason_Code
946 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
948 struct dwarf_fde
*fde
;
949 struct dwarf_cie
*cie
;
950 const unsigned char *aug
, *insn
, *end
;
952 memset (fs
, 0, sizeof (*fs
));
953 context
->args_size
= 0;
956 fde
= _Unwind_Find_FDE (context
->ra
- 1, &context
->bases
);
959 /* Couldn't find frame unwind info for this function. Try a
960 target-specific fallback mechanism. This will necessarily
961 not provide a personality routine or LSDA. */
962 #ifdef MD_FALLBACK_FRAME_STATE_FOR
963 MD_FALLBACK_FRAME_STATE_FOR (context
, fs
, success
);
964 return _URC_END_OF_STACK
;
966 return _URC_NO_REASON
;
968 return _URC_END_OF_STACK
;
972 fs
->pc
= context
->bases
.func
;
975 insn
= extract_cie_info (cie
, context
, fs
);
977 /* CIE contained unknown augmentation. */
978 return _URC_FATAL_PHASE1_ERROR
;
980 /* First decode all the insns in the CIE. */
981 end
= (unsigned char *) next_fde ((struct dwarf_fde
*) cie
);
982 execute_cfa_program (insn
, end
, context
, fs
);
984 /* Locate augmentation for the fde. */
985 aug
= (unsigned char *) fde
+ sizeof (*fde
);
986 aug
+= 2 * size_of_encoded_value (fs
->fde_encoding
);
991 aug
= read_uleb128 (aug
, &i
);
994 if (fs
->lsda_encoding
!= DW_EH_PE_omit
)
995 aug
= read_encoded_value (context
, fs
->lsda_encoding
, aug
,
996 (_Unwind_Ptr
*) &context
->lsda
);
998 /* Then the insns in the FDE up to our target PC. */
1001 end
= (unsigned char *) next_fde (fde
);
1002 execute_cfa_program (insn
, end
, context
, fs
);
1004 return _URC_NO_REASON
;
1007 typedef struct frame_state
1013 long reg_or_offset
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1014 unsigned short cfa_reg
;
1015 unsigned short retaddr_column
;
1016 char saved
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1024 struct frame_state
* __frame_state_for (void *, struct frame_state
*);
1026 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1027 a given PC_TARGET. The caller should allocate a local variable of
1028 `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
;
1078 uw_update_context_1 (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1080 struct _Unwind_Context orig_context
= *context
;
1084 #ifdef EH_RETURN_STACKADJ_RTX
1085 /* Special handling here: Many machines do not use a frame pointer,
1086 and track the CFA only through offsets from the stack pointer from
1087 one frame to the next. In this case, the stack pointer is never
1088 stored, so it has no saved address in the context. What we do
1089 have is the CFA from the previous stack frame.
1091 In very special situations (such as unwind info for signal return),
1092 there may be location expressions that use the stack pointer as well.
1094 Do this conditionally for one frame. This allows the unwind info
1095 for one frame to save a copy of the stack pointer from the previous
1096 frame, and be able to use much easier CFA mechanisms to do it.
1097 Always zap the saved stack pointer value for the next frame; carrying
1098 the value over from one frame to another doesn't make sense. */
1100 _Unwind_Word tmp_sp
;
1102 if (!orig_context
.reg
[__builtin_dwarf_sp_column ()])
1104 tmp_sp
= (_Unwind_Ptr
) context
->cfa
;
1105 orig_context
.reg
[__builtin_dwarf_sp_column ()] = &tmp_sp
;
1107 context
->reg
[__builtin_dwarf_sp_column ()] = NULL
;
1110 /* Compute this frame's CFA. */
1111 switch (fs
->cfa_how
)
1113 case CFA_REG_OFFSET
:
1114 cfa
= (void *) (_Unwind_Ptr
) _Unwind_GetGR (&orig_context
, fs
->cfa_reg
);
1115 cfa
+= fs
->cfa_offset
;
1120 const unsigned char *exp
= fs
->cfa_exp
;
1123 exp
= read_uleb128 (exp
, &len
);
1124 cfa
= (void *) (_Unwind_Ptr
)
1125 execute_stack_op (exp
, exp
+ len
, &orig_context
, 0);
1134 /* Compute the addresses of all registers saved in this frame. */
1135 for (i
= 0; i
< DWARF_FRAME_REGISTERS
+ 1; ++i
)
1136 switch (fs
->regs
.reg
[i
].how
)
1141 case REG_SAVED_OFFSET
:
1142 context
->reg
[i
] = cfa
+ fs
->regs
.reg
[i
].loc
.offset
;
1146 context
->reg
[i
] = orig_context
.reg
[fs
->regs
.reg
[i
].loc
.reg
];
1151 const unsigned char *exp
= fs
->regs
.reg
[i
].loc
.exp
;
1155 exp
= read_uleb128 (exp
, &len
);
1156 val
= execute_stack_op (exp
, exp
+ len
, &orig_context
,
1158 context
->reg
[i
] = (void *) val
;
1164 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1165 of its caller. Update CONTEXT to refer to the caller as well. Note
1166 that the args_size and lsda members are not updated here, but later in
1167 uw_frame_state_for. */
1170 uw_update_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1172 uw_update_context_1 (context
, fs
);
1174 /* Compute the return address now, since the return address column
1175 can change from frame to frame. */
1176 context
->ra
= __builtin_extract_return_addr
1177 ((void *) (_Unwind_Ptr
) _Unwind_GetGR (context
, fs
->retaddr_column
));
1180 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1181 level will be the return address and the CFA. */
1183 #define uw_init_context(CONTEXT) \
1186 /* Do any necessary initialization to access arbitrary stack frames. \
1187 On the SPARC, this means flushing the register windows. */ \
1188 __builtin_unwind_init (); \
1189 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1190 __builtin_return_address (0)); \
1195 uw_init_context_1 (struct _Unwind_Context
*context
,
1196 void *outer_cfa
, void *outer_ra
)
1198 void *ra
= __builtin_extract_return_addr (__builtin_return_address (0));
1199 _Unwind_FrameState fs
;
1200 _Unwind_Word sp_slot
;
1202 memset (context
, 0, sizeof (struct _Unwind_Context
));
1205 if (uw_frame_state_for (context
, &fs
) != _URC_NO_REASON
)
1208 /* Force the frame state to use the known cfa value. */
1209 sp_slot
= (_Unwind_Ptr
) outer_cfa
;
1210 context
->reg
[__builtin_dwarf_sp_column ()] = &sp_slot
;
1211 fs
.cfa_how
= CFA_REG_OFFSET
;
1212 fs
.cfa_reg
= __builtin_dwarf_sp_column ();
1215 uw_update_context_1 (context
, &fs
);
1217 /* If the return address column was saved in a register in the
1218 initialization context, then we can't see it in the given
1219 call frame data. So have the initialization context tell us. */
1220 context
->ra
= __builtin_extract_return_addr (outer_ra
);
1224 /* Install TARGET into CURRENT so that we can return to it. This is a
1225 macro because __builtin_eh_return must be invoked in the context of
1228 #define uw_install_context(CURRENT, TARGET) \
1231 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1232 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1233 __builtin_eh_return (offset, handler); \
1238 init_dwarf_reg_size_table (void)
1240 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table
);
1244 uw_install_context_1 (struct _Unwind_Context
*current
,
1245 struct _Unwind_Context
*target
)
1251 static __gthread_once_t once_regsizes
= __GTHREAD_ONCE_INIT
;
1252 if (__gthread_once (&once_regsizes
, init_dwarf_reg_size_table
) != 0
1253 || dwarf_reg_size_table
[0] == 0)
1254 init_dwarf_reg_size_table ();
1257 if (dwarf_reg_size_table
[0] == 0)
1258 init_dwarf_reg_size_table ();
1261 for (i
= 0; i
< DWARF_FRAME_REGISTERS
; ++i
)
1263 void *c
= current
->reg
[i
];
1264 void *t
= target
->reg
[i
];
1265 if (t
&& c
&& t
!= c
)
1266 memcpy (c
, t
, dwarf_reg_size_table
[i
]);
1269 #ifdef EH_RETURN_STACKADJ_RTX
1273 /* If the last frame records a saved stack pointer, use it. */
1274 if (target
->reg
[__builtin_dwarf_sp_column ()])
1275 target_cfa
= (void *)(_Unwind_Ptr
)
1276 _Unwind_GetGR (target
, __builtin_dwarf_sp_column ());
1278 target_cfa
= target
->cfa
;
1280 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1281 if (STACK_GROWS_DOWNWARD
)
1282 return target_cfa
- current
->cfa
+ target
->args_size
;
1284 return current
->cfa
- target_cfa
- target
->args_size
;
1291 static inline _Unwind_Ptr
1292 uw_identify_context (struct _Unwind_Context
*context
)
1294 return _Unwind_GetIP (context
);
1298 #include "unwind.inc"