mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-13 21:01:29 +08:00
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:
parent
6df11ca1be
commit
754e45a867
@ -1,3 +1,33 @@
|
||||
2006-02-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
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.
|
||||
|
||||
2006-02-27 Daniel Berlin <dberlin@dberlin.org>
|
||||
|
||||
* tree-ssa-structalias.c (get_constraint_for): Move code to deal
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Header file for the ARM EABI unwinder
|
||||
Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
Contributed by Paul Brook
|
||||
|
||||
This file is free software; you can redistribute it and/or modify it
|
||||
@ -250,6 +250,9 @@ extern "C" {
|
||||
#define _Unwind_GetIP(context) \
|
||||
(_Unwind_GetGR (context, 15) & ~(_Unwind_Word)1)
|
||||
|
||||
#define _Unwind_GetIP(context, ip_before_insn) \
|
||||
(*ip_before_insn = 0, _Unwind_GetGR (context, 15) & ~(_Unwind_Word)1)
|
||||
|
||||
static inline void
|
||||
_Unwind_SetGR (_Unwind_Context *context, int regno, _Unwind_Word val)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* DWARF2 EH unwinding support for AMD x86-64 and x86.
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@ -100,6 +100,7 @@ x86_64_fallback_frame_state (struct _Unwind_Context *context,
|
||||
fs->regs.reg[16].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[16].loc.offset = (long)&sc->rip - new_cfa;
|
||||
fs->retaddr_column = 16;
|
||||
fs->signal_frame = 1;
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
@ -172,6 +173,7 @@ x86_fallback_frame_state (struct _Unwind_Context *context,
|
||||
fs->regs.reg[8].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[8].loc.offset = (long)&sc->REG_NAME(eip) - new_cfa;
|
||||
fs->retaddr_column = 8;
|
||||
fs->signal_frame = 1;
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
#endif /* not glibc 2.0 */
|
||||
|
@ -1704,6 +1704,13 @@ _Unwind_GetIP (struct _Unwind_Context *context)
|
||||
return context->rp;
|
||||
}
|
||||
|
||||
inline _Unwind_Ptr
|
||||
_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
|
||||
{
|
||||
*ip_before_insn = 0;
|
||||
return context->rp;
|
||||
}
|
||||
|
||||
/* Overwrite the return address for CONTEXT with VAL. */
|
||||
|
||||
inline void
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* DWARF2 EH unwinding support for PowerPC and PowerPC64 Linux.
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@ -89,26 +89,6 @@ struct gcc_ucontext
|
||||
|
||||
enum { SIGNAL_FRAMESIZE = 128 };
|
||||
|
||||
/* If the current unwind info (FS) does not contain explicit info
|
||||
saving R2, then we have to do a minor amount of code reading to
|
||||
figure out if it was saved. The big problem here is that the
|
||||
code that does the save/restore is generated by the linker, so
|
||||
we have no good way to determine at compile time what to do. */
|
||||
|
||||
#define MD_FROB_UPDATE_CONTEXT frob_update_context
|
||||
|
||||
static void
|
||||
frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
||||
{
|
||||
if (fs->regs.reg[2].how == REG_UNSAVED)
|
||||
{
|
||||
unsigned int *insn
|
||||
= (unsigned int *) _Unwind_GetGR (context, LINK_REGISTER_REGNUM);
|
||||
if (*insn == 0xE8410028)
|
||||
_Unwind_SetGRPtr (context, 2, context->cfa + 40);
|
||||
}
|
||||
}
|
||||
|
||||
/* If PC is at a sigreturn trampoline, return a pointer to the
|
||||
regs. Otherwise return NULL. */
|
||||
|
||||
@ -272,6 +252,7 @@ ppc_fallback_frame_state (struct _Unwind_Context *context,
|
||||
fs->regs.reg[ARG_POINTER_REGNUM].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[ARG_POINTER_REGNUM].loc.offset = (long) ®s->nip - new_cfa;
|
||||
fs->retaddr_column = ARG_POINTER_REGNUM;
|
||||
fs->signal_frame = 1;
|
||||
|
||||
if (hwcap == 0)
|
||||
{
|
||||
@ -322,3 +303,46 @@ ppc_fallback_frame_state (struct _Unwind_Context *context,
|
||||
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
#define MD_FROB_UPDATE_CONTEXT frob_update_context
|
||||
|
||||
static void
|
||||
frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
||||
{
|
||||
const unsigned int *pc = (const unsigned int *) context->ra;
|
||||
|
||||
/* Fix up for 2.6.12 - 2.6.16 Linux kernels that have vDSO, but don't
|
||||
have S flag in it. */
|
||||
#ifdef __powerpc64__
|
||||
/* addi r1, r1, 128; li r0, 0x0077; sc (sigreturn) */
|
||||
/* addi r1, r1, 128; li r0, 0x00AC; sc (rt_sigreturn) */
|
||||
if (pc[0] == 0x38210000 + SIGNAL_FRAMESIZE
|
||||
&& (pc[1] == 0x38000077 || pc[1] == 0x380000AC)
|
||||
&& pc[2] == 0x44000002)
|
||||
context->signal_frame = 1;
|
||||
#else
|
||||
/* li r0, 0x7777; sc (sigreturn old) */
|
||||
/* li r0, 0x0077; sc (sigreturn new) */
|
||||
/* li r0, 0x6666; sc (rt_sigreturn old) */
|
||||
/* li r0, 0x00AC; sc (rt_sigreturn new) */
|
||||
if ((pc[0] == 0x38007777 || pc[0] == 0x38000077
|
||||
|| pc[0] == 0x38006666 || pc[0] == 0x380000AC)
|
||||
&& pc[1] == 0x44000002)
|
||||
context->signal_frame = 1;
|
||||
#endif
|
||||
|
||||
#ifdef __powerpc64__
|
||||
if (fs->regs.reg[2].how == REG_UNSAVED)
|
||||
{
|
||||
/* If the current unwind info (FS) does not contain explicit info
|
||||
saving R2, then we have to do a minor amount of code reading to
|
||||
figure out if it was saved. The big problem here is that the
|
||||
code that does the save/restore is generated by the linker, so
|
||||
we have no good way to determine at compile time what to do. */
|
||||
unsigned int *insn
|
||||
= (unsigned int *) _Unwind_GetGR (context, LINK_REGISTER_REGNUM);
|
||||
if (*insn == 0xE8410028)
|
||||
_Unwind_SetGRPtr (context, 2, context->cfa + 40);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* DWARF2 EH unwinding support for S/390 Linux.
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@ -113,27 +113,11 @@ s390_fallback_frame_state (struct _Unwind_Context *context,
|
||||
fs->regs.reg[32].how = REG_SAVED_OFFSET;
|
||||
fs->regs.reg[32].loc.offset = (long)®s->psw_addr - new_cfa;
|
||||
fs->retaddr_column = 32;
|
||||
|
||||
/* If we got a SIGSEGV or a SIGBUS, the PSW address points *to*
|
||||
the faulting instruction, not after it. This causes the logic
|
||||
in unwind-dw2.c that decrements the RA to determine the correct
|
||||
CFI region to get confused. To fix that, we *increment* the RA
|
||||
here in that case. Note that we cannot modify the RA in place,
|
||||
and the frame state wants a *pointer*, not a value; thus we put
|
||||
the modified RA value into the unused register 33 slot of FS and
|
||||
have the register 32 save address point to that slot.
|
||||
|
||||
Unfortunately, for regular signals on old kernels, we don't know
|
||||
the signal number. We default to not fiddling with the RA;
|
||||
that can fail in rare cases. Upgrade your kernel. */
|
||||
|
||||
if (signo && (*signo == 11 || *signo == 7))
|
||||
{
|
||||
fs->regs.reg[33].loc.exp =
|
||||
(unsigned char *)regs->psw_addr + 1;
|
||||
fs->regs.reg[32].loc.offset =
|
||||
(long)&fs->regs.reg[33].loc.exp - new_cfa;
|
||||
}
|
||||
/* SIGILL, SIGFPE and SIGTRAP are delivered with psw_addr
|
||||
after the faulting instruction rather than before it.
|
||||
Don't set FS->signal_frame in that case. */
|
||||
if (!signo || (*signo != 4 && *signo != 5 && *signo != 8))
|
||||
fs->signal_frame = 1;
|
||||
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
@ -272,4 +272,5 @@ GCC_4.2.0 {
|
||||
__floatuntisf
|
||||
__floatuntixf
|
||||
__floatuntitf
|
||||
_Unwind_GetIPInfo
|
||||
}
|
||||
|
@ -127,6 +127,7 @@ PERSONALITY_FUNCTION (int version,
|
||||
lsda_header_info info;
|
||||
const unsigned char *language_specific_data, *p, *action_record;
|
||||
_Unwind_Ptr landing_pad, ip;
|
||||
int ip_before_insn = 0;
|
||||
|
||||
#ifdef __ARM_EABI_UNWINDER__
|
||||
if ((state & _US_ACTION_MASK) != _US_UNWIND_FRAME_STARTING)
|
||||
@ -156,7 +157,9 @@ PERSONALITY_FUNCTION (int version,
|
||||
|
||||
/* Parse the LSDA header. */
|
||||
p = parse_lsda_header (context, language_specific_data, &info);
|
||||
ip = _Unwind_GetIP (context) - 1;
|
||||
ip = _Unwind_GetIPInfo (context, &ip_before_insn);
|
||||
if (! ip_before_insn)
|
||||
--ip;
|
||||
landing_pad = 0;
|
||||
|
||||
#ifdef __USING_SJLJ_EXCEPTIONS__
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Backward compatibility unwind routines.
|
||||
Copyright (C) 2004, 2005
|
||||
Copyright (C) 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
@ -136,6 +136,13 @@ _Unwind_GetIP (struct _Unwind_Context *context)
|
||||
}
|
||||
symver (_Unwind_GetIP, GCC_3.0);
|
||||
|
||||
_Unwind_Ptr
|
||||
_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
|
||||
{
|
||||
*ip_before_insn = 0;
|
||||
return __libunwind_Unwind_GetIP (context);
|
||||
}
|
||||
|
||||
extern void *__libunwind_Unwind_GetLanguageSpecificData
|
||||
(struct _Unwind_Context *);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* DWARF2 exception handling and frame unwind runtime interface routines.
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
@ -71,6 +71,7 @@ struct _Unwind_Context
|
||||
void *lsda;
|
||||
struct dwarf_eh_bases bases;
|
||||
_Unwind_Word args_size;
|
||||
char signal_frame;
|
||||
};
|
||||
|
||||
/* Byte size of every register managed by these routines. */
|
||||
@ -207,6 +208,16 @@ _Unwind_GetIP (struct _Unwind_Context *context)
|
||||
return (_Unwind_Ptr) context->ra;
|
||||
}
|
||||
|
||||
/* Retrieve the return address and flag whether that IP is before
|
||||
or after first not yet fully executed instruction. */
|
||||
|
||||
inline _Unwind_Ptr
|
||||
_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
|
||||
{
|
||||
*ip_before_insn = context->signal_frame != 0;
|
||||
return (_Unwind_Ptr) context->ra;
|
||||
}
|
||||
|
||||
/* Overwrite the return address for CONTEXT with VAL. */
|
||||
|
||||
inline void
|
||||
@ -327,6 +338,13 @@ extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
|
||||
aug += 1;
|
||||
}
|
||||
|
||||
/* "S" indicates a signal frame. */
|
||||
else if (aug[0] == 'S')
|
||||
{
|
||||
fs->signal_frame = 1;
|
||||
aug += 1;
|
||||
}
|
||||
|
||||
/* Otherwise we have an unknown augmentation string.
|
||||
Bail unless we saw a 'z' prefix. */
|
||||
else
|
||||
@ -761,8 +779,10 @@ execute_cfa_program (const unsigned char *insn_ptr,
|
||||
a different stack configuration that we are not interested in. We
|
||||
assume that the call itself is unwind info-neutral; if not, or if
|
||||
there are delay instructions that adjust the stack, these must be
|
||||
reflected at the point immediately before the call insn. */
|
||||
while (insn_ptr < insn_end && fs->pc < context->ra)
|
||||
reflected at the point immediately before the call insn.
|
||||
In signal frames, return address is after last completed instruction,
|
||||
so we add 1 to return address to make the comparison <=. */
|
||||
while (insn_ptr < insn_end && fs->pc < context->ra + context->signal_frame)
|
||||
{
|
||||
unsigned char insn = *insn_ptr++;
|
||||
_Unwind_Word reg, utmp;
|
||||
@ -974,7 +994,8 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
||||
if (context->ra == 0)
|
||||
return _URC_END_OF_STACK;
|
||||
|
||||
fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
|
||||
fde = _Unwind_Find_FDE (context->ra + context->signal_frame - 1,
|
||||
&context->bases);
|
||||
if (fde == NULL)
|
||||
{
|
||||
#ifdef MD_FALLBACK_FRAME_STATE_FOR
|
||||
@ -1192,6 +1213,8 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
||||
break;
|
||||
}
|
||||
|
||||
context->signal_frame = fs->signal_frame;
|
||||
|
||||
#ifdef MD_FROB_UPDATE_CONTEXT
|
||||
MD_FROB_UPDATE_CONTEXT (context, fs);
|
||||
#endif
|
||||
|
@ -83,6 +83,7 @@ typedef struct
|
||||
unsigned char fde_encoding;
|
||||
unsigned char lsda_encoding;
|
||||
unsigned char saw_z;
|
||||
unsigned char signal_frame;
|
||||
void *eh_ptr;
|
||||
} _Unwind_FrameState;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Exception handling and frame unwind runtime interface routines.
|
||||
Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2001, 2003, 2004, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@ -155,6 +155,7 @@ extern _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *, int);
|
||||
extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word);
|
||||
|
||||
extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *);
|
||||
extern _Unwind_Ptr _Unwind_GetIPInfo (struct _Unwind_Context *, int *);
|
||||
extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr);
|
||||
|
||||
/* @@@ Retrieve the CFA of the given context. */
|
||||
|
@ -214,6 +214,13 @@ _Unwind_GetIP (struct _Unwind_Context *context)
|
||||
return context->fc->call_site + 1;
|
||||
}
|
||||
|
||||
_Unwind_Ptr
|
||||
_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
|
||||
{
|
||||
*ip_before_insn = 0;
|
||||
return context->fc->call_site + 1;
|
||||
}
|
||||
|
||||
/* Set the return landing pad index in CONTEXT. */
|
||||
|
||||
void
|
||||
|
@ -1,3 +1,16 @@
|
||||
2006-02-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR other/26208
|
||||
* 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.
|
||||
|
||||
2006-02-23 Scott Gilbertson <scottg@mantatest.com>
|
||||
|
||||
* gnu/awt/j2d/IntegerGraphicsState.java (getClip): Clone clip
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Functions for Exception Support for Java.
|
||||
|
||||
/* 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.
|
||||
|
||||
@ -197,6 +197,7 @@ PERSONALITY_FUNCTION (int version,
|
||||
int handler_switch_value;
|
||||
bool saw_cleanup;
|
||||
bool saw_handler;
|
||||
int ip_before_insn = 0;
|
||||
|
||||
|
||||
// Interface version check.
|
||||
@ -212,10 +213,10 @@ PERSONALITY_FUNCTION (int version,
|
||||
goto install_context;
|
||||
}
|
||||
|
||||
// FIXME: In Phase 1, record _Unwind_GetIP in xh->obj as a part of
|
||||
// FIXME: In Phase 1, record _Unwind_GetIPInfo in xh->obj as a part of
|
||||
// the stack trace for this exception. This will only collect Java
|
||||
// frames, but perhaps that is acceptable.
|
||||
// FIXME2: _Unwind_GetIP is nonsensical for SJLJ, being a call-site
|
||||
// FIXME2: _Unwind_GetIPInfo is nonsensical for SJLJ, being a call-site
|
||||
// index instead of a PC value. We could perhaps arrange for
|
||||
// _Unwind_GetRegionStart to return context->fc->jbuf[1], which
|
||||
// is the address of the handler label for __builtin_longjmp, but
|
||||
@ -230,7 +231,9 @@ PERSONALITY_FUNCTION (int version,
|
||||
|
||||
// Parse the LSDA header.
|
||||
p = parse_lsda_header (context, language_specific_data, &info);
|
||||
ip = _Unwind_GetIP (context) - 1;
|
||||
ip = _Unwind_GetIPInfo (context, &ip_before_insn);
|
||||
if (! ip_before_insn)
|
||||
--ip;
|
||||
landing_pad = 0;
|
||||
action_record = 0;
|
||||
handler_switch_value = 0;
|
||||
|
@ -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) \
|
||||
|
@ -1,3 +1,9 @@
|
||||
2006-02-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR other/26208
|
||||
* libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Use
|
||||
_Unwind_GetIPInfo instead of _Unwind_GetIP.
|
||||
|
||||
2006-02-27 Paolo Carlini <pcarlini@suse.de>
|
||||
|
||||
PR libstdc++/14866
|
||||
|
@ -364,6 +364,7 @@ PERSONALITY_FUNCTION (int version,
|
||||
int handler_switch_value;
|
||||
void* thrown_ptr = ue_header + 1;
|
||||
bool foreign_exception;
|
||||
int ip_before_insn = 0;
|
||||
|
||||
#ifdef __ARM_EABI_UNWINDER__
|
||||
_Unwind_Action actions;
|
||||
@ -430,7 +431,9 @@ PERSONALITY_FUNCTION (int version,
|
||||
// Parse the LSDA header.
|
||||
p = parse_lsda_header (context, language_specific_data, &info);
|
||||
info.ttype_base = base_of_encoded_value (info.ttype_encoding, context);
|
||||
ip = _Unwind_GetIP (context) - 1;
|
||||
ip = _Unwind_GetIPInfo (context, &ip_before_insn);
|
||||
if (! ip_before_insn)
|
||||
--ip;
|
||||
landing_pad = 0;
|
||||
action_record = 0;
|
||||
handler_switch_value = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user