Commit bf4db96c by Eric Botcazou Committed by Eric Botcazou

re PR ada/41929 (64-bit null_pointer_deref1 gnat.dg test consumes all available memory)

	PR ada/41929
	* config/sparc/sol2-unwind.h (sparc64_is_sighandler): Remove SAVPC and
	add CFA.  Revert back to old code for Solaris 8+ multi-threaded.
	(sparc_is_sighandler): Likewise.
	(MD_FALLBACK_FRAME_STATE_FOR): Adjust call to IS_SIGHANDLER.

From-SVN: r183005
parent b492b686
2012-01-09 Eric Botcazou <ebotcazou@adacore.com>
PR ada/41929
* config/sparc/sol2-unwind.h (sparc64_is_sighandler): Remove SAVPC and
add CFA. Revert back to old code for Solaris 8+ multi-threaded.
(sparc_is_sighandler): Likewise.
(MD_FALLBACK_FRAME_STATE_FOR): Adjust call to IS_SIGHANDLER.
2012-01-06 Tristan Gingold <gingold@adacore.com> 2012-01-06 Tristan Gingold <gingold@adacore.com>
* config/ia64/t-ia64 (LIB1ASMFUNCS): Move backward * config/ia64/t-ia64 (LIB1ASMFUNCS): Move backward
......
/* DWARF2 EH unwinding support for SPARC Solaris. /* DWARF2 EH unwinding support for SPARC Solaris.
Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc. Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -34,7 +34,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ...@@ -34,7 +34,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define IS_SIGHANDLER sparc64_is_sighandler #define IS_SIGHANDLER sparc64_is_sighandler
static int static int
sparc64_is_sighandler (unsigned int *pc, unsigned int *savpc, int *nframes) sparc64_is_sighandler (unsigned int *pc, void *cfa, int *nframes)
{ {
if (/* Solaris 8 - single-threaded if (/* Solaris 8 - single-threaded
---------------------------- ----------------------------
...@@ -110,29 +110,41 @@ sparc64_is_sighandler (unsigned int *pc, unsigned int *savpc, int *nframes) ...@@ -110,29 +110,41 @@ sparc64_is_sighandler (unsigned int *pc, unsigned int *savpc, int *nframes)
&& pc[ 0] == 0x81c7e008 && pc[ 0] == 0x81c7e008
&& pc[ 1] == 0x81e80000) && pc[ 1] == 0x81e80000)
{ {
if (/* Solaris 8 /usr/lib/sparcv9/libthread.so.1 /* We have observed different calling frames among different
------------------------------------------ versions of the operating system, so that we need to
Before patch 108827-08: discriminate using the upper frame. We look for the return
<sigacthandler+1760>: st %g4, [ %i1 + 0x1c ] address of the caller frame (there is an offset of 15 double
words between the frame address and the place where this return
Since patch 108827-08: address is stored) in order to do some more pattern matching. */
<sigacthandler+1816>: st %l0, [ %i4 + 0x10 ] */ unsigned int cuh_pattern
savpc[-1] == 0xc826601c = *(unsigned int *)(*(unsigned long *)(cfa + 15*8) - 4);
|| savpc[-1] == 0xe0272010)
if (cuh_pattern == 0xd25fa7ef)
{ {
/* We need to move up three frames: /* This matches the call_user_handler pattern for Solaris 10.
There are 2 cases so we look for the return address of the
caller's caller frame in order to do more pattern matching. */
unsigned int sah_pattern
= *(unsigned int *)(*(unsigned long *)(cfa + 176 + 15*8) - 4);
if (sah_pattern == 0x92100019)
/* This is the same setup as for Solaris 9, see below. */
*nframes = 3;
else
/* The sigacthandler frame isn't present in the chain.
We need to move up two frames:
<signal handler> <-- context->cfa <signal handler> <-- context->cfa
__sighndlr __sighndlr
sigacthandler call_user_handler frame
<kernel> <kernel>
*/ */
*nframes = 2; *nframes = 2;
} }
else /* Solaris 8 /usr/lib/lwp/sparcv9/libthread.so.1, Solaris 9+ else if (cuh_pattern == 0x9410001a || cuh_pattern == 0x94100013)
---------------------------------------------------------- */ /* This matches the call_user_handler pattern for Solaris 9 and
{ for Solaris 8 running inside Solaris Containers respectively
/* We need to move up three frames: We need to move up three frames:
<signal handler> <-- context->cfa <signal handler> <-- context->cfa
__sighndlr __sighndlr
...@@ -141,7 +153,16 @@ sparc64_is_sighandler (unsigned int *pc, unsigned int *savpc, int *nframes) ...@@ -141,7 +153,16 @@ sparc64_is_sighandler (unsigned int *pc, unsigned int *savpc, int *nframes)
<kernel> <kernel>
*/ */
*nframes = 3; *nframes = 3;
} else
/* This is the default Solaris 8 case.
We need to move up two frames:
<signal handler> <-- context->cfa
__sighndlr
sigacthandler
<kernel>
*/
*nframes = 2;
return 1; return 1;
} }
...@@ -181,7 +202,7 @@ sparc64_frob_update_context (struct _Unwind_Context *context, ...@@ -181,7 +202,7 @@ sparc64_frob_update_context (struct _Unwind_Context *context,
#define IS_SIGHANDLER sparc_is_sighandler #define IS_SIGHANDLER sparc_is_sighandler
static int static int
sparc_is_sighandler (unsigned int *pc, unsigned int * savpc, int *nframes) sparc_is_sighandler (unsigned int *pc, void *cfa, int *nframes)
{ {
if (/* Solaris 8, 9 - single-threaded if (/* Solaris 8, 9 - single-threaded
------------------------------- -------------------------------
...@@ -209,7 +230,7 @@ sparc_is_sighandler (unsigned int *pc, unsigned int * savpc, int *nframes) ...@@ -209,7 +230,7 @@ sparc_is_sighandler (unsigned int *pc, unsigned int * savpc, int *nframes)
&& pc[-1] == 0x9410001a && pc[-1] == 0x9410001a
&& pc[ 0] == 0x80a62008) && pc[ 0] == 0x80a62008)
{ {
/* Need to move up one frame: /* We need to move up one frame:
<signal handler> <-- context->cfa <signal handler> <-- context->cfa
sigacthandler sigacthandler
...@@ -240,7 +261,7 @@ sparc_is_sighandler (unsigned int *pc, unsigned int * savpc, int *nframes) ...@@ -240,7 +261,7 @@ sparc_is_sighandler (unsigned int *pc, unsigned int * savpc, int *nframes)
&& pc[ 1] == 0x81e80000 && pc[ 1] == 0x81e80000
&& pc[ 2] == 0x80a26000) && pc[ 2] == 0x80a26000)
{ {
/* Need to move up one frame: /* We need to move up one frame:
<signal handler> <-- context->cfa <signal handler> <-- context->cfa
__libthread_segvhdlr __libthread_segvhdlr
...@@ -267,24 +288,41 @@ sparc_is_sighandler (unsigned int *pc, unsigned int * savpc, int *nframes) ...@@ -267,24 +288,41 @@ sparc_is_sighandler (unsigned int *pc, unsigned int * savpc, int *nframes)
&& pc[ 0] == 0x81c7e008 && pc[ 0] == 0x81c7e008
&& pc[ 1] == 0x81e80000) && pc[ 1] == 0x81e80000)
{ {
if (/* Solaris 8 /usr/lib/libthread.so.1 /* We have observed different calling frames among different
---------------------------------- versions of the operating system, so that we need to
<sigacthandler+1796>: mov %i0, %o0 */ discriminate using the upper frame. We look for the return
savpc[-1] == 0x90100018) address of the caller frame (there is an offset of 15 words
between the frame address and the place where this return
address is stored) in order to do some more pattern matching. */
unsigned int cuh_pattern
= *(unsigned int *)(*(unsigned int *)(cfa + 15*4) - 4);
if (cuh_pattern == 0xd407a04c)
{ {
/* We need to move up two frames: /* This matches the call_user_handler pattern for Solaris 10.
There are 2 cases so we look for the return address of the
caller's caller frame in order to do more pattern matching. */
unsigned int sah_pattern
= *(unsigned int *)(*(unsigned int *)(cfa + 96 + 15*4) - 4);
if (sah_pattern == 0x92100019)
/* This is the same setup as for Solaris 9, see below. */
*nframes = 3;
else
/* The sigacthandler frame isn't present in the chain.
We need to move up two frames:
<signal handler> <-- context->cfa <signal handler> <-- context->cfa
__sighndlr __sighndlr
sigacthandler call_user_handler frame
<kernel> <kernel>
*/ */
*nframes = 2; *nframes = 2;
} }
else /* Solaris 8 /usr/lib/lwp/libthread.so.1, Solaris 9+ else if (cuh_pattern == 0x9410001a || cuh_pattern == 0x9410001b)
-------------------------------------------------- */ /* This matches the call_user_handler pattern for Solaris 9 and
{ for Solaris 8 running inside Solaris Containers respectively.
/* We need to move up three frames: We need to move up three frames:
<signal handler> <-- context->cfa <signal handler> <-- context->cfa
__sighndlr __sighndlr
...@@ -293,7 +331,16 @@ sparc_is_sighandler (unsigned int *pc, unsigned int * savpc, int *nframes) ...@@ -293,7 +331,16 @@ sparc_is_sighandler (unsigned int *pc, unsigned int * savpc, int *nframes)
<kernel> <kernel>
*/ */
*nframes = 3; *nframes = 3;
} else
/* This is the default Solaris 8 case.
We need to move up two frames:
<signal handler> <-- context->cfa
__sighndlr
sigacthandler
<kernel>
*/
*nframes = 2;
return 1; return 1;
} }
...@@ -331,7 +378,7 @@ MD_FALLBACK_FRAME_STATE_FOR (struct _Unwind_Context *context, ...@@ -331,7 +378,7 @@ MD_FALLBACK_FRAME_STATE_FOR (struct _Unwind_Context *context,
return _URC_NO_REASON; return _URC_NO_REASON;
} }
if (IS_SIGHANDLER (pc, (unsigned int *)fp->fr_savpc, &nframes)) if (IS_SIGHANDLER (pc, this_cfa, &nframes))
{ {
struct handler_args { struct handler_args {
struct frame frwin; struct frame frwin;
......
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