"Joseph S. Myers" <jos...@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 <r...@cebitec.uni-bielefeld.de> Joseph Myers <jos...@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" - - -/* 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 @@ -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 */ -#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/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