@@ -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. */
@@ -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 \
@@ -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*)
new file mode 100644
@@ -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");
+ }
+}
new file mode 100644
@@ -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);
+}
@@ -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.
new file mode 100644
@@ -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__)))
+{
+}