| Index: gcc/gcc/unwind-dw2.c
|
| diff --git a/gcc/gcc/unwind-dw2.c b/gcc/gcc/unwind-dw2.c
|
| index 27c40b1892690805b4f68fbddcb489c67a3dc435..2b2836f9e06ebd96d0c9c917b34af360622c382c 100644
|
| --- a/gcc/gcc/unwind-dw2.c
|
| +++ b/gcc/gcc/unwind-dw2.c
|
| @@ -404,7 +404,7 @@ extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
|
| else if (aug[0] == 'P')
|
| {
|
| _Unwind_Ptr personality;
|
| -
|
| +
|
| p = read_encoded_value (context, *p, p + 1, &personality);
|
| fs->personality = (_Unwind_Personality_Fn) personality;
|
| aug += 1;
|
| @@ -672,7 +672,7 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
|
| /* Unary operations. */
|
| gcc_assert (stack_elt);
|
| stack_elt -= 1;
|
| -
|
| +
|
| result = stack[stack_elt];
|
|
|
| switch (op)
|
| @@ -749,7 +749,7 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
|
| _Unwind_Word first, second;
|
| gcc_assert (stack_elt >= 2);
|
| stack_elt -= 2;
|
| -
|
| +
|
| second = stack[stack_elt];
|
| first = stack[stack_elt + 1];
|
|
|
| @@ -822,7 +822,7 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
|
| case DW_OP_bra:
|
| gcc_assert (stack_elt);
|
| stack_elt -= 1;
|
| -
|
| +
|
| offset = read_2s (op_ptr);
|
| op_ptr += 2;
|
| if (stack[stack_elt] != 0)
|
| @@ -902,7 +902,7 @@ execute_cfa_program (const unsigned char *insn_ptr,
|
| case DW_CFA_set_loc:
|
| {
|
| _Unwind_Ptr pc;
|
| -
|
| +
|
| insn_ptr = read_encoded_value (context, fs->fde_encoding,
|
| insn_ptr, &pc);
|
| fs->pc = (void *) pc;
|
| @@ -1164,7 +1164,7 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
| if (fs->lsda_encoding != DW_EH_PE_omit)
|
| {
|
| _Unwind_Ptr lsda;
|
| -
|
| +
|
| aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda);
|
| context->lsda = (void *) lsda;
|
| }
|
| @@ -1248,7 +1248,7 @@ _Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
|
| _Unwind_SpTmp *tmp_sp)
|
| {
|
| int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
|
| -
|
| +
|
| if (size == sizeof(_Unwind_Ptr))
|
| tmp_sp->ptr = (_Unwind_Ptr) cfa;
|
| else
|
| @@ -1431,7 +1431,7 @@ init_dwarf_reg_size_table (void)
|
| __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
|
| }
|
|
|
| -static void
|
| +static void __attribute__((noinline))
|
| uw_init_context_1 (struct _Unwind_Context *context,
|
| void *outer_cfa, void *outer_ra)
|
| {
|
| @@ -1473,18 +1473,32 @@ uw_init_context_1 (struct _Unwind_Context *context,
|
| context->ra = __builtin_extract_return_addr (outer_ra);
|
| }
|
|
|
| +static void _Unwind_DebugHook (void *, void *)
|
| + __attribute__ ((__noinline__, __used__, __noclone__));
|
| +
|
| +/* This function is called during unwinding. It is intended as a hook
|
| + for a debugger to intercept exceptions. CFA is the CFA of the
|
| + target frame. HANDLER is the PC to which control will be
|
| + transferred. */
|
| +static void
|
| +_Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
|
| + void *handler __attribute__ ((__unused__)))
|
| +{
|
| + asm ("");
|
| +}
|
|
|
| /* Install TARGET into CURRENT so that we can return to it. This is a
|
| macro because __builtin_eh_return must be invoked in the context of
|
| our caller. */
|
|
|
| -#define uw_install_context(CURRENT, TARGET) \
|
| - do \
|
| - { \
|
| - long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
|
| - void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
|
| - __builtin_eh_return (offset, handler); \
|
| - } \
|
| +#define uw_install_context(CURRENT, TARGET) \
|
| + do \
|
| + { \
|
| + long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
|
| + void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
|
| + _Unwind_DebugHook ((TARGET)->cfa, handler); \
|
| + __builtin_eh_return (offset, handler); \
|
| + } \
|
| while (0)
|
|
|
| static long
|
| @@ -1546,7 +1560,13 @@ uw_install_context_1 (struct _Unwind_Context *current,
|
| static inline _Unwind_Ptr
|
| uw_identify_context (struct _Unwind_Context *context)
|
| {
|
| - return _Unwind_GetCFA (context);
|
| + /* The CFA is not sufficient to disambiguate the context of a function
|
| + interrupted by a signal before establishing its frame and the context
|
| + of the signal itself. */
|
| + if (STACK_GROWS_DOWNWARD)
|
| + return _Unwind_GetCFA (context) - _Unwind_IsSignalFrame (context);
|
| + else
|
| + return _Unwind_GetCFA (context) + _Unwind_IsSignalFrame (context);
|
| }
|
|
|
|
|
|
|