Re: Support Solaris 11/SPARC in MD_FALLBACK_FRAME_STATE_FOR (PR ada/41929)

2012-01-17 Thread Eric Botcazou
 Unfortunately, this version completely breaks Solaris 11.  Given that
 your primary (only?) justification for this patch seems to be a 7-year
 old Beta version of Solaris 10 (s10_72) nobody in his right mind should
 be running right now, I suggest simply reverting this patch.

I think that we shoudn't have changed the pattern matching code in the first 
place, as it had gradually evolved over almost an entire decade.  It was quite 
robust as a consequence and the new code is clearly inferior in this respect.

Usually adapting it to a new version of the OS only takes a handful of minutes.
Would you mind having a quick look?  I don't have access to Solaris 11 myself.

-- 
Eric Botcazou


Re: Support Solaris 11/SPARC in MD_FALLBACK_FRAME_STATE_FOR (PR ada/41929)

2012-01-17 Thread Rainer Orth
Eric Botcazou ebotca...@adacore.com writes:

 Unfortunately, this version completely breaks Solaris 11.  Given that
 your primary (only?) justification for this patch seems to be a 7-year
 old Beta version of Solaris 10 (s10_72) nobody in his right mind should
 be running right now, I suggest simply reverting this patch.

 I think that we shoudn't have changed the pattern matching code in the first 
 place, as it had gradually evolved over almost an entire decade.  It was 
 quite 
 robust as a consequence and the new code is clearly inferior in this respect.

 Usually adapting it to a new version of the OS only takes a handful of 
 minutes.

That's not my experience in the first place: when I tried to get it
working on Solaris 11, I failed so completely that I decided to instead
follow the route already trodden by the Solaris/x86 file.

 Would you mind having a quick look?  I don't have access to Solaris 11 myself.

I doubt I'll have the time: there's quite a lot on my plate before 4.7.0
and I don't have that much time left for gcc issues these days.

Again: what's the justification for changing this code so late in the
game when it has been like this since 4.6.0 with no issues?  I don't buy
it that support for s10_72 (a 7-year old Solaris 10 Beta) is enough to
break Solaris 11 (the current shipping release).

Rainer

-- 
-
Rainer Orth, Center for Biotechnology, Bielefeld University


Re: Support Solaris 11/SPARC in MD_FALLBACK_FRAME_STATE_FOR (PR ada/41929)

2012-01-16 Thread Rainer Orth
Eric Botcazou ebotca...@adacore.com writes:

 All EH-related tests fail with a recent upgrade on Solaris 10. Interestingly,
 the old implementation keeps working with the upgrade.

 I've applied the attached patch to mainline and 4.6 branch.  It reverts back 
 to 
 the old pattern matching code in the Solaris 8+ multi-threaded case, which is 
 clearly more robust.  The rest is left unchanged.  Tested on 5 different OS 
 versions (Solaris 8, Solaris 8 Containers, Solaris 9, old Solaris 10, recent 
 Solaris 10).

Unfortunately, this version completely breaks Solaris 11.  Given that
your primary (only?) justification for this patch seems to be a 7-year
old Beta version of Solaris 10 (s10_72) nobody in his right mind should
be running right now, I suggest simply reverting this patch.

Rainer

-- 
-
Rainer Orth, Center for Biotechnology, Bielefeld University


Re: Support Solaris 11/SPARC in MD_FALLBACK_FRAME_STATE_FOR (PR ada/41929)

2012-01-09 Thread Eric Botcazou
 All EH-related tests fail with a recent upgrade on Solaris 10. Interestingly,
 the old implementation keeps working with the upgrade.

I've applied the attached patch to mainline and 4.6 branch.  It reverts back to 
the old pattern matching code in the Solaris 8+ multi-threaded case, which is 
clearly more robust.  The rest is left unchanged.  Tested on 5 different OS 
versions (Solaris 8, Solaris 8 Containers, Solaris 9, old Solaris 10, recent 
Solaris 10).


2012-01-09  Eric Botcazou  ebotca...@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.


-- 
Eric Botcazou
Index: config/sparc/sol2-unwind.h
===
--- config/sparc/sol2-unwind.h	(revision 183001)
+++ config/sparc/sol2-unwind.h	(working copy)
@@ -1,5 +1,5 @@
 /* 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.
 
@@ -34,7 +34,7 @@ see the files COPYING3 and COPYING.RUNTI
 #define IS_SIGHANDLER sparc64_is_sighandler
 
 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
 	
@@ -110,38 +110,59 @@ sparc64_is_sighandler (unsigned int *pc,
pc[ 0] == 0x81c7e008
pc[ 1] == 0x81e8)
 {
-  if (/* Solaris 8 /usr/lib/sparcv9/libthread.so.1
-	--
-	Before patch 108827-08:
-	sigacthandler+1760: st  %g4, [ %i1 + 0x1c ]
-
-	Since patch 108827-08:
-	sigacthandler+1816: st  %l0, [ %i4 + 0x10 ]  */
-	savpc[-1] == 0xc826601c
-	 || savpc[-1] == 0xe0272010)
+  /* We have observed different calling frames among different
+	 versions of the operating system, so that we need to
+	 discriminate using the upper frame.  We look for the return
+	 address of the caller frame (there is an offset of 15 double
+	 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 long *)(cfa + 15*8) - 4);
+
+  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
 		__sighndlr
-		sigacthandler
+		call_user_handler frame
 		kernel
-	  */
-	  *nframes = 2;
+	*/
+	*nframes = 2;
 	}
-  else /* Solaris 8 /usr/lib/lwp/sparcv9/libthread.so.1, Solaris 9+
-	 --  */
-	{
-	  /* We need to move up three frames:
+  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:
 
 		signal handler	-- context-cfa
 		__sighndlr
 		call_user_handler
 		sigacthandler
 		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;
 }
 
@@ -181,7 +202,7 @@ sparc64_frob_update_context (struct _Unw
 #define IS_SIGHANDLER sparc_is_sighandler
 
 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
 ---
@@ -209,7 +230,7 @@ sparc_is_sighandler (unsigned int *pc, u
pc[-1] == 0x9410001a
pc[ 0] == 0x80a62008)
 {
-  /* Need to move up one frame:
+  /* We need to move up one frame:
 
 		signal handler	-- context-cfa
 		sigacthandler
@@ -240,7 +261,7 @@ sparc_is_sighandler (unsigned int *pc, u
pc[ 1] == 0x81e8
pc[ 2] == 0x80a26000)
 {
-  /* Need to move up one frame:
+  /* We need to move up one frame:
 
 		signal handler	-- context-cfa
 		__libthread_segvhdlr
@@ -267,33 +288,59 @@ 

Re: Support Solaris 11/SPARC in MD_FALLBACK_FRAME_STATE_FOR (PR ada/41929)

2011-11-28 Thread Eric Botcazou
 The result has been bootstrapped by Eric (thanks for this and debugging
 why a first version caused some regressions on Solaris 8) and myself on
 Solaris 8, 9, 10 and 11, and I've performed quite a bit of software
 archaeology (i.e. stared at old libc.so.1 and libthread.so.1 patches) to
 make sure noting got missed in the process.

All EH-related tests fail with a recent upgrade on Solaris 10.  Interestingly, 
the old implementation keeps working with the upgrade.  It seems that the 
__sighndlr case has been over-simplified:

  /* Look for the __sighndlr pattern.  */
  else if (*(unsigned int *)(pc-(4*5)) == sighndlr_pattern[0]
 *(unsigned int *)(pc-(4*4)) == sighndlr_pattern[1]
 *(unsigned int *)(pc-(4*3)) == sighndlr_pattern[2]
 *(unsigned int *)(pc-(4*2)) == sighndlr_pattern[3]
 *(unsigned int *)(pc-(4*1)) == sighndlr_pattern[4]
 *(unsigned int *)(pc-(4*0)) == sighndlr_pattern[5]
 *(unsigned int *)(pc+(4*1)) == sighndlr_pattern[6] )
{
  /* We have observed different calling frames among different
 versions of the operating system, so that we need to
 discriminate using the upper frame.  We look for the return
 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 *)(this_cfa + 15*4) - 4);

  if (cuh_pattern == 0xd407a04c)
{
  /* 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 *)(this_cfa + 96 + 15*4) - 4);

  if (sah_pattern == 0x92100019)
/* This is the same setup as for Solaris 9, see below.  */
regs_off = 96 + 96 + 96 + 160;
  else
/* We need to move up three frames (the kernel frame, the
   call_user_handler frame, the __sighndlr frame).  Two of them
   have the minimum stack frame size (kernel and __sighndlr
   frames) of 96 bytes, and there is another with a stack frame
   of 160 bytes (the call_user_handler frame).  The ucontext_t
   structure is after this offset.  */
regs_off = 96 + 96 + 160;
}
  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 four frames (the kernel frame, the signal
   frame, the call_user_handler frame, the __sighndlr frame).
   Three of them have the minimum stack frame size (kernel,
   signal, and __sighndlr frames) of 96 bytes, and there is
   another with a stack frame of 160 bytes (the call_user_handler
   frame).  The ucontext_t structure is after this offset.  */
regs_off = 96 + 96 + 96 + 160;
  else
/* We need to move up three frames (the kernel frame, the
   sigacthandler frame, and the __sighndlr frame).  Two of them
   have the minimum stack frame size (kernel and __sighndlr
   frames) of 96 bytes, and there is another with a stack frame
   of 216 bytes (the sigacthandler frame).  The ucontext_t 
   structure is after this offset.  */
regs_off = 96 + 96 + 216;
}

to

  if(/* Solaris 8+ - multi-threaded
   
   __sighndlr:save  %sp, -96, %sp
   __sighndlr+4:  mov  %i0, %o0
   __sighndlr+8:  mov  %i1, %o1
   __sighndlr+12: call  %i3
   __sighndlr+16: mov  %i2, %o2
   __sighndlr+20: ret --- PC
   __sighndlr+24: restore  */
pc[-5] == 0x9de3bfa0
  pc[-4] == 0x90100018
  pc[-3] == 0x92100019
  pc[-2] == 0x9fc6c000
  pc[-1] == 0x9410001a
  pc[ 0] == 0x81c7e008
  pc[ 1] == 0x81e8)
{
  if (/* Solaris 8 /usr/lib/libthread.so.1
--
sigacthandler+1796: mov  %i0, %o0  */
  savpc[-1] == 0x90100018)
{
  /* We need to move up two frames:

signal handler-- context-cfa
__sighndlr
sigacthandler
kernel
  */
  *nframes = 2;
}
  else /* Solaris 8 /usr/lib/lwp/libthread.so.1, Solaris 9+
 --  */
{
  /* We need to move up three frames:

signal handler-- context-cfa
__sighndlr
call_user_handler
sigacthandler
kernel