public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
@ 2011-05-30 18:09 Rainer Orth
  2011-05-30 20:09 ` Kai Tietz
                   ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Rainer Orth @ 2011-05-30 18:09 UTC (permalink / raw)
  To: gcc-patches
  Cc: Joseph S. Myers, Paolo Bonzini, Ralf Wildenhues, Mike Stump,
	Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

This is my hopefully last patch for toplevel libgcc moves: it moves
ENABLE_EXECUTE_STACK to $target-lib.h headers in libgcc/config.  Since
gcc/config/sol2.h is only used on Solaris targets anymore and Solaris 8
is the minimal supported version, I've removed both a Solaris 2.6
workaround and include <sys/mman.h> directly.  Same thing in osf5-lib.h.

Since the existance of the macro is used in alpha/alpha.c, i386/i386.c,
and sparc/sparc.c to enable calls to __enable_execute_stack, I had to
define HAVE_ENABLE_EXECUTE_STACK in the gcc/config headers to convey the
necessary information.

The new libgcc/config/$target-lib.h headers are added to libgcc_tm_file
in gcc/config.gcc.  I'd rather add them to libgcc/config.host instead so
the information is kept local to libgcc.

Bootstrapped without regressions on i386-pc-solaris2.11 and
sparc-sun-solaris2.11.

I've Cc'ed the OS port maintainers of the other affected targets and
would appreciate testing/review.  An OpenBSD maintainer isn't listed,
unfortunately.  Also included are the CPU port maintainers for the
modified backends.

Ok for mainline after a week if no problems occur in testing on the
other targets?

Thanks.
        Rainer


2011-05-29  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	gcc:
	* config/alpha/netbsd.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/alpha/osf5.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/darwin.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/i386/mingw32.h (MINGW_ENABLE_EXECUTE_STACK): Remove.
	(ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/i386/netbsd-elf.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/i386/netbsd64.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/netbsd.h (NETBSD_ENABLE_EXECUTE_STACK): Remove.
	* config/openbsd.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/sol2.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/sparc/freebsd.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/sparc/netbsd-elf.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/alpha/alpha.c (alpha_trampoline_init): Test
	HAVE_ENABLE_EXECUTE_STACK.
	* config/i386/i386.c (ix86_trampoline_init): Likewise.
	* config/sparc/sparc.c (sparc32_initialize_trampoline): Likewise.
	(sparc64_initialize_trampoline): Likewise.
	* config.gcc (*-*-darwin*): Add darwin-lib.h to libgcc_tm_file.
	(*-*-openbsd*): Add openbsd-lib.h to libgcc_tm_file.
	(*-*-solaris2*): Add sol2-lib.h to libgcc_tm_file.
	(alpha*-*-netbsd*): Add netbsd-lib.h to libgcc_tm_file.
	(alpha*-dec-osf5.1): Add alpha/osf5-lib.h to libgcc_tm_file.
	(i[34567]86-*-mingw*): Add i386/mingw32-lib.h to libgcc_tm_file.
	(i[34567]86-*-netbsdelf*, x86_64-*-netbsd*): Add netbsd-lib.h to
	libgcc_tm_file.
	(sparc64-*-freebsd*): Add freebsd-lib.h to libgcc_tm_file.
	(sparc-*-netbsdelf*, sparc64-*-netbsd*): Add netbsd-lib.h to
	libgcc_tm_file.
	* system.h (ENABLE_EXECUTE_STACK): Poison.

	libgcc:
	* config/alpha/osf5-lib.h: New file.
	* config/darwin-lib.h: New file.
	* config/freebsd-lib.h: New file.
	* config/i386/mingw32-lib.h: New file.
	* config/netbsd-lib.h: New file.
	* config/openbsd-lib.h: New file.
	* config/sol2-lib.h: New file.

diff --git a/gcc/config.gcc b/gcc/config.gcc
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -487,6 +487,7 @@ case ${target} in
   esac
   tm_file="${tm_file} ${cpu_type}/darwin.h"
   tm_p_file="${tm_p_file} darwin-protos.h"
+  libgcc_tm_file="${libgcc_tm_file} darwin-lib.h"
   target_gtfiles="\$(srcdir)/config/darwin.c"
   extra_options="${extra_options} darwin.opt"
   c_target_objs="${c_target_objs} darwin-c.o"
@@ -648,6 +649,7 @@ case ${target} in
   esac
   ;;
 *-*-openbsd*)
+  libgcc_tm_file="${libgcc_tm_file} openbsd-lib.h"
   tmake_file="t-libc-ok t-openbsd t-libgcc-pic"
   case ${enable_threads} in
     yes)
@@ -673,6 +675,7 @@ case ${target} in
   tm_defines="$tm_defines DEFAULT_LIBC=LIBC_UCLIBC SINGLE_LIBC"
   ;;
 *-*-solaris2*)
+  libgcc_tm_file="${libgcc_tm_file} sol2-lib.h"
   extra_options="${extra_options} sol2.opt"
   ;;
 *-*-*vms*)
@@ -730,6 +733,7 @@ alpha*-*-freebsd*)
 	;;
 alpha*-*-netbsd*)
 	tm_file="${tm_file} netbsd.h alpha/elf.h netbsd-elf.h alpha/netbsd.h"
+	libgcc_tm_file="${libgcc_tm_file} netbsd-lib.h"
 	extra_options="${extra_options} netbsd.opt netbsd-elf.opt \
 		       alpha/elf.opt"
 	target_cpu_default="MASK_GAS"
@@ -758,6 +762,7 @@ alpha*-dec-osf5.1*)
 	tmake_file="t-slibgcc-dummy"
 	tm_file="${tm_file} alpha/osf5.h"
 	tm_defines="${tm_defines} TARGET_SUPPORT_ARCH=1"
+	libgcc_tm_file="${libgcc_tm_file} alpha/osf5-lib.h"
 	extra_options="${extra_options} rpath.opt alpha/osf5.opt"
 	extra_headers=va_list.h
 	use_gcc_stdint=provide
@@ -1197,10 +1202,12 @@ x86_64-*-freebsd*)
 	;;
 i[34567]86-*-netbsdelf*)
 	tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h netbsd.h netbsd-elf.h i386/netbsd-elf.h"
+	libgcc_tm_file="${libgcc_tm_file} netbsd-lib.h"
 	extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
 	;;
 x86_64-*-netbsd*)
 	tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h netbsd.h netbsd-elf.h i386/x86-64.h i386/netbsd64.h"
+	libgcc_tm_file="${libgcc_tm_file} netbsd-lib.h"
 	extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
 	tmake_file="${tmake_file} i386/t-crtstuff"
 	;;
@@ -1447,6 +1454,7 @@ i[34567]86-*-mingw* | x86_64-*-mingw*)
 		tm_file="${tm_file} i386/mingw-pthread.h"
 	fi
 	tm_file="${tm_file} i386/mingw32.h"
+	libgcc_tm_file="${libgcc_tm_file} i386/mingw32-lib.h"
 	# This makes the logic if mingw's or the w64 feature set has to be used
 	case ${target} in
 		*-w64-*)
@@ -2462,6 +2470,7 @@ sparc-*-linux*)
 	;;
 sparc-*-netbsdelf*)
 	tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h netbsd.h netbsd-elf.h sparc/netbsd-elf.h"
+	libgcc_tm_file="${libgcc_tm_file} netbsd-lib.h"
 	extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
 	extra_options="${extra_options} sparc/long-double-switch.opt"
 	;;
@@ -2527,6 +2536,7 @@ sparc64-*-linux*)
 	;;
 sparc64-*-freebsd*|ultrasparc-*-freebsd*)
 	tm_file="${tm_file} ${fbsd_tm_file} dbxelf.h elfos.h sparc/sysv4.h sparc/freebsd.h"
+	libgcc_tm_file="${libgcc_tm_file} freebsd-lib.h"
 	extra_options="${extra_options} sparc/long-double-switch.opt"
 	tmake_file="${tmake_file} sparc/t-crtfm"
 	case "x$with_cpu" in
@@ -2538,6 +2548,7 @@ sparc64-*-freebsd*|ultrasparc-*-freebsd*
 sparc64-*-netbsd*)
 	tm_file="sparc/biarch64.h ${tm_file}"
 	tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h netbsd.h netbsd-elf.h sparc/netbsd-elf.h"
+	libgcc_tm_file="${libgcc_tm_file} netbsd-lib.h"
 	extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
 	extra_options="${extra_options} sparc/long-double-switch.opt"
 	tmake_file="${tmake_file} sparc/t-netbsd64"
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -5395,7 +5395,7 @@ alpha_trampoline_init (rtx m_tramp, tree
   if (TARGET_ABI_OSF)
     {
       emit_insn (gen_imb ());
-#ifdef ENABLE_EXECUTE_STACK
+#ifdef HAVE_ENABLE_EXECUTE_STACK
       emit_library_call (init_one_libfunc ("__enable_execute_stack"),
 			 LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
 #endif
diff --git a/gcc/config/alpha/netbsd.h b/gcc/config/alpha/netbsd.h
--- a/gcc/config/alpha/netbsd.h
+++ b/gcc/config/alpha/netbsd.h
@@ -73,7 +73,4 @@ along with GCC; see the file COPYING3.  
   "%{Ofast|ffast-math|funsafe-math-optimizations:crtfm%O%s} \
    %(netbsd_endfile_spec)"
 
-
-/* Attempt to enable execute permissions on the stack.  */
-
-#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
diff --git a/gcc/config/alpha/osf5.h b/gcc/config/alpha/osf5.h
--- a/gcc/config/alpha/osf5.h
+++ b/gcc/config/alpha/osf5.h
@@ -165,22 +165,7 @@ along with GCC; see the file COPYING3.  
 #define HAVE_STAMP_H 1
 #endif
 
-/* Attempt to turn on access permissions for the stack.  */
-
-#define ENABLE_EXECUTE_STACK						\
-void									\
-__enable_execute_stack (void *addr)					\
-{									\
-  extern int mprotect (const void *, size_t, int);			\
-  long size = getpagesize ();						\
-  long mask = ~(size-1);						\
-  char *page = (char *) (((long) addr) & mask);				\
-  char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
-									\
-  /* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */				\
-  if (mprotect (page, end - page, 7) < 0)				\
-    perror ("mprotect of trampoline code");				\
-}
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /* Digital UNIX V4.0E (1091)/usr/include/sys/types.h 4.3.49.9 1997/08/14 */
 #define SIZE_TYPE	"long unsigned int"
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -923,43 +923,7 @@ void add_framework_path (char *);
 #define TARGET_ASM_OUTPUT_ANCHOR NULL
 #define DARWIN_SECTION_ANCHORS 0
 
-/* Attempt to turn on execute permission for the stack.  This may be
-    used by TARGET_TRAMPOLINE_INIT if the target needs it (that is,
-    if the target machine can change execute permissions on a page).
-
-    There is no way to query the execute permission of the stack, so
-    we always issue the mprotect() call.
-
-    Unfortunately it is not possible to make this namespace-clean.
-
-    Also note that no errors should be emitted by this code; it is
-    considered dangerous for library calls to send messages to
-    stdout/stderr.  */
-
-#define ENABLE_EXECUTE_STACK                                            \
-extern void __enable_execute_stack (void *);                            \
-void                                                                    \
-__enable_execute_stack (void *addr)                                     \
-{                                                                       \
-   extern int mprotect (void *, size_t, int);                           \
-   extern int getpagesize (void);					\
-   static int size;                                                     \
-   static long mask;                                                    \
-                                                                        \
-   char *page, *end;                                                    \
-                                                                        \
-   if (size == 0)                                                       \
-     {                                                                  \
-       size = getpagesize();						\
-       mask = ~((long) size - 1);                                       \
-     }                                                                  \
-                                                                        \
-   page = (char *) (((long) addr) & mask);                              \
-   end  = (char *) ((((long) (addr + (TARGET_64BIT ? 48 : 40))) & mask) + size); \
-                                                                        \
-   /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */                        \
-   (void) mprotect (page, end - page, 7);                               \
-}
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /* For Apple KEXTs, we make the constructors return this to match gcc
    2.95.  */
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -23399,7 +23399,7 @@ ix86_trampoline_init (rtx m_tramp, tree 
       gcc_assert (offset <= TRAMPOLINE_SIZE);
     }
 
-#ifdef ENABLE_EXECUTE_STACK
+#ifdef HAVE_ENABLE_EXECUTE_STACK
 #ifdef CHECK_EXECUTE_STACK_ENABLED
   if (CHECK_EXECUTE_STACK_ENABLED)
 #endif
diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
--- a/gcc/config/i386/mingw32.h
+++ b/gcc/config/i386/mingw32.h
@@ -219,21 +219,7 @@ do {						         \
 /* Let defaults.h definition of TARGET_USE_JCR_SECTION apply. */
 #undef TARGET_USE_JCR_SECTION
 
-#undef MINGW_ENABLE_EXECUTE_STACK
-#define MINGW_ENABLE_EXECUTE_STACK     \
-extern void __enable_execute_stack (void *);    \
-void         \
-__enable_execute_stack (void *addr)					\
-{									\
-  MEMORY_BASIC_INFORMATION b;						\
-  if (!VirtualQuery (addr, &b, sizeof(b)))				\
-    abort ();								\
-  VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE,	\
-		  &b.Protect);						\
-}
-
-#undef ENABLE_EXECUTE_STACK
-#define ENABLE_EXECUTE_STACK MINGW_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
 #undef  CHECK_EXECUTE_STACK_ENABLED
 #define CHECK_EXECUTE_STACK_ENABLED flag_setstackexecutable
 
diff --git a/gcc/config/i386/netbsd-elf.h b/gcc/config/i386/netbsd-elf.h
--- a/gcc/config/i386/netbsd-elf.h
+++ b/gcc/config/i386/netbsd-elf.h
@@ -118,5 +118,4 @@ along with GCC; see the file COPYING3.  
    we don't care about compatibility with older gcc versions.  */
 #define DEFAULT_PCC_STRUCT_RETURN 1
 
-/* Attempt to enable execute permissions on the stack.  */
-#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
diff --git a/gcc/config/i386/netbsd64.h b/gcc/config/i386/netbsd64.h
--- a/gcc/config/i386/netbsd64.h
+++ b/gcc/config/i386/netbsd64.h
@@ -66,5 +66,4 @@ along with GCC; see the file COPYING3.  
     fprintf (FILE, "\tcall __mcount\n");				\
 }
 
-/* Attempt to enable execute permissions on the stack.  */
-#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
diff --git a/gcc/config/netbsd.h b/gcc/config/netbsd.h
--- a/gcc/config/netbsd.h
+++ b/gcc/config/netbsd.h
@@ -1,6 +1,6 @@
 /* Base configuration file for all NetBSD targets.
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2007, 2009, 2010 Free Software Foundation, Inc.
+   2007, 2009, 2010, 2011 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -173,50 +173,3 @@ along with GCC; see the file COPYING3.  
 
 #undef WINT_TYPE
 #define WINT_TYPE "int"
-\f
-
-/* Attempt to turn on execute permission for the stack.  This may be
-   used by TARGET_TRAMPOLINE_INIT if the target needs it (that is,
-   if the target machine can change execute permissions on a page).
-
-   There is no way to query the execute permission of the stack, so
-   we always issue the mprotect() call.
-
-   Note that we go out of our way to use namespace-non-invasive calls
-   here.  Unfortunately, there is no libc-internal name for mprotect().
-
-   Also note that no errors should be emitted by this code; it is considered
-   dangerous for library calls to send messages to stdout/stderr.  */
-
-#define NETBSD_ENABLE_EXECUTE_STACK					\
-extern void __enable_execute_stack (void *);				\
-void									\
-__enable_execute_stack (void *addr)					\
-{									\
-  extern int mprotect (void *, size_t, int);				\
-  extern int __sysctl (int *, unsigned int, void *, size_t *,		\
-		       void *, size_t);					\
-									\
-  static int size;							\
-  static long mask;							\
-									\
-  char *page, *end;							\
-									\
-  if (size == 0)							\
-    {									\
-      int mib[2];							\
-      size_t len;							\
-									\
-      mib[0] = 6; /* CTL_HW */						\
-      mib[1] = 7; /* HW_PAGESIZE */					\
-      len = sizeof (size);						\
-      (void) __sysctl (mib, 2, &size, &len, NULL, 0);			\
-      mask = ~((long) size - 1);					\
-    }									\
-									\
-  page = (char *) (((long) addr) & mask);				\
-  end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size);	\
-									\
-  /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */				\
-  (void) mprotect (page, end - page, 7);				\
-}
diff --git a/gcc/config/openbsd.h b/gcc/config/openbsd.h
--- a/gcc/config/openbsd.h
+++ b/gcc/config/openbsd.h
@@ -281,20 +281,4 @@ do {									 \
 /* Storage layout.  */
 
 \f
-/* Stack is explicitly denied execution rights on OpenBSD platforms.  */
-#define ENABLE_EXECUTE_STACK						\
-extern void __enable_execute_stack (void *);				\
-void									\
-__enable_execute_stack (void *addr)					\
-{									\
-  long size = getpagesize ();						\
-  long mask = ~(size-1);						\
-  char *page = (char *) (((long) addr) & mask); 			\
-  char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
-								      \
-  if (mprotect (page, end - page, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) \
-    perror ("mprotect of trampoline code");				\
-}
-
-#include <sys/types.h>
-#include <sys/mman.h>
+#define HAVE_ENABLE_EXECUTE_STACK
diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -207,52 +207,7 @@ along with GCC; see the file COPYING3.  
 
 #define STDC_0_IN_SYSTEM_HEADERS 1
 \f
-/*
- * Attempt to turn on access permissions for the stack.
- *
- * _SC_STACK_PROT is only defined for post 2.6, but we want this code
- * to run always.  2.6 can change the stack protection but has no way to
- * query it.
- *
- */
-
-/* sys/mman.h is not present on some non-Solaris configurations
-   that use sol2.h, so ENABLE_EXECUTE_STACK must use a magic
-   number instead of the appropriate PROT_* flags.  */
-
-#define ENABLE_EXECUTE_STACK					\
-									\
-/* #define STACK_PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC) */	\
-									\
-static int need_enable_exec_stack;					\
-									\
-static void check_enabling(void) __attribute__ ((constructor));		\
-static void check_enabling(void)					\
-{									\
-  extern long sysconf(int);						\
-									\
-  int prot = (int) sysconf(515 /* _SC_STACK_PROT */);			\
-  if (prot != 7 /* STACK_PROT_RWX */)					\
-    need_enable_exec_stack = 1;						\
-}									\
-									\
-extern void __enable_execute_stack (void *);				\
-void									\
-__enable_execute_stack (void *addr)					\
-{									\
-  extern int mprotect(void *, size_t, int);				\
-  if (!need_enable_exec_stack)						\
-    return;								\
-  else {								\
-    long size = getpagesize ();						\
-    long mask = ~(size-1);						\
-    char *page = (char *) (((long) addr) & mask); 			\
-    char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
-									\
-    if (mprotect (page, end - page, 7 /* STACK_PROT_RWX */) < 0)	\
-      perror ("mprotect of trampoline code");				\
-  }									\
-}
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /* Support Solaris-specific format checking for cmn_err.  */
 #define TARGET_N_FORMAT_TYPES 1
diff --git a/gcc/config/sparc/freebsd.h b/gcc/config/sparc/freebsd.h
--- a/gcc/config/sparc/freebsd.h
+++ b/gcc/config/sparc/freebsd.h
@@ -98,31 +98,7 @@ along with GCC; see the file COPYING3.  
 #undef  SPARC_DEFAULT_CMODEL
 #define SPARC_DEFAULT_CMODEL	CM_MEDLOW
 
-#define ENABLE_EXECUTE_STACK						\
-  static int need_enable_exec_stack;					\
-  static void check_enabling(void) __attribute__ ((constructor));	\
-  static void check_enabling(void)					\
-  {									\
-    extern int sysctlbyname(const char *, void *, size_t *, void *, size_t);\
-    int prot = 0;							\
-    size_t len = sizeof(prot);						\
-									\
-    sysctlbyname ("kern.stackprot", &prot, &len, NULL, 0);		\
-    if (prot != 7)							\
-      need_enable_exec_stack = 1;					\
-  }									\
-  extern void __enable_execute_stack (void *);				\
-  void __enable_execute_stack (void *addr)				\
-  {									\
-    if (!need_enable_exec_stack)					\
-      return;								\
-    else {								\
-      /* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */ 			\
-      if (mprotect (addr, TRAMPOLINE_SIZE, 7) < 0)			\
-        perror ("mprotect of trampoline code");				\
-    }									\
-  }
-
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /************************[  Assembler stuff  ]********************************/
 
diff --git a/gcc/config/sparc/netbsd-elf.h b/gcc/config/sparc/netbsd-elf.h
--- a/gcc/config/sparc/netbsd-elf.h
+++ b/gcc/config/sparc/netbsd-elf.h
@@ -74,8 +74,7 @@ along with GCC; see the file COPYING3.  
 
 #undef STDC_0_IN_SYSTEM_HEADERS
 
-/* Attempt to enable execute permissions on the stack.  */
-#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /* Below here exists the merged NetBSD/sparc & NetBSD/sparc64 compiler
    description, allowing one to build 32-bit or 64-bit applications
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -7998,7 +7998,7 @@ sparc32_initialize_trampoline (rtx m_tra
 
   /* Call __enable_execute_stack after writing onto the stack to make sure
      the stack address is accessible.  */
-#ifdef ENABLE_EXECUTE_STACK
+#ifdef HAVE_ENABLE_EXECUTE_STACK
   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
                      LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
 #endif
@@ -8041,7 +8041,7 @@ sparc64_initialize_trampoline (rtx m_tra
 
   /* Call __enable_execute_stack after writing onto the stack to make sure
      the stack address is accessible.  */
-#ifdef ENABLE_EXECUTE_STACK
+#ifdef HAVE_ENABLE_EXECUTE_STACK
   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
                      LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
 #endif
diff --git a/gcc/system.h b/gcc/system.h
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -764,7 +764,7 @@ extern void fancy_abort (const char *, i
 /* Target macros only used for code built for the target, that have
    moved to libgcc-tm.h or have never been present elsewhere.  */
  #pragma GCC poison DECLARE_LIBRARY_RENAMES LIBGCC2_GNU_PREFIX		\
-	MD_UNWIND_SUPPORT
+	MD_UNWIND_SUPPORT ENABLE_EXECUTE_STACK
 
 /* Other obsolete target macros, or macros that used to be in target
    headers and were not used, and may be obsolete or may never have
diff --git a/libgcc/config/alpha/osf5-lib.h b/libgcc/config/alpha/osf5-lib.h
new file mode 100644
--- /dev/null
+++ b/libgcc/config/alpha/osf5-lib.h
@@ -0,0 +1,38 @@
+/* libgcc configuration file for Tru64 UNIX V5.1.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Attempt to turn on access permissions for the stack.  */
+
+#include <sys/mman.h>
+#include <unistd.h>
+
+#define STACK_PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC)
+
+#define ENABLE_EXECUTE_STACK						\
+void									\
+__enable_execute_stack (void *addr)					\
+{									\
+  long size = getpagesize ();						\
+  long mask = ~(size-1);						\
+  char *page = (char *) (((long) addr) & mask);				\
+  char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
+									\
+  if (mprotect (page, end - page, STACK_PROT_RWX) < 0)			 \
+    perror ("mprotect of trampoline code");				\
+}
diff --git a/libgcc/config/darwin-lib.h b/libgcc/config/darwin-lib.h
new file mode 100644
--- /dev/null
+++ b/libgcc/config/darwin-lib.h
@@ -0,0 +1,56 @@
+/* libgcc configuration file for Darwin.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Attempt to turn on execute permission for the stack.  This may be
+   used by TARGET_TRAMPOLINE_INIT if the target needs it (that is,
+   if the target machine can change execute permissions on a page).
+
+   There is no way to query the execute permission of the stack, so
+   we always issue the mprotect() call.
+
+   Unfortunately it is not possible to make this namespace-clean.
+
+   Also note that no errors should be emitted by this code; it is
+   considered dangerous for library calls to send messages to
+   stdout/stderr.  */
+
+#define ENABLE_EXECUTE_STACK                                            \
+extern void __enable_execute_stack (void *);                            \
+void                                                                    \
+__enable_execute_stack (void *addr)                                     \
+{                                                                       \
+   extern int mprotect (void *, size_t, int);                           \
+   extern int getpagesize (void);					\
+   static int size;                                                     \
+   static long mask;                                                    \
+                                                                        \
+   char *page, *end;                                                    \
+                                                                        \
+   if (size == 0)                                                       \
+     {                                                                  \
+       size = getpagesize();						\
+       mask = ~((long) size - 1);                                       \
+     }                                                                  \
+                                                                        \
+   page = (char *) (((long) addr) & mask);                              \
+   end  = (char *) ((((long) (addr + (TARGET_64BIT ? 48 : 40))) & mask) + size); \
+                                                                        \
+   /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */                        \
+   (void) mprotect (page, end - page, 7);                               \
+}
diff --git a/libgcc/config/freebsd-lib.h b/libgcc/config/freebsd-lib.h
new file mode 100644
--- /dev/null
+++ b/libgcc/config/freebsd-lib.h
@@ -0,0 +1,43 @@
+/* libgcc configuration file for FreeBSD.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#define ENABLE_EXECUTE_STACK						\
+  static int need_enable_exec_stack;					\
+  static void check_enabling(void) __attribute__ ((constructor));	\
+  static void check_enabling(void)					\
+  {									\
+    extern int sysctlbyname(const char *, void *, size_t *, void *, size_t);\
+    int prot = 0;							\
+    size_t len = sizeof(prot);						\
+									\
+    sysctlbyname ("kern.stackprot", &prot, &len, NULL, 0);		\
+    if (prot != 7)							\
+      need_enable_exec_stack = 1;					\
+  }									\
+  extern void __enable_execute_stack (void *);				\
+  void __enable_execute_stack (void *addr)				\
+  {									\
+    if (!need_enable_exec_stack)					\
+      return;								\
+    else {								\
+      /* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */ 			\
+      if (mprotect (addr, TRAMPOLINE_SIZE, 7) < 0)			\
+        perror ("mprotect of trampoline code");				\
+    }									\
+  }
diff --git a/libgcc/config/i386/mingw32-lib.h b/libgcc/config/i386/mingw32-lib.h
new file mode 100644
--- /dev/null
+++ b/libgcc/config/i386/mingw32-lib.h
@@ -0,0 +1,30 @@
+/* libgcc configuration file for Windows32.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#define ENABLE_EXECUTE_STACK     \
+extern void __enable_execute_stack (void *);    \
+void         \
+__enable_execute_stack (void *addr)					\
+{									\
+  MEMORY_BASIC_INFORMATION b;						\
+  if (!VirtualQuery (addr, &b, sizeof(b)))				\
+    abort ();								\
+  VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE,	\
+		  &b.Protect);						\
+}
diff --git a/libgcc/config/netbsd-lib.h b/libgcc/config/netbsd-lib.h
new file mode 100644
--- /dev/null
+++ b/libgcc/config/netbsd-lib.h
@@ -0,0 +1,64 @@
+/* libgcc configuration file for NetBSD.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Attempt to turn on execute permission for the stack.  This may be
+   used by TARGET_TRAMPOLINE_INIT if the target needs it (that is,
+   if the target machine can change execute permissions on a page).
+
+   There is no way to query the execute permission of the stack, so
+   we always issue the mprotect() call.
+
+   Note that we go out of our way to use namespace-non-invasive calls
+   here.  Unfortunately, there is no libc-internal name for mprotect().
+
+   Also note that no errors should be emitted by this code; it is considered
+   dangerous for library calls to send messages to stdout/stderr.  */
+
+#define ENABLE_EXECUTE_STACK					\
+extern void __enable_execute_stack (void *);				\
+void									\
+__enable_execute_stack (void *addr)					\
+{									\
+  extern int mprotect (void *, size_t, int);				\
+  extern int __sysctl (int *, unsigned int, void *, size_t *,		\
+		       void *, size_t);					\
+									\
+  static int size;							\
+  static long mask;							\
+									\
+  char *page, *end;							\
+									\
+  if (size == 0)							\
+    {									\
+      int mib[2];							\
+      size_t len;							\
+									\
+      mib[0] = 6; /* CTL_HW */						\
+      mib[1] = 7; /* HW_PAGESIZE */					\
+      len = sizeof (size);						\
+      (void) __sysctl (mib, 2, &size, &len, NULL, 0);			\
+      mask = ~((long) size - 1);					\
+    }									\
+									\
+  page = (char *) (((long) addr) & mask);				\
+  end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size);	\
+									\
+  /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */				\
+  (void) mprotect (page, end - page, 7);				\
+}
diff --git a/libgcc/config/openbsd-lib.h b/libgcc/config/openbsd-lib.h
new file mode 100644
--- /dev/null
+++ b/libgcc/config/openbsd-lib.h
@@ -0,0 +1,36 @@
+/* libgcc configuration file for OpenBSD.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Stack is explicitly denied execution rights on OpenBSD platforms.  */
+#define ENABLE_EXECUTE_STACK						\
+extern void __enable_execute_stack (void *);				\
+void									\
+__enable_execute_stack (void *addr)					\
+{									\
+  long size = getpagesize ();						\
+  long mask = ~(size-1);						\
+  char *page = (char *) (((long) addr) & mask); 			\
+  char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
+								      \
+  if (mprotect (page, end - page, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) \
+    perror ("mprotect of trampoline code");				\
+}
+
+#include <sys/types.h>
+#include <sys/mman.h>
diff --git a/libgcc/config/sol2-lib.h b/libgcc/config/sol2-lib.h
new file mode 100644
--- /dev/null
+++ b/libgcc/config/sol2-lib.h
@@ -0,0 +1,54 @@
+/* libgcc configuration file for Solaris 2.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Attempt to turn on access permissions for the stack.  */
+
+#include <sys/mman.h>
+#include <unistd.h>
+
+#define STACK_PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC)
+
+#define ENABLE_EXECUTE_STACK						\
+									\
+static int need_enable_exec_stack;					\
+									\
+static void check_enabling(void) __attribute__ ((constructor));		\
+static void check_enabling(void)					\
+{									\
+  int prot = (int) sysconf(_SC_STACK_PROT);				\
+  if (prot != STACK_PROT_RWX)						\
+    need_enable_exec_stack = 1;						\
+}									\
+									\
+extern void __enable_execute_stack (void *);				\
+void									\
+__enable_execute_stack (void *addr)					\
+{									\
+  if (!need_enable_exec_stack)						\
+    return;								\
+  else {								\
+    long size = getpagesize ();						\
+    long mask = ~(size-1);						\
+    char *page = (char *) (((long) addr) & mask); 			\
+    char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
+									\
+    if (mprotect (page, end - page, STACK_PROT_RWX) < 0)		\
+      perror ("mprotect of trampoline code");				\
+  }									\
+}

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

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-05-30 18:09 [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc Rainer Orth
@ 2011-05-30 20:09 ` Kai Tietz
  2011-05-31  9:45 ` Paolo Bonzini
  2011-05-31 18:11 ` Mike Stump
  2 siblings, 0 replies; 21+ messages in thread
From: Kai Tietz @ 2011-05-30 20:09 UTC (permalink / raw)
  To: Rainer Orth
  Cc: Joseph S. Myers, Paolo Bonzini, Ralf Wildenhues, Mike Stump,
	Loren J. Rittle, Dave Korn, Jason Thorpe, Krister Walfridsson,
	Uros Bizjak, Richard Henderson, Eric Botcazou, gcc-patches

----- Original Message -----
From: "Rainer Orth" <ro@CeBiTec.Uni-Bielefeld.DE>
To: gcc-patches@gcc.gnu.org
Cc: "Joseph S. Myers" <joseph@codesourcery.com>, "Paolo Bonzini" <bonzini@gnu.org>, "Ralf Wildenhues" <Ralf.Wildenhues@gmx.de>, "Mike Stump" <mikestump@comcast.net>, "Loren J. Rittle" <ljrittle@acm.org>, "Kai Tietz" <ktietz@redhat.com>, "Dave Korn" <dave.korn.cygwin@gmail.com>, "Jason Thorpe" <thorpej@netbsd.org>, "Krister Walfridsson" <krister.walfridsson@gmail.com>, "Uros Bizjak" <ubizjak@gmail.com>, "Richard Henderson" <rth@redhat.com>, "Eric Botcazou" <ebotcazou@adacore.com>
Sent: Monday, May 30, 2011 5:59:10 PM
Subject: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc

This is my hopefully last patch for toplevel libgcc moves: it moves
ENABLE_EXECUTE_STACK to $target-lib.h headers in libgcc/config.  Since
gcc/config/sol2.h is only used on Solaris targets anymore and Solaris 8
is the minimal supported version, I've removed both a Solaris 2.6
workaround and include <sys/mman.h> directly.  Same thing in osf5-lib.h.

Since the existance of the macro is used in alpha/alpha.c, i386/i386.c,
and sparc/sparc.c to enable calls to __enable_execute_stack, I had to
define HAVE_ENABLE_EXECUTE_STACK in the gcc/config headers to convey the
necessary information.

The new libgcc/config/$target-lib.h headers are added to libgcc_tm_file
in gcc/config.gcc.  I'd rather add them to libgcc/config.host instead so
the information is kept local to libgcc.

Bootstrapped without regressions on i386-pc-solaris2.11 and
sparc-sun-solaris2.11.

I've Cc'ed the OS port maintainers of the other affected targets and
would appreciate testing/review.  An OpenBSD maintainer isn't listed,
unfortunately.  Also included are the CPU port maintainers for the
modified backends.

Ok for mainline after a week if no problems occur in testing on the
other targets?

Thanks.
        Rainer


2011-05-29  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	gcc:
	* config/alpha/netbsd.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/alpha/osf5.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/darwin.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/i386/mingw32.h (MINGW_ENABLE_EXECUTE_STACK): Remove.
	(ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/i386/netbsd-elf.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/i386/netbsd64.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/netbsd.h (NETBSD_ENABLE_EXECUTE_STACK): Remove.
	* config/openbsd.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/sol2.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/sparc/freebsd.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/sparc/netbsd-elf.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/alpha/alpha.c (alpha_trampoline_init): Test
	HAVE_ENABLE_EXECUTE_STACK.
	* config/i386/i386.c (ix86_trampoline_init): Likewise.
	* config/sparc/sparc.c (sparc32_initialize_trampoline): Likewise.
	(sparc64_initialize_trampoline): Likewise.
	* config.gcc (*-*-darwin*): Add darwin-lib.h to libgcc_tm_file.
	(*-*-openbsd*): Add openbsd-lib.h to libgcc_tm_file.
	(*-*-solaris2*): Add sol2-lib.h to libgcc_tm_file.
	(alpha*-*-netbsd*): Add netbsd-lib.h to libgcc_tm_file.
	(alpha*-dec-osf5.1): Add alpha/osf5-lib.h to libgcc_tm_file.
	(i[34567]86-*-mingw*): Add i386/mingw32-lib.h to libgcc_tm_file.
	(i[34567]86-*-netbsdelf*, x86_64-*-netbsd*): Add netbsd-lib.h to
	libgcc_tm_file.
	(sparc64-*-freebsd*): Add freebsd-lib.h to libgcc_tm_file.
	(sparc-*-netbsdelf*, sparc64-*-netbsd*): Add netbsd-lib.h to
	libgcc_tm_file.
	* system.h (ENABLE_EXECUTE_STACK): Poison.

	libgcc:
	* config/alpha/osf5-lib.h: New file.
	* config/darwin-lib.h: New file.
	* config/freebsd-lib.h: New file.
	* config/i386/mingw32-lib.h: New file.
	* config/netbsd-lib.h: New file.
	* config/openbsd-lib.h: New file.
	* config/sol2-lib.h: New file.

diff --git a/gcc/config.gcc b/gcc/config.gcc
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -487,6 +487,7 @@ case ${target} in
   esac
   tm_file="${tm_file} ${cpu_type}/darwin.h"
   tm_p_file="${tm_p_file} darwin-protos.h"
+  libgcc_tm_file="${libgcc_tm_file} darwin-lib.h"
   target_gtfiles="\$(srcdir)/config/darwin.c"
   extra_options="${extra_options} darwin.opt"
   c_target_objs="${c_target_objs} darwin-c.o"
@@ -648,6 +649,7 @@ case ${target} in
   esac
   ;;
 *-*-openbsd*)
+  libgcc_tm_file="${libgcc_tm_file} openbsd-lib.h"
   tmake_file="t-libc-ok t-openbsd t-libgcc-pic"
   case ${enable_threads} in
     yes)
@@ -673,6 +675,7 @@ case ${target} in
   tm_defines="$tm_defines DEFAULT_LIBC=LIBC_UCLIBC SINGLE_LIBC"
   ;;
 *-*-solaris2*)
+  libgcc_tm_file="${libgcc_tm_file} sol2-lib.h"
   extra_options="${extra_options} sol2.opt"
   ;;
 *-*-*vms*)
@@ -730,6 +733,7 @@ alpha*-*-freebsd*)
 	;;
 alpha*-*-netbsd*)
 	tm_file="${tm_file} netbsd.h alpha/elf.h netbsd-elf.h alpha/netbsd.h"
+	libgcc_tm_file="${libgcc_tm_file} netbsd-lib.h"
 	extra_options="${extra_options} netbsd.opt netbsd-elf.opt \
 		       alpha/elf.opt"
 	target_cpu_default="MASK_GAS"
@@ -758,6 +762,7 @@ alpha*-dec-osf5.1*)
 	tmake_file="t-slibgcc-dummy"
 	tm_file="${tm_file} alpha/osf5.h"
 	tm_defines="${tm_defines} TARGET_SUPPORT_ARCH=1"
+	libgcc_tm_file="${libgcc_tm_file} alpha/osf5-lib.h"
 	extra_options="${extra_options} rpath.opt alpha/osf5.opt"
 	extra_headers=va_list.h
 	use_gcc_stdint=provide
@@ -1197,10 +1202,12 @@ x86_64-*-freebsd*)
 	;;
 i[34567]86-*-netbsdelf*)
 	tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h netbsd.h netbsd-elf.h i386/netbsd-elf.h"
+	libgcc_tm_file="${libgcc_tm_file} netbsd-lib.h"
 	extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
 	;;
 x86_64-*-netbsd*)
 	tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h netbsd.h netbsd-elf.h i386/x86-64.h i386/netbsd64.h"
+	libgcc_tm_file="${libgcc_tm_file} netbsd-lib.h"
 	extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
 	tmake_file="${tmake_file} i386/t-crtstuff"
 	;;
@@ -1447,6 +1454,7 @@ i[34567]86-*-mingw* | x86_64-*-mingw*)
 		tm_file="${tm_file} i386/mingw-pthread.h"
 	fi
 	tm_file="${tm_file} i386/mingw32.h"
+	libgcc_tm_file="${libgcc_tm_file} i386/mingw32-lib.h"
 	# This makes the logic if mingw's or the w64 feature set has to be used
 	case ${target} in
 		*-w64-*)
@@ -2462,6 +2470,7 @@ sparc-*-linux*)
 	;;
 sparc-*-netbsdelf*)
 	tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h netbsd.h netbsd-elf.h sparc/netbsd-elf.h"
+	libgcc_tm_file="${libgcc_tm_file} netbsd-lib.h"
 	extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
 	extra_options="${extra_options} sparc/long-double-switch.opt"
 	;;
@@ -2527,6 +2536,7 @@ sparc64-*-linux*)
 	;;
 sparc64-*-freebsd*|ultrasparc-*-freebsd*)
 	tm_file="${tm_file} ${fbsd_tm_file} dbxelf.h elfos.h sparc/sysv4.h sparc/freebsd.h"
+	libgcc_tm_file="${libgcc_tm_file} freebsd-lib.h"
 	extra_options="${extra_options} sparc/long-double-switch.opt"
 	tmake_file="${tmake_file} sparc/t-crtfm"
 	case "x$with_cpu" in
@@ -2538,6 +2548,7 @@ sparc64-*-freebsd*|ultrasparc-*-freebsd*
 sparc64-*-netbsd*)
 	tm_file="sparc/biarch64.h ${tm_file}"
 	tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h netbsd.h netbsd-elf.h sparc/netbsd-elf.h"
+	libgcc_tm_file="${libgcc_tm_file} netbsd-lib.h"
 	extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
 	extra_options="${extra_options} sparc/long-double-switch.opt"
 	tmake_file="${tmake_file} sparc/t-netbsd64"
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -5395,7 +5395,7 @@ alpha_trampoline_init (rtx m_tramp, tree
   if (TARGET_ABI_OSF)
     {
       emit_insn (gen_imb ());
-#ifdef ENABLE_EXECUTE_STACK
+#ifdef HAVE_ENABLE_EXECUTE_STACK
       emit_library_call (init_one_libfunc ("__enable_execute_stack"),
 			 LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
 #endif
diff --git a/gcc/config/alpha/netbsd.h b/gcc/config/alpha/netbsd.h
--- a/gcc/config/alpha/netbsd.h
+++ b/gcc/config/alpha/netbsd.h
@@ -73,7 +73,4 @@ along with GCC; see the file COPYING3.  
   "%{Ofast|ffast-math|funsafe-math-optimizations:crtfm%O%s} \
    %(netbsd_endfile_spec)"
 
-
-/* Attempt to enable execute permissions on the stack.  */
-
-#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
diff --git a/gcc/config/alpha/osf5.h b/gcc/config/alpha/osf5.h
--- a/gcc/config/alpha/osf5.h
+++ b/gcc/config/alpha/osf5.h
@@ -165,22 +165,7 @@ along with GCC; see the file COPYING3.  
 #define HAVE_STAMP_H 1
 #endif
 
-/* Attempt to turn on access permissions for the stack.  */
-
-#define ENABLE_EXECUTE_STACK						\
-void									\
-__enable_execute_stack (void *addr)					\
-{									\
-  extern int mprotect (const void *, size_t, int);			\
-  long size = getpagesize ();						\
-  long mask = ~(size-1);						\
-  char *page = (char *) (((long) addr) & mask);				\
-  char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
-									\
-  /* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */				\
-  if (mprotect (page, end - page, 7) < 0)				\
-    perror ("mprotect of trampoline code");				\
-}
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /* Digital UNIX V4.0E (1091)/usr/include/sys/types.h 4.3.49.9 1997/08/14 */
 #define SIZE_TYPE	"long unsigned int"
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -923,43 +923,7 @@ void add_framework_path (char *);
 #define TARGET_ASM_OUTPUT_ANCHOR NULL
 #define DARWIN_SECTION_ANCHORS 0
 
-/* Attempt to turn on execute permission for the stack.  This may be
-    used by TARGET_TRAMPOLINE_INIT if the target needs it (that is,
-    if the target machine can change execute permissions on a page).
-
-    There is no way to query the execute permission of the stack, so
-    we always issue the mprotect() call.
-
-    Unfortunately it is not possible to make this namespace-clean.
-
-    Also note that no errors should be emitted by this code; it is
-    considered dangerous for library calls to send messages to
-    stdout/stderr.  */
-
-#define ENABLE_EXECUTE_STACK                                            \
-extern void __enable_execute_stack (void *);                            \
-void                                                                    \
-__enable_execute_stack (void *addr)                                     \
-{                                                                       \
-   extern int mprotect (void *, size_t, int);                           \
-   extern int getpagesize (void);					\
-   static int size;                                                     \
-   static long mask;                                                    \
-                                                                        \
-   char *page, *end;                                                    \
-                                                                        \
-   if (size == 0)                                                       \
-     {                                                                  \
-       size = getpagesize();						\
-       mask = ~((long) size - 1);                                       \
-     }                                                                  \
-                                                                        \
-   page = (char *) (((long) addr) & mask);                              \
-   end  = (char *) ((((long) (addr + (TARGET_64BIT ? 48 : 40))) & mask) + size); \
-                                                                        \
-   /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */                        \
-   (void) mprotect (page, end - page, 7);                               \
-}
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /* For Apple KEXTs, we make the constructors return this to match gcc
    2.95.  */
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -23399,7 +23399,7 @@ ix86_trampoline_init (rtx m_tramp, tree 
       gcc_assert (offset <= TRAMPOLINE_SIZE);
     }
 
-#ifdef ENABLE_EXECUTE_STACK
+#ifdef HAVE_ENABLE_EXECUTE_STACK
 #ifdef CHECK_EXECUTE_STACK_ENABLED
   if (CHECK_EXECUTE_STACK_ENABLED)
 #endif
diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
--- a/gcc/config/i386/mingw32.h
+++ b/gcc/config/i386/mingw32.h
@@ -219,21 +219,7 @@ do {						         \
 /* Let defaults.h definition of TARGET_USE_JCR_SECTION apply. */
 #undef TARGET_USE_JCR_SECTION
 
-#undef MINGW_ENABLE_EXECUTE_STACK
-#define MINGW_ENABLE_EXECUTE_STACK     \
-extern void __enable_execute_stack (void *);    \
-void         \
-__enable_execute_stack (void *addr)					\
-{									\
-  MEMORY_BASIC_INFORMATION b;						\
-  if (!VirtualQuery (addr, &b, sizeof(b)))				\
-    abort ();								\
-  VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE,	\
-		  &b.Protect);						\
-}
-
-#undef ENABLE_EXECUTE_STACK
-#define ENABLE_EXECUTE_STACK MINGW_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
 #undef  CHECK_EXECUTE_STACK_ENABLED
 #define CHECK_EXECUTE_STACK_ENABLED flag_setstackexecutable
 
diff --git a/gcc/config/i386/netbsd-elf.h b/gcc/config/i386/netbsd-elf.h
--- a/gcc/config/i386/netbsd-elf.h
+++ b/gcc/config/i386/netbsd-elf.h
@@ -118,5 +118,4 @@ along with GCC; see the file COPYING3.  
    we don't care about compatibility with older gcc versions.  */
 #define DEFAULT_PCC_STRUCT_RETURN 1
 
-/* Attempt to enable execute permissions on the stack.  */
-#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
diff --git a/gcc/config/i386/netbsd64.h b/gcc/config/i386/netbsd64.h
--- a/gcc/config/i386/netbsd64.h
+++ b/gcc/config/i386/netbsd64.h
@@ -66,5 +66,4 @@ along with GCC; see the file COPYING3.  
     fprintf (FILE, "\tcall __mcount\n");				\
 }
 
-/* Attempt to enable execute permissions on the stack.  */
-#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
diff --git a/gcc/config/netbsd.h b/gcc/config/netbsd.h
--- a/gcc/config/netbsd.h
+++ b/gcc/config/netbsd.h
@@ -1,6 +1,6 @@
 /* Base configuration file for all NetBSD targets.
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2007, 2009, 2010 Free Software Foundation, Inc.
+   2007, 2009, 2010, 2011 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -173,50 +173,3 @@ along with GCC; see the file COPYING3.  
 
 #undef WINT_TYPE
 #define WINT_TYPE "int"
-
-
-/* Attempt to turn on execute permission for the stack.  This may be
-   used by TARGET_TRAMPOLINE_INIT if the target needs it (that is,
-   if the target machine can change execute permissions on a page).
-
-   There is no way to query the execute permission of the stack, so
-   we always issue the mprotect() call.
-
-   Note that we go out of our way to use namespace-non-invasive calls
-   here.  Unfortunately, there is no libc-internal name for mprotect().
-
-   Also note that no errors should be emitted by this code; it is considered
-   dangerous for library calls to send messages to stdout/stderr.  */
-
-#define NETBSD_ENABLE_EXECUTE_STACK					\
-extern void __enable_execute_stack (void *);				\
-void									\
-__enable_execute_stack (void *addr)					\
-{									\
-  extern int mprotect (void *, size_t, int);				\
-  extern int __sysctl (int *, unsigned int, void *, size_t *,		\
-		       void *, size_t);					\
-									\
-  static int size;							\
-  static long mask;							\
-									\
-  char *page, *end;							\
-									\
-  if (size == 0)							\
-    {									\
-      int mib[2];							\
-      size_t len;							\
-									\
-      mib[0] = 6; /* CTL_HW */						\
-      mib[1] = 7; /* HW_PAGESIZE */					\
-      len = sizeof (size);						\
-      (void) __sysctl (mib, 2, &size, &len, NULL, 0);			\
-      mask = ~((long) size - 1);					\
-    }									\
-									\
-  page = (char *) (((long) addr) & mask);				\
-  end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size);	\
-									\
-  /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */				\
-  (void) mprotect (page, end - page, 7);				\
-}
diff --git a/gcc/config/openbsd.h b/gcc/config/openbsd.h
--- a/gcc/config/openbsd.h
+++ b/gcc/config/openbsd.h
@@ -281,20 +281,4 @@ do {									 \
 /* Storage layout.  */
 
 
-/* Stack is explicitly denied execution rights on OpenBSD platforms.  */
-#define ENABLE_EXECUTE_STACK						\
-extern void __enable_execute_stack (void *);				\
-void									\
-__enable_execute_stack (void *addr)					\
-{									\
-  long size = getpagesize ();						\
-  long mask = ~(size-1);						\
-  char *page = (char *) (((long) addr) & mask); 			\
-  char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
-								      \
-  if (mprotect (page, end - page, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) \
-    perror ("mprotect of trampoline code");				\
-}
-
-#include <sys/types.h>
-#include <sys/mman.h>
+#define HAVE_ENABLE_EXECUTE_STACK
diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -207,52 +207,7 @@ along with GCC; see the file COPYING3.  
 
 #define STDC_0_IN_SYSTEM_HEADERS 1
 
-/*
- * Attempt to turn on access permissions for the stack.
- *
- * _SC_STACK_PROT is only defined for post 2.6, but we want this code
- * to run always.  2.6 can change the stack protection but has no way to
- * query it.
- *
- */
-
-/* sys/mman.h is not present on some non-Solaris configurations
-   that use sol2.h, so ENABLE_EXECUTE_STACK must use a magic
-   number instead of the appropriate PROT_* flags.  */
-
-#define ENABLE_EXECUTE_STACK					\
-									\
-/* #define STACK_PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC) */	\
-									\
-static int need_enable_exec_stack;					\
-									\
-static void check_enabling(void) __attribute__ ((constructor));		\
-static void check_enabling(void)					\
-{									\
-  extern long sysconf(int);						\
-									\
-  int prot = (int) sysconf(515 /* _SC_STACK_PROT */);			\
-  if (prot != 7 /* STACK_PROT_RWX */)					\
-    need_enable_exec_stack = 1;						\
-}									\
-									\
-extern void __enable_execute_stack (void *);				\
-void									\
-__enable_execute_stack (void *addr)					\
-{									\
-  extern int mprotect(void *, size_t, int);				\
-  if (!need_enable_exec_stack)						\
-    return;								\
-  else {								\
-    long size = getpagesize ();						\
-    long mask = ~(size-1);						\
-    char *page = (char *) (((long) addr) & mask); 			\
-    char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
-									\
-    if (mprotect (page, end - page, 7 /* STACK_PROT_RWX */) < 0)	\
-      perror ("mprotect of trampoline code");				\
-  }									\
-}
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /* Support Solaris-specific format checking for cmn_err.  */
 #define TARGET_N_FORMAT_TYPES 1
diff --git a/gcc/config/sparc/freebsd.h b/gcc/config/sparc/freebsd.h
--- a/gcc/config/sparc/freebsd.h
+++ b/gcc/config/sparc/freebsd.h
@@ -98,31 +98,7 @@ along with GCC; see the file COPYING3.  
 #undef  SPARC_DEFAULT_CMODEL
 #define SPARC_DEFAULT_CMODEL	CM_MEDLOW
 
-#define ENABLE_EXECUTE_STACK						\
-  static int need_enable_exec_stack;					\
-  static void check_enabling(void) __attribute__ ((constructor));	\
-  static void check_enabling(void)					\
-  {									\
-    extern int sysctlbyname(const char *, void *, size_t *, void *, size_t);\
-    int prot = 0;							\
-    size_t len = sizeof(prot);						\
-									\
-    sysctlbyname ("kern.stackprot", &prot, &len, NULL, 0);		\
-    if (prot != 7)							\
-      need_enable_exec_stack = 1;					\
-  }									\
-  extern void __enable_execute_stack (void *);				\
-  void __enable_execute_stack (void *addr)				\
-  {									\
-    if (!need_enable_exec_stack)					\
-      return;								\
-    else {								\
-      /* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */ 			\
-      if (mprotect (addr, TRAMPOLINE_SIZE, 7) < 0)			\
-        perror ("mprotect of trampoline code");				\
-    }									\
-  }
-
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /************************[  Assembler stuff  ]********************************/
 
diff --git a/gcc/config/sparc/netbsd-elf.h b/gcc/config/sparc/netbsd-elf.h
--- a/gcc/config/sparc/netbsd-elf.h
+++ b/gcc/config/sparc/netbsd-elf.h
@@ -74,8 +74,7 @@ along with GCC; see the file COPYING3.  
 
 #undef STDC_0_IN_SYSTEM_HEADERS
 
-/* Attempt to enable execute permissions on the stack.  */
-#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /* Below here exists the merged NetBSD/sparc & NetBSD/sparc64 compiler
    description, allowing one to build 32-bit or 64-bit applications
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -7998,7 +7998,7 @@ sparc32_initialize_trampoline (rtx m_tra
 
   /* Call __enable_execute_stack after writing onto the stack to make sure
      the stack address is accessible.  */
-#ifdef ENABLE_EXECUTE_STACK
+#ifdef HAVE_ENABLE_EXECUTE_STACK
   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
                      LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
 #endif
@@ -8041,7 +8041,7 @@ sparc64_initialize_trampoline (rtx m_tra
 
   /* Call __enable_execute_stack after writing onto the stack to make sure
      the stack address is accessible.  */
-#ifdef ENABLE_EXECUTE_STACK
+#ifdef HAVE_ENABLE_EXECUTE_STACK
   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
                      LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
 #endif
diff --git a/gcc/system.h b/gcc/system.h
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -764,7 +764,7 @@ extern void fancy_abort (const char *, i
 /* Target macros only used for code built for the target, that have
    moved to libgcc-tm.h or have never been present elsewhere.  */
  #pragma GCC poison DECLARE_LIBRARY_RENAMES LIBGCC2_GNU_PREFIX		\
-	MD_UNWIND_SUPPORT
+	MD_UNWIND_SUPPORT ENABLE_EXECUTE_STACK
 
 /* Other obsolete target macros, or macros that used to be in target
    headers and were not used, and may be obsolete or may never have
diff --git a/libgcc/config/alpha/osf5-lib.h b/libgcc/config/alpha/osf5-lib.h
new file mode 100644
--- /dev/null
+++ b/libgcc/config/alpha/osf5-lib.h
@@ -0,0 +1,38 @@
+/* libgcc configuration file for Tru64 UNIX V5.1.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Attempt to turn on access permissions for the stack.  */
+
+#include <sys/mman.h>
+#include <unistd.h>
+
+#define STACK_PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC)
+
+#define ENABLE_EXECUTE_STACK						\
+void									\
+__enable_execute_stack (void *addr)					\
+{									\
+  long size = getpagesize ();						\
+  long mask = ~(size-1);						\
+  char *page = (char *) (((long) addr) & mask);				\
+  char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
+									\
+  if (mprotect (page, end - page, STACK_PROT_RWX) < 0)			 \
+    perror ("mprotect of trampoline code");				\
+}
diff --git a/libgcc/config/darwin-lib.h b/libgcc/config/darwin-lib.h
new file mode 100644
--- /dev/null
+++ b/libgcc/config/darwin-lib.h
@@ -0,0 +1,56 @@
+/* libgcc configuration file for Darwin.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Attempt to turn on execute permission for the stack.  This may be
+   used by TARGET_TRAMPOLINE_INIT if the target needs it (that is,
+   if the target machine can change execute permissions on a page).
+
+   There is no way to query the execute permission of the stack, so
+   we always issue the mprotect() call.
+
+   Unfortunately it is not possible to make this namespace-clean.
+
+   Also note that no errors should be emitted by this code; it is
+   considered dangerous for library calls to send messages to
+   stdout/stderr.  */
+
+#define ENABLE_EXECUTE_STACK                                            \
+extern void __enable_execute_stack (void *);                            \
+void                                                                    \
+__enable_execute_stack (void *addr)                                     \
+{                                                                       \
+   extern int mprotect (void *, size_t, int);                           \
+   extern int getpagesize (void);					\
+   static int size;                                                     \
+   static long mask;                                                    \
+                                                                        \
+   char *page, *end;                                                    \
+                                                                        \
+   if (size == 0)                                                       \
+     {                                                                  \
+       size = getpagesize();						\
+       mask = ~((long) size - 1);                                       \
+     }                                                                  \
+                                                                        \
+   page = (char *) (((long) addr) & mask);                              \
+   end  = (char *) ((((long) (addr + (TARGET_64BIT ? 48 : 40))) & mask) + size); \
+                                                                        \
+   /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */                        \
+   (void) mprotect (page, end - page, 7);                               \
+}
diff --git a/libgcc/config/freebsd-lib.h b/libgcc/config/freebsd-lib.h
new file mode 100644
--- /dev/null
+++ b/libgcc/config/freebsd-lib.h
@@ -0,0 +1,43 @@
+/* libgcc configuration file for FreeBSD.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#define ENABLE_EXECUTE_STACK						\
+  static int need_enable_exec_stack;					\
+  static void check_enabling(void) __attribute__ ((constructor));	\
+  static void check_enabling(void)					\
+  {									\
+    extern int sysctlbyname(const char *, void *, size_t *, void *, size_t);\
+    int prot = 0;							\
+    size_t len = sizeof(prot);						\
+									\
+    sysctlbyname ("kern.stackprot", &prot, &len, NULL, 0);		\
+    if (prot != 7)							\
+      need_enable_exec_stack = 1;					\
+  }									\
+  extern void __enable_execute_stack (void *);				\
+  void __enable_execute_stack (void *addr)				\
+  {									\
+    if (!need_enable_exec_stack)					\
+      return;								\
+    else {								\
+      /* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */ 			\
+      if (mprotect (addr, TRAMPOLINE_SIZE, 7) < 0)			\
+        perror ("mprotect of trampoline code");				\
+    }									\
+  }
diff --git a/libgcc/config/i386/mingw32-lib.h b/libgcc/config/i386/mingw32-lib.h
new file mode 100644
--- /dev/null
+++ b/libgcc/config/i386/mingw32-lib.h
@@ -0,0 +1,30 @@
+/* libgcc configuration file for Windows32.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#define ENABLE_EXECUTE_STACK     \
+extern void __enable_execute_stack (void *);    \
+void         \
+__enable_execute_stack (void *addr)					\
+{									\
+  MEMORY_BASIC_INFORMATION b;						\
+  if (!VirtualQuery (addr, &b, sizeof(b)))				\
+    abort ();								\
+  VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE,	\
+		  &b.Protect);						\
+}
diff --git a/libgcc/config/netbsd-lib.h b/libgcc/config/netbsd-lib.h
new file mode 100644
--- /dev/null
+++ b/libgcc/config/netbsd-lib.h
@@ -0,0 +1,64 @@
+/* libgcc configuration file for NetBSD.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Attempt to turn on execute permission for the stack.  This may be
+   used by TARGET_TRAMPOLINE_INIT if the target needs it (that is,
+   if the target machine can change execute permissions on a page).
+
+   There is no way to query the execute permission of the stack, so
+   we always issue the mprotect() call.
+
+   Note that we go out of our way to use namespace-non-invasive calls
+   here.  Unfortunately, there is no libc-internal name for mprotect().
+
+   Also note that no errors should be emitted by this code; it is considered
+   dangerous for library calls to send messages to stdout/stderr.  */
+
+#define ENABLE_EXECUTE_STACK					\
+extern void __enable_execute_stack (void *);				\
+void									\
+__enable_execute_stack (void *addr)					\
+{									\
+  extern int mprotect (void *, size_t, int);				\
+  extern int __sysctl (int *, unsigned int, void *, size_t *,		\
+		       void *, size_t);					\
+									\
+  static int size;							\
+  static long mask;							\
+									\
+  char *page, *end;							\
+									\
+  if (size == 0)							\
+    {									\
+      int mib[2];							\
+      size_t len;							\
+									\
+      mib[0] = 6; /* CTL_HW */						\
+      mib[1] = 7; /* HW_PAGESIZE */					\
+      len = sizeof (size);						\
+      (void) __sysctl (mib, 2, &size, &len, NULL, 0);			\
+      mask = ~((long) size - 1);					\
+    }									\
+									\
+  page = (char *) (((long) addr) & mask);				\
+  end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size);	\
+									\
+  /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */				\
+  (void) mprotect (page, end - page, 7);				\
+}
diff --git a/libgcc/config/openbsd-lib.h b/libgcc/config/openbsd-lib.h
new file mode 100644
--- /dev/null
+++ b/libgcc/config/openbsd-lib.h
@@ -0,0 +1,36 @@
+/* libgcc configuration file for OpenBSD.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Stack is explicitly denied execution rights on OpenBSD platforms.  */
+#define ENABLE_EXECUTE_STACK						\
+extern void __enable_execute_stack (void *);				\
+void									\
+__enable_execute_stack (void *addr)					\
+{									\
+  long size = getpagesize ();						\
+  long mask = ~(size-1);						\
+  char *page = (char *) (((long) addr) & mask); 			\
+  char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
+								      \
+  if (mprotect (page, end - page, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) \
+    perror ("mprotect of trampoline code");				\
+}
+
+#include <sys/types.h>
+#include <sys/mman.h>
diff --git a/libgcc/config/sol2-lib.h b/libgcc/config/sol2-lib.h
new file mode 100644
--- /dev/null
+++ b/libgcc/config/sol2-lib.h
@@ -0,0 +1,54 @@
+/* libgcc configuration file for Solaris 2.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Attempt to turn on access permissions for the stack.  */
+
+#include <sys/mman.h>
+#include <unistd.h>
+
+#define STACK_PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC)
+
+#define ENABLE_EXECUTE_STACK						\
+									\
+static int need_enable_exec_stack;					\
+									\
+static void check_enabling(void) __attribute__ ((constructor));		\
+static void check_enabling(void)					\
+{									\
+  int prot = (int) sysconf(_SC_STACK_PROT);				\
+  if (prot != STACK_PROT_RWX)						\
+    need_enable_exec_stack = 1;						\
+}									\
+									\
+extern void __enable_execute_stack (void *);				\
+void									\
+__enable_execute_stack (void *addr)					\
+{									\
+  if (!need_enable_exec_stack)						\
+    return;								\
+  else {								\
+    long size = getpagesize ();						\
+    long mask = ~(size-1);						\
+    char *page = (char *) (((long) addr) & mask); 			\
+    char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
+									\
+    if (mprotect (page, end - page, STACK_PROT_RWX) < 0)		\
+      perror ("mprotect of trampoline code");				\
+  }									\
+}

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

Mingw part of patch is ok.

Thanks,
Kai

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-05-30 18:09 [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc Rainer Orth
  2011-05-30 20:09 ` Kai Tietz
@ 2011-05-31  9:45 ` Paolo Bonzini
  2011-05-31 16:40   ` Rainer Orth
  2011-05-31 18:11 ` Mike Stump
  2 siblings, 1 reply; 21+ messages in thread
From: Paolo Bonzini @ 2011-05-31  9:45 UTC (permalink / raw)
  To: Rainer Orth
  Cc: gcc-patches, Joseph S. Myers, Ralf Wildenhues, Mike Stump,
	Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

On 05/30/2011 05:59 PM, Rainer Orth wrote:
> This is my hopefully last patch for toplevel libgcc moves: it moves
> ENABLE_EXECUTE_STACK to $target-lib.h headers in libgcc/config.  Since
> gcc/config/sol2.h is only used on Solaris targets anymore and Solaris 8
> is the minimal supported version, I've removed both a Solaris 2.6
> workaround and include<sys/mman.h>  directly.  Same thing in osf5-lib.h.
>
> Since the existance of the macro is used in alpha/alpha.c, i386/i386.c,
> and sparc/sparc.c to enable calls to __enable_execute_stack, I had to
> define HAVE_ENABLE_EXECUTE_STACK in the gcc/config headers to convey the
> necessary information.
>
> The new libgcc/config/$target-lib.h headers are added to libgcc_tm_file
> in gcc/config.gcc.  I'd rather add them to libgcc/config.host instead so
> the information is kept local to libgcc.

Did you have any problems doing so?

Long term, it would be even better to do something like this in 
libgcc/config.host:

enable_execute_stack=enable-execute-stack-empty.c
case $host in
   ...) enable_execute_stack=config/enable-execute-stack-mprotect.c ;;
   ...
esac

in libgcc/configure.ac:

AC_CONFIG_LINKS(enable-execute-stack.c:$enable_execute_stack)

in libgcc/Makefile.in:

LIB2ADD += enable-execute-stack.c

and drop this hunk altogether from gcc/libgcc2.c:

#ifdef L_enable_execute_stack
/* Attempt to turn on execute permission for the stack.  */

#ifdef ENABLE_EXECUTE_STACK
   ENABLE_EXECUTE_STACK
#else
void
__enable_execute_stack (void *addr __attribute__((__unused__)))
{}
#endif /* ENABLE_EXECUTE_STACK */

#endif /* L_enable_execute_stack */


> Bootstrapped without regressions on i386-pc-solaris2.11 and
> sparc-sun-solaris2.11.
>
> I've Cc'ed the OS port maintainers of the other affected targets and
> would appreciate testing/review.  An OpenBSD maintainer isn't listed,
> unfortunately.  Also included are the CPU port maintainers for the
> modified backends.
>
> Ok for mainline after a week if no problems occur in testing on the
> other targets?

It's a good start, but at least you need changes to the documentation; 
if you can make the above work, that would be great as an example of how 
to move stuff to the libgcc toplevel directory.

Paolo

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-05-31  9:45 ` Paolo Bonzini
@ 2011-05-31 16:40   ` Rainer Orth
  2011-05-31 16:57     ` Paolo Bonzini
  0 siblings, 1 reply; 21+ messages in thread
From: Rainer Orth @ 2011-05-31 16:40 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: gcc-patches, Joseph S. Myers, Ralf Wildenhues, Mike Stump,
	Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

Paolo Bonzini <bonzini@gnu.org> writes:

>> The new libgcc/config/$target-lib.h headers are added to libgcc_tm_file
>> in gcc/config.gcc.  I'd rather add them to libgcc/config.host instead so
>> the information is kept local to libgcc.
>
> Did you have any problems doing so?

There weren't any provisions in libgcc/configure.ac similar to
libgcc_tm_file in gcc/configure.ac, so I took the easy way out.

> Long term, it would be even better to do something like this in
> libgcc/config.host:
>
> enable_execute_stack=enable-execute-stack-empty.c
> case $host in
>   ...) enable_execute_stack=config/enable-execute-stack-mprotect.c ;;
>   ...
> esac
>
> in libgcc/configure.ac:
>
> AC_CONFIG_LINKS(enable-execute-stack.c:$enable_execute_stack)
>
> in libgcc/Makefile.in:
>
> LIB2ADD += enable-execute-stack.c
>
> and drop this hunk altogether from gcc/libgcc2.c:
>
> #ifdef L_enable_execute_stack
> /* Attempt to turn on execute permission for the stack.  */
>
> #ifdef ENABLE_EXECUTE_STACK
>   ENABLE_EXECUTE_STACK
> #else
> void
> __enable_execute_stack (void *addr __attribute__((__unused__)))
> {}
> #endif /* ENABLE_EXECUTE_STACK */
>
> #endif /* L_enable_execute_stack */

Seems like a plan, but I didn't go in this direction since I couldn't
test anything like this.  The various __enable_execute_stack
implementations differ in minor ways that would have to be autoconf'ed.
This should be done by someone with access to the affected platforms.

One other caveat: I don't know if I like grouping the configure support
for the enable-execute-stack.c variants together or would rather keep
all configuration for a single platform (or OS) together.  Probably a
matter of taste.

Another question: should we keep the variants in libgcc/config (like
your config/enable-execute-stack-mprotect.c) or at the toplevel (like 
enable-execute-stack-empty.c)?  At the moment I see a mixture of files
at the libgcc toplevel and others in config.

>> Bootstrapped without regressions on i386-pc-solaris2.11 and
>> sparc-sun-solaris2.11.
>>
>> I've Cc'ed the OS port maintainers of the other affected targets and
>> would appreciate testing/review.  An OpenBSD maintainer isn't listed,
>> unfortunately.  Also included are the CPU port maintainers for the
>> modified backends.
>>
>> Ok for mainline after a week if no problems occur in testing on the
>> other targets?
>
> It's a good start, but at least you need changes to the documentation; if

I'd thought about it, but refrained since HAVE_ENABLE_EXECUTE_STACK
affects only three cpus.  Currently, our documentation of libgcc
configury and macros used is close to non-existant.  That's probably for
someone who has implemented this stuff.

> you can make the above work, that would be great as an example of how to
> move stuff to the libgcc toplevel directory.

I'll give it a try, but it might take over the weekend.

Thanks.

	Rainer

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

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-05-31 16:40   ` Rainer Orth
@ 2011-05-31 16:57     ` Paolo Bonzini
  2011-06-03 15:45       ` Rainer Orth
  2011-06-07 14:00       ` Joseph S. Myers
  0 siblings, 2 replies; 21+ messages in thread
From: Paolo Bonzini @ 2011-05-31 16:57 UTC (permalink / raw)
  To: Rainer Orth
  Cc: gcc-patches, Joseph S. Myers, Ralf Wildenhues, Mike Stump,
	Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

> Seems like a plan, but I didn't go in this direction since I couldn't
> test anything like this.

As long as you test the general configury on 1-2 platforms, it's not any 
less tested than what you have now.

> The various __enable_execute_stack
> implementations differ in minor ways that would have to be autoconf'ed.

Just select them by $host.

> One other caveat: I don't know if I like grouping the configure support
> for the enable-execute-stack.c variants together or would rather keep
> all configuration for a single platform (or OS) together.  Probably a
> matter of taste.

In case it wasn't clear, I was proposing the latter.

> Another question: should we keep the variants in libgcc/config (like
> your config/enable-execute-stack-mprotect.c) or at the toplevel (like
> enable-execute-stack-empty.c)?  At the moment I see a mixture of files
> at the libgcc toplevel and others in config.

I would put them under config/ unless they are platform-independent.

> I'd thought about it, but refrained since HAVE_ENABLE_EXECUTE_STACK
> affects only three cpus.  Currently, our documentation of libgcc
> configury and macros used is close to non-existant.  That's probably for
> someone who has implemented this stuff.

True, OTOH HAVE_ENABLE_EXECUTE_STACK is a target macro, and those are 
well documented.  Just say that it has to be defined if libgcc provides 
a non-trivial implementation of __enable_execute_stack; it doesn't need 
to delve into how to hack libgcc.

>> you can make the above work, that would be great as an example of how to
>> move stuff to the libgcc toplevel directory.
>
> I'll give it a try, but it might take over the weekend.

Take your time, we're in stage1 now.

Paolo

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-05-30 18:09 [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc Rainer Orth
  2011-05-30 20:09 ` Kai Tietz
  2011-05-31  9:45 ` Paolo Bonzini
@ 2011-05-31 18:11 ` Mike Stump
  2 siblings, 0 replies; 21+ messages in thread
From: Mike Stump @ 2011-05-31 18:11 UTC (permalink / raw)
  To: Rainer Orth
  Cc: gcc-patches, Joseph S. Myers, Paolo Bonzini, Ralf Wildenhues,
	Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

On May 30, 2011, at 8:59 AM, Rainer Orth wrote:
> This is my hopefully last patch for toplevel libgcc moves: it moves
> ENABLE_EXECUTE_STACK to $target-lib.h headers in libgcc/config.

> Ok for mainline after a week if no problems occur in testing on the
> other targets?

Ok for the darwin bits.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-05-31 16:57     ` Paolo Bonzini
@ 2011-06-03 15:45       ` Rainer Orth
  2011-06-03 16:01         ` Paolo Bonzini
                           ` (2 more replies)
  2011-06-07 14:00       ` Joseph S. Myers
  1 sibling, 3 replies; 21+ messages in thread
From: Rainer Orth @ 2011-06-03 15:45 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: gcc-patches, Joseph S. Myers, Ralf Wildenhues, Mike Stump,
	Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

Paolo Bonzini <bonzini@gnu.org> writes:

>> Seems like a plan, but I didn't go in this direction since I couldn't
>> test anything like this.
>
> As long as you test the general configury on 1-2 platforms, it's not any
> less tested than what you have now.

Unfortunately, that's not true: my original patch just moved the
existing ENABLE_EXECUTE_STACK definitions to new headers in libgcc and
used them as is.  The revised one below consolidates them into two new
files, only one of them has been tested so far.

>> The various __enable_execute_stack
>> implementations differ in minor ways that would have to be autoconf'ed.
>
> Just select them by $host.

Ok, I've done that.

>> One other caveat: I don't know if I like grouping the configure support
>> for the enable-execute-stack.c variants together or would rather keep
>> all configuration for a single platform (or OS) together.  Probably a
>> matter of taste.
>
> In case it wasn't clear, I was proposing the latter.

I suppose you mean the former, i.e. grouping them together and not
setting enable_execute_stack in the existing host cases?

>> Another question: should we keep the variants in libgcc/config (like
>> your config/enable-execute-stack-mprotect.c) or at the toplevel (like
>> enable-execute-stack-empty.c)?  At the moment I see a mixture of files
>> at the libgcc toplevel and others in config.
>
> I would put them under config/ unless they are platform-independent.

Ok, done.

>> I'd thought about it, but refrained since HAVE_ENABLE_EXECUTE_STACK
>> affects only three cpus.  Currently, our documentation of libgcc
>> configury and macros used is close to non-existant.  That's probably for
>> someone who has implemented this stuff.
>
> True, OTOH HAVE_ENABLE_EXECUTE_STACK is a target macro, and those are well
> documented.  Just say that it has to be defined if libgcc provides a
> non-trivial implementation of __enable_execute_stack; it doesn't need to
> delve into how to hack libgcc.

Will do when I submit the final patch.  Right now, I've got a plan and a
draft where I'm looking for comments.

>>> you can make the above work, that would be great as an example of how to
>>> move stuff to the libgcc toplevel directory.
>>
>> I'll give it a try, but it might take over the weekend.
>
> Take your time, we're in stage1 now.

We had a public holiday yesterday :-)

So here we go: I'm including only the libgcc part of the patch, the rest
is unchanged.

The patch is only lightly tested so far, i.e. bootstrapped on
i386-pc-solaris2.8 and i386-pc-solaris2.11.

The existing variants (listed by the previous libgcc headers) are:

      alpha/osf5-lib.h		mprotect
      				addr & page, end + TRAMPOLINE_SIZE
      darwin-lib.h		mprotect
      				addr & page, end + TARGET_64BIT ? 48 : 40
      				rs6000_trampoline_size, cannot use
      				trampoline size which is a function call
      freebsd-lib.h		mprotect
      				addr, TRAMPOLINE_SIZE, why no & page?
      				check_enabling via sysctlbyname
      i386/mingw32-lib.h	VirtualProtect
      netbsd-lib.h		mprotect
      				addr & page, end + TRAMPOLINE_SIZE
      				pagesize via __sysctl
      openbsd-lib.h		mprotect
      				addr & page, end + TRAMPOLINE_SIZE
      sol2-lib.h		mprotect
      				addr & page, end + TRAMPOLINE_SIZE
      				check_enabling via sysconf

mingw32 is completely separate, while the others have much in common,
namely the use of mprotect to enable stack RWX permissions.

But there are also considerable differences:

* Except for Darwin, the code uses TRAMPOLINE_SIZE.  This only exists in
  the backend headers.  While it could be duplicated somewhere in the
  libgcc configury, I'd rather propose that gcc define
  __TRAMPOLINE_SIZE__ (in gcc/c-family/c-cppbuiltin.c (c_cpp_builtins)
  to avoid this.  On PowerPC Darwin, one cannot use TRAMPOLINE_SIZE
  definition right now since the macro calls the rs6000_trampoline_size
  function in rs6000/rs6000.c.  This would be solved nicely by
  __TRAMPOLINE_SIZE__.

* FreeBSD and Solaris use a check_enabling function to check if
  __enable_execute_stack needs to run at all.  Initially, I had
  enable-execute-stack-{freebsd, netbsd, sol2}.c, all including a common
  enable-execute-stack-mprotect.c to avoid code duplication.  I now
  consider that ugly and hard to read, and merged everything into a
  common enable-execute-stack-mprotect.c below.  Right now, the file
  uses __FreeBSD__, __NetBSD__, and __sun__ && __svr4__ to select the
  right code, but this could be autoconf'ed if desired.  There are a
  couple of FIXME comments in the code.

* NetBSD is extremely careful to avoid namespace pollution and uses
  private __sysctl (declared privately) to avoid using getpagesize.
  Either this is an issue, and we might do something similar on all
  platforms, or it's not and we should avoid special-casing NetBSD
  here.

* FreeBSD uses the unmodified address passed to __enable_execute_stack
  to call mprocted, while all others round both address and size to a
  pagesize boundary.  I cannot imagine that FreeBSD supports
  byte-granularity mprotect, so this seems an oversight.

* Windows32 calls abort when VirtualProtect fails.  With the exception
  of Darwin and NetBSD, all others call perror, which seems to be
  frowned upon.  We should be consistent here.

* gcc/config/i386/mingw32.h has

#ifdef IN_LIBGCC2
#include <windows.h>
#endif

  I strongly suspect that this is only to declare VirtualQuery and
  VirtualProtect and can go if ENABLE_EXECUTE_STACK is removed?

* Finally, __enable_execute_stack is only used on those NetBSD targets
  that actually define HAVE_ENABLE_EXECUTE_STACK, while OpenBSD uses it
  everywhere.  config.host could be simplyfied if NetBSD behaved the
  same.

As you can see, quite a can of worms, but I'm getting closer to a clean
solution.

	Rainer


2011-05-29  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	gcc:
	* libgcc2.c [L_enable_execute_stack]: Remove.

	libgcc:
	* enable-execute-stack-empty.c: New file.
	* config/enable-execute-stack-mprotect.c: New file.
	* config/i386/enable-execute-stack-mingw32.c: New file.
	* config.host (enable_execute_stack): New variable.
	Select appropriate variants.
	* configure.ac: Link enable-execute-stack.c to
	$enable_execute_stack.
	* configure: Regenerate.
	* Makefile.in (LIB2ADD): Add enable-execute-stack.c.
	(lib2funcs): Remove _enable_execute_stack.

diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -1,7 +1,7 @@
 /* More subroutines needed by GCC output code on some machines.  */
 /* Compile this one with gcc.  */
 /* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
+   2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -2027,19 +2027,6 @@ __clear_cache (char *beg __attribute__((
 
 #endif /* L_clear_cache */
 \f
-#ifdef L_enable_execute_stack
-/* Attempt to turn on execute permission for the stack.  */
-
-#ifdef ENABLE_EXECUTE_STACK
-  ENABLE_EXECUTE_STACK
-#else
-void
-__enable_execute_stack (void *addr __attribute__((__unused__)))
-{}
-#endif /* ENABLE_EXECUTE_STACK */
-
-#endif /* L_enable_execute_stack */
-\f
 #ifdef L_trampoline
 
 /* Jump to a trampoline, loading the static chain address.  */
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -313,9 +313,11 @@ ifneq ($(GCC_EXTRA_PARTS),)
 endif
 endif
 
+LIB2ADD += enable-execute-stack.c
+
 # Library members defined in libgcc2.c.
 lib2funcs = _muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3 _cmpdi2 _ucmpdi2	   \
-	    _clear_cache _enable_execute_stack _trampoline __main _absvsi2 \
+	    _clear_cache _trampoline __main _absvsi2 \
 	    _absvdi2 _addvsi3 _addvdi3 _subvsi3 _subvdi3 _mulvsi3 _mulvdi3 \
 	    _negvsi2 _negvdi2 _ctors _ffssi2 _ffsdi2 _clz _clzsi2 _clzdi2  \
 	    _ctzsi2 _ctzdi2 _popcount_tab _popcountsi2 _popcountdi2	   \
diff --git a/libgcc/config.host b/libgcc/config.host
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -44,6 +44,8 @@
 #			The default is ".hidden".
 #  cpu_type		The name of the cpu, if different from the first
 #			chunk of the canonical host name.
+#  enable_execute_stack The name of a source file implementing
+#			__enable_execute_stack.
 #  extra_parts		List of extra object files that should be compiled
 #			for this target machine.  This may be overridden
 #			by setting EXTRA_PARTS in a tmake_file fragment.
@@ -57,6 +59,7 @@
 #			"$cpu_type/t-$cpu_type".
 
 asm_hidden_op=.hidden
+enable_execute_stack=
 extra_parts=
 tmake_file=
 md_unwind_header=no-unwind.h
@@ -202,6 +205,26 @@ case ${host} in
   ;;
 esac
 
+# FIXME: Apply to *-*-netbsd*?
+case ${host} in
+*-*-darwin* | \
+  *-*-openbsd* | \
+  *-*-solaris2* | \
+  alpha*-dec-osf5.1* | \
+  alpha*-*-netbsd* | \
+  i[34567]86-*-netbsdelf* | x86_64-*-netbsd* | \
+  sparc-*-netbsdelf* | sparc64-*-netbsd* | \
+  sparc64-*-freebsd* | ultrasparc-*-freebsd*)
+  enable_execute_stack=config/enable-execute-stack-mprotect.c
+  ;;
+i[34567]86-*-mingw* | x86_64-*-mingw*)
+  enable_execute_stack=config/i386/enable-execute-stack-mingw32.c
+  ;;
+*)
+  enable_execute_stack=enable-execute-stack-empty.c;
+  ;;
+esac
+
 case ${host} in
 # Support site-specific machine types.
 *local*)
diff --git a/libgcc/config/enable-execute-stack-mprotect.c b/libgcc/config/enable-execute-stack-mprotect.c
new file mode 100644
--- /dev/null
+++ b/libgcc/config/enable-execute-stack-mprotect.c
@@ -0,0 +1,114 @@
+/* Implement __enable_execute_stack using mprotect(2).
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 3, or (at your option) any later
+   version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sys/mman.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#define STACK_PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC)
+
+static int need_enable_exec_stack;
+
+static void check_enabling(void) __attribute__ ((constructor));
+extern void __enable_execute_stack (void *);
+
+#if defined __FreeBSD__
+/* FIXME: Use HAVE_SYSCTLBYNAME instead?  Need libgcc config.h for that,
+   and perhaps check for kern.stackprot.  */
+#include <sys/sysctl.h>
+
+static void
+check_enabling (void)
+{
+  int prot = 0;
+  size_t len = sizeof (prot);
+
+  sysctlbyname ("kern.stackprot", &prot, &len, NULL, 0);
+  if (prot != STACK_PROT_RWX)
+    need_enable_exec_stack = 1;
+}
+#elif defined __sun__ && defined __svr4__
+/* FIXME: Use defined _SC_STACK_PROT instead?  */
+static void
+check_enabling (void)
+{
+  int prot = (int) sysconf (_SC_STACK_PROT);
+
+  if (prot != STACK_PROT_RWX)
+    need_enable_exec_stack = 1;
+}
+#else
+static void
+check_enabling (void)
+{
+  need_enable_exec_stack = 1;
+}
+#endif
+
+#if defined __NetBSD__
+/* FIXME: Use HAVE___SYSCTL instead?  */
+#include <sys/sysctl.h>
+
+/* FIXME: Include comment wrt. namespace cleanlyness.  */
+/* FIXME: Header?  */
+extern int __sysctl (int *, unsigned int, void *, size_t *, void *, size_t);
+
+static int
+getpagesize (void)
+{
+  static int size;
+
+  if (size == 0)
+    {
+      int mib[2];
+      size_t len;
+
+      mib[0] = CTL_HW;
+      mib[1] = HW_PAGESIZE;
+      len = sizeof (size);
+      (void) __sysctl (mib, 2, &size, &len, NULL, 0);
+    }
+  return size;
+}
+#endif /* __NetBSD__ */
+
+void
+__enable_execute_stack (void *addr)
+{
+  if (!need_enable_exec_stack)
+    return;
+  else
+    {
+      long size = getpagesize ();
+      long mask = ~(size - 1);
+      char *page = (char *) (((long) addr) & mask);
+      char *end  = (char *) ((((long) (addr + __TRAMPOLINE_SIZE__)) & mask)
+			     + size);
+
+      /* FIXME: Use addr, __TRAMPOLINE_SIZE__ directly on FreeBSD!?  */
+      if (mprotect (page, end - page, STACK_PROT_RWX) < 0)
+	/* FIXME: Make conditional, use abort instead?  */
+	perror ("mprotect of trampoline code");
+    }
+}
diff --git a/libgcc/config/i386/enable-execute-stack-mingw32.c b/libgcc/config/i386/enable-execute-stack-mingw32.c
new file mode 100644
--- /dev/null
+++ b/libgcc/config/i386/enable-execute-stack-mingw32.c
@@ -0,0 +1,16 @@
+/* Implement __enable_execute_stack for Windows32.  */
+
+#include <windows.h>
+
+extern void __enable_execute_stack (void *);
+
+void
+__enable_execute_stack (void *addr)
+{
+  MEMORY_BASIC_INFORMATION b;
+
+  if (!VirtualQuery (addr, &b, sizeof(b)))
+    abort ();
+  VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE,
+		  &b.Protect);
+}
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -278,6 +278,7 @@ AC_SUBST(tmake_file)
 AC_SUBST(cpu_type)
 AC_SUBST(extra_parts)
 AC_SUBST(asm_hidden_op)
+AC_CONFIG_LINKS([enable-execute-stack.c:$enable_execute_stack])
 AC_CONFIG_LINKS([md-unwind-support.h:config/$md_unwind_header])
 
 # We need multilib support.
diff --git a/libgcc/enable-execute-stack-empty.c b/libgcc/enable-execute-stack-empty.c
new file mode 100644
--- /dev/null
+++ b/libgcc/enable-execute-stack-empty.c
@@ -0,0 +1,7 @@
+/* Dummy implementation of __enable_execute_stack.  */
+
+/* Attempt to turn on execute permission for the stack.  */
+void
+__enable_execute_stack (void *addr __attribute__((__unused__)))
+{
+}


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

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-06-03 15:45       ` Rainer Orth
@ 2011-06-03 16:01         ` Paolo Bonzini
  2011-06-06  9:18           ` Rainer Orth
  2011-06-04 11:00         ` Gerald Pfeifer
  2011-06-04 11:17         ` Andreas Schwab
  2 siblings, 1 reply; 21+ messages in thread
From: Paolo Bonzini @ 2011-06-03 16:01 UTC (permalink / raw)
  To: Rainer Orth
  Cc: gcc-patches, Joseph S. Myers, Ralf Wildenhues, Mike Stump,
	Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

On 06/03/2011 05:45 PM, Rainer Orth wrote:
> Paolo Bonzini<bonzini@gnu.org>  writes:
>
>>> >>  Seems like a plan, but I didn't go in this direction since I couldn't
>>> >>  test anything like this.
>> >
>> >  As long as you test the general configury on 1-2 platforms, it's not any
>> >  less tested than what you have now.
> Unfortunately, that's not true: my original patch just moved the
> existing ENABLE_EXECUTE_STACK definitions to new headers in libgcc and
> used them as is.  The revised one below consolidates them into two new
> files, only one of them has been tested so far.

Yes, I wasn't expecting to go to this length.  But thanks for doing it.

>>> >>  One other caveat: I don't know if I like grouping the configure support
>>> >>  for the enable-execute-stack.c variants together or would rather keep
>>> >>  all configuration for a single platform (or OS) together.  Probably a
>>> >>  matter of taste.
>> >
>> >  In case it wasn't clear, I was proposing the latter.
> I suppose you mean the former, i.e. grouping them together and not
> setting enable_execute_stack in the existing host cases?

I meant doing it in config.host, because I was expecting you to keep all 
implementations in separate *.c files, even for all the mprotect 
variants, but I agree your patch is better.

> Will do when I submit the final patch.  Right now, I've got a plan and a
> draft where I'm looking for comments.

Makes sense.

> * Except for Darwin, the code uses TRAMPOLINE_SIZE.  This only exists in
>    the backend headers.  While it could be duplicated somewhere in the
>    libgcc configury, I'd rather propose that gcc define
>    __TRAMPOLINE_SIZE__ (in gcc/c-family/c-cppbuiltin.c (c_cpp_builtins)
>    to avoid this.  On PowerPC Darwin, one cannot use TRAMPOLINE_SIZE
>    definition right now since the macro calls the rs6000_trampoline_size
>    function in rs6000/rs6000.c.  This would be solved nicely by
>    __TRAMPOLINE_SIZE__.

Good idea.

> * FreeBSD and Solaris use a check_enabling function to check if
>    __enable_execute_stack needs to run at all.  Initially, I had
>    enable-execute-stack-{freebsd, netbsd, sol2}.c, all including a common
>    enable-execute-stack-mprotect.c to avoid code duplication.  I now
>    consider that ugly and hard to read, and merged everything into a
>    common enable-execute-stack-mprotect.c below.  Right now, the file
>    uses __FreeBSD__, __NetBSD__, and __sun__&&  __svr4__ to select the
>    right code, but this could be autoconf'ed if desired.  There are a
>    couple of FIXME comments in the code.

Please avoid putting the ((constructor)) in common code.  You can put

static int i = 1;

in the #else case, and leave

static int i;

in common code.

> * NetBSD is extremely careful to avoid namespace pollution and uses
>    private __sysctl (declared privately) to avoid using getpagesize.
>    Either this is an issue, and we might do something similar on all
>    platforms, or it's not and we should avoid special-casing NetBSD
>    here.

Perhaps it has to do with getpagesize not being available for old 
versions of NetBSD.  No idea, but I'd leave it as is.

> * FreeBSD uses the unmodified address passed to __enable_execute_stack
>    to call mprocted, while all others round both address and size to a
>    pagesize boundary.  I cannot imagine that FreeBSD supports
>    byte-granularity mprotect, so this seems an oversight.

Agreed.

> * Windows32 calls abort when VirtualProtect fails.  With the exception
>    of Darwin and NetBSD, all others call perror, which seems to be
>    frowned upon.  We should be consistent here.

I think it should either abort() or do nothing, consistently across all 
platforms.

> * gcc/config/i386/mingw32.h has
>
> #ifdef IN_LIBGCC2
> #include<windows.h>
> #endif
>
>    I strongly suspect that this is only to declare VirtualQuery and
>    VirtualProtect and can go if ENABLE_EXECUTE_STACK is removed?

Yes, it should go.

> * Finally, __enable_execute_stack is only used on those NetBSD targets
> that actually define HAVE_ENABLE_EXECUTE_STACK, while OpenBSD uses it
> everywhere.  config.host could be simplyfied if NetBSD behaved the
> same.

I would add it to all NetBSDs, and perhaps all FreeBSDs too?  Do you 
know why SPARC is special?

Paolo

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-06-03 15:45       ` Rainer Orth
  2011-06-03 16:01         ` Paolo Bonzini
@ 2011-06-04 11:00         ` Gerald Pfeifer
  2011-06-04 11:17         ` Andreas Schwab
  2 siblings, 0 replies; 21+ messages in thread
From: Gerald Pfeifer @ 2011-06-04 11:00 UTC (permalink / raw)
  To: Rainer Orth
  Cc: Paolo Bonzini, gcc-patches, Joseph S. Myers, Ralf Wildenhues,
	Mike Stump, Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

On Fri, 3 Jun 2011, Rainer Orth wrote:
> * FreeBSD uses the unmodified address passed to __enable_execute_stack
>   to call mprocted, while all others round both address and size to a
>   pagesize boundary.  I cannot imagine that FreeBSD supports
>   byte-granularity mprotect, so this seems an oversight.

The man page of mprotect on FreeBSD 9 (the next release) states the
following which seems supportive of your theory:

  NAME
     mprotect -- control the protection of pages
  :
  DESCRIPTION
     The mprotect() system call changes the specified pages to have protection
     prot.  Not all implementations will guarantee protection on a page basis;
     the granularity of protection changes may be as large as an entire
     region.  A region is the virtual address space defined by the start and
     end addresses of a struct vm_map_entry.


Gerald

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-06-03 15:45       ` Rainer Orth
  2011-06-03 16:01         ` Paolo Bonzini
  2011-06-04 11:00         ` Gerald Pfeifer
@ 2011-06-04 11:17         ` Andreas Schwab
  2 siblings, 0 replies; 21+ messages in thread
From: Andreas Schwab @ 2011-06-04 11:17 UTC (permalink / raw)
  To: Rainer Orth
  Cc: Paolo Bonzini, gcc-patches, Joseph S. Myers, Ralf Wildenhues,
	Mike Stump, Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:

> * FreeBSD uses the unmodified address passed to __enable_execute_stack
>   to call mprocted, while all others round both address and size to a
>   pagesize boundary.  I cannot imagine that FreeBSD supports
>   byte-granularity mprotect, so this seems an oversight.

Apparently freebsd's mprotect aligns the address by itself, so it will
not make any difference.  At least linux's mprotect will barf if the
address is unaligned.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-06-03 16:01         ` Paolo Bonzini
@ 2011-06-06  9:18           ` Rainer Orth
  2011-06-06  9:23             ` Paolo Bonzini
  2011-06-07 15:20             ` Joseph S. Myers
  0 siblings, 2 replies; 21+ messages in thread
From: Rainer Orth @ 2011-06-06  9:18 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: gcc-patches, Joseph S. Myers, Ralf Wildenhues, Mike Stump,
	Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

Paolo Bonzini <bonzini@gnu.org> writes:

>> * Except for Darwin, the code uses TRAMPOLINE_SIZE.  This only exists in
>>    the backend headers.  While it could be duplicated somewhere in the
>>    libgcc configury, I'd rather propose that gcc define
>>    __TRAMPOLINE_SIZE__ (in gcc/c-family/c-cppbuiltin.c (c_cpp_builtins)
>>    to avoid this.  On PowerPC Darwin, one cannot use TRAMPOLINE_SIZE
>>    definition right now since the macro calls the rs6000_trampoline_size
>>    function in rs6000/rs6000.c.  This would be solved nicely by
>>    __TRAMPOLINE_SIZE__.
>
> Good idea.

Included in the revised patch below.  This part will need Joseph's approval.

>> * FreeBSD and Solaris use a check_enabling function to check if
>>    __enable_execute_stack needs to run at all.  Initially, I had
>>    enable-execute-stack-{freebsd, netbsd, sol2}.c, all including a common
>>    enable-execute-stack-mprotect.c to avoid code duplication.  I now
>>    consider that ugly and hard to read, and merged everything into a
>>    common enable-execute-stack-mprotect.c below.  Right now, the file
>>    uses __FreeBSD__, __NetBSD__, and __sun__&&  __svr4__ to select the
>>    right code, but this could be autoconf'ed if desired.  There are a
>>    couple of FIXME comments in the code.
>
> Please avoid putting the ((constructor)) in common code.  You can put
>
> static int i = 1;
>
> in the #else case, and leave
>
> static int i;
>
> in common code.

Ok, done.

>> * NetBSD is extremely careful to avoid namespace pollution and uses
>>    private __sysctl (declared privately) to avoid using getpagesize.
>>    Either this is an issue, and we might do something similar on all
>>    platforms, or it's not and we should avoid special-casing NetBSD
>>    here.
>
> Perhaps it has to do with getpagesize not being available for old versions
> of NetBSD.  No idea, but I'd leave it as is.

I've now included the relevant comments from the old
ENABLE_EXECUTE_STACK definitions where it's claimed this is done for
namespace cleanliness.

>> * Windows32 calls abort when VirtualProtect fails.  With the exception
>>    of Darwin and NetBSD, all others call perror, which seems to be
>>    frowned upon.  We should be consistent here.
>
> I think it should either abort() or do nothing, consistently across all
> platforms.

I'm going for abort then.  Silently failing here is bad IMO since the
user will have to debug an issue in the runtime library.  libgcc2.c is
already using abort in a couple of places, so there's a precedent.

>> * gcc/config/i386/mingw32.h has
>>
>> #ifdef IN_LIBGCC2
>> #include<windows.h>
>> #endif
>>
>>    I strongly suspect that this is only to declare VirtualQuery and
>>    VirtualProtect and can go if ENABLE_EXECUTE_STACK is removed?
>
> Yes, it should go.

Done.

>> * Finally, __enable_execute_stack is only used on those NetBSD targets
>> that actually define HAVE_ENABLE_EXECUTE_STACK, while OpenBSD uses it
>> everywhere.  config.host could be simplyfied if NetBSD behaved the
>> same.
>
> I would add it to all NetBSDs, and perhaps all FreeBSDs too?  Do you know
> why SPARC is special?

I've no idea.  Given that OpenBSD uses the same implementation across
all targets, I'm treating the two other BSDs the same now, unless the
maintainers objects.

I've removed a couple of FIXME comments I had in the last version:

* Instead of __FreeBSD__, one could use HAVE_SYSCTLBYNAME instead, but
  that would need a new libgcc config.h header.  In addition, we might
  have to check for kern.stackprot to make sure the code really works.

* Similarly, instead of testing __sun__ && __svr4__, one could check
  _SC_STACK_PROT.

* Last, rather than checking __NetBSD__, one could go for HAVE___SYSCTL.

* __sysctl is currently declared manully.  AFAICS there's no header for
  that.  At least the FreeBSD libc declares it itself in two places:
  lib/libc/sys/stack_protector.c and lib/libc/gen/sysctl.c.

Given that this is closely tied to the various platforms, it seems
appropriate to continue to use the OS defines.

Here's the full patch, regtested without regressions on
i386-pc-solaris2.11.

Ok for mainline?

	Rainer


2011-05-29  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	gcc:
	* config/alpha/netbsd.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/alpha/osf5.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/darwin.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/i386/mingw32.h (MINGW_ENABLE_EXECUTE_STACK): Remove.
	(ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	[IN_LIBGCC2]: Don't include <windows.h>.
	* config/i386/netbsd-elf.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/i386/netbsd64.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/netbsd.h (NETBSD_ENABLE_EXECUTE_STACK): Remove.
	* config/openbsd.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/sol2.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/sparc/freebsd.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/sparc/netbsd-elf.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/alpha/alpha.c (alpha_trampoline_init): Test
	HAVE_ENABLE_EXECUTE_STACK.
	* config/i386/i386.c (ix86_trampoline_init): Likewise.
	* config/sparc/sparc.c (sparc32_initialize_trampoline): Likewise.
	(sparc64_initialize_trampoline): Likewise.
	* libgcc2.c [L_enable_execute_stack]: Remove.
	* system.h (ENABLE_EXECUTE_STACK): Poison.
	* doc/tm.texi.in (Trampolines, HAVE_ENABLE_EXECUTE_STACK): Document.
	(Trampolines, ENABLE_EXECUTE_STACK): Remove.
	* doc/tm.texi: Regenerate.

	gcc/c-family:
	* c-cppbuiltin.c (c_cpp_builtins): Define __TRAMPOLINE_SIZE__.

	libgcc:
	* enable-execute-stack-empty.c: New file.
	* enable-execute-stack-mprotect.c: New file.
	* config/i386/enable-execute-stack-mingw32.c: New file.
	* config.host (enable_execute_stack): New variable.
	Select appropriate variants.
	* configure.ac: Link enable-execute-stack.c to
	$enable_execute_stack.
	* configure: Regenerate.
	* Makefile.in (LIB2ADD): Add enable-execute-stack.c.
	(lib2funcs): Remove _enable_execute_stack.

diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -1,5 +1,5 @@
 /* Define builtin-in macros for the C family front ends.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -727,6 +727,9 @@ c_cpp_builtins (cpp_reader *pfile)
       builtin_define_fixed_point_constants ("UTA", "", uta_type_node);
     }
 
+  /* For libgcc enable-execute-stack.c.  */
+  builtin_define_with_int_value ("__TRAMPOLINE_SIZE__", TRAMPOLINE_SIZE);
+
   /* For use in assembly language.  */
   builtin_define_with_value ("__REGISTER_PREFIX__", REGISTER_PREFIX, 0);
   builtin_define_with_value ("__USER_LABEL_PREFIX__", user_label_prefix, 0);
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -5395,7 +5395,7 @@ alpha_trampoline_init (rtx m_tramp, tree
   if (TARGET_ABI_OSF)
     {
       emit_insn (gen_imb ());
-#ifdef ENABLE_EXECUTE_STACK
+#ifdef HAVE_ENABLE_EXECUTE_STACK
       emit_library_call (init_one_libfunc ("__enable_execute_stack"),
 			 LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
 #endif
diff --git a/gcc/config/alpha/netbsd.h b/gcc/config/alpha/netbsd.h
--- a/gcc/config/alpha/netbsd.h
+++ b/gcc/config/alpha/netbsd.h
@@ -73,7 +73,4 @@ along with GCC; see the file COPYING3.  
   "%{Ofast|ffast-math|funsafe-math-optimizations:crtfm%O%s} \
    %(netbsd_endfile_spec)"
 
-
-/* Attempt to enable execute permissions on the stack.  */
-
-#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
diff --git a/gcc/config/alpha/osf5.h b/gcc/config/alpha/osf5.h
--- a/gcc/config/alpha/osf5.h
+++ b/gcc/config/alpha/osf5.h
@@ -165,22 +165,7 @@ along with GCC; see the file COPYING3.  
 #define HAVE_STAMP_H 1
 #endif
 
-/* Attempt to turn on access permissions for the stack.  */
-
-#define ENABLE_EXECUTE_STACK						\
-void									\
-__enable_execute_stack (void *addr)					\
-{									\
-  extern int mprotect (const void *, size_t, int);			\
-  long size = getpagesize ();						\
-  long mask = ~(size-1);						\
-  char *page = (char *) (((long) addr) & mask);				\
-  char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
-									\
-  /* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */				\
-  if (mprotect (page, end - page, 7) < 0)				\
-    perror ("mprotect of trampoline code");				\
-}
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /* Digital UNIX V4.0E (1091)/usr/include/sys/types.h 4.3.49.9 1997/08/14 */
 #define SIZE_TYPE	"long unsigned int"
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -919,43 +919,7 @@ void add_framework_path (char *);
 #define TARGET_ASM_OUTPUT_ANCHOR NULL
 #define DARWIN_SECTION_ANCHORS 0
 
-/* Attempt to turn on execute permission for the stack.  This may be
-    used by TARGET_TRAMPOLINE_INIT if the target needs it (that is,
-    if the target machine can change execute permissions on a page).
-
-    There is no way to query the execute permission of the stack, so
-    we always issue the mprotect() call.
-
-    Unfortunately it is not possible to make this namespace-clean.
-
-    Also note that no errors should be emitted by this code; it is
-    considered dangerous for library calls to send messages to
-    stdout/stderr.  */
-
-#define ENABLE_EXECUTE_STACK                                            \
-extern void __enable_execute_stack (void *);                            \
-void                                                                    \
-__enable_execute_stack (void *addr)                                     \
-{                                                                       \
-   extern int mprotect (void *, size_t, int);                           \
-   extern int getpagesize (void);					\
-   static int size;                                                     \
-   static long mask;                                                    \
-                                                                        \
-   char *page, *end;                                                    \
-                                                                        \
-   if (size == 0)                                                       \
-     {                                                                  \
-       size = getpagesize();						\
-       mask = ~((long) size - 1);                                       \
-     }                                                                  \
-                                                                        \
-   page = (char *) (((long) addr) & mask);                              \
-   end  = (char *) ((((long) (addr + (TARGET_64BIT ? 48 : 40))) & mask) + size); \
-                                                                        \
-   /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */                        \
-   (void) mprotect (page, end - page, 7);                               \
-}
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /* For Apple KEXTs, we make the constructors return this to match gcc
    2.95.  */
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -23387,7 +23387,7 @@ ix86_trampoline_init (rtx m_tramp, tree 
       gcc_assert (offset <= TRAMPOLINE_SIZE);
     }
 
-#ifdef ENABLE_EXECUTE_STACK
+#ifdef HAVE_ENABLE_EXECUTE_STACK
 #ifdef CHECK_EXECUTE_STACK_ENABLED
   if (CHECK_EXECUTE_STACK_ENABLED)
 #endif
diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
--- a/gcc/config/i386/mingw32.h
+++ b/gcc/config/i386/mingw32.h
@@ -219,28 +219,10 @@ do {						         \
 /* Let defaults.h definition of TARGET_USE_JCR_SECTION apply. */
 #undef TARGET_USE_JCR_SECTION
 
-#undef MINGW_ENABLE_EXECUTE_STACK
-#define MINGW_ENABLE_EXECUTE_STACK     \
-extern void __enable_execute_stack (void *);    \
-void         \
-__enable_execute_stack (void *addr)					\
-{									\
-  MEMORY_BASIC_INFORMATION b;						\
-  if (!VirtualQuery (addr, &b, sizeof(b)))				\
-    abort ();								\
-  VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE,	\
-		  &b.Protect);						\
-}
-
-#undef ENABLE_EXECUTE_STACK
-#define ENABLE_EXECUTE_STACK MINGW_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
 #undef  CHECK_EXECUTE_STACK_ENABLED
 #define CHECK_EXECUTE_STACK_ENABLED flag_setstackexecutable
 
-#ifdef IN_LIBGCC2
-#include <windows.h>
-#endif
-
 /* This matches SHLIB_SONAME and SHLIB_SOVERSION in t-cygming. */
 /* This matches SHLIB_SONAME and SHLIB_SOVERSION in t-cygwin. */
 #if DWARF2_UNWIND_INFO
diff --git a/gcc/config/i386/netbsd-elf.h b/gcc/config/i386/netbsd-elf.h
--- a/gcc/config/i386/netbsd-elf.h
+++ b/gcc/config/i386/netbsd-elf.h
@@ -118,5 +118,4 @@ along with GCC; see the file COPYING3.  
    we don't care about compatibility with older gcc versions.  */
 #define DEFAULT_PCC_STRUCT_RETURN 1
 
-/* Attempt to enable execute permissions on the stack.  */
-#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
diff --git a/gcc/config/i386/netbsd64.h b/gcc/config/i386/netbsd64.h
--- a/gcc/config/i386/netbsd64.h
+++ b/gcc/config/i386/netbsd64.h
@@ -66,5 +66,4 @@ along with GCC; see the file COPYING3.  
     fprintf (FILE, "\tcall __mcount\n");				\
 }
 
-/* Attempt to enable execute permissions on the stack.  */
-#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
diff --git a/gcc/config/netbsd.h b/gcc/config/netbsd.h
--- a/gcc/config/netbsd.h
+++ b/gcc/config/netbsd.h
@@ -1,6 +1,6 @@
 /* Base configuration file for all NetBSD targets.
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2007, 2009, 2010 Free Software Foundation, Inc.
+   2007, 2009, 2010, 2011 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -173,50 +173,3 @@ along with GCC; see the file COPYING3.  
 
 #undef WINT_TYPE
 #define WINT_TYPE "int"
-\f
-
-/* Attempt to turn on execute permission for the stack.  This may be
-   used by TARGET_TRAMPOLINE_INIT if the target needs it (that is,
-   if the target machine can change execute permissions on a page).
-
-   There is no way to query the execute permission of the stack, so
-   we always issue the mprotect() call.
-
-   Note that we go out of our way to use namespace-non-invasive calls
-   here.  Unfortunately, there is no libc-internal name for mprotect().
-
-   Also note that no errors should be emitted by this code; it is considered
-   dangerous for library calls to send messages to stdout/stderr.  */
-
-#define NETBSD_ENABLE_EXECUTE_STACK					\
-extern void __enable_execute_stack (void *);				\
-void									\
-__enable_execute_stack (void *addr)					\
-{									\
-  extern int mprotect (void *, size_t, int);				\
-  extern int __sysctl (int *, unsigned int, void *, size_t *,		\
-		       void *, size_t);					\
-									\
-  static int size;							\
-  static long mask;							\
-									\
-  char *page, *end;							\
-									\
-  if (size == 0)							\
-    {									\
-      int mib[2];							\
-      size_t len;							\
-									\
-      mib[0] = 6; /* CTL_HW */						\
-      mib[1] = 7; /* HW_PAGESIZE */					\
-      len = sizeof (size);						\
-      (void) __sysctl (mib, 2, &size, &len, NULL, 0);			\
-      mask = ~((long) size - 1);					\
-    }									\
-									\
-  page = (char *) (((long) addr) & mask);				\
-  end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size);	\
-									\
-  /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */				\
-  (void) mprotect (page, end - page, 7);				\
-}
diff --git a/gcc/config/openbsd.h b/gcc/config/openbsd.h
--- a/gcc/config/openbsd.h
+++ b/gcc/config/openbsd.h
@@ -281,20 +281,4 @@ do {									 \
 /* Storage layout.  */
 
 \f
-/* Stack is explicitly denied execution rights on OpenBSD platforms.  */
-#define ENABLE_EXECUTE_STACK						\
-extern void __enable_execute_stack (void *);				\
-void									\
-__enable_execute_stack (void *addr)					\
-{									\
-  long size = getpagesize ();						\
-  long mask = ~(size-1);						\
-  char *page = (char *) (((long) addr) & mask); 			\
-  char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
-								      \
-  if (mprotect (page, end - page, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) \
-    perror ("mprotect of trampoline code");				\
-}
-
-#include <sys/types.h>
-#include <sys/mman.h>
+#define HAVE_ENABLE_EXECUTE_STACK
diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -207,52 +207,7 @@ along with GCC; see the file COPYING3.  
 
 #define STDC_0_IN_SYSTEM_HEADERS 1
 \f
-/*
- * Attempt to turn on access permissions for the stack.
- *
- * _SC_STACK_PROT is only defined for post 2.6, but we want this code
- * to run always.  2.6 can change the stack protection but has no way to
- * query it.
- *
- */
-
-/* sys/mman.h is not present on some non-Solaris configurations
-   that use sol2.h, so ENABLE_EXECUTE_STACK must use a magic
-   number instead of the appropriate PROT_* flags.  */
-
-#define ENABLE_EXECUTE_STACK					\
-									\
-/* #define STACK_PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC) */	\
-									\
-static int need_enable_exec_stack;					\
-									\
-static void check_enabling(void) __attribute__ ((constructor));		\
-static void check_enabling(void)					\
-{									\
-  extern long sysconf(int);						\
-									\
-  int prot = (int) sysconf(515 /* _SC_STACK_PROT */);			\
-  if (prot != 7 /* STACK_PROT_RWX */)					\
-    need_enable_exec_stack = 1;						\
-}									\
-									\
-extern void __enable_execute_stack (void *);				\
-void									\
-__enable_execute_stack (void *addr)					\
-{									\
-  extern int mprotect(void *, size_t, int);				\
-  if (!need_enable_exec_stack)						\
-    return;								\
-  else {								\
-    long size = getpagesize ();						\
-    long mask = ~(size-1);						\
-    char *page = (char *) (((long) addr) & mask); 			\
-    char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
-									\
-    if (mprotect (page, end - page, 7 /* STACK_PROT_RWX */) < 0)	\
-      perror ("mprotect of trampoline code");				\
-  }									\
-}
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /* Support Solaris-specific format checking for cmn_err.  */
 #define TARGET_N_FORMAT_TYPES 1
diff --git a/gcc/config/sparc/freebsd.h b/gcc/config/sparc/freebsd.h
--- a/gcc/config/sparc/freebsd.h
+++ b/gcc/config/sparc/freebsd.h
@@ -98,31 +98,7 @@ along with GCC; see the file COPYING3.  
 #undef  SPARC_DEFAULT_CMODEL
 #define SPARC_DEFAULT_CMODEL	CM_MEDLOW
 
-#define ENABLE_EXECUTE_STACK						\
-  static int need_enable_exec_stack;					\
-  static void check_enabling(void) __attribute__ ((constructor));	\
-  static void check_enabling(void)					\
-  {									\
-    extern int sysctlbyname(const char *, void *, size_t *, void *, size_t);\
-    int prot = 0;							\
-    size_t len = sizeof(prot);						\
-									\
-    sysctlbyname ("kern.stackprot", &prot, &len, NULL, 0);		\
-    if (prot != 7)							\
-      need_enable_exec_stack = 1;					\
-  }									\
-  extern void __enable_execute_stack (void *);				\
-  void __enable_execute_stack (void *addr)				\
-  {									\
-    if (!need_enable_exec_stack)					\
-      return;								\
-    else {								\
-      /* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */ 			\
-      if (mprotect (addr, TRAMPOLINE_SIZE, 7) < 0)			\
-        perror ("mprotect of trampoline code");				\
-    }									\
-  }
-
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /************************[  Assembler stuff  ]********************************/
 
diff --git a/gcc/config/sparc/netbsd-elf.h b/gcc/config/sparc/netbsd-elf.h
--- a/gcc/config/sparc/netbsd-elf.h
+++ b/gcc/config/sparc/netbsd-elf.h
@@ -74,8 +74,7 @@ along with GCC; see the file COPYING3.  
 
 #undef STDC_0_IN_SYSTEM_HEADERS
 
-/* Attempt to enable execute permissions on the stack.  */
-#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /* Below here exists the merged NetBSD/sparc & NetBSD/sparc64 compiler
    description, allowing one to build 32-bit or 64-bit applications
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -8002,7 +8002,7 @@ sparc32_initialize_trampoline (rtx m_tra
 
   /* Call __enable_execute_stack after writing onto the stack to make sure
      the stack address is accessible.  */
-#ifdef ENABLE_EXECUTE_STACK
+#ifdef HAVE_ENABLE_EXECUTE_STACK
   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
                      LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
 #endif
@@ -8045,7 +8045,7 @@ sparc64_initialize_trampoline (rtx m_tra
 
   /* Call __enable_execute_stack after writing onto the stack to make sure
      the stack address is accessible.  */
-#ifdef ENABLE_EXECUTE_STACK
+#ifdef HAVE_ENABLE_EXECUTE_STACK
   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
                      LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
 #endif
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -5142,13 +5142,11 @@ typically be a series of @code{asm} stat
 @end defmac
 
 The operating system may also require the stack to be made executable
-before calling the trampoline.  To implement this requirement, define
-the following macro.
-
-@defmac ENABLE_EXECUTE_STACK
+before calling the trampoline.  If so, define the following macro.
+
+@defmac HAVE_ENABLE_EXECUTE_STACK
 Define this macro if certain operations must be performed before executing
-code located on the stack.  The macro should expand to a series of C
-file-scope constructs (e.g.@: functions) and provide a unique entry point
+code located on the stack.  libgcc must provide a unique entry point
 named @code{__enable_execute_stack}.  The target is responsible for
 emitting calls to the entry point in the code, for example from the
 @code{TARGET_TRAMPOLINE_INIT} hook.
diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -1,7 +1,7 @@
 /* More subroutines needed by GCC output code on some machines.  */
 /* Compile this one with gcc.  */
 /* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
+   2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -2027,19 +2027,6 @@ __clear_cache (char *beg __attribute__((
 
 #endif /* L_clear_cache */
 \f
-#ifdef L_enable_execute_stack
-/* Attempt to turn on execute permission for the stack.  */
-
-#ifdef ENABLE_EXECUTE_STACK
-  ENABLE_EXECUTE_STACK
-#else
-void
-__enable_execute_stack (void *addr __attribute__((__unused__)))
-{}
-#endif /* ENABLE_EXECUTE_STACK */
-
-#endif /* L_enable_execute_stack */
-\f
 #ifdef L_trampoline
 
 /* Jump to a trampoline, loading the static chain address.  */
diff --git a/gcc/system.h b/gcc/system.h
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -764,7 +764,7 @@ extern void fancy_abort (const char *, i
 /* Target macros only used for code built for the target, that have
    moved to libgcc-tm.h or have never been present elsewhere.  */
  #pragma GCC poison DECLARE_LIBRARY_RENAMES LIBGCC2_GNU_PREFIX		\
-	MD_UNWIND_SUPPORT
+	MD_UNWIND_SUPPORT ENABLE_EXECUTE_STACK
 
 /* Other obsolete target macros, or macros that used to be in target
    headers and were not used, and may be obsolete or may never have
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -313,9 +313,11 @@ ifneq ($(GCC_EXTRA_PARTS),)
 endif
 endif
 
+LIB2ADD += enable-execute-stack.c
+
 # Library members defined in libgcc2.c.
 lib2funcs = _muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3 _cmpdi2 _ucmpdi2	   \
-	    _clear_cache _enable_execute_stack _trampoline __main _absvsi2 \
+	    _clear_cache _trampoline __main _absvsi2 \
 	    _absvdi2 _addvsi3 _addvdi3 _subvsi3 _subvdi3 _mulvsi3 _mulvdi3 \
 	    _negvsi2 _negvdi2 _ctors _ffssi2 _ffsdi2 _clz _clzsi2 _clzdi2  \
 	    _ctzsi2 _ctzdi2 _popcount_tab _popcountsi2 _popcountdi2	   \
diff --git a/libgcc/config.host b/libgcc/config.host
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -44,6 +44,8 @@
 #			The default is ".hidden".
 #  cpu_type		The name of the cpu, if different from the first
 #			chunk of the canonical host name.
+#  enable_execute_stack The name of a source file implementing
+#			__enable_execute_stack.
 #  extra_parts		List of extra object files that should be compiled
 #			for this target machine.  This may be overridden
 #			by setting EXTRA_PARTS in a tmake_file fragment.
@@ -57,6 +59,7 @@
 #			"$cpu_type/t-$cpu_type".
 
 asm_hidden_op=.hidden
+enable_execute_stack=
 extra_parts=
 tmake_file=
 md_unwind_header=no-unwind.h
@@ -203,6 +206,19 @@ case ${host} in
 esac
 
 case ${host} in
+*-*-darwin* | *-*-freebsd* | *-*-netbsd* | *-*-openbsd* | *-*-solaris2* | \
+  alpha*-dec-osf5.1*)
+  enable_execute_stack=enable-execute-stack-mprotect.c
+  ;;
+i[34567]86-*-mingw* | x86_64-*-mingw*)
+  enable_execute_stack=config/i386/enable-execute-stack-mingw32.c
+  ;;
+*)
+  enable_execute_stack=enable-execute-stack-empty.c;
+  ;;
+esac
+
+case ${host} in
 # Support site-specific machine types.
 *local*)
 	rest=`echo ${host} | sed -e "s/$cpu_type-//"`
diff --git a/libgcc/config/i386/enable-execute-stack-mingw32.c b/libgcc/config/i386/enable-execute-stack-mingw32.c
new file mode 100644
--- /dev/null
+++ b/libgcc/config/i386/enable-execute-stack-mingw32.c
@@ -0,0 +1,38 @@
+/* Implement __enable_execute_stack for Windows32.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 3, or (at your option) any later
+   version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <windows.h>
+
+extern void __enable_execute_stack (void *);
+
+void
+__enable_execute_stack (void *addr)
+{
+  MEMORY_BASIC_INFORMATION b;
+
+  if (!VirtualQuery (addr, &b, sizeof(b)))
+    abort ();
+  VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE,
+		  &b.Protect);
+}
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -278,6 +278,7 @@ AC_SUBST(tmake_file)
 AC_SUBST(cpu_type)
 AC_SUBST(extra_parts)
 AC_SUBST(asm_hidden_op)
+AC_CONFIG_LINKS([enable-execute-stack.c:$enable_execute_stack])
 AC_CONFIG_LINKS([md-unwind-support.h:config/$md_unwind_header])
 
 # We need multilib support.
diff --git a/libgcc/enable-execute-stack-empty.c b/libgcc/enable-execute-stack-empty.c
new file mode 100644
--- /dev/null
+++ b/libgcc/enable-execute-stack-empty.c
@@ -0,0 +1,7 @@
+/* Dummy implementation of __enable_execute_stack.  */
+
+/* Attempt to turn on execute permission for the stack.  */
+void
+__enable_execute_stack (void *addr __attribute__((__unused__)))
+{
+}
diff --git a/libgcc/enable-execute-stack-mprotect.c b/libgcc/enable-execute-stack-mprotect.c
new file mode 100644
--- /dev/null
+++ b/libgcc/enable-execute-stack-mprotect.c
@@ -0,0 +1,119 @@
+/* Implement __enable_execute_stack using mprotect(2).
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 3, or (at your option) any later
+   version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sys/mman.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#define STACK_PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC)
+
+static int need_enable_exec_stack;
+
+static void check_enabling (void) __attribute__ ((unused));
+extern void __enable_execute_stack (void *);
+
+#if defined __FreeBSD__
+#include <sys/sysctl.h>
+
+static void __attribute__ ((constructor))
+check_enabling (void)
+{
+  int prot = 0;
+  size_t len = sizeof (prot);
+
+  sysctlbyname ("kern.stackprot", &prot, &len, NULL, 0);
+  if (prot != STACK_PROT_RWX)
+    need_enable_exec_stack = 1;
+}
+#elif defined __sun__ && defined __svr4__
+static void __attribute__ ((constructor))
+check_enabling (void)
+{
+  int prot = (int) sysconf (_SC_STACK_PROT);
+
+  if (prot != STACK_PROT_RWX)
+    need_enable_exec_stack = 1;
+}
+#else
+/* There is no way to query the execute permission of the stack, so
+   we always issue the mprotect() call.  */
+
+static int need_enable_exec_stack = 1;
+#endif
+
+#if defined __NetBSD__
+/* Note that we go out of our way to use namespace-non-invasive calls
+   here.  Unfortunately, there is no libc-internal name for mprotect().  */
+
+#include <sys/sysctl.h>
+
+extern int __sysctl (int *, unsigned int, void *, size_t *, void *, size_t);
+
+static int
+getpagesize (void)
+{
+  static int size;
+
+  if (size == 0)
+    {
+      int mib[2];
+      size_t len;
+
+      mib[0] = CTL_HW;
+      mib[1] = HW_PAGESIZE;
+      len = sizeof (size);
+      (void) __sysctl (mib, 2, &size, &len, NULL, 0);
+    }
+  return size;
+}
+#endif /* __NetBSD__ */
+
+/* Attempt to turn on access permissions for the stack.  Unfortunately it
+   is not possible to make this namespace-clean.*/
+
+void
+__enable_execute_stack (void *addr)
+{
+  if (!need_enable_exec_stack)
+    return;
+  else
+    {
+      static long size, mask;
+
+      if (size == 0) {
+	size = getpagesize ();
+	mask = ~(size - 1);
+      }
+
+      char *page = (char *) (((long) addr) & mask);
+      char *end  = (char *) ((((long) (addr + __TRAMPOLINE_SIZE__)) & mask)
+			     + size);
+
+      if (mprotect (page, end - page, STACK_PROT_RWX) < 0)
+	/* Note that no errors should be emitted by this code; it is
+	   considered dangerous for library calls to send messages to
+	   stdout/stderr.  */
+	abort ();
+    }
+}

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

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-06-06  9:18           ` Rainer Orth
@ 2011-06-06  9:23             ` Paolo Bonzini
  2011-06-07 15:20             ` Joseph S. Myers
  1 sibling, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2011-06-06  9:23 UTC (permalink / raw)
  To: Rainer Orth
  Cc: gcc-patches, Joseph S. Myers, Ralf Wildenhues, Mike Stump,
	Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

On 06/06/2011 11:17 AM, Rainer Orth wrote:
> * Instead of __FreeBSD__, one could use HAVE_SYSCTLBYNAME instead, but
>    that would need a new libgcc config.h header.  In addition, we might
>    have to check for kern.stackprot to make sure the code really works.
>
> * Similarly, instead of testing __sun__&&  __svr4__, one could check
>    _SC_STACK_PROT.
>
> * Last, rather than checking __NetBSD__, one could go for HAVE___SYSCTL.
>
> * __sysctl is currently declared manully.  AFAICS there's no header for
>    that.  At least the FreeBSD libc declares it itself in two places:
>    lib/libc/sys/stack_protector.c and lib/libc/gen/sysctl.c.
>
> Given that this is closely tied to the various platforms, it seems
> appropriate to continue to use the OS defines.

Agreed, it would be a worse can of worms when bootstrapping a target 
(i.e. no target headers are available).

Parts I can approve are good.  Thanks!

Paolo

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-05-31 16:57     ` Paolo Bonzini
  2011-06-03 15:45       ` Rainer Orth
@ 2011-06-07 14:00       ` Joseph S. Myers
  2011-06-07 14:57         ` Rainer Orth
  1 sibling, 1 reply; 21+ messages in thread
From: Joseph S. Myers @ 2011-06-07 14:00 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Rainer Orth, gcc-patches, Ralf Wildenhues, Mike Stump,
	Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

On Tue, 31 May 2011, Paolo Bonzini wrote:

> > I'd thought about it, but refrained since HAVE_ENABLE_EXECUTE_STACK
> > affects only three cpus.  Currently, our documentation of libgcc
> > configury and macros used is close to non-existant.  That's probably for
> > someone who has implemented this stuff.
> 
> True, OTOH HAVE_ENABLE_EXECUTE_STACK is a target macro, and those are well
> documented.  Just say that it has to be defined if libgcc provides a
> non-trivial implementation of __enable_execute_stack; it doesn't need to delve
> into how to hack libgcc.

As I understand it, HAVE_ENABLE_EXECUTE_STACK is only used in code under 
gcc/config/.  That is, it is not a target macro as usually understood but 
is logically private to a few back ends (and it would be a bug to 
introduce uses of it elsewhere, just like it was a bug to introduce uses 
of TARGET_64BIT outside gcc/config/ when that macro also is logically 
private).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-06-07 14:00       ` Joseph S. Myers
@ 2011-06-07 14:57         ` Rainer Orth
  0 siblings, 0 replies; 21+ messages in thread
From: Rainer Orth @ 2011-06-07 14:57 UTC (permalink / raw)
  To: Joseph S. Myers
  Cc: Paolo Bonzini, gcc-patches, Ralf Wildenhues, Mike Stump,
	Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

"Joseph S. Myers" <joseph@codesourcery.com> writes:

> On Tue, 31 May 2011, Paolo Bonzini wrote:
>
>> > I'd thought about it, but refrained since HAVE_ENABLE_EXECUTE_STACK
>> > affects only three cpus.  Currently, our documentation of libgcc
>> > configury and macros used is close to non-existant.  That's probably for
>> > someone who has implemented this stuff.
>> 
>> True, OTOH HAVE_ENABLE_EXECUTE_STACK is a target macro, and those are well
>> documented.  Just say that it has to be defined if libgcc provides a
>> non-trivial implementation of __enable_execute_stack; it doesn't need to delve
>> into how to hack libgcc.
>
> As I understand it, HAVE_ENABLE_EXECUTE_STACK is only used in code under 
> gcc/config/.  That is, it is not a target macro as usually understood but 
> is logically private to a few back ends (and it would be a bug to 
> introduce uses of it elsewhere, just like it was a bug to introduce uses 
> of TARGET_64BIT outside gcc/config/ when that macro also is logically 
> private).

That was my reasoning when originally not including the documenation in
my patch.  So I'll just remove the HAVE_ENABLE_EXECUTE_STACK docs from
my revised patch

	http://gcc.gnu.org/ml/gcc-patches/2011-06/msg00366.html

Are you ok with that and the __TRAMPOLINE_SIZE__ definition in
c-cppbuiltin.c (c_cpp_builtins)?

Thanks.
        Rainer

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

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-06-06  9:18           ` Rainer Orth
  2011-06-06  9:23             ` Paolo Bonzini
@ 2011-06-07 15:20             ` Joseph S. Myers
  2011-06-07 15:31               ` Rainer Orth
  1 sibling, 1 reply; 21+ messages in thread
From: Joseph S. Myers @ 2011-06-07 15:20 UTC (permalink / raw)
  To: Rainer Orth
  Cc: Paolo Bonzini, gcc-patches, Ralf Wildenhues, Mike Stump,
	Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

On Mon, 6 Jun 2011, Rainer Orth wrote:

> Paolo Bonzini <bonzini@gnu.org> writes:
> 
> >> * Except for Darwin, the code uses TRAMPOLINE_SIZE.  This only exists in
> >>    the backend headers.  While it could be duplicated somewhere in the
> >>    libgcc configury, I'd rather propose that gcc define
> >>    __TRAMPOLINE_SIZE__ (in gcc/c-family/c-cppbuiltin.c (c_cpp_builtins)
> >>    to avoid this.  On PowerPC Darwin, one cannot use TRAMPOLINE_SIZE
> >>    definition right now since the macro calls the rs6000_trampoline_size
> >>    function in rs6000/rs6000.c.  This would be solved nicely by
> >>    __TRAMPOLINE_SIZE__.
> >
> > Good idea.
> 
> Included in the revised patch below.  This part will need Joseph's approval.

Is this definition ever going to be of use to user code, or even to system 
headers?  It looks purely like an implementation detail rather than 
something meaningful for users.  That would tend to suggest conditioning 
it on the proposed new -fbuilding-libgcc option that I suggested in 
<http://gcc.gnu.org/ml/gcc-patches/2010-10/msg01206.html>.  (There are a 
*lot* of target macros that are in a similar position - see the list under 
"used by the compiler itself and libgcc" in 
<http://gcc.gnu.org/wiki/Top-Level_Libgcc_Migration>.  Even if we could 
define and document public semantics for corresponding predefined macros, 
I don't think they would be of practical use to users of GCC, so for most 
of them I expect defining __LIBGCC_<macro>, only if -fbuilding-libgcc, is 
the best way of eliminating the dependence on host tm.h without making 
implementation details visible to users of GCC.)

So my view is that you should define __LIBGCC_TRAMPOLINE_SIZE__, only if 
-fbuilding-libgcc.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-06-07 15:20             ` Joseph S. Myers
@ 2011-06-07 15:31               ` Rainer Orth
  2011-06-07 15:45                 ` Paolo Bonzini
  2011-06-07 19:17                 ` Joseph S. Myers
  0 siblings, 2 replies; 21+ messages in thread
From: Rainer Orth @ 2011-06-07 15:31 UTC (permalink / raw)
  To: Joseph S. Myers
  Cc: Paolo Bonzini, gcc-patches, Ralf Wildenhues, Mike Stump,
	Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

"Joseph S. Myers" <joseph@codesourcery.com> writes:

> On Mon, 6 Jun 2011, Rainer Orth wrote:
>
>> Paolo Bonzini <bonzini@gnu.org> writes:
>> 
>> >> * Except for Darwin, the code uses TRAMPOLINE_SIZE.  This only exists in
>> >>    the backend headers.  While it could be duplicated somewhere in the
>> >>    libgcc configury, I'd rather propose that gcc define
>> >>    __TRAMPOLINE_SIZE__ (in gcc/c-family/c-cppbuiltin.c (c_cpp_builtins)
>> >>    to avoid this.  On PowerPC Darwin, one cannot use TRAMPOLINE_SIZE
>> >>    definition right now since the macro calls the rs6000_trampoline_size
>> >>    function in rs6000/rs6000.c.  This would be solved nicely by
>> >>    __TRAMPOLINE_SIZE__.
>> >
>> > Good idea.
>> 
>> Included in the revised patch below.  This part will need Joseph's approval.
>
> Is this definition ever going to be of use to user code, or even to system 
> headers?  It looks purely like an implementation detail rather than 
> something meaningful for users.  That would tend to suggest conditioning 
> it on the proposed new -fbuilding-libgcc option that I suggested in 
> <http://gcc.gnu.org/ml/gcc-patches/2010-10/msg01206.html>.  (There are a 
> *lot* of target macros that are in a similar position - see the list under 
> "used by the compiler itself and libgcc" in 
> <http://gcc.gnu.org/wiki/Top-Level_Libgcc_Migration>.  Even if we could 
> define and document public semantics for corresponding predefined macros, 
> I don't think they would be of practical use to users of GCC, so for most 
> of them I expect defining __LIBGCC_<macro>, only if -fbuilding-libgcc, is 
> the best way of eliminating the dependence on host tm.h without making 
> implementation details visible to users of GCC.)
>
> So my view is that you should define __LIBGCC_TRAMPOLINE_SIZE__, only if 
> -fbuilding-libgcc.

I can give it a try if I can figure out how to define -fbuilding-libgcc
via the option handling machinery.  I just want to avoid having to
implement too many unrelated cleanups, otherwise it will take a year to
get this single patch done.

	Rainer

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

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-06-07 15:31               ` Rainer Orth
@ 2011-06-07 15:45                 ` Paolo Bonzini
  2011-06-07 19:17                 ` Joseph S. Myers
  1 sibling, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2011-06-07 15:45 UTC (permalink / raw)
  To: Rainer Orth
  Cc: Joseph S. Myers, gcc-patches, Ralf Wildenhues, Mike Stump,
	Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

On 06/07/2011 05:30 PM, Rainer Orth wrote:
>> >  So my view is that you should define __LIBGCC_TRAMPOLINE_SIZE__, only if
>> >  -fbuilding-libgcc.
> I can give it a try if I can figure out how to define -fbuilding-libgcc
> via the option handling machinery.  I just want to avoid having to
> implement too many unrelated cleanups, otherwise it will take a year to
> get this single patch done.

Agreed, what about just renaming the macro to __LIBGCC_TRAMPOLINE_SIZE__ 
for now?  I don't think it's fair to put on Rainer the burden of 
implementing the new flag right now.

If no one beats me to it, I'll look at it when coming back from holidays 
in two weeks.

Paolo

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-06-07 15:31               ` Rainer Orth
  2011-06-07 15:45                 ` Paolo Bonzini
@ 2011-06-07 19:17                 ` Joseph S. Myers
  2011-06-09  7:50                   ` Rainer Orth
  1 sibling, 1 reply; 21+ messages in thread
From: Joseph S. Myers @ 2011-06-07 19:17 UTC (permalink / raw)
  To: Rainer Orth
  Cc: Paolo Bonzini, gcc-patches, Ralf Wildenhues, Mike Stump,
	Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

On Tue, 7 Jun 2011, Rainer Orth wrote:

> > So my view is that you should define __LIBGCC_TRAMPOLINE_SIZE__, only if 
> > -fbuilding-libgcc.
> 
> I can give it a try if I can figure out how to define -fbuilding-libgcc
> via the option handling machinery.  I just want to avoid having to

That should be no more than

; Define extra predefined macros for use in libgcc.
fbuilding-libgcc
C ObjC C++ ObjC++ Undocumented Var(flag_building_libgcc)

in c.opt.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-06-07 19:17                 ` Joseph S. Myers
@ 2011-06-09  7:50                   ` Rainer Orth
  2011-06-09  9:57                     ` Joseph S. Myers
  2011-06-09 12:06                     ` Bernd Schmidt
  0 siblings, 2 replies; 21+ messages in thread
From: Rainer Orth @ 2011-06-09  7:50 UTC (permalink / raw)
  To: Joseph S. Myers
  Cc: Paolo Bonzini, gcc-patches, Ralf Wildenhues, Mike Stump,
	Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

"Joseph S. Myers" <joseph@codesourcery.com> writes:

> On Tue, 7 Jun 2011, Rainer Orth wrote:
>
>> > So my view is that you should define __LIBGCC_TRAMPOLINE_SIZE__, only if 
>> > -fbuilding-libgcc.
>> 
>> I can give it a try if I can figure out how to define -fbuilding-libgcc
>> via the option handling machinery.  I just want to avoid having to
>
> That should be no more than
>
> ; Define extra predefined macros for use in libgcc.
> fbuilding-libgcc
> C ObjC C++ ObjC++ Undocumented Var(flag_building_libgcc)
>
> in c.opt.

Indeed, that did the trick.  The following revised patch has been
bootstrapped without regressions on i386-pc-solaris2.10.  I've already
got build, Darwin and Mingw approval and can commit the osf and solaris
parts on my own.  If the C parts are ok now, I suppose I still need
approval either from the various *BSD maintainers (who haven't chimed in
yet) of from a global reviewer?

Thanks.
        Rainer


2011-05-29  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
	    Joseph Myers  <joseph@codesourcery.com>

	gcc:
	* config/alpha/netbsd.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/alpha/osf5.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/darwin.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/i386/mingw32.h (MINGW_ENABLE_EXECUTE_STACK): Remove.
	(ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	[IN_LIBGCC2]: Don't include <windows.h>.
	* config/i386/netbsd-elf.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/i386/netbsd64.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/netbsd.h (NETBSD_ENABLE_EXECUTE_STACK): Remove.
	* config/openbsd.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/sol2.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/sparc/freebsd.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/sparc/netbsd-elf.h (ENABLE_EXECUTE_STACK): Remove.
	(HAVE_ENABLE_EXECUTE_STACK): Define.
	* config/alpha/alpha.c (alpha_trampoline_init): Test
	HAVE_ENABLE_EXECUTE_STACK.
	* config/i386/i386.c (ix86_trampoline_init): Likewise.
	* config/sparc/sparc.c (sparc32_initialize_trampoline): Likewise.
	(sparc64_initialize_trampoline): Likewise.
	* libgcc2.c [L_enable_execute_stack]: Remove.
	* system.h (ENABLE_EXECUTE_STACK): Poison.
	* doc/tm.texi.in (Trampolines, ENABLE_EXECUTE_STACK): Remove.
	* doc/tm.texi: Regenerate.
	* Makefile.in (LIBGCC2_CFLAGS): Add -fbuilding-libgcc.

	gcc/c-family:
	* c.opt (fbuilding-libgcc): New option.
	* c-cppbuiltin.c (c_cpp_builtins): Define
	__LIBGCC_TRAMPOLINE_SIZE__ if flag_building_libgcc.

	libgcc:
	* enable-execute-stack-empty.c: New file.
	* enable-execute-stack-mprotect.c: New file.
	* config/i386/enable-execute-stack-mingw32.c: New file.
	* config.host (enable_execute_stack): New variable.
	Select appropriate variants.
	* configure.ac: Link enable-execute-stack.c to
	$enable_execute_stack.
	* configure: Regenerate.
	* Makefile.in (LIB2ADD): Add enable-execute-stack.c.
	(lib2funcs): Remove _enable_execute_stack.

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -722,7 +722,7 @@ LIBGCC2_DEBUG_CFLAGS = -g
 LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(TARGET_LIBGCC2_CFLAGS) \
 		 $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) \
 		 -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED \
-		 -fno-stack-protector \
+		 -fbuilding-libgcc -fno-stack-protector \
 		 $(INHIBIT_LIBC_CFLAGS)
 
 # Additional options to use when compiling libgcc2.a.
diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -1,5 +1,5 @@
 /* Define builtin-in macros for the C family front ends.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -727,6 +727,12 @@ c_cpp_builtins (cpp_reader *pfile)
       builtin_define_fixed_point_constants ("UTA", "", uta_type_node);
     }
 
+  /* For libgcc-internal use only.  */
+  if (flag_building_libgcc)
+    /* For libgcc enable-execute-stack.c.  */
+    builtin_define_with_int_value ("__LIBGCC_TRAMPOLINE_SIZE__",
+				   TRAMPOLINE_SIZE);
+
   /* For use in assembly language.  */
   builtin_define_with_value ("__REGISTER_PREFIX__", REGISTER_PREFIX, 0);
   builtin_define_with_value ("__USER_LABEL_PREFIX__", user_label_prefix, 0);
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -700,6 +700,10 @@ fasm
 C ObjC C++ ObjC++ Var(flag_no_asm, 0)
 Recognize the \"asm\" keyword
 
+; Define extra predefined macros for use in libgcc.
+fbuilding-libgcc
+C ObjC C++ ObjC++ Undocumented Var(flag_building_libgcc)
+
 fbuiltin
 C ObjC C++ ObjC++ Var(flag_no_builtin, 0)
 Recognize built-in functions
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -5395,7 +5395,7 @@ alpha_trampoline_init (rtx m_tramp, tree
   if (TARGET_ABI_OSF)
     {
       emit_insn (gen_imb ());
-#ifdef ENABLE_EXECUTE_STACK
+#ifdef HAVE_ENABLE_EXECUTE_STACK
       emit_library_call (init_one_libfunc ("__enable_execute_stack"),
 			 LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
 #endif
diff --git a/gcc/config/alpha/netbsd.h b/gcc/config/alpha/netbsd.h
--- a/gcc/config/alpha/netbsd.h
+++ b/gcc/config/alpha/netbsd.h
@@ -73,7 +73,4 @@ along with GCC; see the file COPYING3.  
   "%{Ofast|ffast-math|funsafe-math-optimizations:crtfm%O%s} \
    %(netbsd_endfile_spec)"
 
-
-/* Attempt to enable execute permissions on the stack.  */
-
-#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
diff --git a/gcc/config/alpha/osf5.h b/gcc/config/alpha/osf5.h
--- a/gcc/config/alpha/osf5.h
+++ b/gcc/config/alpha/osf5.h
@@ -165,22 +165,7 @@ along with GCC; see the file COPYING3.  
 #define HAVE_STAMP_H 1
 #endif
 
-/* Attempt to turn on access permissions for the stack.  */
-
-#define ENABLE_EXECUTE_STACK						\
-void									\
-__enable_execute_stack (void *addr)					\
-{									\
-  extern int mprotect (const void *, size_t, int);			\
-  long size = getpagesize ();						\
-  long mask = ~(size-1);						\
-  char *page = (char *) (((long) addr) & mask);				\
-  char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
-									\
-  /* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */				\
-  if (mprotect (page, end - page, 7) < 0)				\
-    perror ("mprotect of trampoline code");				\
-}
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /* Digital UNIX V4.0E (1091)/usr/include/sys/types.h 4.3.49.9 1997/08/14 */
 #define SIZE_TYPE	"long unsigned int"
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -919,43 +919,7 @@ void add_framework_path (char *);
 #define TARGET_ASM_OUTPUT_ANCHOR NULL
 #define DARWIN_SECTION_ANCHORS 0
 
-/* Attempt to turn on execute permission for the stack.  This may be
-    used by TARGET_TRAMPOLINE_INIT if the target needs it (that is,
-    if the target machine can change execute permissions on a page).
-
-    There is no way to query the execute permission of the stack, so
-    we always issue the mprotect() call.
-
-    Unfortunately it is not possible to make this namespace-clean.
-
-    Also note that no errors should be emitted by this code; it is
-    considered dangerous for library calls to send messages to
-    stdout/stderr.  */
-
-#define ENABLE_EXECUTE_STACK                                            \
-extern void __enable_execute_stack (void *);                            \
-void                                                                    \
-__enable_execute_stack (void *addr)                                     \
-{                                                                       \
-   extern int mprotect (void *, size_t, int);                           \
-   extern int getpagesize (void);					\
-   static int size;                                                     \
-   static long mask;                                                    \
-                                                                        \
-   char *page, *end;                                                    \
-                                                                        \
-   if (size == 0)                                                       \
-     {                                                                  \
-       size = getpagesize();						\
-       mask = ~((long) size - 1);                                       \
-     }                                                                  \
-                                                                        \
-   page = (char *) (((long) addr) & mask);                              \
-   end  = (char *) ((((long) (addr + (TARGET_64BIT ? 48 : 40))) & mask) + size); \
-                                                                        \
-   /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */                        \
-   (void) mprotect (page, end - page, 7);                               \
-}
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /* For Apple KEXTs, we make the constructors return this to match gcc
    2.95.  */
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -23387,7 +23387,7 @@ ix86_trampoline_init (rtx m_tramp, tree 
       gcc_assert (offset <= TRAMPOLINE_SIZE);
     }
 
-#ifdef ENABLE_EXECUTE_STACK
+#ifdef HAVE_ENABLE_EXECUTE_STACK
 #ifdef CHECK_EXECUTE_STACK_ENABLED
   if (CHECK_EXECUTE_STACK_ENABLED)
 #endif
diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
--- a/gcc/config/i386/mingw32.h
+++ b/gcc/config/i386/mingw32.h
@@ -219,28 +219,10 @@ do {						         \
 /* Let defaults.h definition of TARGET_USE_JCR_SECTION apply. */
 #undef TARGET_USE_JCR_SECTION
 
-#undef MINGW_ENABLE_EXECUTE_STACK
-#define MINGW_ENABLE_EXECUTE_STACK     \
-extern void __enable_execute_stack (void *);    \
-void         \
-__enable_execute_stack (void *addr)					\
-{									\
-  MEMORY_BASIC_INFORMATION b;						\
-  if (!VirtualQuery (addr, &b, sizeof(b)))				\
-    abort ();								\
-  VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE,	\
-		  &b.Protect);						\
-}
-
-#undef ENABLE_EXECUTE_STACK
-#define ENABLE_EXECUTE_STACK MINGW_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
 #undef  CHECK_EXECUTE_STACK_ENABLED
 #define CHECK_EXECUTE_STACK_ENABLED flag_setstackexecutable
 
-#ifdef IN_LIBGCC2
-#include <windows.h>
-#endif
-
 /* This matches SHLIB_SONAME and SHLIB_SOVERSION in t-cygming. */
 /* This matches SHLIB_SONAME and SHLIB_SOVERSION in t-cygwin. */
 #if DWARF2_UNWIND_INFO
diff --git a/gcc/config/i386/netbsd-elf.h b/gcc/config/i386/netbsd-elf.h
--- a/gcc/config/i386/netbsd-elf.h
+++ b/gcc/config/i386/netbsd-elf.h
@@ -118,5 +118,4 @@ along with GCC; see the file COPYING3.  
    we don't care about compatibility with older gcc versions.  */
 #define DEFAULT_PCC_STRUCT_RETURN 1
 
-/* Attempt to enable execute permissions on the stack.  */
-#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
diff --git a/gcc/config/i386/netbsd64.h b/gcc/config/i386/netbsd64.h
--- a/gcc/config/i386/netbsd64.h
+++ b/gcc/config/i386/netbsd64.h
@@ -66,5 +66,4 @@ along with GCC; see the file COPYING3.  
     fprintf (FILE, "\tcall __mcount\n");				\
 }
 
-/* Attempt to enable execute permissions on the stack.  */
-#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
diff --git a/gcc/config/netbsd.h b/gcc/config/netbsd.h
--- a/gcc/config/netbsd.h
+++ b/gcc/config/netbsd.h
@@ -1,6 +1,6 @@
 /* Base configuration file for all NetBSD targets.
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2007, 2009, 2010 Free Software Foundation, Inc.
+   2007, 2009, 2010, 2011 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -173,50 +173,3 @@ along with GCC; see the file COPYING3.  
 
 #undef WINT_TYPE
 #define WINT_TYPE "int"
-\f
-
-/* Attempt to turn on execute permission for the stack.  This may be
-   used by TARGET_TRAMPOLINE_INIT if the target needs it (that is,
-   if the target machine can change execute permissions on a page).
-
-   There is no way to query the execute permission of the stack, so
-   we always issue the mprotect() call.
-
-   Note that we go out of our way to use namespace-non-invasive calls
-   here.  Unfortunately, there is no libc-internal name for mprotect().
-
-   Also note that no errors should be emitted by this code; it is considered
-   dangerous for library calls to send messages to stdout/stderr.  */
-
-#define NETBSD_ENABLE_EXECUTE_STACK					\
-extern void __enable_execute_stack (void *);				\
-void									\
-__enable_execute_stack (void *addr)					\
-{									\
-  extern int mprotect (void *, size_t, int);				\
-  extern int __sysctl (int *, unsigned int, void *, size_t *,		\
-		       void *, size_t);					\
-									\
-  static int size;							\
-  static long mask;							\
-									\
-  char *page, *end;							\
-									\
-  if (size == 0)							\
-    {									\
-      int mib[2];							\
-      size_t len;							\
-									\
-      mib[0] = 6; /* CTL_HW */						\
-      mib[1] = 7; /* HW_PAGESIZE */					\
-      len = sizeof (size);						\
-      (void) __sysctl (mib, 2, &size, &len, NULL, 0);			\
-      mask = ~((long) size - 1);					\
-    }									\
-									\
-  page = (char *) (((long) addr) & mask);				\
-  end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size);	\
-									\
-  /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */				\
-  (void) mprotect (page, end - page, 7);				\
-}
diff --git a/gcc/config/openbsd.h b/gcc/config/openbsd.h
--- a/gcc/config/openbsd.h
+++ b/gcc/config/openbsd.h
@@ -281,20 +281,4 @@ do {									 \
 /* Storage layout.  */
 
 \f
-/* Stack is explicitly denied execution rights on OpenBSD platforms.  */
-#define ENABLE_EXECUTE_STACK						\
-extern void __enable_execute_stack (void *);				\
-void									\
-__enable_execute_stack (void *addr)					\
-{									\
-  long size = getpagesize ();						\
-  long mask = ~(size-1);						\
-  char *page = (char *) (((long) addr) & mask); 			\
-  char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
-								      \
-  if (mprotect (page, end - page, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) \
-    perror ("mprotect of trampoline code");				\
-}
-
-#include <sys/types.h>
-#include <sys/mman.h>
+#define HAVE_ENABLE_EXECUTE_STACK
diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -207,52 +207,7 @@ along with GCC; see the file COPYING3.  
 
 #define STDC_0_IN_SYSTEM_HEADERS 1
 \f
-/*
- * Attempt to turn on access permissions for the stack.
- *
- * _SC_STACK_PROT is only defined for post 2.6, but we want this code
- * to run always.  2.6 can change the stack protection but has no way to
- * query it.
- *
- */
-
-/* sys/mman.h is not present on some non-Solaris configurations
-   that use sol2.h, so ENABLE_EXECUTE_STACK must use a magic
-   number instead of the appropriate PROT_* flags.  */
-
-#define ENABLE_EXECUTE_STACK					\
-									\
-/* #define STACK_PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC) */	\
-									\
-static int need_enable_exec_stack;					\
-									\
-static void check_enabling(void) __attribute__ ((constructor));		\
-static void check_enabling(void)					\
-{									\
-  extern long sysconf(int);						\
-									\
-  int prot = (int) sysconf(515 /* _SC_STACK_PROT */);			\
-  if (prot != 7 /* STACK_PROT_RWX */)					\
-    need_enable_exec_stack = 1;						\
-}									\
-									\
-extern void __enable_execute_stack (void *);				\
-void									\
-__enable_execute_stack (void *addr)					\
-{									\
-  extern int mprotect(void *, size_t, int);				\
-  if (!need_enable_exec_stack)						\
-    return;								\
-  else {								\
-    long size = getpagesize ();						\
-    long mask = ~(size-1);						\
-    char *page = (char *) (((long) addr) & mask); 			\
-    char *end  = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \
-									\
-    if (mprotect (page, end - page, 7 /* STACK_PROT_RWX */) < 0)	\
-      perror ("mprotect of trampoline code");				\
-  }									\
-}
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /* Support Solaris-specific format checking for cmn_err.  */
 #define TARGET_N_FORMAT_TYPES 1
diff --git a/gcc/config/sparc/freebsd.h b/gcc/config/sparc/freebsd.h
--- a/gcc/config/sparc/freebsd.h
+++ b/gcc/config/sparc/freebsd.h
@@ -98,31 +98,7 @@ along with GCC; see the file COPYING3.  
 #undef  SPARC_DEFAULT_CMODEL
 #define SPARC_DEFAULT_CMODEL	CM_MEDLOW
 
-#define ENABLE_EXECUTE_STACK						\
-  static int need_enable_exec_stack;					\
-  static void check_enabling(void) __attribute__ ((constructor));	\
-  static void check_enabling(void)					\
-  {									\
-    extern int sysctlbyname(const char *, void *, size_t *, void *, size_t);\
-    int prot = 0;							\
-    size_t len = sizeof(prot);						\
-									\
-    sysctlbyname ("kern.stackprot", &prot, &len, NULL, 0);		\
-    if (prot != 7)							\
-      need_enable_exec_stack = 1;					\
-  }									\
-  extern void __enable_execute_stack (void *);				\
-  void __enable_execute_stack (void *addr)				\
-  {									\
-    if (!need_enable_exec_stack)					\
-      return;								\
-    else {								\
-      /* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */ 			\
-      if (mprotect (addr, TRAMPOLINE_SIZE, 7) < 0)			\
-        perror ("mprotect of trampoline code");				\
-    }									\
-  }
-
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /************************[  Assembler stuff  ]********************************/
 
diff --git a/gcc/config/sparc/netbsd-elf.h b/gcc/config/sparc/netbsd-elf.h
--- a/gcc/config/sparc/netbsd-elf.h
+++ b/gcc/config/sparc/netbsd-elf.h
@@ -74,8 +74,7 @@ along with GCC; see the file COPYING3.  
 
 #undef STDC_0_IN_SYSTEM_HEADERS
 
-/* Attempt to enable execute permissions on the stack.  */
-#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
+#define HAVE_ENABLE_EXECUTE_STACK
 
 /* Below here exists the merged NetBSD/sparc & NetBSD/sparc64 compiler
    description, allowing one to build 32-bit or 64-bit applications
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -8004,7 +8004,7 @@ sparc32_initialize_trampoline (rtx m_tra
 
   /* Call __enable_execute_stack after writing onto the stack to make sure
      the stack address is accessible.  */
-#ifdef ENABLE_EXECUTE_STACK
+#ifdef HAVE_ENABLE_EXECUTE_STACK
   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
                      LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
 #endif
@@ -8047,7 +8047,7 @@ sparc64_initialize_trampoline (rtx m_tra
 
   /* Call __enable_execute_stack after writing onto the stack to make sure
      the stack address is accessible.  */
-#ifdef ENABLE_EXECUTE_STACK
+#ifdef HAVE_ENABLE_EXECUTE_STACK
   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
                      LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
 #endif
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -5141,19 +5141,6 @@ typically be a series of @code{asm} stat
 @var{end} are both pointer expressions.
 @end defmac
 
-The operating system may also require the stack to be made executable
-before calling the trampoline.  To implement this requirement, define
-the following macro.
-
-@defmac ENABLE_EXECUTE_STACK
-Define this macro if certain operations must be performed before executing
-code located on the stack.  The macro should expand to a series of C
-file-scope constructs (e.g.@: functions) and provide a unique entry point
-named @code{__enable_execute_stack}.  The target is responsible for
-emitting calls to the entry point in the code, for example from the
-@code{TARGET_TRAMPOLINE_INIT} hook.
-@end defmac
-
 To use a standard subroutine, define the following macro.  In addition,
 you must make sure that the instructions in a trampoline fill an entire
 cache line with identical instructions, or else ensure that the
diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -1,7 +1,7 @@
 /* More subroutines needed by GCC output code on some machines.  */
 /* Compile this one with gcc.  */
 /* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
+   2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -2027,19 +2027,6 @@ __clear_cache (char *beg __attribute__((
 
 #endif /* L_clear_cache */
 \f
-#ifdef L_enable_execute_stack
-/* Attempt to turn on execute permission for the stack.  */
-
-#ifdef ENABLE_EXECUTE_STACK
-  ENABLE_EXECUTE_STACK
-#else
-void
-__enable_execute_stack (void *addr __attribute__((__unused__)))
-{}
-#endif /* ENABLE_EXECUTE_STACK */
-
-#endif /* L_enable_execute_stack */
-\f
 #ifdef L_trampoline
 
 /* Jump to a trampoline, loading the static chain address.  */
diff --git a/gcc/system.h b/gcc/system.h
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -764,7 +764,7 @@ extern void fancy_abort (const char *, i
 /* Target macros only used for code built for the target, that have
    moved to libgcc-tm.h or have never been present elsewhere.  */
  #pragma GCC poison DECLARE_LIBRARY_RENAMES LIBGCC2_GNU_PREFIX		\
-	MD_UNWIND_SUPPORT
+	MD_UNWIND_SUPPORT ENABLE_EXECUTE_STACK
 
 /* Other obsolete target macros, or macros that used to be in target
    headers and were not used, and may be obsolete or may never have
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -313,9 +313,11 @@ ifneq ($(GCC_EXTRA_PARTS),)
 endif
 endif
 
+LIB2ADD += enable-execute-stack.c
+
 # Library members defined in libgcc2.c.
 lib2funcs = _muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3 _cmpdi2 _ucmpdi2	   \
-	    _clear_cache _enable_execute_stack _trampoline __main _absvsi2 \
+	    _clear_cache _trampoline __main _absvsi2 \
 	    _absvdi2 _addvsi3 _addvdi3 _subvsi3 _subvdi3 _mulvsi3 _mulvdi3 \
 	    _negvsi2 _negvdi2 _ctors _ffssi2 _ffsdi2 _clz _clzsi2 _clzdi2  \
 	    _ctzsi2 _ctzdi2 _popcount_tab _popcountsi2 _popcountdi2	   \
diff --git a/libgcc/config.host b/libgcc/config.host
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -44,6 +44,8 @@
 #			The default is ".hidden".
 #  cpu_type		The name of the cpu, if different from the first
 #			chunk of the canonical host name.
+#  enable_execute_stack The name of a source file implementing
+#			__enable_execute_stack.
 #  extra_parts		List of extra object files that should be compiled
 #			for this target machine.  This may be overridden
 #			by setting EXTRA_PARTS in a tmake_file fragment.
@@ -57,6 +59,7 @@
 #			"$cpu_type/t-$cpu_type".
 
 asm_hidden_op=.hidden
+enable_execute_stack=
 extra_parts=
 tmake_file=
 md_unwind_header=no-unwind.h
@@ -203,6 +206,19 @@ case ${host} in
 esac
 
 case ${host} in
+*-*-darwin* | *-*-freebsd* | *-*-netbsd* | *-*-openbsd* | *-*-solaris2* | \
+  alpha*-dec-osf5.1*)
+  enable_execute_stack=enable-execute-stack-mprotect.c
+  ;;
+i[34567]86-*-mingw* | x86_64-*-mingw*)
+  enable_execute_stack=config/i386/enable-execute-stack-mingw32.c
+  ;;
+*)
+  enable_execute_stack=enable-execute-stack-empty.c;
+  ;;
+esac
+
+case ${host} in
 # Support site-specific machine types.
 *local*)
 	rest=`echo ${host} | sed -e "s/$cpu_type-//"`
diff --git a/libgcc/config/i386/enable-execute-stack-mingw32.c b/libgcc/config/i386/enable-execute-stack-mingw32.c
new file mode 100644
--- /dev/null
+++ b/libgcc/config/i386/enable-execute-stack-mingw32.c
@@ -0,0 +1,38 @@
+/* Implement __enable_execute_stack for Windows32.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 3, or (at your option) any later
+   version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <windows.h>
+
+extern void __enable_execute_stack (void *);
+
+void
+__enable_execute_stack (void *addr)
+{
+  MEMORY_BASIC_INFORMATION b;
+
+  if (!VirtualQuery (addr, &b, sizeof(b)))
+    abort ();
+  VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE,
+		  &b.Protect);
+}
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -278,6 +278,7 @@ AC_SUBST(tmake_file)
 AC_SUBST(cpu_type)
 AC_SUBST(extra_parts)
 AC_SUBST(asm_hidden_op)
+AC_CONFIG_LINKS([enable-execute-stack.c:$enable_execute_stack])
 AC_CONFIG_LINKS([md-unwind-support.h:config/$md_unwind_header])
 
 # We need multilib support.
diff --git a/libgcc/enable-execute-stack-empty.c b/libgcc/enable-execute-stack-empty.c
new file mode 100644
--- /dev/null
+++ b/libgcc/enable-execute-stack-empty.c
@@ -0,0 +1,7 @@
+/* Dummy implementation of __enable_execute_stack.  */
+
+/* Attempt to turn on execute permission for the stack.  */
+void
+__enable_execute_stack (void *addr __attribute__((__unused__)))
+{
+}
diff --git a/libgcc/enable-execute-stack-mprotect.c b/libgcc/enable-execute-stack-mprotect.c
new file mode 100644
--- /dev/null
+++ b/libgcc/enable-execute-stack-mprotect.c
@@ -0,0 +1,119 @@
+/* Implement __enable_execute_stack using mprotect(2).
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 3, or (at your option) any later
+   version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sys/mman.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#define STACK_PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC)
+
+static int need_enable_exec_stack;
+
+static void check_enabling (void) __attribute__ ((unused));
+extern void __enable_execute_stack (void *);
+
+#if defined __FreeBSD__
+#include <sys/sysctl.h>
+
+static void __attribute__ ((constructor))
+check_enabling (void)
+{
+  int prot = 0;
+  size_t len = sizeof (prot);
+
+  sysctlbyname ("kern.stackprot", &prot, &len, NULL, 0);
+  if (prot != STACK_PROT_RWX)
+    need_enable_exec_stack = 1;
+}
+#elif defined __sun__ && defined __svr4__
+static void __attribute__ ((constructor))
+check_enabling (void)
+{
+  int prot = (int) sysconf (_SC_STACK_PROT);
+
+  if (prot != STACK_PROT_RWX)
+    need_enable_exec_stack = 1;
+}
+#else
+/* There is no way to query the execute permission of the stack, so
+   we always issue the mprotect() call.  */
+
+static int need_enable_exec_stack = 1;
+#endif
+
+#if defined __NetBSD__
+/* Note that we go out of our way to use namespace-non-invasive calls
+   here.  Unfortunately, there is no libc-internal name for mprotect().  */
+
+#include <sys/sysctl.h>
+
+extern int __sysctl (int *, unsigned int, void *, size_t *, void *, size_t);
+
+static int
+getpagesize (void)
+{
+  static int size;
+
+  if (size == 0)
+    {
+      int mib[2];
+      size_t len;
+
+      mib[0] = CTL_HW;
+      mib[1] = HW_PAGESIZE;
+      len = sizeof (size);
+      (void) __sysctl (mib, 2, &size, &len, NULL, 0);
+    }
+  return size;
+}
+#endif /* __NetBSD__ */
+
+/* Attempt to turn on access permissions for the stack.  Unfortunately it
+   is not possible to make this namespace-clean.*/
+
+void
+__enable_execute_stack (void *addr)
+{
+  if (!need_enable_exec_stack)
+    return;
+  else
+    {
+      static long size, mask;
+
+      if (size == 0) {
+	size = getpagesize ();
+	mask = ~(size - 1);
+      }
+
+      char *page = (char *) (((long) addr) & mask);
+      char *end  = (char *)
+	((((long) (addr + __LIBGCC_TRAMPOLINE_SIZE__)) & mask) + size);
+
+      if (mprotect (page, end - page, STACK_PROT_RWX) < 0)
+	/* Note that no errors should be emitted by this code; it is
+	   considered dangerous for library calls to send messages to
+	   stdout/stderr.  */
+	abort ();
+    }
+}


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

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-06-09  7:50                   ` Rainer Orth
@ 2011-06-09  9:57                     ` Joseph S. Myers
  2011-06-09 12:06                     ` Bernd Schmidt
  1 sibling, 0 replies; 21+ messages in thread
From: Joseph S. Myers @ 2011-06-09  9:57 UTC (permalink / raw)
  To: Rainer Orth
  Cc: Paolo Bonzini, gcc-patches, Ralf Wildenhues, Mike Stump,
	Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

On Thu, 9 Jun 2011, Rainer Orth wrote:

> Indeed, that did the trick.  The following revised patch has been
> bootstrapped without regressions on i386-pc-solaris2.10.  I've already
> got build, Darwin and Mingw approval and can commit the osf and solaris
> parts on my own.  If the C parts are ok now, I suppose I still need
> approval either from the various *BSD maintainers (who haven't chimed in
> yet) of from a global reviewer?

The C parts of this version are OK.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc
  2011-06-09  7:50                   ` Rainer Orth
  2011-06-09  9:57                     ` Joseph S. Myers
@ 2011-06-09 12:06                     ` Bernd Schmidt
  1 sibling, 0 replies; 21+ messages in thread
From: Bernd Schmidt @ 2011-06-09 12:06 UTC (permalink / raw)
  To: Rainer Orth
  Cc: Joseph S. Myers, Paolo Bonzini, gcc-patches, Ralf Wildenhues,
	Mike Stump, Loren J. Rittle, Kai Tietz, Dave Korn, Jason Thorpe,
	Krister Walfridsson, Uros Bizjak, Richard Henderson,
	Eric Botcazou

On 06/09/2011 09:42 AM, Rainer Orth wrote:
> Indeed, that did the trick.  The following revised patch has been
> bootstrapped without regressions on i386-pc-solaris2.10.  I've already
> got build, Darwin and Mingw approval and can commit the osf and solaris
> parts on my own.  If the C parts are ok now, I suppose I still need
> approval either from the various *BSD maintainers (who haven't chimed in
> yet) of from a global reviewer?

Presumably the BSD folks will eventually complain if something breaks.
Patch is OK.


bernd

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2011-06-09 11:44 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-30 18:09 [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc Rainer Orth
2011-05-30 20:09 ` Kai Tietz
2011-05-31  9:45 ` Paolo Bonzini
2011-05-31 16:40   ` Rainer Orth
2011-05-31 16:57     ` Paolo Bonzini
2011-06-03 15:45       ` Rainer Orth
2011-06-03 16:01         ` Paolo Bonzini
2011-06-06  9:18           ` Rainer Orth
2011-06-06  9:23             ` Paolo Bonzini
2011-06-07 15:20             ` Joseph S. Myers
2011-06-07 15:31               ` Rainer Orth
2011-06-07 15:45                 ` Paolo Bonzini
2011-06-07 19:17                 ` Joseph S. Myers
2011-06-09  7:50                   ` Rainer Orth
2011-06-09  9:57                     ` Joseph S. Myers
2011-06-09 12:06                     ` Bernd Schmidt
2011-06-04 11:00         ` Gerald Pfeifer
2011-06-04 11:17         ` Andreas Schwab
2011-06-07 14:00       ` Joseph S. Myers
2011-06-07 14:57         ` Rainer Orth
2011-05-31 18:11 ` Mike Stump

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).