1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997-2017 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
27 #include "coretypes.h"
31 #ifdef __USING_SJLJ_EXCEPTIONS__
32 # define NO_SIZE_OF_ENCODED_VALUE
34 #include "unwind-pe.h"
35 #include "unwind-dw2-fde.h"
37 #include "unwind-dw2.h"
43 #ifndef __USING_SJLJ_EXCEPTIONS__
45 #ifndef __LIBGCC_STACK_GROWS_DOWNWARD__
46 #define __LIBGCC_STACK_GROWS_DOWNWARD__ 0
48 #undef __LIBGCC_STACK_GROWS_DOWNWARD__
49 #define __LIBGCC_STACK_GROWS_DOWNWARD__ 1
52 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
53 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
54 #define PRE_GCC3_DWARF_FRAME_REGISTERS __LIBGCC_DWARF_FRAME_REGISTERS__
57 #ifndef DWARF_REG_TO_UNWIND_COLUMN
58 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
61 #ifdef REG_VALUE_IN_UNWIND_CONTEXT
62 typedef _Unwind_Word _Unwind_Context_Reg_Val
;
64 #ifndef ASSUME_EXTENDED_UNWIND_CONTEXT
65 #define ASSUME_EXTENDED_UNWIND_CONTEXT 1
68 static inline _Unwind_Word
69 _Unwind_Get_Unwind_Word (_Unwind_Context_Reg_Val val
)
74 static inline _Unwind_Context_Reg_Val
75 _Unwind_Get_Unwind_Context_Reg_Val (_Unwind_Word val
)
80 typedef void *_Unwind_Context_Reg_Val
;
82 static inline _Unwind_Word
83 _Unwind_Get_Unwind_Word (_Unwind_Context_Reg_Val val
)
85 return (_Unwind_Word
) (_Unwind_Internal_Ptr
) val
;
88 static inline _Unwind_Context_Reg_Val
89 _Unwind_Get_Unwind_Context_Reg_Val (_Unwind_Word val
)
91 return (_Unwind_Context_Reg_Val
) (_Unwind_Internal_Ptr
) val
;
95 #ifndef ASSUME_EXTENDED_UNWIND_CONTEXT
96 #define ASSUME_EXTENDED_UNWIND_CONTEXT 0
99 /* This is the register and unwind state for a particular frame. This
100 provides the information necessary to unwind up past a frame and return
102 struct _Unwind_Context
104 _Unwind_Context_Reg_Val reg
[__LIBGCC_DWARF_FRAME_REGISTERS__
+1];
108 struct dwarf_eh_bases bases
;
109 /* Signal frame context. */
110 #define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
111 /* Context which has version/args_size/by_value fields. */
112 #define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
114 /* 0 for now, can be increased when further fields are added to
115 struct _Unwind_Context. */
116 _Unwind_Word version
;
117 _Unwind_Word args_size
;
118 char by_value
[__LIBGCC_DWARF_FRAME_REGISTERS__
+1];
121 /* Byte size of every register managed by these routines. */
122 static unsigned char dwarf_reg_size_table
[__LIBGCC_DWARF_FRAME_REGISTERS__
+1];
125 /* Read unaligned data from the instruction buffer. */
130 unsigned u2
__attribute__ ((mode (HI
)));
131 unsigned u4
__attribute__ ((mode (SI
)));
132 unsigned u8
__attribute__ ((mode (DI
)));
133 signed s2
__attribute__ ((mode (HI
)));
134 signed s4
__attribute__ ((mode (SI
)));
135 signed s8
__attribute__ ((mode (DI
)));
136 } __attribute__ ((packed
));
138 static void uw_update_context (struct _Unwind_Context
*, _Unwind_FrameState
*);
139 static _Unwind_Reason_Code
uw_frame_state_for (struct _Unwind_Context
*,
140 _Unwind_FrameState
*);
143 read_pointer (const void *p
) { const union unaligned
*up
= p
; return up
->p
; }
146 read_1u (const void *p
) { return *(const unsigned char *) p
; }
149 read_1s (const void *p
) { return *(const signed char *) p
; }
152 read_2u (const void *p
) { const union unaligned
*up
= p
; return up
->u2
; }
155 read_2s (const void *p
) { const union unaligned
*up
= p
; return up
->s2
; }
157 static inline unsigned int
158 read_4u (const void *p
) { const union unaligned
*up
= p
; return up
->u4
; }
161 read_4s (const void *p
) { const union unaligned
*up
= p
; return up
->s4
; }
163 static inline unsigned long
164 read_8u (const void *p
) { const union unaligned
*up
= p
; return up
->u8
; }
166 static inline unsigned long
167 read_8s (const void *p
) { const union unaligned
*up
= p
; return up
->s8
; }
169 static inline _Unwind_Word
170 _Unwind_IsSignalFrame (struct _Unwind_Context
*context
)
172 return (context
->flags
& SIGNAL_FRAME_BIT
) ? 1 : 0;
176 _Unwind_SetSignalFrame (struct _Unwind_Context
*context
, int val
)
179 context
->flags
|= SIGNAL_FRAME_BIT
;
181 context
->flags
&= ~SIGNAL_FRAME_BIT
;
184 static inline _Unwind_Word
185 _Unwind_IsExtendedContext (struct _Unwind_Context
*context
)
187 return (ASSUME_EXTENDED_UNWIND_CONTEXT
188 || (context
->flags
& EXTENDED_CONTEXT_BIT
));
191 /* Get the value of register INDEX as saved in CONTEXT. */
194 _Unwind_GetGR (struct _Unwind_Context
*context
, int index
)
197 _Unwind_Context_Reg_Val val
;
199 #ifdef DWARF_ZERO_REG
200 if (index
== DWARF_ZERO_REG
)
204 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
205 gcc_assert (index
< (int) sizeof(dwarf_reg_size_table
));
206 size
= dwarf_reg_size_table
[index
];
207 val
= context
->reg
[index
];
209 if (_Unwind_IsExtendedContext (context
) && context
->by_value
[index
])
210 return _Unwind_Get_Unwind_Word (val
);
212 /* This will segfault if the register hasn't been saved. */
213 if (size
== sizeof(_Unwind_Ptr
))
214 return * (_Unwind_Ptr
*) (_Unwind_Internal_Ptr
) val
;
217 gcc_assert (size
== sizeof(_Unwind_Word
));
218 return * (_Unwind_Word
*) (_Unwind_Internal_Ptr
) val
;
223 _Unwind_GetPtr (struct _Unwind_Context
*context
, int index
)
225 return (void *)(_Unwind_Ptr
) _Unwind_GetGR (context
, index
);
228 /* Get the value of the CFA as saved in CONTEXT. */
231 _Unwind_GetCFA (struct _Unwind_Context
*context
)
233 return (_Unwind_Ptr
) context
->cfa
;
236 /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
239 _Unwind_SetGR (struct _Unwind_Context
*context
, int index
, _Unwind_Word val
)
244 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
245 gcc_assert (index
< (int) sizeof(dwarf_reg_size_table
));
246 size
= dwarf_reg_size_table
[index
];
248 if (_Unwind_IsExtendedContext (context
) && context
->by_value
[index
])
250 context
->reg
[index
] = _Unwind_Get_Unwind_Context_Reg_Val (val
);
254 ptr
= (void *) (_Unwind_Internal_Ptr
) context
->reg
[index
];
256 if (size
== sizeof(_Unwind_Ptr
))
257 * (_Unwind_Ptr
*) ptr
= val
;
260 #if defined( __CR16C__ )
261 if (size
== sizeof(_Unwind_Word
))
262 * (_Unwind_Word
*) ptr
= val
;
265 typedef unsigned _CR16_Unwind_Word
__attribute__((__mode__(__word__
)));
266 gcc_assert (index
+ 1 < (int) sizeof(dwarf_reg_size_table
));
267 * (_CR16_Unwind_Word
*) ptr
= val
& 0xffff ; /* low 16-bit */
268 ptr
= context
->reg
[index
+ 1];
269 * (_CR16_Unwind_Word
*) ptr
= val
>> 16 ; /* high 16-bit */
272 gcc_assert (size
== sizeof(_Unwind_Word
));
273 * (_Unwind_Word
*) ptr
= val
;
278 /* Get the pointer to a register INDEX as saved in CONTEXT. */
281 _Unwind_GetGRPtr (struct _Unwind_Context
*context
, int index
)
283 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
284 if (_Unwind_IsExtendedContext (context
) && context
->by_value
[index
])
285 return &context
->reg
[index
];
286 return (void *) (_Unwind_Internal_Ptr
) context
->reg
[index
];
289 /* Set the pointer to a register INDEX as saved in CONTEXT. */
292 _Unwind_SetGRPtr (struct _Unwind_Context
*context
, int index
, void *p
)
294 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
295 if (_Unwind_IsExtendedContext (context
))
296 context
->by_value
[index
] = 0;
297 context
->reg
[index
] = (_Unwind_Context_Reg_Val
) (_Unwind_Internal_Ptr
) p
;
300 /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
303 _Unwind_SetGRValue (struct _Unwind_Context
*context
, int index
,
306 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
307 gcc_assert (index
< (int) sizeof(dwarf_reg_size_table
));
308 gcc_assert (dwarf_reg_size_table
[index
] == sizeof (_Unwind_Context_Reg_Val
));
310 context
->by_value
[index
] = 1;
311 context
->reg
[index
] = _Unwind_Get_Unwind_Context_Reg_Val (val
);
314 /* Return nonzero if register INDEX is stored by value rather than
318 _Unwind_GRByValue (struct _Unwind_Context
*context
, int index
)
320 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
321 return context
->by_value
[index
];
324 /* Retrieve the return address for CONTEXT. */
327 _Unwind_GetIP (struct _Unwind_Context
*context
)
329 return (_Unwind_Ptr
) context
->ra
;
332 /* Retrieve the return address and flag whether that IP is before
333 or after first not yet fully executed instruction. */
336 _Unwind_GetIPInfo (struct _Unwind_Context
*context
, int *ip_before_insn
)
338 *ip_before_insn
= _Unwind_IsSignalFrame (context
);
339 return (_Unwind_Ptr
) context
->ra
;
342 /* Overwrite the return address for CONTEXT with VAL. */
345 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
347 context
->ra
= (void *) val
;
351 _Unwind_GetLanguageSpecificData (struct _Unwind_Context
*context
)
353 return context
->lsda
;
357 _Unwind_GetRegionStart (struct _Unwind_Context
*context
)
359 return (_Unwind_Ptr
) context
->bases
.func
;
363 _Unwind_FindEnclosingFunction (void *pc
)
365 struct dwarf_eh_bases bases
;
366 const struct dwarf_fde
*fde
= _Unwind_Find_FDE (pc
-1, &bases
);
374 _Unwind_GetDataRelBase (struct _Unwind_Context
*context
)
376 return (_Unwind_Ptr
) context
->bases
.dbase
;
380 _Unwind_GetTextRelBase (struct _Unwind_Context
*context
)
382 return (_Unwind_Ptr
) context
->bases
.tbase
;
385 #include "md-unwind-support.h"
387 /* Extract any interesting information from the CIE for the translation
388 unit F belongs to. Return a pointer to the byte after the augmentation,
389 or NULL if we encountered an undecipherable augmentation. */
391 static const unsigned char *
392 extract_cie_info (const struct dwarf_cie
*cie
, struct _Unwind_Context
*context
,
393 _Unwind_FrameState
*fs
)
395 const unsigned char *aug
= cie
->augmentation
;
396 const unsigned char *p
= aug
+ strlen ((const char *)aug
) + 1;
397 const unsigned char *ret
= NULL
;
401 /* g++ v2 "eh" has pointer immediately following augmentation string,
402 so it must be handled first. */
403 if (aug
[0] == 'e' && aug
[1] == 'h')
405 fs
->eh_ptr
= read_pointer (p
);
406 p
+= sizeof (void *);
410 /* After the augmentation resp. pointer for "eh" augmentation
411 follows for CIE version >= 4 address size byte and
412 segment size byte. */
413 if (__builtin_expect (cie
->version
>= 4, 0))
415 if (p
[0] != sizeof (void *) || p
[1] != 0)
419 /* Immediately following this are the code and
420 data alignment and return address column. */
421 p
= read_uleb128 (p
, &utmp
);
422 fs
->code_align
= (_Unwind_Word
)utmp
;
423 p
= read_sleb128 (p
, &stmp
);
424 fs
->data_align
= (_Unwind_Sword
)stmp
;
425 if (cie
->version
== 1)
426 fs
->retaddr_column
= *p
++;
429 p
= read_uleb128 (p
, &utmp
);
430 fs
->retaddr_column
= (_Unwind_Word
)utmp
;
432 fs
->lsda_encoding
= DW_EH_PE_omit
;
434 /* If the augmentation starts with 'z', then a uleb128 immediately
435 follows containing the length of the augmentation field following
439 p
= read_uleb128 (p
, &utmp
);
446 /* Iterate over recognized augmentation subsequences. */
449 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
452 fs
->lsda_encoding
= *p
++;
456 /* "R" indicates a byte indicating how FDE addresses are encoded. */
457 else if (aug
[0] == 'R')
459 fs
->fde_encoding
= *p
++;
463 /* "P" indicates a personality routine in the CIE augmentation. */
464 else if (aug
[0] == 'P')
466 _Unwind_Ptr personality
;
468 p
= read_encoded_value (context
, *p
, p
+ 1, &personality
);
469 fs
->personality
= (_Unwind_Personality_Fn
) personality
;
473 /* "S" indicates a signal frame. */
474 else if (aug
[0] == 'S')
476 fs
->signal_frame
= 1;
480 /* Otherwise we have an unknown augmentation string.
481 Bail unless we saw a 'z' prefix. */
486 return ret
? ret
: p
;
490 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
491 onto the stack to start. */
494 execute_stack_op (const unsigned char *op_ptr
, const unsigned char *op_end
,
495 struct _Unwind_Context
*context
, _Unwind_Word initial
)
497 _Unwind_Word stack
[64]; /* ??? Assume this is enough. */
503 while (op_ptr
< op_end
)
505 enum dwarf_location_atom op
= *op_ptr
++;
507 _uleb128_t reg
, utmp
;
508 _sleb128_t offset
, stmp
;
544 result
= op
- DW_OP_lit0
;
548 result
= (_Unwind_Word
) (_Unwind_Ptr
) read_pointer (op_ptr
);
549 op_ptr
+= sizeof (void *);
552 case DW_OP_GNU_encoded_addr
:
555 op_ptr
= read_encoded_value (context
, *op_ptr
, op_ptr
+1, &presult
);
561 result
= read_1u (op_ptr
);
565 result
= read_1s (op_ptr
);
569 result
= read_2u (op_ptr
);
573 result
= read_2s (op_ptr
);
577 result
= read_4u (op_ptr
);
581 result
= read_4s (op_ptr
);
585 result
= read_8u (op_ptr
);
589 result
= read_8s (op_ptr
);
593 op_ptr
= read_uleb128 (op_ptr
, &utmp
);
594 result
= (_Unwind_Word
)utmp
;
597 op_ptr
= read_sleb128 (op_ptr
, &stmp
);
598 result
= (_Unwind_Sword
)stmp
;
633 result
= _Unwind_GetGR (context
, op
- DW_OP_reg0
);
636 op_ptr
= read_uleb128 (op_ptr
, ®
);
637 result
= _Unwind_GetGR (context
, reg
);
672 op_ptr
= read_sleb128 (op_ptr
, &offset
);
673 result
= _Unwind_GetGR (context
, op
- DW_OP_breg0
) + offset
;
676 op_ptr
= read_uleb128 (op_ptr
, ®
);
677 op_ptr
= read_sleb128 (op_ptr
, &offset
);
678 result
= _Unwind_GetGR (context
, reg
) + (_Unwind_Word
)offset
;
682 gcc_assert (stack_elt
);
683 result
= stack
[stack_elt
- 1];
687 gcc_assert (stack_elt
);
693 gcc_assert (offset
< stack_elt
- 1);
694 result
= stack
[stack_elt
- 1 - offset
];
698 gcc_assert (stack_elt
>= 2);
699 result
= stack
[stack_elt
- 2];
705 gcc_assert (stack_elt
>= 2);
706 t
= stack
[stack_elt
- 1];
707 stack
[stack_elt
- 1] = stack
[stack_elt
- 2];
708 stack
[stack_elt
- 2] = t
;
714 _Unwind_Word t1
, t2
, t3
;
716 gcc_assert (stack_elt
>= 3);
717 t1
= stack
[stack_elt
- 1];
718 t2
= stack
[stack_elt
- 2];
719 t3
= stack
[stack_elt
- 3];
720 stack
[stack_elt
- 1] = t2
;
721 stack
[stack_elt
- 2] = t3
;
722 stack
[stack_elt
- 3] = t1
;
727 case DW_OP_deref_size
:
731 case DW_OP_plus_uconst
:
732 /* Unary operations. */
733 gcc_assert (stack_elt
);
736 result
= stack
[stack_elt
];
742 void *ptr
= (void *) (_Unwind_Ptr
) result
;
743 result
= (_Unwind_Ptr
) read_pointer (ptr
);
747 case DW_OP_deref_size
:
749 void *ptr
= (void *) (_Unwind_Ptr
) result
;
753 result
= read_1u (ptr
);
756 result
= read_2u (ptr
);
759 result
= read_4u (ptr
);
762 result
= read_8u (ptr
);
771 if ((_Unwind_Sword
) result
< 0)
780 case DW_OP_plus_uconst
:
781 op_ptr
= read_uleb128 (op_ptr
, &utmp
);
782 result
+= (_Unwind_Word
)utmp
;
808 /* Binary operations. */
809 _Unwind_Word first
, second
;
810 gcc_assert (stack_elt
>= 2);
813 second
= stack
[stack_elt
];
814 first
= stack
[stack_elt
+ 1];
819 result
= second
& first
;
822 result
= (_Unwind_Sword
) second
/ (_Unwind_Sword
) first
;
825 result
= second
- first
;
828 result
= second
% first
;
831 result
= second
* first
;
834 result
= second
| first
;
837 result
= second
+ first
;
840 result
= second
<< first
;
843 result
= second
>> first
;
846 result
= (_Unwind_Sword
) second
>> first
;
849 result
= second
^ first
;
852 result
= (_Unwind_Sword
) second
<= (_Unwind_Sword
) first
;
855 result
= (_Unwind_Sword
) second
>= (_Unwind_Sword
) first
;
858 result
= (_Unwind_Sword
) second
== (_Unwind_Sword
) first
;
861 result
= (_Unwind_Sword
) second
< (_Unwind_Sword
) first
;
864 result
= (_Unwind_Sword
) second
> (_Unwind_Sword
) first
;
867 result
= (_Unwind_Sword
) second
!= (_Unwind_Sword
) first
;
877 offset
= read_2s (op_ptr
);
883 gcc_assert (stack_elt
);
886 offset
= read_2s (op_ptr
);
888 if (stack
[stack_elt
] != 0)
899 /* Most things push a result value. */
900 gcc_assert ((size_t) stack_elt
< sizeof(stack
)/sizeof(*stack
));
901 stack
[stack_elt
++] = result
;
905 /* We were executing this program to get a value. It should be
907 gcc_assert (stack_elt
);
909 return stack
[stack_elt
];
913 /* Decode DWARF 2 call frame information. Takes pointers the
914 instruction sequence to decode, current register information and
915 CIE info, and the PC range to evaluate. */
918 execute_cfa_program (const unsigned char *insn_ptr
,
919 const unsigned char *insn_end
,
920 struct _Unwind_Context
*context
,
921 _Unwind_FrameState
*fs
)
923 struct frame_state_reg_info
*unused_rs
= NULL
;
925 /* Don't allow remember/restore between CIE and FDE programs. */
926 fs
->regs
.prev
= NULL
;
928 /* The comparison with the return address uses < rather than <= because
929 we are only interested in the effects of code before the call; for a
930 noreturn function, the return address may point to unrelated code with
931 a different stack configuration that we are not interested in. We
932 assume that the call itself is unwind info-neutral; if not, or if
933 there are delay instructions that adjust the stack, these must be
934 reflected at the point immediately before the call insn.
935 In signal frames, return address is after last completed instruction,
936 so we add 1 to return address to make the comparison <=. */
937 while (insn_ptr
< insn_end
938 && fs
->pc
< context
->ra
+ _Unwind_IsSignalFrame (context
))
940 unsigned char insn
= *insn_ptr
++;
941 _uleb128_t reg
, utmp
;
942 _sleb128_t offset
, stmp
;
944 if ((insn
& 0xc0) == DW_CFA_advance_loc
)
945 fs
->pc
+= (insn
& 0x3f) * fs
->code_align
;
946 else if ((insn
& 0xc0) == DW_CFA_offset
)
949 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
950 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
951 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
953 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
955 else if ((insn
& 0xc0) == DW_CFA_restore
)
958 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_UNSAVED
;
966 insn_ptr
= read_encoded_value (context
, fs
->fde_encoding
,
968 fs
->pc
= (void *) pc
;
972 case DW_CFA_advance_loc1
:
973 fs
->pc
+= read_1u (insn_ptr
) * fs
->code_align
;
976 case DW_CFA_advance_loc2
:
977 fs
->pc
+= read_2u (insn_ptr
) * fs
->code_align
;
980 case DW_CFA_advance_loc4
:
981 fs
->pc
+= read_4u (insn_ptr
) * fs
->code_align
;
985 case DW_CFA_offset_extended
:
986 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
987 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
988 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
989 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
991 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
994 case DW_CFA_restore_extended
:
995 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
996 /* FIXME, this is wrong; the CIE might have said that the
997 register was saved somewhere. */
998 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN(reg
)].how
= REG_UNSAVED
;
1001 case DW_CFA_same_value
:
1002 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1003 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN(reg
)].how
= REG_UNSAVED
;
1006 case DW_CFA_undefined
:
1007 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1008 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN(reg
)].how
= REG_UNDEFINED
;
1014 case DW_CFA_register
:
1017 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1018 insn_ptr
= read_uleb128 (insn_ptr
, ®2
);
1019 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_SAVED_REG
;
1020 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.reg
=
1025 case DW_CFA_remember_state
:
1027 struct frame_state_reg_info
*new_rs
;
1031 unused_rs
= unused_rs
->prev
;
1034 new_rs
= alloca (sizeof (struct frame_state_reg_info
));
1037 fs
->regs
.prev
= new_rs
;
1041 case DW_CFA_restore_state
:
1043 struct frame_state_reg_info
*old_rs
= fs
->regs
.prev
;
1045 old_rs
->prev
= unused_rs
;
1050 case DW_CFA_def_cfa
:
1051 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1052 fs
->regs
.cfa_reg
= (_Unwind_Word
)utmp
;
1053 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1054 fs
->regs
.cfa_offset
= (_Unwind_Word
)utmp
;
1055 fs
->regs
.cfa_how
= CFA_REG_OFFSET
;
1058 case DW_CFA_def_cfa_register
:
1059 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1060 fs
->regs
.cfa_reg
= (_Unwind_Word
)utmp
;
1061 fs
->regs
.cfa_how
= CFA_REG_OFFSET
;
1064 case DW_CFA_def_cfa_offset
:
1065 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1066 fs
->regs
.cfa_offset
= utmp
;
1067 /* cfa_how deliberately not set. */
1070 case DW_CFA_def_cfa_expression
:
1071 fs
->regs
.cfa_exp
= insn_ptr
;
1072 fs
->regs
.cfa_how
= CFA_EXP
;
1073 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1077 case DW_CFA_expression
:
1078 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1079 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
= REG_SAVED_EXP
;
1080 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.exp
= insn_ptr
;
1081 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1086 case DW_CFA_offset_extended_sf
:
1087 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1088 insn_ptr
= read_sleb128 (insn_ptr
, &stmp
);
1089 offset
= stmp
* fs
->data_align
;
1090 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
1092 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
1095 case DW_CFA_def_cfa_sf
:
1096 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1097 fs
->regs
.cfa_reg
= (_Unwind_Word
)utmp
;
1098 insn_ptr
= read_sleb128 (insn_ptr
, &stmp
);
1099 fs
->regs
.cfa_offset
= (_Unwind_Sword
)stmp
;
1100 fs
->regs
.cfa_how
= CFA_REG_OFFSET
;
1101 fs
->regs
.cfa_offset
*= fs
->data_align
;
1104 case DW_CFA_def_cfa_offset_sf
:
1105 insn_ptr
= read_sleb128 (insn_ptr
, &stmp
);
1106 fs
->regs
.cfa_offset
= (_Unwind_Sword
)stmp
;
1107 fs
->regs
.cfa_offset
*= fs
->data_align
;
1108 /* cfa_how deliberately not set. */
1111 case DW_CFA_val_offset
:
1112 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1113 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1114 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
1115 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
1116 = REG_SAVED_VAL_OFFSET
;
1117 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
1120 case DW_CFA_val_offset_sf
:
1121 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1122 insn_ptr
= read_sleb128 (insn_ptr
, &stmp
);
1123 offset
= stmp
* fs
->data_align
;
1124 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
1125 = REG_SAVED_VAL_OFFSET
;
1126 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= offset
;
1129 case DW_CFA_val_expression
:
1130 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1131 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
1132 = REG_SAVED_VAL_EXP
;
1133 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.exp
= insn_ptr
;
1134 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1138 case DW_CFA_GNU_window_save
:
1139 /* ??? Hardcoded for SPARC register window configuration. */
1140 for (reg
= 16; reg
< 32; ++reg
)
1142 fs
->regs
.reg
[reg
].how
= REG_SAVED_OFFSET
;
1143 fs
->regs
.reg
[reg
].loc
.offset
= (reg
- 16) * sizeof (void *);
1147 case DW_CFA_GNU_args_size
:
1148 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1149 context
->args_size
= (_Unwind_Word
)utmp
;
1152 case DW_CFA_GNU_negative_offset_extended
:
1153 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
1154 older PowerPC code. */
1155 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1156 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1157 offset
= (_Unwind_Word
) utmp
* fs
->data_align
;
1158 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].how
1160 fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (reg
)].loc
.offset
= -offset
;
1169 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
1170 its caller and decode it into FS. This function also sets the
1171 args_size and lsda members of CONTEXT, as they are really information
1172 about the caller's frame. */
1174 static _Unwind_Reason_Code
1175 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1177 const struct dwarf_fde
*fde
;
1178 const struct dwarf_cie
*cie
;
1179 const unsigned char *aug
, *insn
, *end
;
1181 memset (fs
, 0, sizeof (*fs
));
1182 context
->args_size
= 0;
1185 if (context
->ra
== 0)
1186 return _URC_END_OF_STACK
;
1188 fde
= _Unwind_Find_FDE (context
->ra
+ _Unwind_IsSignalFrame (context
) - 1,
1192 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1193 /* Couldn't find frame unwind info for this function. Try a
1194 target-specific fallback mechanism. This will necessarily
1195 not provide a personality routine or LSDA. */
1196 return MD_FALLBACK_FRAME_STATE_FOR (context
, fs
);
1198 return _URC_END_OF_STACK
;
1202 fs
->pc
= context
->bases
.func
;
1204 cie
= get_cie (fde
);
1205 insn
= extract_cie_info (cie
, context
, fs
);
1207 /* CIE contained unknown augmentation. */
1208 return _URC_FATAL_PHASE1_ERROR
;
1210 /* First decode all the insns in the CIE. */
1211 end
= (const unsigned char *) next_fde ((const struct dwarf_fde
*) cie
);
1212 execute_cfa_program (insn
, end
, context
, fs
);
1214 /* Locate augmentation for the fde. */
1215 aug
= (const unsigned char *) fde
+ sizeof (*fde
);
1216 aug
+= 2 * size_of_encoded_value (fs
->fde_encoding
);
1221 aug
= read_uleb128 (aug
, &i
);
1224 if (fs
->lsda_encoding
!= DW_EH_PE_omit
)
1228 aug
= read_encoded_value (context
, fs
->lsda_encoding
, aug
, &lsda
);
1229 context
->lsda
= (void *) lsda
;
1232 /* Then the insns in the FDE up to our target PC. */
1235 end
= (const unsigned char *) next_fde (fde
);
1236 execute_cfa_program (insn
, end
, context
, fs
);
1238 return _URC_NO_REASON
;
1241 typedef struct frame_state
1247 long reg_or_offset
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1248 unsigned short cfa_reg
;
1249 unsigned short retaddr_column
;
1250 char saved
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1253 struct frame_state
* __frame_state_for (void *, struct frame_state
*);
1255 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1256 a given PC_TARGET. The caller should allocate a local variable of
1257 `struct frame_state' and pass its address to STATE_IN. */
1259 struct frame_state
*
1260 __frame_state_for (void *pc_target
, struct frame_state
*state_in
)
1262 struct _Unwind_Context context
;
1263 _Unwind_FrameState fs
;
1266 memset (&context
, 0, sizeof (struct _Unwind_Context
));
1267 if (!ASSUME_EXTENDED_UNWIND_CONTEXT
)
1268 context
.flags
= EXTENDED_CONTEXT_BIT
;
1269 context
.ra
= pc_target
+ 1;
1271 if (uw_frame_state_for (&context
, &fs
) != _URC_NO_REASON
)
1274 /* We have no way to pass a location expression for the CFA to our
1275 caller. It wouldn't understand it anyway. */
1276 if (fs
.regs
.cfa_how
== CFA_EXP
)
1279 for (reg
= 0; reg
< PRE_GCC3_DWARF_FRAME_REGISTERS
+ 1; reg
++)
1281 state_in
->saved
[reg
] = fs
.regs
.reg
[reg
].how
;
1282 switch (state_in
->saved
[reg
])
1285 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.reg
;
1287 case REG_SAVED_OFFSET
:
1288 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.offset
;
1291 state_in
->reg_or_offset
[reg
] = 0;
1296 state_in
->cfa_offset
= fs
.regs
.cfa_offset
;
1297 state_in
->cfa_reg
= fs
.regs
.cfa_reg
;
1298 state_in
->retaddr_column
= fs
.retaddr_column
;
1299 state_in
->args_size
= context
.args_size
;
1300 state_in
->eh_ptr
= fs
.eh_ptr
;
1305 typedef union { _Unwind_Ptr ptr
; _Unwind_Word word
; } _Unwind_SpTmp
;
1308 _Unwind_SetSpColumn (struct _Unwind_Context
*context
, void *cfa
,
1309 _Unwind_SpTmp
*tmp_sp
)
1311 int size
= dwarf_reg_size_table
[__builtin_dwarf_sp_column ()];
1313 if (size
== sizeof(_Unwind_Ptr
))
1314 tmp_sp
->ptr
= (_Unwind_Ptr
) cfa
;
1317 gcc_assert (size
== sizeof(_Unwind_Word
));
1318 tmp_sp
->word
= (_Unwind_Ptr
) cfa
;
1320 _Unwind_SetGRPtr (context
, __builtin_dwarf_sp_column (), tmp_sp
);
1324 uw_update_context_1 (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1326 struct _Unwind_Context orig_context
= *context
;
1330 #ifdef __LIBGCC_EH_RETURN_STACKADJ_RTX__
1331 /* Special handling here: Many machines do not use a frame pointer,
1332 and track the CFA only through offsets from the stack pointer from
1333 one frame to the next. In this case, the stack pointer is never
1334 stored, so it has no saved address in the context. What we do
1335 have is the CFA from the previous stack frame.
1337 In very special situations (such as unwind info for signal return),
1338 there may be location expressions that use the stack pointer as well.
1340 Do this conditionally for one frame. This allows the unwind info
1341 for one frame to save a copy of the stack pointer from the previous
1342 frame, and be able to use much easier CFA mechanisms to do it.
1343 Always zap the saved stack pointer value for the next frame; carrying
1344 the value over from one frame to another doesn't make sense. */
1346 _Unwind_SpTmp tmp_sp
;
1348 if (!_Unwind_GetGRPtr (&orig_context
, __builtin_dwarf_sp_column ()))
1349 _Unwind_SetSpColumn (&orig_context
, context
->cfa
, &tmp_sp
);
1350 _Unwind_SetGRPtr (context
, __builtin_dwarf_sp_column (), NULL
);
1353 /* Compute this frame's CFA. */
1354 switch (fs
->regs
.cfa_how
)
1356 case CFA_REG_OFFSET
:
1357 cfa
= _Unwind_GetPtr (&orig_context
, fs
->regs
.cfa_reg
);
1358 cfa
+= fs
->regs
.cfa_offset
;
1363 const unsigned char *exp
= fs
->regs
.cfa_exp
;
1366 exp
= read_uleb128 (exp
, &len
);
1367 cfa
= (void *) (_Unwind_Ptr
)
1368 execute_stack_op (exp
, exp
+ len
, &orig_context
, 0);
1377 /* Compute the addresses of all registers saved in this frame. */
1378 for (i
= 0; i
< __LIBGCC_DWARF_FRAME_REGISTERS__
+ 1; ++i
)
1379 switch (fs
->regs
.reg
[i
].how
)
1385 case REG_SAVED_OFFSET
:
1386 _Unwind_SetGRPtr (context
, i
,
1387 (void *) (cfa
+ fs
->regs
.reg
[i
].loc
.offset
));
1391 if (_Unwind_GRByValue (&orig_context
, fs
->regs
.reg
[i
].loc
.reg
))
1392 _Unwind_SetGRValue (context
, i
,
1393 _Unwind_GetGR (&orig_context
,
1394 fs
->regs
.reg
[i
].loc
.reg
));
1396 _Unwind_SetGRPtr (context
, i
,
1397 _Unwind_GetGRPtr (&orig_context
,
1398 fs
->regs
.reg
[i
].loc
.reg
));
1403 const unsigned char *exp
= fs
->regs
.reg
[i
].loc
.exp
;
1407 exp
= read_uleb128 (exp
, &len
);
1408 val
= execute_stack_op (exp
, exp
+ len
, &orig_context
,
1410 _Unwind_SetGRPtr (context
, i
, (void *) val
);
1414 case REG_SAVED_VAL_OFFSET
:
1415 _Unwind_SetGRValue (context
, i
,
1416 (_Unwind_Internal_Ptr
)
1417 (cfa
+ fs
->regs
.reg
[i
].loc
.offset
));
1420 case REG_SAVED_VAL_EXP
:
1422 const unsigned char *exp
= fs
->regs
.reg
[i
].loc
.exp
;
1426 exp
= read_uleb128 (exp
, &len
);
1427 val
= execute_stack_op (exp
, exp
+ len
, &orig_context
,
1429 _Unwind_SetGRValue (context
, i
, val
);
1434 _Unwind_SetSignalFrame (context
, fs
->signal_frame
);
1436 #ifdef MD_FROB_UPDATE_CONTEXT
1437 MD_FROB_UPDATE_CONTEXT (context
, fs
);
1441 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1442 of its caller. Update CONTEXT to refer to the caller as well. Note
1443 that the args_size and lsda members are not updated here, but later in
1444 uw_frame_state_for. */
1447 uw_update_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1449 uw_update_context_1 (context
, fs
);
1451 /* In general this unwinder doesn't make any distinction between
1452 undefined and same_value rule. Call-saved registers are assumed
1453 to have same_value rule by default and explicit undefined
1454 rule is handled like same_value. The only exception is
1455 DW_CFA_undefined on retaddr_column which is supposed to
1456 mark outermost frame in DWARF 3. */
1457 if (fs
->regs
.reg
[DWARF_REG_TO_UNWIND_COLUMN (fs
->retaddr_column
)].how
1459 /* uw_frame_state_for uses context->ra == 0 check to find outermost
1463 /* Compute the return address now, since the return address column
1464 can change from frame to frame. */
1465 context
->ra
= __builtin_extract_return_addr
1466 (_Unwind_GetPtr (context
, fs
->retaddr_column
));
1467 #if defined( __CR16C__ )
1468 context
->ra
= (void*)( ( (unsigned)context
->ra
) << 1 ) ;
1473 uw_advance_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1475 uw_update_context (context
, fs
);
1478 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1479 level will be the return address and the CFA. */
1481 #define uw_init_context(CONTEXT) \
1484 /* Do any necessary initialization to access arbitrary stack frames. \
1485 On the SPARC, this means flushing the register windows. */ \
1486 __builtin_unwind_init (); \
1487 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1488 __builtin_return_address (0)); \
1493 init_dwarf_reg_size_table (void)
1495 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table
);
1498 static void __attribute__((noinline
))
1499 uw_init_context_1 (struct _Unwind_Context
*context
,
1500 void *outer_cfa
, void *outer_ra
)
1502 void *ra
= __builtin_extract_return_addr (__builtin_return_address (0));
1503 _Unwind_FrameState fs
;
1504 _Unwind_SpTmp sp_slot
;
1505 _Unwind_Reason_Code code
;
1507 memset (context
, 0, sizeof (struct _Unwind_Context
));
1509 if (!ASSUME_EXTENDED_UNWIND_CONTEXT
)
1510 context
->flags
= EXTENDED_CONTEXT_BIT
;
1512 code
= uw_frame_state_for (context
, &fs
);
1513 gcc_assert (code
== _URC_NO_REASON
);
1517 static __gthread_once_t once_regsizes
= __GTHREAD_ONCE_INIT
;
1518 if (__gthread_once (&once_regsizes
, init_dwarf_reg_size_table
) != 0
1519 && dwarf_reg_size_table
[0] == 0)
1520 init_dwarf_reg_size_table ();
1523 if (dwarf_reg_size_table
[0] == 0)
1524 init_dwarf_reg_size_table ();
1527 /* Force the frame state to use the known cfa value. */
1528 _Unwind_SetSpColumn (context
, outer_cfa
, &sp_slot
);
1529 fs
.regs
.cfa_how
= CFA_REG_OFFSET
;
1530 fs
.regs
.cfa_reg
= __builtin_dwarf_sp_column ();
1531 #if !defined( __CR16C__ )
1532 fs
.regs
.cfa_offset
= 0;
1534 fs
.regs
.cfa_offset
-= context
->args_size
;
1537 uw_update_context_1 (context
, &fs
);
1539 /* If the return address column was saved in a register in the
1540 initialization context, then we can't see it in the given
1541 call frame data. So have the initialization context tell us. */
1542 context
->ra
= __builtin_extract_return_addr (outer_ra
);
1545 static void _Unwind_DebugHook (void *, void *)
1546 __attribute__ ((__noinline__
, __used__
, __noclone__
));
1548 /* This function is called during unwinding. It is intended as a hook
1549 for a debugger to intercept exceptions. CFA is the CFA of the
1550 target frame. HANDLER is the PC to which control will be
1553 _Unwind_DebugHook (void *cfa
__attribute__ ((__unused__
)),
1554 void *handler
__attribute__ ((__unused__
)))
1556 /* We only want to use stap probes starting with v3. Earlier
1557 versions added too much startup cost. */
1558 #if defined (HAVE_SYS_SDT_H) && defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3
1559 STAP_PROBE2 (libgcc
, unwind
, cfa
, handler
);
1565 /* Install TARGET into CURRENT so that we can return to it. This is a
1566 macro because __builtin_eh_return must be invoked in the context of
1568 #if defined( __CR16C__ )
1570 #define uw_install_context(CURRENT, TARGET) \
1573 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1574 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1575 handler = (void*)( ( (unsigned)handler ) >> 1 ) ; \
1576 _Unwind_DebugHook ((TARGET)->cfa, handler); \
1577 __builtin_eh_return (offset, handler); \
1581 #define uw_install_context(CURRENT, TARGET) \
1584 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1585 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1586 _Unwind_DebugHook ((TARGET)->cfa, handler); \
1587 __builtin_eh_return (offset, handler); \
1590 #endif /* __CR16C__ */
1593 uw_install_context_1 (struct _Unwind_Context
*current
,
1594 struct _Unwind_Context
*target
)
1597 _Unwind_SpTmp sp_slot
;
1599 /* If the target frame does not have a saved stack pointer,
1600 then set up the target's CFA. */
1601 if (!_Unwind_GetGRPtr (target
, __builtin_dwarf_sp_column ()))
1602 _Unwind_SetSpColumn (target
, target
->cfa
, &sp_slot
);
1604 for (i
= 0; i
< __LIBGCC_DWARF_FRAME_REGISTERS__
; ++i
)
1606 void *c
= (void *) (_Unwind_Internal_Ptr
) current
->reg
[i
];
1607 void *t
= (void *) (_Unwind_Internal_Ptr
)target
->reg
[i
];
1609 gcc_assert (current
->by_value
[i
] == 0);
1610 if (target
->by_value
[i
] && c
)
1614 if (dwarf_reg_size_table
[i
] == sizeof (_Unwind_Word
))
1616 w
= (_Unwind_Internal_Ptr
) t
;
1617 memcpy (c
, &w
, sizeof (_Unwind_Word
));
1621 gcc_assert (dwarf_reg_size_table
[i
] == sizeof (_Unwind_Ptr
));
1622 p
= (_Unwind_Internal_Ptr
) t
;
1623 memcpy (c
, &p
, sizeof (_Unwind_Ptr
));
1626 else if (t
&& c
&& t
!= c
)
1627 memcpy (c
, t
, dwarf_reg_size_table
[i
]);
1630 /* If the current frame doesn't have a saved stack pointer, then we
1631 need to rely on EH_RETURN_STACKADJ_RTX to get our target stack
1632 pointer value reloaded. */
1633 if (!_Unwind_GetGRPtr (current
, __builtin_dwarf_sp_column ()))
1637 target_cfa
= _Unwind_GetPtr (target
, __builtin_dwarf_sp_column ());
1639 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1640 if (__LIBGCC_STACK_GROWS_DOWNWARD__
)
1641 return target_cfa
- current
->cfa
+ target
->args_size
;
1643 return current
->cfa
- target_cfa
- target
->args_size
;
1648 static inline _Unwind_Ptr
1649 uw_identify_context (struct _Unwind_Context
*context
)
1651 /* The CFA is not sufficient to disambiguate the context of a function
1652 interrupted by a signal before establishing its frame and the context
1653 of the signal itself. */
1654 if (__LIBGCC_STACK_GROWS_DOWNWARD__
)
1655 return _Unwind_GetCFA (context
) - _Unwind_IsSignalFrame (context
);
1657 return _Unwind_GetCFA (context
) + _Unwind_IsSignalFrame (context
);
1661 #include "unwind.inc"
1663 #if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
1664 alias (_Unwind_Backtrace
);
1665 alias (_Unwind_DeleteException
);
1666 alias (_Unwind_FindEnclosingFunction
);
1667 alias (_Unwind_ForcedUnwind
);
1668 alias (_Unwind_GetDataRelBase
);
1669 alias (_Unwind_GetTextRelBase
);
1670 alias (_Unwind_GetCFA
);
1671 alias (_Unwind_GetGR
);
1672 alias (_Unwind_GetIP
);
1673 alias (_Unwind_GetLanguageSpecificData
);
1674 alias (_Unwind_GetRegionStart
);
1675 alias (_Unwind_RaiseException
);
1676 alias (_Unwind_Resume
);
1677 alias (_Unwind_Resume_or_Rethrow
);
1678 alias (_Unwind_SetGR
);
1679 alias (_Unwind_SetIP
);
1682 #endif /* !USING_SJLJ_EXCEPTIONS */