This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix Sparc dwarf2 MAKE_THROW_FRAME



[ gcc-patches, this is the other half of the changes needed
  to fix PR target/6422 ]

As discussed at length in:

	http://gcc.gnu.org/ml/java/2002-04/msg00357.hrml
	http://gcc.gnu.org/ml/java/2002-04/msg00358.hrml
	http://gcc.gnu.org/ml/java/2002-04/msg00359.hrml
	http://gcc.gnu.org/ml/java/2002-04/msg00360.hrml

MAKE_THROW_FRAME is behaving improperly in it's sparc implementation,
and this is half of the reason for the libjava testsuite failures
for sparc-linux, as per PR target/6422.

Java folks, is this ok?

Mark, assuming Java approval, ok for 3.1 branch?

Thanks.

2002-04-25  David S. Miller  <davem@redhat.com>

	PR target/6422
	* include/dwarf2-signal.h (MAKE_THROW_FRAME for sparc*): Set
	program counter to next program counter minus 8.  Update
	comments in this macro to explain why.

--- include/dwarf2-signal.h.~1~	Sun Apr 21 04:01:38 2002
+++ include/dwarf2-signal.h	Thu Apr 25 21:41:23 2002
@@ -67,11 +67,15 @@ while (0)
 do									\
 {									\
   /* Sparc-32 leaves PC pointing at a faulting instruction		\
-   always.  So we adjust the saved PC to point to the following		\
-   instruction; this is what the handler in libgcc expects.  */		\
-  /* Note that we are lying to the unwinder here, which expects the	\
-   faulting pc, not pc+1.  But we claim the unwind information can't	\
-   be changed by such a ld or st instruction, so it doesn't matter. */	\
+   always.								\
+   We advance the PC one instruction past the exception causing PC.	\
+   This is done because FDEs are found with "context->ra - 1" in the	\
+   unwinder.								\
+   Also, the dwarf2 unwind machinery is going to add 8 to the		\
+   PC it uses on Sparc.  So we adjust the PC here.  We do it here	\
+   because we run once for such an exception, however the Sparc specific\
+   unwind can run multiple times for the same exception and it would	\
+   adjust the PC more than once resulting in a bogus value.  */		\
   struct sig_regs {							\
     unsigned int psr, pc, npc, y, u_regs[16];				\
   } *regp;								\
@@ -83,8 +87,7 @@ do									\
   else									\
     /* mov __NR_rt_sigaction, %g1; New signal stack layout */		\
     regp = (struct sig_regs *) (_sip + 1);				\
-  regp->pc = regp->npc;							\
-  regp->npc += 4;							\
+  regp->pc = (regp->npc - 8);						\
 }									\
 while (0)
 #else
@@ -92,18 +95,20 @@ while (0)
 do									\
 {									\
   /* Sparc-64 leaves PC pointing at a faulting instruction		\
-   always.  So we adjust the saved PC to point to the following		\
-   instruction; this is what the handler in libgcc expects.  */		\
-  /* Note that we are lying to the unwinder here, which expects the	\
-   faulting pc, not pc+1.  But we claim the unwind information can't	\
-   be changed by such a ld or st instruction, so it doesn't matter. */	\
+   always.								\
+   This is done because FDEs are found with "context->ra - 1" in the	\
+   unwinder.								\
+   Also, the dwarf2 unwind machinery is going to add 8 to the		\
+   PC it uses on Sparc.  So we adjust the PC here.  We do it here	\
+   because we run once for such an exception, however the Sparc specific\
+   unwind can run multiple times for the same exception and it would	\
+   adjust the PC more than once resulting in a bogus value.  */		\
   struct pt_regs {							\
     unsigned long u_regs[16];						\
     unsigned long tstate, tpc, tnpc;					\
     unsigned int y, fprs;						\
   } *regp = (struct pt_regs *) (_sip + 1);				\
-  regp->tpc = regp->tnpc;						\
-  regp->tnpc += 4;							\
+  regp->tpc = (regp->tnpc - 8);						\
 }									\
 while (0)
 #endif


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]