re PR other/26208 (Serious problem with unwinding through signal frames)
PR other/26208 * unwind-dw2.c (struct _Unwind_Context): Add signal_frame field. (extract_cie_info): Handle S flag in augmentation string. (execute_cfa_program): If context->signal_frame, execute also fs->pc == context->ra instructions. (uw_frame_state_for): If context->signal_frame, don't subtract one from context->ra to find FDE. (uw_update_context_1): Set context->signal_frame to fs->signal_frame. (_Unwind_GetIPInfo): New function. * unwind-dw2.h (_Unwind_FrameState): Add signal_frame field. * unwind-c.c (PERSONALITY_FUNCTION): Use _Unwind_GetIPInfo instead of _Unwind_GetIP. * unwind-sjlj.c (_Unwind_GetIPInfo): New function. * unwind-generic.h (_Unwind_GetIPInfo): New prototype. * unwind-compat.c (_Unwind_GetIPInfo): New function. * libgcc-std.ver (_Unwind_GetIPInfo): Export @@GCC_4.2.0. * config/ia64/unwind-ia64.c (_Unwind_GetIPInfo): New function. * config/arm/unwind-arm.h (_Unwind_GetIPInfo): Define. * config/i386/linux-unwind.h (x86_fallback_frame_state, x86_64_fallback_frame_state): Set fs->signal_frame. * config/rs6000/linux-unwind.h (ppc_fallback_frame_state): Likewise. (MD_FROB_UPDATE_CONTEXT): Define unconditionally. (frob_update_context): Likewise. Workaround missing S flag in Linux 2.6.12 - 2.6.16 kernel vDSOs. * config/s390/linux-unwind.h (s390_fallback_frame_state): Likewise. Remove the psw_addr + 1 hack. libjava/ * exception.cc (PERSONALITY_FUNCTION): Use _Unwind_GetIPInfo instead of _Unwind_GetIP. * include/i386-signal.h (MAKE_THROW_FRAME): Change into empty macro. (HANDLE_DIVIDE_OVERFLOW): Don't adjust _res->eip if falling through to throw. * include/x86_64-signal.h (MAKE_THROW_FRAME): Change into empty macro. * include/powerpc-signal.h (MAKE_THROW_FRAME): Change into empty macro. libstdc++-v3/ * libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Use _Unwind_GetIPInfo instead of _Unwind_GetIP. From-SVN: r111488
This commit is contained in:
committed by
Jakub Jelinek
parent
6df11ca1be
commit
754e45a867
@@ -1,7 +1,7 @@
|
||||
// i386-signal.h - Catch runtime signals and turn them into exceptions
|
||||
// on an i386 based Linux system.
|
||||
|
||||
/* Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation
|
||||
/* Copyright (C) 1998, 1999, 2001, 2002, 2006 Free Software Foundation
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
@@ -22,19 +22,7 @@ details. */
|
||||
#define SIGNAL_HANDLER(_name) \
|
||||
static void _name (int _dummy __attribute__ ((__unused__)))
|
||||
|
||||
#define MAKE_THROW_FRAME(_exception) \
|
||||
do \
|
||||
{ \
|
||||
void **_p = (void **)&_dummy; \
|
||||
volatile struct sigcontext_struct *_regs = (struct sigcontext_struct *)++_p; \
|
||||
\
|
||||
/* Advance the program counter so that it is after the start of the \
|
||||
instruction: the x86 exception handler expects \
|
||||
the PC to point to the instruction after a call. */ \
|
||||
_regs->eip += 2; \
|
||||
\
|
||||
} \
|
||||
while (0)
|
||||
#define MAKE_THROW_FRAME(_exception)
|
||||
|
||||
#define HANDLE_DIVIDE_OVERFLOW \
|
||||
do \
|
||||
@@ -91,14 +79,6 @@ do \
|
||||
_regs->eip = (unsigned long)_eip; \
|
||||
return; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Advance the program counter so that it is after the start \
|
||||
of the instruction: this is because the x86 exception \
|
||||
handler expects the PC to point to the instruction after a \
|
||||
call. */ \
|
||||
_regs->eip += 2; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// powerpc-signal.h - Catch runtime signals and turn them into exceptions
|
||||
// on a powerpc based Linux system.
|
||||
|
||||
/* Copyright (C) 2003 Free Software Foundation
|
||||
/* Copyright (C) 2003, 2006 Free Software Foundation
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
@@ -22,18 +22,12 @@ details. */
|
||||
#define SIGNAL_HANDLER(_name) \
|
||||
static void _name (int /* _signal */, struct sigcontext *_sc)
|
||||
|
||||
/* PPC either leaves PC pointing at a faulting instruction or the
|
||||
following instruction, depending on the signal. SEGV always does
|
||||
the former, so we adjust the saved PC to point to the following
|
||||
instruction. This is what the handler in libgcc expects. */
|
||||
/* MD_FALBACK_FRAME_STATE_FOR takes care of special casing PC
|
||||
before the faulting instruction, so we don't need to do anything
|
||||
here. */
|
||||
|
||||
#define MAKE_THROW_FRAME(_exception)
|
||||
|
||||
#define MAKE_THROW_FRAME(_exception) \
|
||||
do \
|
||||
{ \
|
||||
_sc->regs->nip += 4; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* For an explanation why we cannot simply use sigaction to
|
||||
install the handlers, see i386-signal.h. */
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// x86_64-signal.h - Catch runtime signals and turn them into exceptions
|
||||
// on an x86_64 based GNU/Linux system.
|
||||
|
||||
/* Copyright (C) 2003 Free Software Foundation
|
||||
/* Copyright (C) 2003, 2006 Free Software Foundation
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
@@ -34,16 +34,7 @@ extern "C"
|
||||
};
|
||||
}
|
||||
|
||||
#define MAKE_THROW_FRAME(_exception) \
|
||||
do \
|
||||
{ \
|
||||
/* Advance the program counter so that it is after the start of the \
|
||||
instruction: the x86_64 exception handler expects \
|
||||
the PC to point to the instruction after a call. */ \
|
||||
struct ucontext *_uc = (struct ucontext *)_p; \
|
||||
_uc->uc_mcontext.gregs[REG_RIP] += 2; \
|
||||
} \
|
||||
while (0)
|
||||
#define MAKE_THROW_FRAME(_exception)
|
||||
|
||||
#define RESTORE(name, syscall) RESTORE2 (name, syscall)
|
||||
#define RESTORE2(name, syscall) \
|
||||
|
||||
Reference in New Issue
Block a user