Commit 754e45a8 by Jakub Jelinek Committed by Jakub Jelinek

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
parent 6df11ca1
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> 2006-02-27 Daniel Berlin <dberlin@dberlin.org>
* tree-ssa-structalias.c (get_constraint_for): Move code to deal * tree-ssa-structalias.c (get_constraint_for): Move code to deal
......
/* Header file for the ARM EABI unwinder /* 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 Contributed by Paul Brook
This file is free software; you can redistribute it and/or modify it This file is free software; you can redistribute it and/or modify it
...@@ -250,6 +250,9 @@ extern "C" { ...@@ -250,6 +250,9 @@ extern "C" {
#define _Unwind_GetIP(context) \ #define _Unwind_GetIP(context) \
(_Unwind_GetGR (context, 15) & ~(_Unwind_Word)1) (_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 static inline void
_Unwind_SetGR (_Unwind_Context *context, int regno, _Unwind_Word val) _Unwind_SetGR (_Unwind_Context *context, int regno, _Unwind_Word val)
{ {
......
/* DWARF2 EH unwinding support for AMD x86-64 and x86. /* 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. This file is part of GCC.
...@@ -100,6 +100,7 @@ x86_64_fallback_frame_state (struct _Unwind_Context *context, ...@@ -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].how = REG_SAVED_OFFSET;
fs->regs.reg[16].loc.offset = (long)&sc->rip - new_cfa; fs->regs.reg[16].loc.offset = (long)&sc->rip - new_cfa;
fs->retaddr_column = 16; fs->retaddr_column = 16;
fs->signal_frame = 1;
return _URC_NO_REASON; return _URC_NO_REASON;
} }
...@@ -172,6 +173,7 @@ x86_fallback_frame_state (struct _Unwind_Context *context, ...@@ -172,6 +173,7 @@ x86_fallback_frame_state (struct _Unwind_Context *context,
fs->regs.reg[8].how = REG_SAVED_OFFSET; fs->regs.reg[8].how = REG_SAVED_OFFSET;
fs->regs.reg[8].loc.offset = (long)&sc->REG_NAME(eip) - new_cfa; fs->regs.reg[8].loc.offset = (long)&sc->REG_NAME(eip) - new_cfa;
fs->retaddr_column = 8; fs->retaddr_column = 8;
fs->signal_frame = 1;
return _URC_NO_REASON; return _URC_NO_REASON;
} }
#endif /* not glibc 2.0 */ #endif /* not glibc 2.0 */
......
...@@ -1704,6 +1704,13 @@ _Unwind_GetIP (struct _Unwind_Context *context) ...@@ -1704,6 +1704,13 @@ _Unwind_GetIP (struct _Unwind_Context *context)
return context->rp; 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. */ /* Overwrite the return address for CONTEXT with VAL. */
inline void inline void
......
/* DWARF2 EH unwinding support for PowerPC and PowerPC64 Linux. /* 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. This file is part of GCC.
...@@ -89,26 +89,6 @@ struct gcc_ucontext ...@@ -89,26 +89,6 @@ struct gcc_ucontext
enum { SIGNAL_FRAMESIZE = 128 }; 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 /* If PC is at a sigreturn trampoline, return a pointer to the
regs. Otherwise return NULL. */ regs. Otherwise return NULL. */
...@@ -272,6 +252,7 @@ ppc_fallback_frame_state (struct _Unwind_Context *context, ...@@ -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].how = REG_SAVED_OFFSET;
fs->regs.reg[ARG_POINTER_REGNUM].loc.offset = (long) &regs->nip - new_cfa; fs->regs.reg[ARG_POINTER_REGNUM].loc.offset = (long) &regs->nip - new_cfa;
fs->retaddr_column = ARG_POINTER_REGNUM; fs->retaddr_column = ARG_POINTER_REGNUM;
fs->signal_frame = 1;
if (hwcap == 0) if (hwcap == 0)
{ {
...@@ -322,3 +303,46 @@ ppc_fallback_frame_state (struct _Unwind_Context *context, ...@@ -322,3 +303,46 @@ ppc_fallback_frame_state (struct _Unwind_Context *context,
return _URC_NO_REASON; 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
}
/* DWARF2 EH unwinding support for S/390 Linux. /* 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. This file is part of GCC.
...@@ -113,27 +113,11 @@ s390_fallback_frame_state (struct _Unwind_Context *context, ...@@ -113,27 +113,11 @@ s390_fallback_frame_state (struct _Unwind_Context *context,
fs->regs.reg[32].how = REG_SAVED_OFFSET; fs->regs.reg[32].how = REG_SAVED_OFFSET;
fs->regs.reg[32].loc.offset = (long)&regs->psw_addr - new_cfa; fs->regs.reg[32].loc.offset = (long)&regs->psw_addr - new_cfa;
fs->retaddr_column = 32; fs->retaddr_column = 32;
/* SIGILL, SIGFPE and SIGTRAP are delivered with psw_addr
/* If we got a SIGSEGV or a SIGBUS, the PSW address points *to* after the faulting instruction rather than before it.
the faulting instruction, not after it. This causes the logic Don't set FS->signal_frame in that case. */
in unwind-dw2.c that decrements the RA to determine the correct if (!signo || (*signo != 4 && *signo != 5 && *signo != 8))
CFI region to get confused. To fix that, we *increment* the RA fs->signal_frame = 1;
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;
}
return _URC_NO_REASON; return _URC_NO_REASON;
} }
...@@ -272,4 +272,5 @@ GCC_4.2.0 { ...@@ -272,4 +272,5 @@ GCC_4.2.0 {
__floatuntisf __floatuntisf
__floatuntixf __floatuntixf
__floatuntitf __floatuntitf
_Unwind_GetIPInfo
} }
...@@ -127,6 +127,7 @@ PERSONALITY_FUNCTION (int version, ...@@ -127,6 +127,7 @@ PERSONALITY_FUNCTION (int version,
lsda_header_info info; lsda_header_info info;
const unsigned char *language_specific_data, *p, *action_record; const unsigned char *language_specific_data, *p, *action_record;
_Unwind_Ptr landing_pad, ip; _Unwind_Ptr landing_pad, ip;
int ip_before_insn = 0;
#ifdef __ARM_EABI_UNWINDER__ #ifdef __ARM_EABI_UNWINDER__
if ((state & _US_ACTION_MASK) != _US_UNWIND_FRAME_STARTING) if ((state & _US_ACTION_MASK) != _US_UNWIND_FRAME_STARTING)
...@@ -156,7 +157,9 @@ PERSONALITY_FUNCTION (int version, ...@@ -156,7 +157,9 @@ PERSONALITY_FUNCTION (int version,
/* Parse the LSDA header. */ /* Parse the LSDA header. */
p = parse_lsda_header (context, language_specific_data, &info); 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; landing_pad = 0;
#ifdef __USING_SJLJ_EXCEPTIONS__ #ifdef __USING_SJLJ_EXCEPTIONS__
......
/* Backward compatibility unwind routines. /* Backward compatibility unwind routines.
Copyright (C) 2004, 2005 Copyright (C) 2004, 2005, 2006
Free Software Foundation, Inc. Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -136,6 +136,13 @@ _Unwind_GetIP (struct _Unwind_Context *context) ...@@ -136,6 +136,13 @@ _Unwind_GetIP (struct _Unwind_Context *context)
} }
symver (_Unwind_GetIP, GCC_3.0); 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 extern void *__libunwind_Unwind_GetLanguageSpecificData
(struct _Unwind_Context *); (struct _Unwind_Context *);
......
/* DWARF2 exception handling and frame unwind runtime interface routines. /* 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. Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -71,6 +71,7 @@ struct _Unwind_Context ...@@ -71,6 +71,7 @@ struct _Unwind_Context
void *lsda; void *lsda;
struct dwarf_eh_bases bases; struct dwarf_eh_bases bases;
_Unwind_Word args_size; _Unwind_Word args_size;
char signal_frame;
}; };
/* Byte size of every register managed by these routines. */ /* Byte size of every register managed by these routines. */
...@@ -207,6 +208,16 @@ _Unwind_GetIP (struct _Unwind_Context *context) ...@@ -207,6 +208,16 @@ _Unwind_GetIP (struct _Unwind_Context *context)
return (_Unwind_Ptr) context->ra; 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. */ /* Overwrite the return address for CONTEXT with VAL. */
inline void inline void
...@@ -327,6 +338,13 @@ extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context, ...@@ -327,6 +338,13 @@ extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
aug += 1; 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. /* Otherwise we have an unknown augmentation string.
Bail unless we saw a 'z' prefix. */ Bail unless we saw a 'z' prefix. */
else else
...@@ -761,8 +779,10 @@ execute_cfa_program (const unsigned char *insn_ptr, ...@@ -761,8 +779,10 @@ execute_cfa_program (const unsigned char *insn_ptr,
a different stack configuration that we are not interested in. We a different stack configuration that we are not interested in. We
assume that the call itself is unwind info-neutral; if not, or if assume that the call itself is unwind info-neutral; if not, or if
there are delay instructions that adjust the stack, these must be there are delay instructions that adjust the stack, these must be
reflected at the point immediately before the call insn. */ reflected at the point immediately before the call insn.
while (insn_ptr < insn_end && fs->pc < context->ra) 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++; unsigned char insn = *insn_ptr++;
_Unwind_Word reg, utmp; _Unwind_Word reg, utmp;
...@@ -974,7 +994,8 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs) ...@@ -974,7 +994,8 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
if (context->ra == 0) if (context->ra == 0)
return _URC_END_OF_STACK; 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) if (fde == NULL)
{ {
#ifdef MD_FALLBACK_FRAME_STATE_FOR #ifdef MD_FALLBACK_FRAME_STATE_FOR
...@@ -1192,6 +1213,8 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs) ...@@ -1192,6 +1213,8 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
break; break;
} }
context->signal_frame = fs->signal_frame;
#ifdef MD_FROB_UPDATE_CONTEXT #ifdef MD_FROB_UPDATE_CONTEXT
MD_FROB_UPDATE_CONTEXT (context, fs); MD_FROB_UPDATE_CONTEXT (context, fs);
#endif #endif
......
...@@ -83,6 +83,7 @@ typedef struct ...@@ -83,6 +83,7 @@ typedef struct
unsigned char fde_encoding; unsigned char fde_encoding;
unsigned char lsda_encoding; unsigned char lsda_encoding;
unsigned char saw_z; unsigned char saw_z;
unsigned char signal_frame;
void *eh_ptr; void *eh_ptr;
} _Unwind_FrameState; } _Unwind_FrameState;
/* Exception handling and frame unwind runtime interface routines. /* 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. This file is part of GCC.
...@@ -155,6 +155,7 @@ extern _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *, int); ...@@ -155,6 +155,7 @@ extern _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *, int);
extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word); extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word);
extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *); 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); extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr);
/* @@@ Retrieve the CFA of the given context. */ /* @@@ Retrieve the CFA of the given context. */
......
...@@ -214,6 +214,13 @@ _Unwind_GetIP (struct _Unwind_Context *context) ...@@ -214,6 +214,13 @@ _Unwind_GetIP (struct _Unwind_Context *context)
return context->fc->call_site + 1; 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. */ /* Set the return landing pad index in CONTEXT. */
void void
......
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> 2006-02-23 Scott Gilbertson <scottg@mantatest.com>
* gnu/awt/j2d/IntegerGraphicsState.java (getClip): Clone clip * gnu/awt/j2d/IntegerGraphicsState.java (getClip): Clone clip
......
// Functions for Exception Support for Java. // 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. This file is part of libgcj.
...@@ -197,6 +197,7 @@ PERSONALITY_FUNCTION (int version, ...@@ -197,6 +197,7 @@ PERSONALITY_FUNCTION (int version,
int handler_switch_value; int handler_switch_value;
bool saw_cleanup; bool saw_cleanup;
bool saw_handler; bool saw_handler;
int ip_before_insn = 0;
// Interface version check. // Interface version check.
...@@ -212,10 +213,10 @@ PERSONALITY_FUNCTION (int version, ...@@ -212,10 +213,10 @@ PERSONALITY_FUNCTION (int version,
goto install_context; 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 // the stack trace for this exception. This will only collect Java
// frames, but perhaps that is acceptable. // 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 // index instead of a PC value. We could perhaps arrange for
// _Unwind_GetRegionStart to return context->fc->jbuf[1], which // _Unwind_GetRegionStart to return context->fc->jbuf[1], which
// is the address of the handler label for __builtin_longjmp, but // is the address of the handler label for __builtin_longjmp, but
...@@ -230,7 +231,9 @@ PERSONALITY_FUNCTION (int version, ...@@ -230,7 +231,9 @@ PERSONALITY_FUNCTION (int version,
// Parse the LSDA header. // Parse the LSDA header.
p = parse_lsda_header (context, language_specific_data, &info); 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; landing_pad = 0;
action_record = 0; action_record = 0;
handler_switch_value = 0; handler_switch_value = 0;
......
// i386-signal.h - Catch runtime signals and turn them into exceptions // i386-signal.h - Catch runtime signals and turn them into exceptions
// on an i386 based Linux system. // 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. This file is part of libgcj.
...@@ -22,19 +22,7 @@ details. */ ...@@ -22,19 +22,7 @@ details. */
#define SIGNAL_HANDLER(_name) \ #define SIGNAL_HANDLER(_name) \
static void _name (int _dummy __attribute__ ((__unused__))) static void _name (int _dummy __attribute__ ((__unused__)))
#define MAKE_THROW_FRAME(_exception) \ #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 HANDLE_DIVIDE_OVERFLOW \ #define HANDLE_DIVIDE_OVERFLOW \
do \ do \
...@@ -91,14 +79,6 @@ do \ ...@@ -91,14 +79,6 @@ do \
_regs->eip = (unsigned long)_eip; \ _regs->eip = (unsigned long)_eip; \
return; \ 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) while (0)
......
// powerpc-signal.h - Catch runtime signals and turn them into exceptions // powerpc-signal.h - Catch runtime signals and turn them into exceptions
// on a powerpc based Linux system. // 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. This file is part of libgcj.
...@@ -22,18 +22,12 @@ details. */ ...@@ -22,18 +22,12 @@ details. */
#define SIGNAL_HANDLER(_name) \ #define SIGNAL_HANDLER(_name) \
static void _name (int /* _signal */, struct sigcontext *_sc) static void _name (int /* _signal */, struct sigcontext *_sc)
/* PPC either leaves PC pointing at a faulting instruction or the /* MD_FALBACK_FRAME_STATE_FOR takes care of special casing PC
following instruction, depending on the signal. SEGV always does before the faulting instruction, so we don't need to do anything
the former, so we adjust the saved PC to point to the following here. */
instruction. This is what the handler in libgcc expects. */
#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 /* For an explanation why we cannot simply use sigaction to
install the handlers, see i386-signal.h. */ install the handlers, see i386-signal.h. */
......
// x86_64-signal.h - Catch runtime signals and turn them into exceptions // x86_64-signal.h - Catch runtime signals and turn them into exceptions
// on an x86_64 based GNU/Linux system. // 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. This file is part of libgcj.
...@@ -34,16 +34,7 @@ extern "C" ...@@ -34,16 +34,7 @@ extern "C"
}; };
} }
#define MAKE_THROW_FRAME(_exception) \ #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 RESTORE(name, syscall) RESTORE2 (name, syscall) #define RESTORE(name, syscall) RESTORE2 (name, syscall)
#define RESTORE2(name, syscall) \ #define RESTORE2(name, syscall) \
......
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> 2006-02-27 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/14866 PR libstdc++/14866
......
...@@ -364,6 +364,7 @@ PERSONALITY_FUNCTION (int version, ...@@ -364,6 +364,7 @@ PERSONALITY_FUNCTION (int version,
int handler_switch_value; int handler_switch_value;
void* thrown_ptr = ue_header + 1; void* thrown_ptr = ue_header + 1;
bool foreign_exception; bool foreign_exception;
int ip_before_insn = 0;
#ifdef __ARM_EABI_UNWINDER__ #ifdef __ARM_EABI_UNWINDER__
_Unwind_Action actions; _Unwind_Action actions;
...@@ -430,7 +431,9 @@ PERSONALITY_FUNCTION (int version, ...@@ -430,7 +431,9 @@ PERSONALITY_FUNCTION (int version,
// Parse the LSDA header. // Parse the LSDA header.
p = parse_lsda_header (context, language_specific_data, &info); p = parse_lsda_header (context, language_specific_data, &info);
info.ttype_base = base_of_encoded_value (info.ttype_encoding, context); 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; landing_pad = 0;
action_record = 0; action_record = 0;
handler_switch_value = 0; handler_switch_value = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment