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 */
 
-#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 */
-
 #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__)))
+{
+}
