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 #ifdef __USING_SJLJ_EXCEPTIONS__
38 # define NO_SIZE_OF_ENCODED_VALUE
40 #include "unwind-pe.h"
41 #include "unwind-dw2-fde.h"
45 #ifndef __USING_SJLJ_EXCEPTIONS__
47 #ifndef STACK_GROWS_DOWNWARD
48 #define STACK_GROWS_DOWNWARD 0
50 #undef STACK_GROWS_DOWNWARD
51 #define STACK_GROWS_DOWNWARD 1
54 /* A target can override (perhaps for backward compatibility) how
55 many dwarf2 columns are unwound. */
56 #ifndef DWARF_FRAME_REGISTERS
57 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
60 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
61 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
62 #define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
65 #ifndef DWARF_REG_TO_UNWIND_COLUMN
66 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
69 /* A target can do some update context frobbing. */
70 #ifndef MD_FROB_UPDATE_CONTEXT
71 #define MD_FROB_UPDATE_CONTEXT(CTX, FS) do { } while (0)
74 /* This is the register and unwind state for a particular frame. This
75 provides the information necessary to unwind up past a frame and return
77 struct _Unwind_Context
79 void *reg
[DWARF_FRAME_REGISTERS
+1];
83 struct dwarf_eh_bases bases
;
84 _Unwind_Word args_size
;
87 /* Byte size of every register managed by these routines. */
88 static unsigned char dwarf_reg_size_table
[DWARF_FRAME_REGISTERS
+1];
91 /* The result of interpreting the frame unwind info for a frame.
92 This is all symbolic at this point, as none of the values can
93 be resolved until the target pc is located. */
96 /* Each register save state can be described in terms of a CFA slot,
97 another register, or a location expression. */
98 struct frame_state_reg_info
103 _Unwind_Sword offset
;
104 const unsigned char *exp
;
112 } reg
[DWARF_FRAME_REGISTERS
+1];
114 /* Used to implement DW_CFA_remember_state. */
115 struct frame_state_reg_info
*prev
;
118 /* The CFA can be described in terms of a reg+offset or a
119 location expression. */
120 _Unwind_Sword cfa_offset
;
121 _Unwind_Word cfa_reg
;
122 const unsigned char *cfa_exp
;
129 /* The PC described by the current frame state. */
132 /* The information we care about from the CIE/FDE. */
133 _Unwind_Personality_Fn personality
;
134 _Unwind_Sword data_align
;
135 _Unwind_Word code_align
;
136 unsigned char retaddr_column
;
137 unsigned char fde_encoding
;
138 unsigned char lsda_encoding
;
141 } _Unwind_FrameState
;
143 /* Read unaligned data from the instruction buffer. */
148 unsigned u2
__attribute__ ((mode (HI
)));
149 unsigned u4
__attribute__ ((mode (SI
)));
150 unsigned u8
__attribute__ ((mode (DI
)));
151 signed s2
__attribute__ ((mode (HI
)));
152 signed s4
__attribute__ ((mode (SI
)));
153 signed s8
__attribute__ ((mode (DI
)));
154 } __attribute__ ((packed
));
157 read_pointer (const void *p
) { const union unaligned
*up
= p
; return up
->p
; }
160 read_1u (const void *p
) { return *(const unsigned char *) p
; }
163 read_1s (const void *p
) { return *(const signed char *) p
; }
166 read_2u (const void *p
) { const union unaligned
*up
= p
; return up
->u2
; }
169 read_2s (const void *p
) { const union unaligned
*up
= p
; return up
->s2
; }
171 static inline unsigned int
172 read_4u (const void *p
) { const union unaligned
*up
= p
; return up
->u4
; }
175 read_4s (const void *p
) { const union unaligned
*up
= p
; return up
->s4
; }
177 static inline unsigned long
178 read_8u (const void *p
) { const union unaligned
*up
= p
; return up
->u8
; }
180 static inline unsigned long
181 read_8s (const void *p
) { const union unaligned
*up
= p
; return up
->s8
; }
183 /* Get the value of register REG as saved in CONTEXT. */
186 _Unwind_GetGR (struct _Unwind_Context
*context
, int index
)
191 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
192 if (index
>= (int) sizeof(dwarf_reg_size_table
))
194 size
= dwarf_reg_size_table
[index
];
195 ptr
= context
->reg
[index
];
197 /* This will segfault if the register hasn't been saved. */
198 if (size
== sizeof(_Unwind_Ptr
))
199 return * (_Unwind_Ptr
*) ptr
;
201 if (size
== sizeof(_Unwind_Word
))
202 return * (_Unwind_Word
*) ptr
;
208 _Unwind_GetPtr (struct _Unwind_Context
*context
, int index
)
210 return (void *)(_Unwind_Ptr
) _Unwind_GetGR (context
, index
);
213 /* Get the value of the CFA as saved in CONTEXT. */
216 _Unwind_GetCFA (struct _Unwind_Context
*context
)
218 return (_Unwind_Ptr
) context
->cfa
;
221 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
224 _Unwind_SetGR (struct _Unwind_Context
*context
, int index
, _Unwind_Word val
)
229 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
230 if (index
>= (int) sizeof(dwarf_reg_size_table
))
232 size
= dwarf_reg_size_table
[index
];
233 ptr
= context
->reg
[index
];
235 if (size
== sizeof(_Unwind_Ptr
))
236 * (_Unwind_Ptr
*) ptr
= val
;
237 else if (size
== sizeof(_Unwind_Word
))
238 * (_Unwind_Word
*) ptr
= val
;
243 /* Get the pointer to a register INDEX as saved in CONTEXT. */
246 _Unwind_GetGRPtr (struct _Unwind_Context
*context
, int index
)
248 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
249 return context
->reg
[index
];
252 /* Set the pointer to a register INDEX as saved in CONTEXT. */
255 _Unwind_SetGRPtr (struct _Unwind_Context
*context
, int index
, void *p
)
257 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
258 context
->reg
[index
] = p
;
261 /* Retrieve the return address for CONTEXT. */
264 _Unwind_GetIP (struct _Unwind_Context
*context
)
266 return (_Unwind_Ptr
) context
->ra
;
269 /* Overwrite the return address for CONTEXT with VAL. */
272 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
274 context
->ra
= (void *) val
;
278 _Unwind_GetLanguageSpecificData (struct _Unwind_Context
*context
)
280 return context
->lsda
;
284 _Unwind_GetRegionStart (struct _Unwind_Context
*context
)
286 return (_Unwind_Ptr
) context
->bases
.func
;
290 _Unwind_FindEnclosingFunction (void *pc
)
292 struct dwarf_eh_bases bases
;
293 const struct dwarf_fde
*fde
= _Unwind_Find_FDE (pc
-1, &bases
);
302 _Unwind_GetDataRelBase (struct _Unwind_Context
*context
)
304 return (_Unwind_Ptr
) context
->bases
.dbase
;
308 _Unwind_GetTextRelBase (struct _Unwind_Context
*context
)
310 return (_Unwind_Ptr
) context
->bases
.tbase
;
314 /* Extract any interesting information from the CIE for the translation
315 unit F belongs to. Return a pointer to the byte after the augmentation,
316 or NULL if we encountered an undecipherable augmentation. */
318 static const unsigned char *
319 extract_cie_info (const struct dwarf_cie
*cie
, struct _Unwind_Context
*context
,
320 _Unwind_FrameState
*fs
)
322 const unsigned char *aug
= cie
->augmentation
;
323 const unsigned char *p
= aug
+ strlen (aug
) + 1;
324 const unsigned char *ret
= NULL
;
327 /* g++ v2 "eh" has pointer immediately following augmentation string,
328 so it must be handled first. */
329 if (aug
[0] == 'e' && aug
[1] == 'h')
331 fs
->eh_ptr
= read_pointer (p
);
332 p
+= sizeof (void *);
336 /* Immediately following the augmentation are the code and
337 data alignment and return address column. */
338 p
= read_uleb128 (p
, &fs
->code_align
);
339 p
= read_sleb128 (p
, &fs
->data_align
);
340 fs
->retaddr_column
= *p
++;
341 fs
->lsda_encoding
= DW_EH_PE_omit
;
343 /* If the augmentation starts with 'z', then a uleb128 immediately
344 follows containing the length of the augmentation field following
348 p
= read_uleb128 (p
, &utmp
);
355 /* Iterate over recognized augmentation subsequences. */
358 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
361 fs
->lsda_encoding
= *p
++;
365 /* "R" indicates a byte indicating how FDE addresses are encoded. */
366 else if (aug
[0] == 'R')
368 fs
->fde_encoding
= *p
++;
372 /* "P" indicates a personality routine in the CIE augmentation. */
373 else if (aug
[0] == 'P')
375 p
= read_encoded_value (context
, *p
, p
+ 1,
376 (_Unwind_Ptr
*) &fs
->personality
);
380 /* Otherwise we have an unknown augmentation string.
381 Bail unless we saw a 'z' prefix. */
386 return ret
? ret
: p
;
390 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
391 onto the stack to start. */
394 execute_stack_op (const unsigned char *op_ptr
, const unsigned char *op_end
,
395 struct _Unwind_Context
*context
, _Unwind_Word initial
)
397 _Unwind_Word stack
[64]; /* ??? Assume this is enough. */
403 while (op_ptr
< op_end
)
405 enum dwarf_location_atom op
= *op_ptr
++;
406 _Unwind_Word result
, reg
, utmp
;
407 _Unwind_Sword offset
, stmp
;
443 result
= op
- DW_OP_lit0
;
447 result
= (_Unwind_Word
) (_Unwind_Ptr
) read_pointer (op_ptr
);
448 op_ptr
+= sizeof (void *);
452 result
= read_1u (op_ptr
);
456 result
= read_1s (op_ptr
);
460 result
= read_2u (op_ptr
);
464 result
= read_2s (op_ptr
);
468 result
= read_4u (op_ptr
);
472 result
= read_4s (op_ptr
);
476 result
= read_8u (op_ptr
);
480 result
= read_8s (op_ptr
);
484 op_ptr
= read_uleb128 (op_ptr
, &result
);
487 op_ptr
= read_sleb128 (op_ptr
, &stmp
);
523 result
= _Unwind_GetGR (context
, op
- DW_OP_reg0
);
526 op_ptr
= read_uleb128 (op_ptr
, ®
);
527 result
= _Unwind_GetGR (context
, reg
);
562 op_ptr
= read_sleb128 (op_ptr
, &offset
);
563 result
= _Unwind_GetGR (context
, op
- DW_OP_breg0
) + offset
;
566 op_ptr
= read_uleb128 (op_ptr
, ®
);
567 op_ptr
= read_sleb128 (op_ptr
, &offset
);
568 result
= _Unwind_GetGR (context
, reg
) + offset
;
574 result
= stack
[stack_elt
- 1];
584 if (offset
>= stack_elt
- 1)
586 result
= stack
[stack_elt
- 1 - offset
];
592 result
= stack
[stack_elt
- 2];
597 _Unwind_Word t1
, t2
, t3
;
601 t1
= stack
[stack_elt
- 1];
602 t2
= stack
[stack_elt
- 2];
603 t3
= stack
[stack_elt
- 3];
604 stack
[stack_elt
- 1] = t2
;
605 stack
[stack_elt
- 2] = t3
;
606 stack
[stack_elt
- 3] = t1
;
611 case DW_OP_deref_size
:
615 case DW_OP_plus_uconst
:
616 /* Unary operations. */
619 result
= stack
[stack_elt
];
625 void *ptr
= (void *) (_Unwind_Ptr
) result
;
626 result
= (_Unwind_Ptr
) read_pointer (ptr
);
630 case DW_OP_deref_size
:
632 void *ptr
= (void *) (_Unwind_Ptr
) result
;
636 result
= read_1u (ptr
);
639 result
= read_2u (ptr
);
642 result
= read_4u (ptr
);
645 result
= read_8u (ptr
);
654 if ((_Unwind_Sword
) result
< 0)
663 case DW_OP_plus_uconst
:
664 op_ptr
= read_uleb128 (op_ptr
, &utmp
);
687 /* Binary operations. */
688 _Unwind_Word first
, second
;
689 if ((stack_elt
-= 2) < 0)
691 second
= stack
[stack_elt
];
692 first
= stack
[stack_elt
+ 1];
697 result
= second
& first
;
700 result
= (_Unwind_Sword
) second
/ (_Unwind_Sword
) first
;
703 result
= second
- first
;
706 result
= (_Unwind_Sword
) second
% (_Unwind_Sword
) first
;
709 result
= second
* first
;
712 result
= second
| first
;
715 result
= second
+ first
;
718 result
= second
<< first
;
721 result
= second
>> first
;
724 result
= (_Unwind_Sword
) second
>> first
;
727 result
= second
^ first
;
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
;
745 result
= (_Unwind_Sword
) first
!= (_Unwind_Sword
) second
;
755 offset
= read_2s (op_ptr
);
763 offset
= read_2s (op_ptr
);
765 if (stack
[stack_elt
] != 0)
776 /* Most things push a result value. */
777 if ((size_t) stack_elt
>= sizeof(stack
)/sizeof(*stack
))
779 stack
[stack_elt
++] = result
;
783 /* We were executing this program to get a value. It should be
787 return stack
[stack_elt
];
791 /* Decode DWARF 2 call frame information. Takes pointers the
792 instruction sequence to decode, current register information and
793 CIE info, and the PC range to evaluate. */
796 execute_cfa_program (const unsigned char *insn_ptr
,
797 const unsigned char *insn_end
,
798 struct _Unwind_Context
*context
,
799 _Unwind_FrameState
*fs
)
801 struct frame_state_reg_info
*unused_rs
= NULL
;
803 /* Don't allow remember/restore between CIE and FDE programs. */
804 fs
->regs
.prev
= NULL
;
806 /* The comparison with the return address uses < rather than <= because
807 we are only interested in the effects of code before the call; for a
808 noreturn function, the return address may point to unrelated code with
809 a different stack configuration that we are not interested in. We
810 assume that the call itself is unwind info-neutral; if not, or if
811 there are delay instructions that adjust the stack, these must be
812 reflected at the point immediately before the call insn. */
813 while (insn_ptr
< insn_end
&& fs
->pc
< context
->ra
)
815 unsigned char insn
= *insn_ptr
++;
816 _Unwind_Word reg
, utmp
;
817 _Unwind_Sword offset
, stmp
;
819 if ((insn
& 0xc0) == DW_CFA_advance_loc
)
820 fs
->pc
+= (insn
& 0x3f) * fs
->code_align
;
821 else if ((insn
& 0xc0) == DW_CFA_offset
)
824 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
825 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
826 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
828 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
830 else if ((insn
& 0xc0) == DW_CFA_restore
)
833 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_UNSAVED
;
838 insn_ptr
= read_encoded_value (context
, fs
->fde_encoding
,
839 insn_ptr
, (_Unwind_Ptr
*) &fs
->pc
);
842 case DW_CFA_advance_loc1
:
843 fs
->pc
+= read_1u (insn_ptr
) * fs
->code_align
;
846 case DW_CFA_advance_loc2
:
847 fs
->pc
+= read_2u (insn_ptr
) * fs
->code_align
;
850 case DW_CFA_advance_loc4
:
851 fs
->pc
+= read_4u (insn_ptr
) * fs
->code_align
;
855 case DW_CFA_offset_extended
:
856 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
857 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
858 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
859 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
861 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
864 case DW_CFA_restore_extended
:
865 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
866 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN(reg
)].how
= REG_UNSAVED
;
869 case DW_CFA_undefined
:
870 case DW_CFA_same_value
:
871 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
877 case DW_CFA_register
:
880 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
881 insn_ptr
= read_uleb128 (insn_ptr
, ®2
);
882 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_SAVED_REG
;
883 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.reg
= reg2
;
887 case DW_CFA_remember_state
:
889 struct frame_state_reg_info
*new_rs
;
893 unused_rs
= unused_rs
->prev
;
896 new_rs
= __builtin_alloca (sizeof (struct frame_state_reg_info
));
899 fs
->regs
.prev
= new_rs
;
903 case DW_CFA_restore_state
:
905 struct frame_state_reg_info
*old_rs
= fs
->regs
.prev
;
907 old_rs
->prev
= unused_rs
;
913 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
914 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
915 fs
->cfa_offset
= utmp
;
916 fs
->cfa_how
= CFA_REG_OFFSET
;
919 case DW_CFA_def_cfa_register
:
920 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
921 fs
->cfa_how
= CFA_REG_OFFSET
;
924 case DW_CFA_def_cfa_offset
:
925 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
926 fs
->cfa_offset
= utmp
;
927 /* cfa_how deliberately not set. */
930 case DW_CFA_def_cfa_expression
:
931 fs
->cfa_exp
= insn_ptr
;
932 fs
->cfa_how
= CFA_EXP
;
933 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
937 case DW_CFA_expression
:
938 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
939 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_SAVED_EXP
;
940 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.exp
= insn_ptr
;
941 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
945 /* From the 2.1 draft. */
946 case DW_CFA_offset_extended_sf
:
947 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
948 insn_ptr
= read_sleb128 (insn_ptr
, &stmp
);
949 offset
= stmp
* fs
->data_align
;
950 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
952 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
955 case DW_CFA_def_cfa_sf
:
956 insn_ptr
= read_uleb128 (insn_ptr
, &fs
->cfa_reg
);
957 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
958 fs
->cfa_how
= CFA_REG_OFFSET
;
961 case DW_CFA_def_cfa_offset_sf
:
962 insn_ptr
= read_sleb128 (insn_ptr
, &fs
->cfa_offset
);
963 /* cfa_how deliberately not set. */
966 case DW_CFA_GNU_window_save
:
967 /* ??? Hardcoded for SPARC register window configuration. */
968 for (reg
= 16; reg
< 32; ++reg
)
970 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
971 fs
->regs
.reg
[reg
].loc
.offset
= (reg
- 16) * sizeof (void *);
975 case DW_CFA_GNU_args_size
:
976 insn_ptr
= read_uleb128 (insn_ptr
, &context
->args_size
);
979 case DW_CFA_GNU_negative_offset_extended
:
980 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
981 older PowerPC code. */
982 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
983 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
984 offset
= (_Unwind_Word
) utmp
* fs
->data_align
;
985 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
987 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= -offset
;
996 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
997 its caller and decode it into FS. This function also sets the
998 args_size and lsda members of CONTEXT, as they are really information
999 about the caller's frame. */
1001 static _Unwind_Reason_Code
1002 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1004 const struct dwarf_fde
*fde
;
1005 const struct dwarf_cie
*cie
;
1006 const unsigned char *aug
, *insn
, *end
;
1008 memset (fs
, 0, sizeof (*fs
));
1009 context
->args_size
= 0;
1012 if (context
->ra
== 0)
1013 return _URC_END_OF_STACK
;
1015 fde
= _Unwind_Find_FDE (context
->ra
- 1, &context
->bases
);
1018 /* Couldn't find frame unwind info for this function. Try a
1019 target-specific fallback mechanism. This will necessarily
1020 not provide a personality routine or LSDA. */
1021 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1022 MD_FALLBACK_FRAME_STATE_FOR (context
, fs
, success
);
1023 return _URC_END_OF_STACK
;
1025 return _URC_NO_REASON
;
1027 return _URC_END_OF_STACK
;
1031 fs
->pc
= context
->bases
.func
;
1033 cie
= get_cie (fde
);
1034 insn
= extract_cie_info (cie
, context
, fs
);
1036 /* CIE contained unknown augmentation. */
1037 return _URC_FATAL_PHASE1_ERROR
;
1039 /* First decode all the insns in the CIE. */
1040 end
= (unsigned char *) next_fde ((struct dwarf_fde
*) cie
);
1041 execute_cfa_program (insn
, end
, context
, fs
);
1043 /* Locate augmentation for the fde. */
1044 aug
= (unsigned char *) fde
+ sizeof (*fde
);
1045 aug
+= 2 * size_of_encoded_value (fs
->fde_encoding
);
1050 aug
= read_uleb128 (aug
, &i
);
1053 if (fs
->lsda_encoding
!= DW_EH_PE_omit
)
1054 aug
= read_encoded_value (context
, fs
->lsda_encoding
, aug
,
1055 (_Unwind_Ptr
*) &context
->lsda
);
1057 /* Then the insns in the FDE up to our target PC. */
1060 end
= (unsigned char *) next_fde (fde
);
1061 execute_cfa_program (insn
, end
, context
, fs
);
1063 return _URC_NO_REASON
;
1066 typedef struct frame_state
1072 long reg_or_offset
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1073 unsigned short cfa_reg
;
1074 unsigned short retaddr_column
;
1075 char saved
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1078 struct frame_state
* __frame_state_for (void *, struct frame_state
*);
1080 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1081 a given PC_TARGET. The caller should allocate a local variable of
1082 `struct frame_state' and pass its address to STATE_IN. */
1084 struct frame_state
*
1085 __frame_state_for (void *pc_target
, struct frame_state
*state_in
)
1087 struct _Unwind_Context context
;
1088 _Unwind_FrameState fs
;
1091 memset (&context
, 0, sizeof (struct _Unwind_Context
));
1092 context
.ra
= pc_target
+ 1;
1094 if (uw_frame_state_for (&context
, &fs
) != _URC_NO_REASON
)
1097 /* We have no way to pass a location expression for the CFA to our
1098 caller. It wouldn't understand it anyway. */
1099 if (fs
.cfa_how
== CFA_EXP
)
1102 for (reg
= 0; reg
< PRE_GCC3_DWARF_FRAME_REGISTERS
+ 1; reg
++)
1104 state_in
->saved
[reg
] = fs
.regs
.reg
[reg
].how
;
1105 switch (state_in
->saved
[reg
])
1108 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.reg
;
1110 case REG_SAVED_OFFSET
:
1111 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.offset
;
1114 state_in
->reg_or_offset
[reg
] = 0;
1119 state_in
->cfa_offset
= fs
.cfa_offset
;
1120 state_in
->cfa_reg
= fs
.cfa_reg
;
1121 state_in
->retaddr_column
= fs
.retaddr_column
;
1122 state_in
->args_size
= context
.args_size
;
1123 state_in
->eh_ptr
= fs
.eh_ptr
;
1128 typedef union { _Unwind_Ptr ptr
; _Unwind_Word word
; } _Unwind_SpTmp
;
1131 _Unwind_SetSpColumn (struct _Unwind_Context
*context
, void *cfa
,
1132 _Unwind_SpTmp
*tmp_sp
)
1134 int size
= dwarf_reg_size_table
[__builtin_dwarf_sp_column ()];
1136 if (size
== sizeof(_Unwind_Ptr
))
1137 tmp_sp
->ptr
= (_Unwind_Ptr
) cfa
;
1138 else if (size
== sizeof(_Unwind_Word
))
1139 tmp_sp
->word
= (_Unwind_Ptr
) cfa
;
1142 _Unwind_SetGRPtr (context
, __builtin_dwarf_sp_column (), tmp_sp
);
1146 uw_update_context_1 (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1148 struct _Unwind_Context orig_context
= *context
;
1152 #ifdef EH_RETURN_STACKADJ_RTX
1153 /* Special handling here: Many machines do not use a frame pointer,
1154 and track the CFA only through offsets from the stack pointer from
1155 one frame to the next. In this case, the stack pointer is never
1156 stored, so it has no saved address in the context. What we do
1157 have is the CFA from the previous stack frame.
1159 In very special situations (such as unwind info for signal return),
1160 there may be location expressions that use the stack pointer as well.
1162 Do this conditionally for one frame. This allows the unwind info
1163 for one frame to save a copy of the stack pointer from the previous
1164 frame, and be able to use much easier CFA mechanisms to do it.
1165 Always zap the saved stack pointer value for the next frame; carrying
1166 the value over from one frame to another doesn't make sense. */
1168 _Unwind_SpTmp tmp_sp
;
1170 if (!_Unwind_GetGRPtr (&orig_context
, __builtin_dwarf_sp_column ()))
1171 _Unwind_SetSpColumn (&orig_context
, context
->cfa
, &tmp_sp
);
1172 _Unwind_SetGRPtr (context
, __builtin_dwarf_sp_column (), NULL
);
1175 /* Compute this frame's CFA. */
1176 switch (fs
->cfa_how
)
1178 case CFA_REG_OFFSET
:
1179 cfa
= _Unwind_GetPtr (&orig_context
, fs
->cfa_reg
);
1180 cfa
+= fs
->cfa_offset
;
1185 const unsigned char *exp
= fs
->cfa_exp
;
1188 exp
= read_uleb128 (exp
, &len
);
1189 cfa
= (void *) (_Unwind_Ptr
)
1190 execute_stack_op (exp
, exp
+ len
, &orig_context
, 0);
1199 /* Compute the addresses of all registers saved in this frame. */
1200 for (i
= 0; i
< DWARF_FRAME_REGISTERS
+ 1; ++i
)
1201 switch (fs
->regs
.reg
[i
].how
)
1206 case REG_SAVED_OFFSET
:
1207 _Unwind_SetGRPtr (context
, i
,
1208 (void *) (cfa
+ fs
->regs
.reg
[i
].loc
.offset
));
1214 _Unwind_GetGRPtr (&orig_context
, fs
->regs
.reg
[i
].loc
.reg
));
1219 const unsigned char *exp
= fs
->regs
.reg
[i
].loc
.exp
;
1223 exp
= read_uleb128 (exp
, &len
);
1224 val
= execute_stack_op (exp
, exp
+ len
, &orig_context
,
1226 _Unwind_SetGRPtr (context
, i
, (void *) val
);
1231 MD_FROB_UPDATE_CONTEXT (context
, fs
);
1234 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1235 of its caller. Update CONTEXT to refer to the caller as well. Note
1236 that the args_size and lsda members are not updated here, but later in
1237 uw_frame_state_for. */
1240 uw_update_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1242 uw_update_context_1 (context
, fs
);
1244 /* Compute the return address now, since the return address column
1245 can change from frame to frame. */
1246 context
->ra
= __builtin_extract_return_addr
1247 (_Unwind_GetPtr (context
, fs
->retaddr_column
));
1250 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1251 level will be the return address and the CFA. */
1253 #define uw_init_context(CONTEXT) \
1256 /* Do any necessary initialization to access arbitrary stack frames. \
1257 On the SPARC, this means flushing the register windows. */ \
1258 __builtin_unwind_init (); \
1259 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1260 __builtin_return_address (0)); \
1265 init_dwarf_reg_size_table (void)
1267 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table
);
1271 uw_init_context_1 (struct _Unwind_Context
*context
,
1272 void *outer_cfa
, void *outer_ra
)
1274 void *ra
= __builtin_extract_return_addr (__builtin_return_address (0));
1275 _Unwind_FrameState fs
;
1276 _Unwind_SpTmp sp_slot
;
1278 memset (context
, 0, sizeof (struct _Unwind_Context
));
1281 if (uw_frame_state_for (context
, &fs
) != _URC_NO_REASON
)
1286 static __gthread_once_t once_regsizes
= __GTHREAD_ONCE_INIT
;
1287 if (__gthread_once (&once_regsizes
, init_dwarf_reg_size_table
) != 0
1288 || dwarf_reg_size_table
[0] == 0)
1289 init_dwarf_reg_size_table ();
1292 if (dwarf_reg_size_table
[0] == 0)
1293 init_dwarf_reg_size_table ();
1296 /* Force the frame state to use the known cfa value. */
1297 _Unwind_SetSpColumn (context
, outer_cfa
, &sp_slot
);
1298 fs
.cfa_how
= CFA_REG_OFFSET
;
1299 fs
.cfa_reg
= __builtin_dwarf_sp_column ();
1302 uw_update_context_1 (context
, &fs
);
1304 /* If the return address column was saved in a register in the
1305 initialization context, then we can't see it in the given
1306 call frame data. So have the initialization context tell us. */
1307 context
->ra
= __builtin_extract_return_addr (outer_ra
);
1311 /* Install TARGET into CURRENT so that we can return to it. This is a
1312 macro because __builtin_eh_return must be invoked in the context of
1315 #define uw_install_context(CURRENT, TARGET) \
1318 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1319 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1320 __builtin_eh_return (offset, handler); \
1325 uw_install_context_1 (struct _Unwind_Context
*current
,
1326 struct _Unwind_Context
*target
)
1330 for (i
= 0; i
< DWARF_FRAME_REGISTERS
; ++i
)
1332 void *c
= current
->reg
[i
];
1333 void *t
= target
->reg
[i
];
1335 if (t
&& c
&& t
!= c
)
1336 memcpy (c
, t
, dwarf_reg_size_table
[i
]);
1339 #ifdef EH_RETURN_STACKADJ_RTX
1343 /* If the last frame records a saved stack pointer, use it. */
1344 if (_Unwind_GetGRPtr (target
, __builtin_dwarf_sp_column ()))
1345 target_cfa
= _Unwind_GetPtr (target
, __builtin_dwarf_sp_column ());
1347 target_cfa
= target
->cfa
;
1349 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1350 if (STACK_GROWS_DOWNWARD
)
1351 return target_cfa
- current
->cfa
+ target
->args_size
;
1353 return current
->cfa
- target_cfa
- target
->args_size
;
1360 static inline _Unwind_Ptr
1361 uw_identify_context (struct _Unwind_Context
*context
)
1363 return _Unwind_GetIP (context
);
1367 #include "unwind.inc"
1369 #endif /* !USING_SJLJ_EXCEPTIONS */