1 /* DWARF2 exception handling and frame unwind runtime interface routines.
2 Copyright (C) 1997-2022 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"
29 #include "libgcc_tm.h"
32 #ifdef __USING_SJLJ_EXCEPTIONS__
33 # define NO_SIZE_OF_ENCODED_VALUE
35 #include "unwind-pe.h"
36 #include "unwind-dw2-fde.h"
38 #include "unwind-dw2.h"
45 #ifndef __USING_SJLJ_EXCEPTIONS__
47 #ifndef __LIBGCC_STACK_GROWS_DOWNWARD__
48 #define __LIBGCC_STACK_GROWS_DOWNWARD__ 0
50 #undef __LIBGCC_STACK_GROWS_DOWNWARD__
51 #define __LIBGCC_STACK_GROWS_DOWNWARD__ 1
54 /* Dwarf frame registers used for pre gcc 3.0 compiled glibc. */
55 #ifndef PRE_GCC3_DWARF_FRAME_REGISTERS
56 #define PRE_GCC3_DWARF_FRAME_REGISTERS __LIBGCC_DWARF_FRAME_REGISTERS__
59 /* ??? For the public function interfaces, we tend to gcc_assert that the
60 column numbers are in range. For the dwarf2 unwind info this does happen,
61 although so far in a case that doesn't actually matter.
63 See PR49146, in which a call from x86_64 ms abi to x86_64 unix abi stores
64 the call-saved xmm registers and annotates them. We havn't bothered
65 providing support for the xmm registers for the x86_64 port primarily
66 because the 64-bit windows targets don't use dwarf2 unwind, using sjlj or
67 SEH instead. Adding the support for unix targets would generally be a
68 waste. However, some runtime libraries supplied with ICC do contain such
69 an unorthodox transition, as well as the unwind info to match. This loss
70 of register restoration doesn't matter in practice, because the exception
71 is caught in the native unix abi, where all of the xmm registers are
74 Ideally, we'd record some bit to notice when we're failing to restore some
75 register recorded in the unwind info, but to do that we need annotation on
76 the unix->ms abi edge, so that we know when the register data may be
77 discarded. And since this edge is also within the ICC library, we're
78 unlikely to be able to get the new annotation.
80 Barring a magic solution to restore the ms abi defined 128-bit xmm registers
81 (as distictly opposed to the full runtime width) without causing extra
82 overhead for normal unix abis, the best solution seems to be to simply
83 ignore unwind data for unknown columns. */
85 #define UNWIND_COLUMN_IN_RANGE(x) \
86 __builtin_expect((x) <= __LIBGCC_DWARF_FRAME_REGISTERS__, 1)
88 #ifdef REG_VALUE_IN_UNWIND_CONTEXT
89 typedef _Unwind_Word _Unwind_Context_Reg_Val
;
91 #ifndef ASSUME_EXTENDED_UNWIND_CONTEXT
92 #define ASSUME_EXTENDED_UNWIND_CONTEXT 1
95 static inline _Unwind_Word
96 _Unwind_Get_Unwind_Word (_Unwind_Context_Reg_Val val
)
101 static inline _Unwind_Context_Reg_Val
102 _Unwind_Get_Unwind_Context_Reg_Val (_Unwind_Word val
)
107 typedef void *_Unwind_Context_Reg_Val
;
109 static inline _Unwind_Word
110 _Unwind_Get_Unwind_Word (_Unwind_Context_Reg_Val val
)
112 return (_Unwind_Word
) (_Unwind_Internal_Ptr
) val
;
115 static inline _Unwind_Context_Reg_Val
116 _Unwind_Get_Unwind_Context_Reg_Val (_Unwind_Word val
)
118 return (_Unwind_Context_Reg_Val
) (_Unwind_Internal_Ptr
) val
;
122 #ifndef ASSUME_EXTENDED_UNWIND_CONTEXT
123 #define ASSUME_EXTENDED_UNWIND_CONTEXT 0
126 /* This is the register and unwind state for a particular frame. This
127 provides the information necessary to unwind up past a frame and return
129 struct _Unwind_Context
131 _Unwind_Context_Reg_Val reg
[__LIBGCC_DWARF_FRAME_REGISTERS__
+1];
135 struct dwarf_eh_bases bases
;
136 /* Signal frame context. */
137 #define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
138 /* Context which has version/args_size/by_value fields. */
139 #define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
140 /* Bit reserved on AArch64, return address has been signed with A or B
142 #define RA_SIGNED_BIT ((~(_Unwind_Word) 0 >> 3) + 1)
144 /* 0 for now, can be increased when further fields are added to
145 struct _Unwind_Context. */
146 _Unwind_Word version
;
147 _Unwind_Word args_size
;
148 char by_value
[__LIBGCC_DWARF_FRAME_REGISTERS__
+1];
151 /* Byte size of every register managed by these routines. */
152 static unsigned char dwarf_reg_size_table
[__LIBGCC_DWARF_FRAME_REGISTERS__
+1];
155 /* Read unaligned data from the instruction buffer. */
160 unsigned u2
__attribute__ ((mode (HI
)));
161 unsigned u4
__attribute__ ((mode (SI
)));
162 unsigned u8
__attribute__ ((mode (DI
)));
163 signed s2
__attribute__ ((mode (HI
)));
164 signed s4
__attribute__ ((mode (SI
)));
165 signed s8
__attribute__ ((mode (DI
)));
166 } __attribute__ ((packed
));
168 static void uw_update_context (struct _Unwind_Context
*, _Unwind_FrameState
*);
169 static _Unwind_Reason_Code
uw_frame_state_for (struct _Unwind_Context
*,
170 _Unwind_FrameState
*);
173 read_pointer (const void *p
) { const union unaligned
*up
= p
; return up
->p
; }
176 read_1u (const void *p
) { return *(const unsigned char *) p
; }
179 read_1s (const void *p
) { return *(const signed char *) p
; }
182 read_2u (const void *p
) { const union unaligned
*up
= p
; return up
->u2
; }
185 read_2s (const void *p
) { const union unaligned
*up
= p
; return up
->s2
; }
187 static inline unsigned int
188 read_4u (const void *p
) { const union unaligned
*up
= p
; return up
->u4
; }
191 read_4s (const void *p
) { const union unaligned
*up
= p
; return up
->s4
; }
193 static inline unsigned long
194 read_8u (const void *p
) { const union unaligned
*up
= p
; return up
->u8
; }
196 static inline unsigned long
197 read_8s (const void *p
) { const union unaligned
*up
= p
; return up
->s8
; }
199 static inline _Unwind_Word
200 _Unwind_IsSignalFrame (struct _Unwind_Context
*context
)
202 return (context
->flags
& SIGNAL_FRAME_BIT
) ? 1 : 0;
206 _Unwind_SetSignalFrame (struct _Unwind_Context
*context
, int val
)
209 context
->flags
|= SIGNAL_FRAME_BIT
;
211 context
->flags
&= ~SIGNAL_FRAME_BIT
;
214 static inline _Unwind_Word
215 _Unwind_IsExtendedContext (struct _Unwind_Context
*context
)
217 return (ASSUME_EXTENDED_UNWIND_CONTEXT
218 || (context
->flags
& EXTENDED_CONTEXT_BIT
));
221 /* Get the value of register REGNO as saved in CONTEXT. */
224 _Unwind_GetGR (struct _Unwind_Context
*context
, int regno
)
227 _Unwind_Context_Reg_Val val
;
229 #ifdef DWARF_ZERO_REG
230 if (regno
== DWARF_ZERO_REG
)
234 index
= DWARF_REG_TO_UNWIND_COLUMN (regno
);
235 gcc_assert (index
< (int) sizeof(dwarf_reg_size_table
));
236 size
= dwarf_reg_size_table
[index
];
237 val
= context
->reg
[index
];
239 if (_Unwind_IsExtendedContext (context
) && context
->by_value
[index
])
240 return _Unwind_Get_Unwind_Word (val
);
242 #ifdef DWARF_LAZY_REGISTER_VALUE
245 if (DWARF_LAZY_REGISTER_VALUE (regno
, &value
))
250 /* This will segfault if the register hasn't been saved. */
251 if (size
== sizeof(_Unwind_Ptr
))
252 return * (_Unwind_Ptr
*) (_Unwind_Internal_Ptr
) val
;
255 gcc_assert (size
== sizeof(_Unwind_Word
));
256 return * (_Unwind_Word
*) (_Unwind_Internal_Ptr
) val
;
261 _Unwind_GetPtr (struct _Unwind_Context
*context
, int index
)
263 return (void *)(_Unwind_Ptr
) _Unwind_GetGR (context
, index
);
266 /* Get the value of the CFA as saved in CONTEXT. */
269 _Unwind_GetCFA (struct _Unwind_Context
*context
)
271 return (_Unwind_Ptr
) context
->cfa
;
274 /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
277 _Unwind_SetGR (struct _Unwind_Context
*context
, int index
, _Unwind_Word val
)
282 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
283 gcc_assert (index
< (int) sizeof(dwarf_reg_size_table
));
284 size
= dwarf_reg_size_table
[index
];
286 if (_Unwind_IsExtendedContext (context
) && context
->by_value
[index
])
288 context
->reg
[index
] = _Unwind_Get_Unwind_Context_Reg_Val (val
);
292 ptr
= (void *) (_Unwind_Internal_Ptr
) context
->reg
[index
];
294 if (size
== sizeof(_Unwind_Ptr
))
295 * (_Unwind_Ptr
*) ptr
= val
;
298 gcc_assert (size
== sizeof(_Unwind_Word
));
299 * (_Unwind_Word
*) ptr
= val
;
303 /* Get the pointer to a register INDEX as saved in CONTEXT. */
306 _Unwind_GetGRPtr (struct _Unwind_Context
*context
, int index
)
308 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
309 if (_Unwind_IsExtendedContext (context
) && context
->by_value
[index
])
310 return &context
->reg
[index
];
311 return (void *) (_Unwind_Internal_Ptr
) context
->reg
[index
];
314 /* Set the pointer to a register INDEX as saved in CONTEXT. */
317 _Unwind_SetGRPtr (struct _Unwind_Context
*context
, int index
, void *p
)
319 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
320 if (_Unwind_IsExtendedContext (context
))
321 context
->by_value
[index
] = 0;
322 context
->reg
[index
] = (_Unwind_Context_Reg_Val
) (_Unwind_Internal_Ptr
) p
;
325 /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
328 _Unwind_SetGRValue (struct _Unwind_Context
*context
, int index
,
331 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
332 gcc_assert (index
< (int) sizeof(dwarf_reg_size_table
));
333 /* Return column size may be smaller than _Unwind_Context_Reg_Val. */
334 gcc_assert (dwarf_reg_size_table
[index
] <= sizeof (_Unwind_Context_Reg_Val
));
336 context
->by_value
[index
] = 1;
337 context
->reg
[index
] = _Unwind_Get_Unwind_Context_Reg_Val (val
);
340 /* Return nonzero if register INDEX is stored by value rather than
344 _Unwind_GRByValue (struct _Unwind_Context
*context
, int index
)
346 index
= DWARF_REG_TO_UNWIND_COLUMN (index
);
347 return context
->by_value
[index
];
350 /* Retrieve the return address for CONTEXT. */
353 _Unwind_GetIP (struct _Unwind_Context
*context
)
355 return (_Unwind_Ptr
) context
->ra
;
358 /* Retrieve the return address and flag whether that IP is before
359 or after first not yet fully executed instruction. */
362 _Unwind_GetIPInfo (struct _Unwind_Context
*context
, int *ip_before_insn
)
364 *ip_before_insn
= _Unwind_IsSignalFrame (context
);
365 return (_Unwind_Ptr
) context
->ra
;
368 /* Overwrite the return address for CONTEXT with VAL. */
371 _Unwind_SetIP (struct _Unwind_Context
*context
, _Unwind_Ptr val
)
373 context
->ra
= (void *) val
;
377 _Unwind_GetLanguageSpecificData (struct _Unwind_Context
*context
)
379 return context
->lsda
;
383 _Unwind_GetRegionStart (struct _Unwind_Context
*context
)
385 return (_Unwind_Ptr
) context
->bases
.func
;
389 _Unwind_FindEnclosingFunction (void *pc
)
391 struct dwarf_eh_bases bases
;
392 const struct dwarf_fde
*fde
= _Unwind_Find_FDE (pc
-1, &bases
);
401 _Unwind_GetDataRelBase (struct _Unwind_Context
*context
)
403 return (_Unwind_Ptr
) context
->bases
.dbase
;
407 _Unwind_GetTextRelBase (struct _Unwind_Context
*context
)
409 return (_Unwind_Ptr
) context
->bases
.tbase
;
413 #include "md-unwind-support.h"
415 /* Extract any interesting information from the CIE for the translation
416 unit F belongs to. Return a pointer to the byte after the augmentation,
417 or NULL if we encountered an undecipherable augmentation. */
419 static const unsigned char *
420 extract_cie_info (const struct dwarf_cie
*cie
, struct _Unwind_Context
*context
,
421 _Unwind_FrameState
*fs
)
423 const unsigned char *aug
= cie
->augmentation
;
424 const unsigned char *p
= aug
+ strlen ((const char *)aug
) + 1;
425 const unsigned char *ret
= NULL
;
429 /* g++ v2 "eh" has pointer immediately following augmentation string,
430 so it must be handled first. */
431 if (aug
[0] == 'e' && aug
[1] == 'h')
433 fs
->eh_ptr
= read_pointer (p
);
434 p
+= sizeof (void *);
438 /* After the augmentation resp. pointer for "eh" augmentation
439 follows for CIE version >= 4 address size byte and
440 segment size byte. */
441 if (__builtin_expect (cie
->version
>= 4, 0))
443 if (p
[0] != sizeof (void *) || p
[1] != 0)
447 /* Immediately following this are the code and
448 data alignment and return address column. */
449 p
= read_uleb128 (p
, &utmp
);
450 fs
->code_align
= (_Unwind_Word
)utmp
;
451 p
= read_sleb128 (p
, &stmp
);
452 fs
->data_align
= (_Unwind_Sword
)stmp
;
453 if (cie
->version
== 1)
454 fs
->retaddr_column
= *p
++;
457 p
= read_uleb128 (p
, &utmp
);
458 fs
->retaddr_column
= (_Unwind_Word
)utmp
;
460 fs
->lsda_encoding
= DW_EH_PE_omit
;
462 /* If the augmentation starts with 'z', then a uleb128 immediately
463 follows containing the length of the augmentation field following
467 p
= read_uleb128 (p
, &utmp
);
474 /* Iterate over recognized augmentation subsequences. */
477 /* "L" indicates a byte showing how the LSDA pointer is encoded. */
480 fs
->lsda_encoding
= *p
++;
484 /* "R" indicates a byte indicating how FDE addresses are encoded. */
485 else if (aug
[0] == 'R')
487 fs
->fde_encoding
= *p
++;
491 /* "P" indicates a personality routine in the CIE augmentation. */
492 else if (aug
[0] == 'P')
494 _Unwind_Ptr personality
;
496 p
= read_encoded_value (context
, *p
, p
+ 1, &personality
);
497 fs
->personality
= (_Unwind_Personality_Fn
) personality
;
501 /* "S" indicates a signal frame. */
502 else if (aug
[0] == 'S')
504 fs
->signal_frame
= 1;
507 /* aarch64 B-key pointer authentication. */
508 else if (aug
[0] == 'B')
513 /* Otherwise we have an unknown augmentation string.
514 Bail unless we saw a 'z' prefix. */
519 return ret
? ret
: p
;
523 /* Decode a DW_OP stack program. Return the top of stack. Push INITIAL
524 onto the stack to start. */
527 execute_stack_op (const unsigned char *op_ptr
, const unsigned char *op_end
,
528 struct _Unwind_Context
*context
, _Unwind_Word initial
)
530 _Unwind_Word stack
[64]; /* ??? Assume this is enough. */
536 while (op_ptr
< op_end
)
538 enum dwarf_location_atom op
= *op_ptr
++;
540 _uleb128_t reg
, utmp
;
541 _sleb128_t offset
, stmp
;
577 result
= op
- DW_OP_lit0
;
581 result
= (_Unwind_Word
) (_Unwind_Ptr
) read_pointer (op_ptr
);
582 op_ptr
+= sizeof (void *);
585 case DW_OP_GNU_encoded_addr
:
588 op_ptr
= read_encoded_value (context
, *op_ptr
, op_ptr
+1, &presult
);
594 result
= read_1u (op_ptr
);
598 result
= read_1s (op_ptr
);
602 result
= read_2u (op_ptr
);
606 result
= read_2s (op_ptr
);
610 result
= read_4u (op_ptr
);
614 result
= read_4s (op_ptr
);
618 result
= read_8u (op_ptr
);
622 result
= read_8s (op_ptr
);
626 op_ptr
= read_uleb128 (op_ptr
, &utmp
);
627 result
= (_Unwind_Word
)utmp
;
630 op_ptr
= read_sleb128 (op_ptr
, &stmp
);
631 result
= (_Unwind_Sword
)stmp
;
666 result
= _Unwind_GetGR (context
, op
- DW_OP_reg0
);
669 op_ptr
= read_uleb128 (op_ptr
, ®
);
670 result
= _Unwind_GetGR (context
, reg
);
705 op_ptr
= read_sleb128 (op_ptr
, &offset
);
706 result
= _Unwind_GetGR (context
, op
- DW_OP_breg0
) + offset
;
709 op_ptr
= read_uleb128 (op_ptr
, ®
);
710 op_ptr
= read_sleb128 (op_ptr
, &offset
);
711 result
= _Unwind_GetGR (context
, reg
) + (_Unwind_Word
)offset
;
715 gcc_assert (stack_elt
);
716 result
= stack
[stack_elt
- 1];
720 gcc_assert (stack_elt
);
726 gcc_assert (offset
< stack_elt
- 1);
727 result
= stack
[stack_elt
- 1 - offset
];
731 gcc_assert (stack_elt
>= 2);
732 result
= stack
[stack_elt
- 2];
738 gcc_assert (stack_elt
>= 2);
739 t
= stack
[stack_elt
- 1];
740 stack
[stack_elt
- 1] = stack
[stack_elt
- 2];
741 stack
[stack_elt
- 2] = t
;
747 _Unwind_Word t1
, t2
, t3
;
749 gcc_assert (stack_elt
>= 3);
750 t1
= stack
[stack_elt
- 1];
751 t2
= stack
[stack_elt
- 2];
752 t3
= stack
[stack_elt
- 3];
753 stack
[stack_elt
- 1] = t2
;
754 stack
[stack_elt
- 2] = t3
;
755 stack
[stack_elt
- 3] = t1
;
760 case DW_OP_deref_size
:
764 case DW_OP_plus_uconst
:
765 /* Unary operations. */
766 gcc_assert (stack_elt
);
769 result
= stack
[stack_elt
];
775 void *ptr
= (void *) (_Unwind_Ptr
) result
;
776 result
= (_Unwind_Ptr
) read_pointer (ptr
);
780 case DW_OP_deref_size
:
782 void *ptr
= (void *) (_Unwind_Ptr
) result
;
786 result
= read_1u (ptr
);
789 result
= read_2u (ptr
);
792 result
= read_4u (ptr
);
795 result
= read_8u (ptr
);
804 if ((_Unwind_Sword
) result
< 0)
813 case DW_OP_plus_uconst
:
814 op_ptr
= read_uleb128 (op_ptr
, &utmp
);
815 result
+= (_Unwind_Word
)utmp
;
841 /* Binary operations. */
842 _Unwind_Word first
, second
;
843 gcc_assert (stack_elt
>= 2);
846 second
= stack
[stack_elt
];
847 first
= stack
[stack_elt
+ 1];
852 result
= second
& first
;
855 result
= (_Unwind_Sword
) second
/ (_Unwind_Sword
) first
;
858 result
= second
- first
;
861 result
= second
% first
;
864 result
= second
* first
;
867 result
= second
| first
;
870 result
= second
+ first
;
873 result
= second
<< first
;
876 result
= second
>> first
;
879 result
= (_Unwind_Sword
) second
>> first
;
882 result
= second
^ first
;
885 result
= (_Unwind_Sword
) second
<= (_Unwind_Sword
) first
;
888 result
= (_Unwind_Sword
) second
>= (_Unwind_Sword
) first
;
891 result
= (_Unwind_Sword
) second
== (_Unwind_Sword
) first
;
894 result
= (_Unwind_Sword
) second
< (_Unwind_Sword
) first
;
897 result
= (_Unwind_Sword
) second
> (_Unwind_Sword
) first
;
900 result
= (_Unwind_Sword
) second
!= (_Unwind_Sword
) first
;
910 offset
= read_2s (op_ptr
);
916 gcc_assert (stack_elt
);
919 offset
= read_2s (op_ptr
);
921 if (stack
[stack_elt
] != 0)
932 /* Most things push a result value. */
933 gcc_assert ((size_t) stack_elt
< sizeof(stack
)/sizeof(*stack
));
934 stack
[stack_elt
++] = result
;
938 /* We were executing this program to get a value. It should be
940 gcc_assert (stack_elt
);
942 return stack
[stack_elt
];
946 /* Decode DWARF 2 call frame information. Takes pointers the
947 instruction sequence to decode, current register information and
948 CIE info, and the PC range to evaluate. */
951 execute_cfa_program (const unsigned char *insn_ptr
,
952 const unsigned char *insn_end
,
953 struct _Unwind_Context
*context
,
954 _Unwind_FrameState
*fs
)
956 struct frame_state_reg_info
*unused_rs
= NULL
;
958 /* Don't allow remember/restore between CIE and FDE programs. */
959 fs
->regs
.prev
= NULL
;
961 /* The comparison with the return address uses < rather than <= because
962 we are only interested in the effects of code before the call; for a
963 noreturn function, the return address may point to unrelated code with
964 a different stack configuration that we are not interested in. We
965 assume that the call itself is unwind info-neutral; if not, or if
966 there are delay instructions that adjust the stack, these must be
967 reflected at the point immediately before the call insn.
968 In signal frames, return address is after last completed instruction,
969 so we add 1 to return address to make the comparison <=. */
970 while (insn_ptr
< insn_end
971 && fs
->pc
< context
->ra
+ _Unwind_IsSignalFrame (context
))
973 unsigned char insn
= *insn_ptr
++;
974 _uleb128_t reg
, utmp
;
975 _sleb128_t offset
, stmp
;
977 if ((insn
& 0xc0) == DW_CFA_advance_loc
)
978 fs
->pc
+= (insn
& 0x3f) * fs
->code_align
;
979 else if ((insn
& 0xc0) == DW_CFA_offset
)
982 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
983 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
984 reg
= DWARF_REG_TO_UNWIND_COLUMN (reg
);
985 if (UNWIND_COLUMN_IN_RANGE (reg
))
987 fs
->regs
.how
[reg
] = REG_SAVED_OFFSET
;
988 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
991 else if ((insn
& 0xc0) == DW_CFA_restore
)
994 reg
= DWARF_REG_TO_UNWIND_COLUMN (reg
);
995 if (UNWIND_COLUMN_IN_RANGE (reg
))
996 fs
->regs
.how
[reg
] = REG_UNSAVED
;
1000 case DW_CFA_set_loc
:
1004 insn_ptr
= read_encoded_value (context
, fs
->fde_encoding
,
1006 fs
->pc
= (void *) pc
;
1010 case DW_CFA_advance_loc1
:
1011 fs
->pc
+= read_1u (insn_ptr
) * fs
->code_align
;
1014 case DW_CFA_advance_loc2
:
1015 fs
->pc
+= read_2u (insn_ptr
) * fs
->code_align
;
1018 case DW_CFA_advance_loc4
:
1019 fs
->pc
+= read_4u (insn_ptr
) * fs
->code_align
;
1023 case DW_CFA_offset_extended
:
1024 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1025 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1026 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
1027 reg
= DWARF_REG_TO_UNWIND_COLUMN (reg
);
1028 if (UNWIND_COLUMN_IN_RANGE (reg
))
1030 fs
->regs
.how
[reg
] = REG_SAVED_OFFSET
;
1031 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
1035 case DW_CFA_restore_extended
:
1036 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1037 /* FIXME, this is wrong; the CIE might have said that the
1038 register was saved somewhere. */
1039 reg
= DWARF_REG_TO_UNWIND_COLUMN (reg
);
1040 if (UNWIND_COLUMN_IN_RANGE (reg
))
1041 fs
->regs
.how
[reg
] = REG_UNSAVED
;
1044 case DW_CFA_same_value
:
1045 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1046 reg
= DWARF_REG_TO_UNWIND_COLUMN (reg
);
1047 if (UNWIND_COLUMN_IN_RANGE (reg
))
1048 fs
->regs
.how
[reg
] = REG_UNSAVED
;
1051 case DW_CFA_undefined
:
1052 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1053 reg
= DWARF_REG_TO_UNWIND_COLUMN (reg
);
1054 if (UNWIND_COLUMN_IN_RANGE (reg
))
1055 fs
->regs
.how
[reg
] = REG_UNDEFINED
;
1061 case DW_CFA_register
:
1064 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1065 insn_ptr
= read_uleb128 (insn_ptr
, ®2
);
1066 reg
= DWARF_REG_TO_UNWIND_COLUMN (reg
);
1067 if (UNWIND_COLUMN_IN_RANGE (reg
))
1069 fs
->regs
.how
[reg
] = REG_SAVED_REG
;
1070 fs
->regs
.reg
[reg
].loc
.reg
= (_Unwind_Word
)reg2
;
1075 case DW_CFA_remember_state
:
1077 struct frame_state_reg_info
*new_rs
;
1081 unused_rs
= unused_rs
->prev
;
1084 new_rs
= alloca (sizeof (struct frame_state_reg_info
));
1087 fs
->regs
.prev
= new_rs
;
1091 case DW_CFA_restore_state
:
1093 struct frame_state_reg_info
*old_rs
= fs
->regs
.prev
;
1095 old_rs
->prev
= unused_rs
;
1100 case DW_CFA_def_cfa
:
1101 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1102 fs
->regs
.cfa_reg
= (_Unwind_Word
)utmp
;
1103 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1104 fs
->regs
.cfa_offset
= (_Unwind_Word
)utmp
;
1105 fs
->regs
.cfa_how
= CFA_REG_OFFSET
;
1108 case DW_CFA_def_cfa_register
:
1109 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1110 fs
->regs
.cfa_reg
= (_Unwind_Word
)utmp
;
1111 fs
->regs
.cfa_how
= CFA_REG_OFFSET
;
1114 case DW_CFA_def_cfa_offset
:
1115 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1116 fs
->regs
.cfa_offset
= utmp
;
1117 /* cfa_how deliberately not set. */
1120 case DW_CFA_def_cfa_expression
:
1121 fs
->regs
.cfa_exp
= insn_ptr
;
1122 fs
->regs
.cfa_how
= CFA_EXP
;
1123 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1127 case DW_CFA_expression
:
1128 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1129 reg
= DWARF_REG_TO_UNWIND_COLUMN (reg
);
1130 if (UNWIND_COLUMN_IN_RANGE (reg
))
1132 fs
->regs
.how
[reg
] = REG_SAVED_EXP
;
1133 fs
->regs
.reg
[reg
].loc
.exp
= insn_ptr
;
1135 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1140 case DW_CFA_offset_extended_sf
:
1141 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1142 insn_ptr
= read_sleb128 (insn_ptr
, &stmp
);
1143 offset
= stmp
* fs
->data_align
;
1144 reg
= DWARF_REG_TO_UNWIND_COLUMN (reg
);
1145 if (UNWIND_COLUMN_IN_RANGE (reg
))
1147 fs
->regs
.how
[reg
] = REG_SAVED_OFFSET
;
1148 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
1152 case DW_CFA_def_cfa_sf
:
1153 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1154 fs
->regs
.cfa_reg
= (_Unwind_Word
)utmp
;
1155 insn_ptr
= read_sleb128 (insn_ptr
, &stmp
);
1156 fs
->regs
.cfa_offset
= (_Unwind_Sword
)stmp
;
1157 fs
->regs
.cfa_how
= CFA_REG_OFFSET
;
1158 fs
->regs
.cfa_offset
*= fs
->data_align
;
1161 case DW_CFA_def_cfa_offset_sf
:
1162 insn_ptr
= read_sleb128 (insn_ptr
, &stmp
);
1163 fs
->regs
.cfa_offset
= (_Unwind_Sword
)stmp
;
1164 fs
->regs
.cfa_offset
*= fs
->data_align
;
1165 /* cfa_how deliberately not set. */
1168 case DW_CFA_val_offset
:
1169 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1170 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1171 offset
= (_Unwind_Sword
) utmp
* fs
->data_align
;
1172 reg
= DWARF_REG_TO_UNWIND_COLUMN (reg
);
1173 if (UNWIND_COLUMN_IN_RANGE (reg
))
1175 fs
->regs
.how
[reg
] = REG_SAVED_VAL_OFFSET
;
1176 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
1180 case DW_CFA_val_offset_sf
:
1181 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1182 insn_ptr
= read_sleb128 (insn_ptr
, &stmp
);
1183 offset
= stmp
* fs
->data_align
;
1184 reg
= DWARF_REG_TO_UNWIND_COLUMN (reg
);
1185 if (UNWIND_COLUMN_IN_RANGE (reg
))
1187 fs
->regs
.how
[reg
] = REG_SAVED_VAL_OFFSET
;
1188 fs
->regs
.reg
[reg
].loc
.offset
= offset
;
1192 case DW_CFA_val_expression
:
1193 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1194 reg
= DWARF_REG_TO_UNWIND_COLUMN (reg
);
1195 if (UNWIND_COLUMN_IN_RANGE (reg
))
1197 fs
->regs
.how
[reg
] = REG_SAVED_VAL_EXP
;
1198 fs
->regs
.reg
[reg
].loc
.exp
= insn_ptr
;
1200 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1204 case DW_CFA_GNU_window_save
:
1205 #if defined (__aarch64__) && !defined (__ILP32__)
1206 /* This CFA is multiplexed with Sparc. On AArch64 it's used to toggle
1207 return address signing status. */
1208 reg
= DWARF_REGNUM_AARCH64_RA_STATE
;
1209 gcc_assert (fs
->regs
.how
[reg
] == REG_UNSAVED
);
1210 fs
->regs
.reg
[reg
].loc
.offset
^= 1;
1212 /* ??? Hardcoded for SPARC register window configuration. */
1213 if (__LIBGCC_DWARF_FRAME_REGISTERS__
>= 32)
1214 for (reg
= 16; reg
< 32; ++reg
)
1216 fs
->regs
.how
[reg
] = REG_SAVED_OFFSET
;
1217 fs
->regs
.reg
[reg
].loc
.offset
= (reg
- 16) * sizeof (void *);
1222 case DW_CFA_GNU_args_size
:
1223 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1224 context
->args_size
= (_Unwind_Word
)utmp
;
1227 case DW_CFA_GNU_negative_offset_extended
:
1228 /* Obsoleted by DW_CFA_offset_extended_sf, but used by
1229 older PowerPC code. */
1230 insn_ptr
= read_uleb128 (insn_ptr
, ®
);
1231 insn_ptr
= read_uleb128 (insn_ptr
, &utmp
);
1232 offset
= (_Unwind_Word
) utmp
* fs
->data_align
;
1233 reg
= DWARF_REG_TO_UNWIND_COLUMN (reg
);
1234 if (UNWIND_COLUMN_IN_RANGE (reg
))
1236 fs
->regs
.how
[reg
] = REG_SAVED_OFFSET
;
1237 fs
->regs
.reg
[reg
].loc
.offset
= -offset
;
1247 /* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
1248 its caller and decode it into FS. This function also sets the
1249 args_size and lsda members of CONTEXT, as they are really information
1250 about the caller's frame. */
1252 static _Unwind_Reason_Code
1253 uw_frame_state_for (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1255 const struct dwarf_fde
*fde
;
1256 const struct dwarf_cie
*cie
;
1257 const unsigned char *aug
, *insn
, *end
;
1259 memset (&fs
->regs
.how
[0], 0,
1260 sizeof (*fs
) - offsetof (_Unwind_FrameState
, regs
.how
[0]));
1261 context
->args_size
= 0;
1264 if (context
->ra
== 0)
1265 return _URC_END_OF_STACK
;
1267 fde
= _Unwind_Find_FDE (context
->ra
+ _Unwind_IsSignalFrame (context
) - 1,
1271 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1272 /* Couldn't find frame unwind info for this function. Try a
1273 target-specific fallback mechanism. This will necessarily
1274 not provide a personality routine or LSDA. */
1275 return MD_FALLBACK_FRAME_STATE_FOR (context
, fs
);
1277 return _URC_END_OF_STACK
;
1281 fs
->pc
= context
->bases
.func
;
1283 cie
= get_cie (fde
);
1284 insn
= extract_cie_info (cie
, context
, fs
);
1286 /* CIE contained unknown augmentation. */
1287 return _URC_FATAL_PHASE1_ERROR
;
1289 /* First decode all the insns in the CIE. */
1290 end
= (const unsigned char *) next_fde ((const struct dwarf_fde
*) cie
);
1291 execute_cfa_program (insn
, end
, context
, fs
);
1293 /* Locate augmentation for the fde. */
1294 aug
= (const unsigned char *) fde
+ sizeof (*fde
);
1295 aug
+= 2 * size_of_encoded_value (fs
->fde_encoding
);
1300 aug
= read_uleb128 (aug
, &i
);
1303 if (fs
->lsda_encoding
!= DW_EH_PE_omit
)
1307 aug
= read_encoded_value (context
, fs
->lsda_encoding
, aug
, &lsda
);
1308 context
->lsda
= (void *) lsda
;
1311 /* Then the insns in the FDE up to our target PC. */
1314 end
= (const unsigned char *) next_fde (fde
);
1315 execute_cfa_program (insn
, end
, context
, fs
);
1317 return _URC_NO_REASON
;
1320 typedef struct frame_state
1326 long reg_or_offset
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1327 unsigned short cfa_reg
;
1328 unsigned short retaddr_column
;
1329 char saved
[PRE_GCC3_DWARF_FRAME_REGISTERS
+1];
1332 struct frame_state
* __frame_state_for (void *, struct frame_state
*);
1334 /* Called from pre-G++ 3.0 __throw to find the registers to restore for
1335 a given PC_TARGET. The caller should allocate a local variable of
1336 `struct frame_state' and pass its address to STATE_IN. */
1338 struct frame_state
*
1339 __frame_state_for (void *pc_target
, struct frame_state
*state_in
)
1341 struct _Unwind_Context context
;
1342 _Unwind_FrameState fs
;
1345 memset (&context
, 0, sizeof (struct _Unwind_Context
));
1346 if (!ASSUME_EXTENDED_UNWIND_CONTEXT
)
1347 context
.flags
= EXTENDED_CONTEXT_BIT
;
1348 context
.ra
= pc_target
+ 1;
1350 if (uw_frame_state_for (&context
, &fs
) != _URC_NO_REASON
)
1353 /* We have no way to pass a location expression for the CFA to our
1354 caller. It wouldn't understand it anyway. */
1355 if (fs
.regs
.cfa_how
== CFA_EXP
)
1358 for (reg
= 0; reg
< PRE_GCC3_DWARF_FRAME_REGISTERS
+ 1; reg
++)
1360 state_in
->saved
[reg
] = fs
.regs
.how
[reg
];
1361 switch (state_in
->saved
[reg
])
1364 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.reg
;
1366 case REG_SAVED_OFFSET
:
1367 state_in
->reg_or_offset
[reg
] = fs
.regs
.reg
[reg
].loc
.offset
;
1370 state_in
->reg_or_offset
[reg
] = 0;
1375 state_in
->cfa_offset
= fs
.regs
.cfa_offset
;
1376 state_in
->cfa_reg
= fs
.regs
.cfa_reg
;
1377 state_in
->retaddr_column
= fs
.retaddr_column
;
1378 state_in
->args_size
= context
.args_size
;
1379 state_in
->eh_ptr
= fs
.eh_ptr
;
1384 typedef union { _Unwind_Ptr ptr
; _Unwind_Word word
; } _Unwind_SpTmp
;
1387 _Unwind_SetSpColumn (struct _Unwind_Context
*context
, void *cfa
,
1388 _Unwind_SpTmp
*tmp_sp
)
1390 int size
= dwarf_reg_size_table
[__builtin_dwarf_sp_column ()];
1392 if (size
== sizeof(_Unwind_Ptr
))
1393 tmp_sp
->ptr
= (_Unwind_Ptr
) cfa
;
1396 gcc_assert (size
== sizeof(_Unwind_Word
));
1397 tmp_sp
->word
= (_Unwind_Ptr
) cfa
;
1399 _Unwind_SetGRPtr (context
, __builtin_dwarf_sp_column (), tmp_sp
);
1403 uw_update_context_1 (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1405 struct _Unwind_Context orig_context
= *context
;
1409 #ifdef __LIBGCC_EH_RETURN_STACKADJ_RTX__
1410 /* Special handling here: Many machines do not use a frame pointer,
1411 and track the CFA only through offsets from the stack pointer from
1412 one frame to the next. In this case, the stack pointer is never
1413 stored, so it has no saved address in the context. What we do
1414 have is the CFA from the previous stack frame.
1416 In very special situations (such as unwind info for signal return),
1417 there may be location expressions that use the stack pointer as well.
1419 Do this conditionally for one frame. This allows the unwind info
1420 for one frame to save a copy of the stack pointer from the previous
1421 frame, and be able to use much easier CFA mechanisms to do it.
1422 Always zap the saved stack pointer value for the next frame; carrying
1423 the value over from one frame to another doesn't make sense. */
1425 _Unwind_SpTmp tmp_sp
;
1427 if (!_Unwind_GetGRPtr (&orig_context
, __builtin_dwarf_sp_column ()))
1428 _Unwind_SetSpColumn (&orig_context
, context
->cfa
, &tmp_sp
);
1429 _Unwind_SetGRPtr (context
, __builtin_dwarf_sp_column (), NULL
);
1432 /* Compute this frame's CFA. */
1433 switch (fs
->regs
.cfa_how
)
1435 case CFA_REG_OFFSET
:
1436 cfa
= _Unwind_GetPtr (&orig_context
, fs
->regs
.cfa_reg
);
1437 cfa
+= fs
->regs
.cfa_offset
;
1442 const unsigned char *exp
= fs
->regs
.cfa_exp
;
1445 exp
= read_uleb128 (exp
, &len
);
1446 cfa
= (void *) (_Unwind_Ptr
)
1447 execute_stack_op (exp
, exp
+ len
, &orig_context
, 0);
1456 /* Compute the addresses of all registers saved in this frame. */
1457 for (i
= 0; i
< __LIBGCC_DWARF_FRAME_REGISTERS__
+ 1; ++i
)
1458 switch (fs
->regs
.how
[i
])
1464 case REG_SAVED_OFFSET
:
1465 _Unwind_SetGRPtr (context
, i
,
1466 (void *) (cfa
+ fs
->regs
.reg
[i
].loc
.offset
));
1470 if (_Unwind_GRByValue (&orig_context
, fs
->regs
.reg
[i
].loc
.reg
))
1471 _Unwind_SetGRValue (context
, i
,
1472 _Unwind_GetGR (&orig_context
,
1473 fs
->regs
.reg
[i
].loc
.reg
));
1475 _Unwind_SetGRPtr (context
, i
,
1476 _Unwind_GetGRPtr (&orig_context
,
1477 fs
->regs
.reg
[i
].loc
.reg
));
1482 const unsigned char *exp
= fs
->regs
.reg
[i
].loc
.exp
;
1486 exp
= read_uleb128 (exp
, &len
);
1487 val
= execute_stack_op (exp
, exp
+ len
, &orig_context
,
1489 _Unwind_SetGRPtr (context
, i
, (void *) val
);
1493 case REG_SAVED_VAL_OFFSET
:
1494 _Unwind_SetGRValue (context
, i
,
1495 (_Unwind_Internal_Ptr
)
1496 (cfa
+ fs
->regs
.reg
[i
].loc
.offset
));
1499 case REG_SAVED_VAL_EXP
:
1501 const unsigned char *exp
= fs
->regs
.reg
[i
].loc
.exp
;
1505 exp
= read_uleb128 (exp
, &len
);
1506 val
= execute_stack_op (exp
, exp
+ len
, &orig_context
,
1508 _Unwind_SetGRValue (context
, i
, val
);
1513 _Unwind_SetSignalFrame (context
, fs
->signal_frame
);
1515 #ifdef MD_FROB_UPDATE_CONTEXT
1516 MD_FROB_UPDATE_CONTEXT (context
, fs
);
1520 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
1521 of its caller. Update CONTEXT to refer to the caller as well. Note
1522 that the args_size and lsda members are not updated here, but later in
1523 uw_frame_state_for. */
1526 uw_update_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1528 uw_update_context_1 (context
, fs
);
1530 /* In general this unwinder doesn't make any distinction between
1531 undefined and same_value rule. Call-saved registers are assumed
1532 to have same_value rule by default and explicit undefined
1533 rule is handled like same_value. The only exception is
1534 DW_CFA_undefined on retaddr_column which is supposed to
1535 mark outermost frame in DWARF 3. */
1536 if (fs
->regs
.how
[DWARF_REG_TO_UNWIND_COLUMN (fs
->retaddr_column
)]
1538 /* uw_frame_state_for uses context->ra == 0 check to find outermost
1543 /* Compute the return address now, since the return address column
1544 can change from frame to frame. */
1546 #ifdef MD_DEMANGLE_RETURN_ADDR
1547 _Unwind_Word ra
= _Unwind_GetGR (context
, fs
->retaddr_column
);
1548 ret_addr
= MD_DEMANGLE_RETURN_ADDR (context
, fs
, ra
);
1550 ret_addr
= _Unwind_GetPtr (context
, fs
->retaddr_column
);
1552 context
->ra
= __builtin_extract_return_addr (ret_addr
);
1557 uw_advance_context (struct _Unwind_Context
*context
, _Unwind_FrameState
*fs
)
1559 uw_update_context (context
, fs
);
1562 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
1563 level will be the return address and the CFA. */
1565 #define uw_init_context(CONTEXT) \
1568 /* Do any necessary initialization to access arbitrary stack frames. \
1569 On the SPARC, this means flushing the register windows. */ \
1570 __builtin_unwind_init (); \
1571 uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \
1572 __builtin_return_address (0)); \
1577 init_dwarf_reg_size_table (void)
1579 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table
);
1582 static void __attribute__((noinline
))
1583 uw_init_context_1 (struct _Unwind_Context
*context
,
1584 void *outer_cfa
, void *outer_ra
)
1586 void *ra
= __builtin_extract_return_addr (__builtin_return_address (0));
1587 _Unwind_FrameState fs
;
1588 _Unwind_SpTmp sp_slot
;
1589 _Unwind_Reason_Code code
;
1591 memset (context
, 0, sizeof (struct _Unwind_Context
));
1593 if (!ASSUME_EXTENDED_UNWIND_CONTEXT
)
1594 context
->flags
= EXTENDED_CONTEXT_BIT
;
1596 code
= uw_frame_state_for (context
, &fs
);
1597 gcc_assert (code
== _URC_NO_REASON
);
1601 static __gthread_once_t once_regsizes
= __GTHREAD_ONCE_INIT
;
1602 if (__gthread_once (&once_regsizes
, init_dwarf_reg_size_table
) != 0
1603 && dwarf_reg_size_table
[0] == 0)
1604 init_dwarf_reg_size_table ();
1607 if (dwarf_reg_size_table
[0] == 0)
1608 init_dwarf_reg_size_table ();
1611 /* Force the frame state to use the known cfa value. */
1612 _Unwind_SetSpColumn (context
, outer_cfa
, &sp_slot
);
1613 fs
.regs
.cfa_how
= CFA_REG_OFFSET
;
1614 fs
.regs
.cfa_reg
= __builtin_dwarf_sp_column ();
1615 fs
.regs
.cfa_offset
= 0;
1617 uw_update_context_1 (context
, &fs
);
1619 /* If the return address column was saved in a register in the
1620 initialization context, then we can't see it in the given
1621 call frame data. So have the initialization context tell us. */
1622 context
->ra
= __builtin_extract_return_addr (outer_ra
);
1625 static void _Unwind_DebugHook (void *, void *)
1626 __attribute__ ((__noinline__
, __used__
, __noclone__
));
1628 /* This function is called during unwinding. It is intended as a hook
1629 for a debugger to intercept exceptions. CFA is the CFA of the
1630 target frame. HANDLER is the PC to which control will be
1633 _Unwind_DebugHook (void *cfa
__attribute__ ((__unused__
)),
1634 void *handler
__attribute__ ((__unused__
)))
1636 /* We only want to use stap probes starting with v3. Earlier
1637 versions added too much startup cost. */
1638 #if defined (HAVE_SYS_SDT_H) && defined (STAP_PROBE2) && _SDT_NOTE_TYPE >= 3
1639 STAP_PROBE2 (libgcc
, unwind
, cfa
, handler
);
1645 /* Install TARGET into CURRENT so that we can return to it. This is a
1646 macro because __builtin_eh_return must be invoked in the context of
1647 our caller. FRAMES is a number of frames to be unwind.
1648 _Unwind_Frames_Extra is a macro to do additional work during unwinding
1649 if needed, for example shadow stack pointer adjustment for Intel CET
1652 #define uw_install_context(CURRENT, TARGET, FRAMES) \
1655 long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
1656 void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
1657 _Unwind_DebugHook ((TARGET)->cfa, handler); \
1658 _Unwind_Frames_Extra (FRAMES); \
1659 __builtin_eh_return (offset, handler); \
1664 uw_install_context_1 (struct _Unwind_Context
*current
,
1665 struct _Unwind_Context
*target
)
1668 _Unwind_SpTmp sp_slot
;
1670 /* If the target frame does not have a saved stack pointer,
1671 then set up the target's CFA. */
1672 if (!_Unwind_GetGRPtr (target
, __builtin_dwarf_sp_column ()))
1673 _Unwind_SetSpColumn (target
, target
->cfa
, &sp_slot
);
1675 for (i
= 0; i
< __LIBGCC_DWARF_FRAME_REGISTERS__
; ++i
)
1677 void *c
= (void *) (_Unwind_Internal_Ptr
) current
->reg
[i
];
1678 void *t
= (void *) (_Unwind_Internal_Ptr
)target
->reg
[i
];
1680 gcc_assert (current
->by_value
[i
] == 0);
1681 if (target
->by_value
[i
] && c
)
1685 if (dwarf_reg_size_table
[i
] == sizeof (_Unwind_Word
))
1687 w
= (_Unwind_Internal_Ptr
) t
;
1688 memcpy (c
, &w
, sizeof (_Unwind_Word
));
1692 gcc_assert (dwarf_reg_size_table
[i
] == sizeof (_Unwind_Ptr
));
1693 p
= (_Unwind_Internal_Ptr
) t
;
1694 memcpy (c
, &p
, sizeof (_Unwind_Ptr
));
1697 else if (t
&& c
&& t
!= c
)
1698 memcpy (c
, t
, dwarf_reg_size_table
[i
]);
1701 /* If the current frame doesn't have a saved stack pointer, then we
1702 need to rely on EH_RETURN_STACKADJ_RTX to get our target stack
1703 pointer value reloaded. */
1704 if (!_Unwind_GetGRPtr (current
, __builtin_dwarf_sp_column ()))
1708 target_cfa
= _Unwind_GetPtr (target
, __builtin_dwarf_sp_column ());
1710 /* We adjust SP by the difference between CURRENT and TARGET's CFA. */
1711 if (__LIBGCC_STACK_GROWS_DOWNWARD__
)
1712 return target_cfa
- current
->cfa
+ target
->args_size
;
1714 return current
->cfa
- target_cfa
- target
->args_size
;
1719 static inline _Unwind_Ptr
1720 uw_identify_context (struct _Unwind_Context
*context
)
1722 /* The CFA is not sufficient to disambiguate the context of a function
1723 interrupted by a signal before establishing its frame and the context
1724 of the signal itself. */
1725 if (__LIBGCC_STACK_GROWS_DOWNWARD__
)
1726 return _Unwind_GetCFA (context
) - _Unwind_IsSignalFrame (context
);
1728 return _Unwind_GetCFA (context
) + _Unwind_IsSignalFrame (context
);
1732 #include "unwind.inc"
1734 #if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
1735 alias (_Unwind_Backtrace
);
1736 alias (_Unwind_DeleteException
);
1737 alias (_Unwind_FindEnclosingFunction
);
1738 alias (_Unwind_ForcedUnwind
);
1739 alias (_Unwind_GetDataRelBase
);
1740 alias (_Unwind_GetTextRelBase
);
1741 alias (_Unwind_GetCFA
);
1742 alias (_Unwind_GetGR
);
1743 alias (_Unwind_GetIP
);
1744 alias (_Unwind_GetLanguageSpecificData
);
1745 alias (_Unwind_GetRegionStart
);
1746 alias (_Unwind_RaiseException
);
1747 alias (_Unwind_Resume
);
1748 alias (_Unwind_Resume_or_Rethrow
);
1749 alias (_Unwind_SetGR
);
1750 alias (_Unwind_SetIP
);
1753 #endif /* !USING_SJLJ_EXCEPTIONS */