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]

Re: [PATCH] Fix Sparc `mprotect' trampoline problem


> The patch below fixes problem with making Sparc Solaris trampolines
> executable (I reported the problem as PR target/12865).

The problem is a regression from GCC 2.95.3 present on the 3.3 branch and 
mainline on various versions of Solaris 2.  A stack address is passed to 
mprotect before anything has been written to that address, so it may be 
unaccessible at that time.

The fix proposed by Waldek is to write onto the stack first and call mprotect 
later. I've attached a slightly tweaked patch that bootstrapped/regtested 
(3.3 branch except Ada) on

   sparc64-sun-solaris2.9
   sparc-sun-solaris2.8
   sparc-sun-solaris2.7
   sparc-sun-solaris2.6
   sparc-sun-solaris2.5.1

Ok for mainline and 3.3 branch?


2003-11-06  Waldek Hebisch  <hebisch@math.uni.wroc.pl>

	* config/sparc/sparc.c (sparc_initialize_trampoline): Call
	__enable_execute_stack only after writing onto the stack.
	(sparc64_initialize_trampoline): Likewise.


2003-11-06  Waldek Hebisch  <hebisch@math.uni.wroc.pl>

	* gcc.dg/trampoline-1.c: New test.


-- 
Eric Botcazou
Index: config/sparc/sparc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.c,v
retrieving revision 1.233.4.6
diff -u -p -r1.233.4.6 sparc.c
--- config/sparc/sparc.c	10 Sep 2003 13:03:56 -0000	1.233.4.6
+++ config/sparc/sparc.c	5 Nov 2003 05:25:29 -0000
@@ -6767,7 +6767,7 @@ void
 sparc_initialize_trampoline (tramp, fnaddr, cxt)
      rtx tramp, fnaddr, cxt;
 {
-  /* SPARC 32 bit trampoline:
+  /* SPARC 32-bit trampoline:
 
  	sethi	%hi(fn), %g1
  	sethi	%hi(static), %g2
@@ -6777,10 +6777,6 @@ sparc_initialize_trampoline (tramp, fnad
     SETHI i,r  = 00rr rrr1 00ii iiii iiii iiii iiii iiii
     JMPL r+i,d = 10dd ddd1 1100 0rrr rr1i iiii iiii iiii
    */
-#ifdef TRANSFER_FROM_TRAMPOLINE
-  emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
-                     LCT_NORMAL, VOIDmode, 1, tramp, Pmode);
-#endif
 
   emit_move_insn
     (gen_rtx_MEM (SImode, plus_constant (tramp, 0)),
@@ -6819,9 +6815,17 @@ sparc_initialize_trampoline (tramp, fnad
       && sparc_cpu != PROCESSOR_ULTRASPARC3)
     emit_insn (gen_flush (validize_mem (gen_rtx_MEM (SImode,
 						     plus_constant (tramp, 8)))));
+
+  /* Call __enable_execute_stack after writing onto the stack to make sure
+     the stack address is accessible.  */
+#ifdef TRANSFER_FROM_TRAMPOLINE
+  emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
+                     LCT_NORMAL, VOIDmode, 1, tramp, Pmode);
+#endif
+
 }
 
-/* The 64 bit version is simpler because it makes more sense to load the
+/* The 64-bit version is simpler because it makes more sense to load the
    values as "immediate" data out of the trampoline.  It's also easier since
    we can read the PC without clobbering a register.  */
 
@@ -6829,12 +6833,8 @@ void
 sparc64_initialize_trampoline (tramp, fnaddr, cxt)
      rtx tramp, fnaddr, cxt;
 {
-#ifdef TRANSFER_FROM_TRAMPOLINE
-  emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
-                     LCT_NORMAL, VOIDmode, 1, tramp, Pmode);
-#endif
+  /* SPARC 64-bit trampoline:
 
-  /*
 	rd	%pc, %g1
 	ldx	[%g1+24], %g5
 	jmp	%g5
@@ -6857,6 +6857,13 @@ sparc64_initialize_trampoline (tramp, fn
   if (sparc_cpu != PROCESSOR_ULTRASPARC
       && sparc_cpu != PROCESSOR_ULTRASPARC3)
     emit_insn (gen_flushdi (validize_mem (gen_rtx_MEM (DImode, plus_constant (tramp, 8)))));
+
+  /* Call __enable_execute_stack after writing onto the stack to make sure
+     the stack address is accessible.  */
+#ifdef TRANSFER_FROM_TRAMPOLINE
+  emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
+                     LCT_NORMAL, VOIDmode, 1, tramp, Pmode);
+#endif
 }
 
 /* Subroutines to support a flat (single) register window calling
/* PR target/12865 */
/* Origin: Waldek Hebisch <hebisch@math.uni.wroc.pl> */

/* { dg-do run } */
/* { dg-options "-O2" } */

/* This used to fail on various versions of Solaris 2 because the
   trampoline couldn't be made executable.  */

extern void abort(void);

void foo (void)
{
  const int correct[1100] = {1, 0, -2, 0, 1, 0, 1, -1, -10, -30, -67};
  int i;

  double x1 (void) {return 1; }
  double x2 (void) {return -1;}
  double x3 (void) {return -1;}
  double x4 (void) {return 1; }
  double x5 (void) {return 0; }

  typedef double pfun(void);

  double a (int k, pfun x1, pfun x2, pfun x3, pfun x4, pfun x5)
  {
    double b (void)
    {
      k = k - 1;
      return a (k, b, x1, x2, x3, x4 );
    }

    if (k <= 0)
      return x4 () + x5 ();
    else
      return b ();
  }

  for (i=0; i<=10; i++)
  {
    if (fabs(a( i, x1, x2, x3, x4, x5 ) - correct [i]) > 0.1)
      abort();
  }
}

int main (void)
{
  foo ();
  return 0;
}

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