Patchwork [build] Move ENABLE_EXECUTE_STACK to toplevel libgcc

login
register
mail settings
Submitter Rainer Orth
Date May 30, 2011, 3:59 p.m.
Message ID <yddipssrxgx.fsf@manam.CeBiTec.Uni-Bielefeld.DE>
Download mbox | patch
Permalink /patch/97934/
State New
Headers show

Comments

Rainer Orth - May 30, 2011, 3:59 p.m.
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.
Paolo Bonzini - May 31, 2011, 9:02 a.m.
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
Rainer Orth - May 31, 2011, 3:36 p.m.
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
Paolo Bonzini - May 31, 2011, 3:57 p.m.
> 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
Mike Stump - May 31, 2011, 4:56 p.m.
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.
Joseph S. Myers - June 7, 2011, 1:59 p.m.
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).
Rainer Orth - June 7, 2011, 2:57 p.m.
"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

Patch

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");				\
+  }									\
+}