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 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file into combinations with other programs,
15 and to distribute those combinations without any restriction coming
16 from the use of this file. (The General Public License restrictions
17 do apply in other respects; for example, they cover modification of
18 the file, and distribution when not linked into a combined
21 GCC is distributed in the hope that it will be useful, but WITHOUT
22 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
24 License for more details.
26 You should have received a copy of the GNU General Public License
27 along with GCC; see the file COPYING. If not, write to the Free
28 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
33 #include "coretypes.h"
37 #include "unwind-pe.h"
38 #include "unwind-dw2-fde.h"
42 #ifndef __USING_SJLJ_EXCEPTIONS__
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 #ifndef DWARF_REG_TO_UNWIND_COLUMN
63 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
66 /* A target can do some update context frobbing. */
67 #ifndef MD_FROB_UPDATE_CONTEXT
68 #define MD_FROB_UPDATE_CONTEXT(CTX, FS) do { } while (0)
71 /* This is the register and unwind state for a particular frame. This
72 provides the information necessary to unwind up past a frame and return
74 struct _Unwind_Context
76 void *reg
[DWARF_FRAME_REGISTERS
+1];
80 struct dwarf_eh_bases bases
;
81 _Unwind_Word args_size
;
84 /* Byte size of every register managed by these routines. */
85 static unsigned char dwarf_reg_size_table
[DWARF_FRAME_REGISTERS
+1];
88 /* The result of interpreting the frame unwind info for a frame.
89 This is all symbolic at this point, as none of the values can
90 be resolved until the target pc is located. */
93 /* Each register save state can be described in terms of a CFA slot,
94 another register, or a location expression. */
95 struct frame_state_reg_info
100 _Unwind_Sword offset
;
101 const unsigned char *exp
;
109 } reg
[DWARF_FRAME_REGISTERS
+1];
111 /* Used to implement DW_CFA_remember_state. */
112 struct frame_state_reg_info
*prev
;
115 /* The CFA can be described in terms of a reg+offset or a
116 location expression. */
117 _Unwind_Sword cfa_offset
;
118 _Unwind_Word cfa_reg
;
119 const unsigned char *cfa_exp
;
126 /* The PC described by the current frame state. */
129 /* The information we care about from the CIE/FDE. */
130 _Unwind_Personality_Fn personality
;
131 _Unwind_Sword data_align
;
132 _Unwind_Word code_align
;
133 unsigned char retaddr_column
;
134 unsigned char fde_encoding
;
135 unsigned char lsda_encoding
;
138 } _Unwind_FrameState
;
140 /* Read unaligned data from the instruction buffer. */
145 unsigned u2
__attribute__ ((mode (HI
)));
146 unsigned u4
__attribute__ ((mode (SI
)));
147 unsigned u8
__attribute__ ((mode (DI
)));
148 signed s2
__attribute__ ((mode (HI
)));
149 signed s4
__attribute__ ((mode (SI
)));
150 signed s8
__attribute__ ((mode (DI
)));
151 } __attribute__ ((packed
));
154 read_pointer (const void *p
) { const union unaligned
*up
= p
; return up
->p
; }
157 read_1u (const void *p
) { return *(const unsigned char *) p
; }
160 read_1s (const void *p
) { return *(const signed char *) p
; }
163 read_2u (const void *p
) { const union unaligned
*up
= p
; return up
->u2
; }
166 read_2s (const void *p
) { const union unaligned
*up
= p
; return up
->s2
; }
168 static inline unsigned int
169 read_4u (const void *p
) { const union unaligned
*up
= p
; return up
->u4
; }
172 read_4s (const void *p
) { const union unaligned
*up
= p
; return up
->s4
; }
174 static inline unsigned long
175 read_8u (const void *p
) { const union unaligned
*up
= p
; return up
->u8
; }
177 static inline unsigned long
178 read_8s (const void *p
) { const union unaligned
*up
= p
; return up
->s8
; }
180 /* Get the value of register REG as saved in CONTEXT. */
183 _Unwind_GetGR (struct _Unwind_Context
*context
, int index
)
188 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
189 if (index
>= sizeof(dwarf_reg_size_table
))
191 size
= dwarf_reg_size_table
[index
];
192 ptr
= context
->reg
[index
];
194 /* This will segfault if the register hasn't been saved. */
195 if (size
== sizeof(_Unwind_Ptr
))
196 return * (_Unwind_Ptr
*) ptr
;
198 if (size
== sizeof(_Unwind_Word
))
199 return * (_Unwind_Word
*) ptr
;
205 _Unwind_GetPtr (struct _Unwind_Context
*context
, int index
)
207 return (void *)(_Unwind_Ptr
) _Unwind_GetGR (context
, index
);
210 /* Get the value of the CFA as saved in CONTEXT. */
213 _Unwind_GetCFA (struct _Unwind_Context
*context
)
215 return (_Unwind_Ptr
) context
->cfa
;
218 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
221 _Unwind_SetGR (struct _Unwind_Context
*context
, int index
, _Unwind_Word val
)
226 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
227 if (index
>= sizeof(dwarf_reg_size_table
))
229 size
= dwarf_reg_size_table
[index
];
230 ptr
= context
->reg
[index
];
232 if (size
== sizeof(_Unwind_Ptr
))
233 * (_Unwind_Ptr
*) ptr
= val
;
234 else if (size
== sizeof(_Unwind_Word
))
235 * (_Unwind_Word
*) ptr
= val
;
240 /* Get the pointer to a register INDEX as saved in CONTEXT. */
243 _Unwind_GetGRPtr (struct _Unwind_Context
*context
, int index
)
245 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
246 return context
->reg
[index
];
249 /* Set the pointer to a register INDEX as saved in CONTEXT. */
252 _Unwind_SetGRPtr (struct _Unwind_Context
*context
, int index
, void *p
)
254 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
255 context
->reg
[index
] = p
;
258 /* Retrieve the return address for CONTEXT. */
261 _Unwind_GetIP (struct _Unwind_Context
*context
)
263 return (_Unwind_Ptr
) context
->ra
;
266 /* Overwrite the return address for CONTEXT with VAL. */
269 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
271 context
->ra
= (void *) val
;
275 _Unwind_GetLanguageSpecificData (struct _Unwind_Context
*context
)
277 return context
->lsda
;
281 _Unwind_GetRegionStart (struct _Unwind_Context
*context
)
283 return (_Unwind_Ptr
) context
->bases
.func
;
287 _Unwind_FindEnclosingFunction (void *pc
)
289 struct dwarf_eh_bases bases
;
290 struct dwarf_fde
*fde
= _Unwind_Find_FDE (pc
-1, &bases
);
299 _Unwind_GetDataRelBase (struct _Unwind_Context
*context
)
301 return (_Unwind_Ptr
) context
->bases
.dbase
;
305 _Unwind_GetTextRelBase (struct _Unwind_Context
*context
)
307 return (_Unwind_Ptr
) context
->bases
.tbase
;
311 /* Extract any interesting information from the CIE for the translation
312 unit F belongs to. Return a pointer to the byte after the augmentation,
313 or NULL if we encountered an undecipherable augmentation. */
315 static const unsigned char *
316 extract_cie_info (struct dwarf_cie
*cie
, struct _Unwind_Context
*context
,
317 _Unwind_FrameState
*fs
)
319 const unsigned char *aug
= cie
->augmentation
;
320 const unsigned char *p
= aug
+ strlen (aug
) + 1;
321 const unsigned char *ret
= NULL
;
324 /* g++ v2 "eh" has pointer immediately following augmentation string,
325 so it must be handled first. */
326 if (aug
[0] == 'e' && aug
[1] == 'h')
328 fs
->eh_ptr
= read_pointer (p
);
329 p
+= sizeof (void *);
333 /* Immediately following the augmentation are the code and
334 data alignment and return address column. */
335 p
= read_uleb128 (p
, &fs
->code_align
);
336 p
= read_sleb128 (p
, &fs
->data_align
);
337 fs
->retaddr_column
= *p
++;
338 fs
->lsda_encoding
= DW_EH_PE_omit
;
340 /* If the augmentation starts with 'z', then a uleb128 immediately
341 follows containing the length of the augmentation field following
345 p
= read_uleb128 (p
, &utmp
);
352 /* Iterate over recognized augmentation subsequences. */
355 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
358 fs
->lsda_encoding
= *p
++;
362 /* "R" indicates a byte indicating how FDE addresses are encoded. */
363 else if (aug
[0] == 'R')
365 fs
->fde_encoding
= *p
++;
369 /* "P" indicates a personality routine in the CIE augmentation. */
370 else if (aug
[0] == 'P')
372 p
= read_encoded_value (context
, *p
, p
+ 1,
373 (_Unwind_Ptr
*) &fs
->personality
);
377 /* Otherwise we have an unknown augmentation string.
378 Bail unless we saw a 'z' prefix. */
383 return ret
? ret
: p
;
387 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
388 onto the stack to start. */
391 execute_stack_op (const unsigned char *op_ptr
, const unsigned char *op_end
,
392 struct _Unwind_Context
*context
, _Unwind_Word initial
)
394 _Unwind_Word stack
[64]; /* ??? Assume this is enough. */
400 while (op_ptr
< op_end
)
402 enum dwarf_location_atom op
= *op_ptr
++;
403 _Unwind_Word result
, reg
, utmp
;
404 _Unwind_Sword offset
, stmp
;
440 result
= op
- DW_OP_lit0
;
444 result
= (_Unwind_Word
) (_Unwind_Ptr
) read_pointer (op_ptr
);
445 op_ptr
+= sizeof (void *);
449 result
= read_1u (op_ptr
);
453 result
= read_1s (op_ptr
);
457 result
= read_2u (op_ptr
);
461 result
= read_2s (op_ptr
);
465 result
= read_4u (op_ptr
);
469 result
= read_4s (op_ptr
);
473 result
= read_8u (op_ptr
);
477 result
= read_8s (op_ptr
);
481 op_ptr
= read_uleb128 (op_ptr
, &result
);
484 op_ptr
= read_sleb128 (op_ptr
, &stmp
);
520 result
= _Unwind_GetGR (context
, op
- DW_OP_reg0
);
523 op_ptr
= read_uleb128 (op_ptr
, ®
);
524 result
= _Unwind_GetGR (context
, reg
);
559 op_ptr
= read_sleb128 (op_ptr
, &offset
);
560 result
= _Unwind_GetGR (context
, op
- DW_OP_breg0
) + offset
;
563 op_ptr
= read_uleb128 (op_ptr
, ®
);
564 op_ptr
= read_sleb128 (op_ptr
, &offset
);
565 result
= _Unwind_GetGR (context
, reg
) + offset
;
571 result
= stack
[stack_elt
- 1];
581 if (offset
>= stack_elt
- 1)
583 result
= stack
[stack_elt
- 1 - offset
];
589 result
= stack
[stack_elt
- 2];
594 _Unwind_Word t1
, t2
, t3
;
598 t1
= stack
[stack_elt
- 1];
599 t2
= stack
[stack_elt
- 2];
600 t3
= stack
[stack_elt
- 3];
601 stack
[stack_elt
- 1] = t2
;
602 stack
[stack_elt
- 2] = t3
;
603 stack
[stack_elt
- 3] = t1
;
608 case DW_OP_deref_size
:
612 case DW_OP_plus_uconst
:
613 /* Unary operations. */
616 result
= stack
[stack_elt
];
622 void *ptr
= (void *) (_Unwind_Ptr
) result
;
623 result
= (_Unwind_Ptr
) read_pointer (ptr
);
627 case DW_OP_deref_size
:
629 void *ptr
= (void *) (_Unwind_Ptr
) result
;
633 result
= read_1u (ptr
);
636 result
= read_2u (ptr
);
639 result
= read_4u (ptr
);
642 result
= read_8u (ptr
);
651 if ((_Unwind_Sword
) result
< 0)
660 case DW_OP_plus_uconst
:
661 op_ptr
= read_uleb128 (op_ptr
, &utmp
);
684 /* Binary operations. */
685 _Unwind_Word first
, second
;
686 if ((stack_elt
-= 2) < 0)
688 second
= stack
[stack_elt
];
689 first
= stack
[stack_elt
+ 1];
694 result
= second
& first
;
697 result
= (_Unwind_Sword
) second
/ (_Unwind_Sword
) first
;
700 result
= second
- first
;
703 result
= (_Unwind_Sword
) second
% (_Unwind_Sword
) first
;
706 result
= second
* first
;
709 result
= second
| first
;
712 result
= second
+ first
;
715 result
= second
<< first
;
718 result
= second
>> first
;
721 result
= (_Unwind_Sword
) second
>> first
;
724 result
= second
^ first
;
727 result
= (_Unwind_Sword
) first
<= (_Unwind_Sword
) second
;
730 result
= (_Unwind_Sword
) first
>= (_Unwind_Sword
) second
;
733 result
= (_Unwind_Sword
) first
== (_Unwind_Sword
) second
;
736 result
= (_Unwind_Sword
) first
< (_Unwind_Sword
) second
;
739 result
= (_Unwind_Sword
) first
> (_Unwind_Sword
) second
;
742 result
= (_Unwind_Sword
) first
!= (_Unwind_Sword
) second
;
752 offset
= read_2s (op_ptr
);
760 offset
= read_2s (op_ptr
);
762 if (stack
[stack_elt
] != 0)
773 /* Most things push a result value. */
774 if ((size_t) stack_elt
>= sizeof(stack
)/sizeof(*stack
))
776 stack
[stack_elt
++] = result
;
780 /* We were executing this program to get a value. It should be
784 return stack
[stack_elt
];
788 /* Decode DWARF 2 call frame information. Takes pointers the
789 instruction sequence to decode, current register information and
790 CIE info, and the PC range to evaluate. */
793 execute_cfa_program (const unsigned char *insn_ptr
,
794 const unsigned char *insn_end
,
795 struct _Unwind_Context
*context
,
796 _Unwind_FrameState
*fs
)
798 struct frame_state_reg_info
*unused_rs
= NULL
;
800 /* Don't allow remember/restore between CIE and FDE programs. */
801 fs
->regs
.prev
= NULL
;
803 /* The comparison with the return address uses < rather than <= because
804 we are only interested in the effects of code before the call; for a
805 noreturn function, the return address may point to unrelated code with
806 a different stack configuration that we are not interested in. We
807 assume that the call itself is unwind info-neutral; if not, or if
808 there are delay instructions that adjust the stack, these must be
809 reflected at the point immediately before the call insn. */
810 while (insn_ptr
< insn_end
&& fs
->pc
< context
->ra
)
812 unsigned char insn
= *insn_ptr
++;
813 _Unwind_Word reg
, utmp
;
814 _Unwind_Sword offset
, stmp
;
816 if ((insn
& 0xc0) == DW_CFA_advance_loc
)
817 fs
->pc
+= (insn
& 0x3f) * fs
->code_align
;
818 else if ((insn
& 0xc0) == DW_CFA_offset
)
821 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
822 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
823 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
825 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
827 else if ((insn
& 0xc0) == DW_CFA_restore
)
830 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_UNSAVED
;
835 insn_ptr
= read_encoded_value (context
, fs
->fde_encoding
,
836 insn_ptr
, (_Unwind_Ptr
*) &fs
->pc
);
839 case DW_CFA_advance_loc1
:
840 fs
->pc
+= read_1u (insn_ptr
) * fs
->code_align
;
843 case DW_CFA_advance_loc2
:
844 fs
->pc
+= read_2u (insn_ptr
) * fs
->code_align
;
847 case DW_CFA_advance_loc4
:
848 fs
->pc
+= read_4u (insn_ptr
) * fs
->code_align
;
852 case DW_CFA_offset_extended
:
853 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
854 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
855 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
856 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
858 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
861 case DW_CFA_restore_extended
:
862 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
863 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN(reg
)].how
= REG_UNSAVED
;
866 case DW_CFA_undefined
:
867 case DW_CFA_same_value
:
868 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
874 case DW_CFA_register
:
877 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
878 insn_ptr
= read_uleb128 (insn_ptr
, ®2
);
879 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_SAVED_REG
;
880 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.reg
= reg2
;
884 case DW_CFA_remember_state
:
886 struct frame_state_reg_info
*new_rs
;
890 unused_rs
= unused_rs
->prev
;
893 new_rs
= __builtin_alloca (sizeof (struct frame_state_reg_info
));
896 fs
->regs
.prev
= new_rs
;
900 case DW_CFA_restore_state
:
902 struct frame_state_reg_info
*old_rs
= fs
->regs
.prev
;
904 old_rs
->prev
= unused_rs
;
910 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
911 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
912 fs
->cfa_offset
= utmp
;
913 fs
->cfa_how
= CFA_REG_OFFSET
;
916 case DW_CFA_def_cfa_register
:
917 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
918 fs
->cfa_how
= CFA_REG_OFFSET
;
921 case DW_CFA_def_cfa_offset
:
922 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
923 fs
->cfa_offset
= utmp
;
924 /* cfa_how deliberately not set. */
927 case DW_CFA_def_cfa_expression
:
928 fs
->cfa_exp
= insn_ptr
;
929 fs
->cfa_how
= CFA_EXP
;
930 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
934 case DW_CFA_expression
:
935 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
936 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_SAVED_EXP
;
937 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.exp
= insn_ptr
;
938 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
942 /* From the 2.1 draft. */
943 case DW_CFA_offset_extended_sf
:
944 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
945 insn_ptr
= read_sleb128 (insn_ptr
, &stmp
);
946 offset
= stmp
* fs
->data_align
;
947 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
949 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
952 case DW_CFA_def_cfa_sf
:
953 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
954 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
955 fs
->cfa_how
= CFA_REG_OFFSET
;
958 case DW_CFA_def_cfa_offset_sf
:
959 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
960 /* cfa_how deliberately not set. */
963 case DW_CFA_GNU_window_save
:
964 /* ??? Hardcoded for SPARC register window configuration. */
965 for (reg
= 16; reg
< 32; ++reg
)
967 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
968 fs
->regs
.reg
[reg
].loc
.offset
= (reg
- 16) * sizeof (void *);
972 case DW_CFA_GNU_args_size
:
973 insn_ptr
= read_uleb128 (insn_ptr
, &context
->args_size
);
976 case DW_CFA_GNU_negative_offset_extended
:
977 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
978 older PowerPC code. */
979 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
980 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
981 offset
= (_Unwind_Word
) utmp
* fs
->data_align
;
982 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
984 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= -offset
;
993 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
994 its caller and decode it into FS. This function also sets the
995 args_size and lsda members of CONTEXT, as they are really information
996 about the caller's frame. */
998 static _Unwind_Reason_Code
999 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1001 struct dwarf_fde
*fde
;
1002 struct dwarf_cie
*cie
;
1003 const unsigned char *aug
, *insn
, *end
;
1005 memset (fs
, 0, sizeof (*fs
));
1006 context
->args_size
= 0;
1009 if (context
->ra
== 0)
1010 return _URC_END_OF_STACK
;
1012 fde
= _Unwind_Find_FDE (context
->ra
- 1, &context
->bases
);
1015 /* Couldn't find frame unwind info for this function. Try a
1016 target-specific fallback mechanism. This will necessarily
1017 not provide a personality routine or LSDA. */
1018 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1019 MD_FALLBACK_FRAME_STATE_FOR (context
, fs
, success
);
1020 return _URC_END_OF_STACK
;
1022 return _URC_NO_REASON
;
1024 return _URC_END_OF_STACK
;
1028 fs
->pc
= context
->bases
.func
;
1030 cie
= get_cie (fde
);
1031 insn
= extract_cie_info (cie
, context
, fs
);
1033 /* CIE contained unknown augmentation. */
1034 return _URC_FATAL_PHASE1_ERROR
;
1036 /* First decode all the insns in the CIE. */
1037 end
= (unsigned char *) next_fde ((struct dwarf_fde
*) cie
);
1038 execute_cfa_program (insn
, end
, context
, fs
);
1040 /* Locate augmentation for the fde. */
1041 aug
= (unsigned char *) fde
+ sizeof (*fde
);
1042 aug
+= 2 * size_of_encoded_value (fs
->fde_encoding
);
1047 aug
= read_uleb128 (aug
, &i
);
1050 if (fs
->lsda_encoding
!= DW_EH_PE_omit
)
1051 aug
= read_encoded_value (context
, fs
->lsda_encoding
, aug
,
1052 (_Unwind_Ptr
*) &context
->lsda
);
1054 /* Then the insns in the FDE up to our target PC. */
1057 end
= (unsigned char *) next_fde (fde
);
1058 execute_cfa_program (insn
, end
, context
, fs
);
1060 return _URC_NO_REASON
;
1063 typedef struct frame_state
1069 long reg_or_offset
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1070 unsigned short cfa_reg
;
1071 unsigned short retaddr_column
;
1072 char saved
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1075 struct frame_state
* __frame_state_for (void *, struct frame_state
*);
1077 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1078 a given PC_TARGET. The caller should allocate a local variable of
1079 `struct frame_state' and pass its address to STATE_IN. */
1081 struct frame_state
*
1082 __frame_state_for (void *pc_target
, struct frame_state
*state_in
)
1084 struct _Unwind_Context context
;
1085 _Unwind_FrameState fs
;
1088 memset (&context
, 0, sizeof (struct _Unwind_Context
));
1089 context
.ra
= pc_target
+ 1;
1091 if (uw_frame_state_for (&context
, &fs
) != _URC_NO_REASON
)
1094 /* We have no way to pass a location expression for the CFA to our
1095 caller. It wouldn't understand it anyway. */
1096 if (fs
.cfa_how
== CFA_EXP
)
1099 for (reg
= 0; reg
< PRE_GCC3_DWARF_FRAME_REGISTERS
+ 1; reg
++)
1101 state_in
->saved
[reg
] = fs
.regs
.reg
[reg
].how
;
1102 switch (state_in
->saved
[reg
])
1105 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.reg
;
1107 case REG_SAVED_OFFSET
:
1108 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.offset
;
1111 state_in
->reg_or_offset
[reg
] = 0;
1116 state_in
->cfa_offset
= fs
.cfa_offset
;
1117 state_in
->cfa_reg
= fs
.cfa_reg
;
1118 state_in
->retaddr_column
= fs
.retaddr_column
;
1119 state_in
->args_size
= context
.args_size
;
1120 state_in
->eh_ptr
= fs
.eh_ptr
;
1125 typedef union { _Unwind_Ptr ptr
; _Unwind_Word word
; } _Unwind_SpTmp
;
1128 _Unwind_SetSpColumn (struct _Unwind_Context
*context
, void *cfa
,
1129 _Unwind_SpTmp
*tmp_sp
)
1131 int size
= dwarf_reg_size_table
[__builtin_dwarf_sp_column ()];
1133 if (size
== sizeof(_Unwind_Ptr
))
1134 tmp_sp
->ptr
= (_Unwind_Ptr
) cfa
;
1135 else if (size
== sizeof(_Unwind_Word
))
1136 tmp_sp
->word
= (_Unwind_Ptr
) cfa
;
1139 _Unwind_SetGRPtr (context
, __builtin_dwarf_sp_column (), tmp_sp
);
1143 uw_update_context_1 (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1145 struct _Unwind_Context orig_context
= *context
;
1149 #ifdef EH_RETURN_STACKADJ_RTX
1150 /* Special handling here: Many machines do not use a frame pointer,
1151 and track the CFA only through offsets from the stack pointer from
1152 one frame to the next. In this case, the stack pointer is never
1153 stored, so it has no saved address in the context. What we do
1154 have is the CFA from the previous stack frame.
1156 In very special situations (such as unwind info for signal return),
1157 there may be location expressions that use the stack pointer as well.
1159 Do this conditionally for one frame. This allows the unwind info
1160 for one frame to save a copy of the stack pointer from the previous
1161 frame, and be able to use much easier CFA mechanisms to do it.
1162 Always zap the saved stack pointer value for the next frame; carrying
1163 the value over from one frame to another doesn't make sense. */
1165 _Unwind_SpTmp tmp_sp
;
1167 if (!_Unwind_GetGRPtr (&orig_context
, __builtin_dwarf_sp_column ()))
1168 _Unwind_SetSpColumn (&orig_context
, context
->cfa
, &tmp_sp
);
1169 _Unwind_SetGRPtr (context
, __builtin_dwarf_sp_column (), NULL
);
1172 /* Compute this frame's CFA. */
1173 switch (fs
->cfa_how
)
1175 case CFA_REG_OFFSET
:
1176 cfa
= _Unwind_GetPtr (&orig_context
, fs
->cfa_reg
);
1177 cfa
+= fs
->cfa_offset
;
1182 const unsigned char *exp
= fs
->cfa_exp
;
1185 exp
= read_uleb128 (exp
, &len
);
1186 cfa
= (void *) (_Unwind_Ptr
)
1187 execute_stack_op (exp
, exp
+ len
, &orig_context
, 0);
1196 /* Compute the addresses of all registers saved in this frame. */
1197 for (i
= 0; i
< DWARF_FRAME_REGISTERS
+ 1; ++i
)
1198 switch (fs
->regs
.reg
[i
].how
)
1203 case REG_SAVED_OFFSET
:
1204 _Unwind_SetGRPtr (context
, i
,
1205 (void *) (cfa
+ fs
->regs
.reg
[i
].loc
.offset
));
1211 _Unwind_GetGRPtr (&orig_context
, fs
->regs
.reg
[i
].loc
.reg
));
1216 const unsigned char *exp
= fs
->regs
.reg
[i
].loc
.exp
;
1220 exp
= read_uleb128 (exp
, &len
);
1221 val
= execute_stack_op (exp
, exp
+ len
, &orig_context
,
1223 _Unwind_SetGRPtr (context
, i
, (void *) val
);
1228 MD_FROB_UPDATE_CONTEXT (context
, fs
);
1231 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1232 of its caller. Update CONTEXT to refer to the caller as well. Note
1233 that the args_size and lsda members are not updated here, but later in
1234 uw_frame_state_for. */
1237 uw_update_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1239 uw_update_context_1 (context
, fs
);
1241 /* Compute the return address now, since the return address column
1242 can change from frame to frame. */
1243 context
->ra
= __builtin_extract_return_addr
1244 (_Unwind_GetPtr (context
, fs
->retaddr_column
));
1247 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1248 level will be the return address and the CFA. */
1250 #define uw_init_context(CONTEXT) \
1253 /* Do any necessary initialization to access arbitrary stack frames. \
1254 On the SPARC, this means flushing the register windows. */ \
1255 __builtin_unwind_init (); \
1256 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1257 __builtin_return_address (0)); \
1262 init_dwarf_reg_size_table (void)
1264 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table
);
1268 uw_init_context_1 (struct _Unwind_Context
*context
,
1269 void *outer_cfa
, void *outer_ra
)
1271 void *ra
= __builtin_extract_return_addr (__builtin_return_address (0));
1272 _Unwind_FrameState fs
;
1273 _Unwind_SpTmp sp_slot
;
1275 memset (context
, 0, sizeof (struct _Unwind_Context
));
1278 if (uw_frame_state_for (context
, &fs
) != _URC_NO_REASON
)
1283 static __gthread_once_t once_regsizes
= __GTHREAD_ONCE_INIT
;
1284 if (__gthread_once (&once_regsizes
, init_dwarf_reg_size_table
) != 0
1285 || dwarf_reg_size_table
[0] == 0)
1286 init_dwarf_reg_size_table ();
1289 if (dwarf_reg_size_table
[0] == 0)
1290 init_dwarf_reg_size_table ();
1293 /* Force the frame state to use the known cfa value. */
1294 _Unwind_SetSpColumn (context
, outer_cfa
, &sp_slot
);
1295 fs
.cfa_how
= CFA_REG_OFFSET
;
1296 fs
.cfa_reg
= __builtin_dwarf_sp_column ();
1299 uw_update_context_1 (context
, &fs
);
1301 /* If the return address column was saved in a register in the
1302 initialization context, then we can't see it in the given
1303 call frame data. So have the initialization context tell us. */
1304 context
->ra
= __builtin_extract_return_addr (outer_ra
);
1308 /* Install TARGET into CURRENT so that we can return to it. This is a
1309 macro because __builtin_eh_return must be invoked in the context of
1312 #define uw_install_context(CURRENT, TARGET) \
1315 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1316 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1317 __builtin_eh_return (offset, handler); \
1322 uw_install_context_1 (struct _Unwind_Context
*current
,
1323 struct _Unwind_Context
*target
)
1327 for (i
= 0; i
< DWARF_FRAME_REGISTERS
; ++i
)
1329 void *c
= current
->reg
[i
];
1330 void *t
= target
->reg
[i
];
1332 if (t
&& c
&& t
!= c
)
1333 memcpy (c
, t
, dwarf_reg_size_table
[i
]);
1336 #ifdef EH_RETURN_STACKADJ_RTX
1340 /* If the last frame records a saved stack pointer, use it. */
1341 if (_Unwind_GetGRPtr (target
, __builtin_dwarf_sp_column ()))
1342 target_cfa
= _Unwind_GetPtr (target
, __builtin_dwarf_sp_column ());
1344 target_cfa
= target
->cfa
;
1346 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1347 if (STACK_GROWS_DOWNWARD
)
1348 return target_cfa
- current
->cfa
+ target
->args_size
;
1350 return current
->cfa
- target_cfa
- target
->args_size
;
1357 static inline _Unwind_Ptr
1358 uw_identify_context (struct _Unwind_Context
*context
)
1360 return _Unwind_GetIP (context
);
1364 #include "unwind.inc"
1366 #endif /* !USING_SJLJ_EXCEPTIONS */