[RFC,MIPS] Enable non-executable PT_GNU_STACK support
diff mbox

Message ID 56B4EBAE.1090509@imgtec.com
State New
Headers show

Commit Message

Faraz Shahbazker Feb. 5, 2016, 6:36 p.m. UTC
Enable non-executable stack mode if assembler and linker support it.

Currently the MIPS FPU emulator uses eXecute Out of Line (XOL) on the stack to
handle instructions in the delay slots of FPU branches.  Because of this MIPS
cannot have a non-executable stack. While the solution on the kernel side is
not yet finalized, we propose changes required on the tools-side to make them
ready for a seamless transition whenever a fixed kernel becomes available.

glibc/dynamic linker:
----
* When non-executable stack is requested, first check AT_FLAGS in the
  auxiliary vector to decide if this kernel supports a non-executable
  stack. Persist with the non-executable mode specified on the
  PT_GNU_STACK segment only if kernel supports it, else revert to an
  executable stack.

* The 25th bit (1<<24) in AT_FLAGS is reserved for use by the kernel to
  indicate that it supports a non-executable stack on MIPS.

* glibc's ABIVERSION is incremented from 3 to 5, so that applications linked
  for this glibc can't be accidentally run against older versions. ABIVERSION
  4 has been skipped over because it was chosen for IFUNC support, which is
  still under review.

Patch under review: https://sourceware.org/ml/libc-alpha/2016-01/msg00567.html

binutils:
----
* Increment the ABIVERSION to 5 for objects with non-executable stacks.

Patch under review: https://sourceware.org/ml/binutils/2016-02/msg00087.html

gcc:
----
* Check if assembler/dynamic linker support the new behaviour
  (ABIVERSION >= 5). If yes, enable non-executable stack by default
  for all objects.

gcc/ChangeLog
	* configure.ac: Check if assembler supports the new PT_GNU_STACK
	ABI change; if yes, enable non-executable stack mode by default.
	* configure: Regenerate.
	* config.in: Regenerate.
	* config/mips/mips.c: Define TARGET_ASM_FILE_END to indicate
	stack mode for each C file if LD_MIPS_GNUSTACK is enabled.

libgcc/ChangeLog
	config/mips/crti.S: Add .note.GNU-stack marker if LD_MIPS_GNUSTACK
	support is enabled.
	config/mips/crtn.S: Add .note.GNU-stack marker if LD_MIPS_GNUSTACK
	support is enabled.
	config/mips/mips16.S: Add .note.GNU-stack marker if
	LD_MIPS_GNUSTACK support is enabled.
	config/mips/vr4120-div.S: Add .note.GNU-stack marker if
	LD_MIPS_GNUSTACK support is enabled.

-- gcc/configure.ac gcc/config/mips/mip.c config/mips/crti.S config/mips/crtn.S config/mips/mips16.S config/mips/vr4120-div.S
---
 gcc/config/mips/mips.c          |    5 +++++
 gcc/configure.ac                |   23 +++++++++++++++++++++++
 libgcc/config/mips/crti.S       |    6 ++++++
 libgcc/config/mips/crtn.S       |    6 ++++++
 libgcc/config/mips/mips16.S     |    7 +++++++
 libgcc/config/mips/vr4120-div.S |    7 +++++++
 6 files changed, 54 insertions(+)

Comments

Faraz Shahbazker Feb. 23, 2016, 4:24 p.m. UTC | #1
Bump.

On 02/05/2016 10:36 AM, Faraz Shahbazker wrote:
> Enable non-executable stack mode if assembler and linker support it.
> 
> Currently the MIPS FPU emulator uses eXecute Out of Line (XOL) on the stack to
> handle instructions in the delay slots of FPU branches.  Because of this MIPS
> cannot have a non-executable stack. While the solution on the kernel side is
> not yet finalized, we propose changes required on the tools-side to make them
> ready for a seamless transition whenever a fixed kernel becomes available.
> 
> glibc/dynamic linker:
> ----
> * When non-executable stack is requested, first check AT_FLAGS in the
>   auxiliary vector to decide if this kernel supports a non-executable
>   stack. Persist with the non-executable mode specified on the
>   PT_GNU_STACK segment only if kernel supports it, else revert to an
>   executable stack.
> 
> * The 25th bit (1<<24) in AT_FLAGS is reserved for use by the kernel to
>   indicate that it supports a non-executable stack on MIPS.
> 
> * glibc's ABIVERSION is incremented from 3 to 5, so that applications linked
>   for this glibc can't be accidentally run against older versions. ABIVERSION
>   4 has been skipped over because it was chosen for IFUNC support, which is
>   still under review.
> 
> Patch under review: https://sourceware.org/ml/libc-alpha/2016-01/msg00567.html
> 
> binutils:
> ----
> * Increment the ABIVERSION to 5 for objects with non-executable stacks.
> 
> Patch under review: https://sourceware.org/ml/binutils/2016-02/msg00087.html
> 
> gcc:
> ----
> * Check if assembler/dynamic linker support the new behaviour
>   (ABIVERSION >= 5). If yes, enable non-executable stack by default
>   for all objects.
> 
> gcc/ChangeLog
> 	* configure.ac: Check if assembler supports the new PT_GNU_STACK
> 	ABI change; if yes, enable non-executable stack mode by default.
> 	* configure: Regenerate.
> 	* config.in: Regenerate.
> 	* config/mips/mips.c: Define TARGET_ASM_FILE_END to indicate
> 	stack mode for each C file if LD_MIPS_GNUSTACK is enabled.
> 
> libgcc/ChangeLog
> 	config/mips/crti.S: Add .note.GNU-stack marker if LD_MIPS_GNUSTACK
> 	support is enabled.
> 	config/mips/crtn.S: Add .note.GNU-stack marker if LD_MIPS_GNUSTACK
> 	support is enabled.
> 	config/mips/mips16.S: Add .note.GNU-stack marker if
> 	LD_MIPS_GNUSTACK support is enabled.
> 	config/mips/vr4120-div.S: Add .note.GNU-stack marker if
> 	LD_MIPS_GNUSTACK support is enabled.
> 
> -- gcc/configure.ac gcc/config/mips/mip.c config/mips/crti.S config/mips/crtn.S config/mips/mips16.S config/mips/vr4120-div.S
> ---
>  gcc/config/mips/mips.c          |    5 +++++
>  gcc/configure.ac                |   23 +++++++++++++++++++++++
>  libgcc/config/mips/crti.S       |    6 ++++++
>  libgcc/config/mips/crtn.S       |    6 ++++++
>  libgcc/config/mips/mips16.S     |    7 +++++++
>  libgcc/config/mips/vr4120-div.S |    7 +++++++
>  6 files changed, 54 insertions(+)
> 
> diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
> index ea18ad6..c3eefc0 100644
> --- a/gcc/config/mips/mips.c
> +++ b/gcc/config/mips/mips.c
> @@ -20194,6 +20194,11 @@ mips_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
>  #undef TARGET_HARD_REGNO_SCRATCH_OK
>  #define TARGET_HARD_REGNO_SCRATCH_OK mips_hard_regno_scratch_ok
>  
> +#if HAVE_LD_MIPS_GNUSTACK
> +#undef TARGET_ASM_FILE_END
> +#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
> +#endif
> +
>  struct gcc_target targetm = TARGET_INITIALIZER;
>  
>  #include "gt-mips.h"
> diff --git a/gcc/configure.ac b/gcc/configure.ac
> index 0a626e9..9b8190e 100644
> --- a/gcc/configure.ac
> +++ b/gcc/configure.ac
> @@ -4562,6 +4562,29 @@ pointers into PC-relative form.])
>        AC_MSG_ERROR(
>  	[Requesting --with-nan= requires assembler support for -mnan=])
>      fi
> +
> +    AC_CACHE_CHECK([linker for GNU-stack ABI support],
> +      [gcc_cv_ld_mips_gnustack],
> +      [gcc_cv_ld_mips_gnustack=no
> +       if test x$gcc_cv_as != x \
> +	       -a x$gcc_cv_ld != x \
> +	       -a x$gcc_cv_readelf != x ; then
> +	 cat > conftest.s <<EOF
> +.section .note.GNU-stack,"",%progbits
> +EOF
> +	 if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \
> +	    && $gcc_cv_ld -o conftest conftest.o > /dev/null 2>&1; then
> +	   abi_version=`$gcc_cv_readelf -h conftest 2>&1 | grep "ABI Version:" | cut -d: -f2 | tr -d '[[:space:]]'`
> +	   if test "$abi_version" -ge 5; then
> +	     gcc_cv_ld_mips_gnustack=yes
> +	   fi
> +	 fi
> +       fi
> +       rm -f conftest.s conftest.o conftest])
> +    if test x$gcc_cv_ld_mips_gnustack = xyes; then
> +	    AC_DEFINE(HAVE_LD_MIPS_GNUSTACK, 1,
> +      [Define if your linker can handle PT_GNU_STACK segments correctly.])
> +    fi
>      ;;
>      s390*-*-*)
>      gcc_GAS_CHECK_FEATURE([.gnu_attribute support],
> diff --git a/libgcc/config/mips/crti.S b/libgcc/config/mips/crti.S
> index 8521d3c..aa85d94 100644
> --- a/libgcc/config/mips/crti.S
> +++ b/libgcc/config/mips/crti.S
> @@ -21,6 +21,12 @@ 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 "config.h"
> +#if HAVE_LD_MIPS_GNUSTACK
> +/* An executable stack is *not* required for these functions.  */
> +	.section .note.GNU-stack,"",%progbits
> +#endif
> +
>  /* 4 slots for argument spill area.  1 for cpreturn, 1 for stack.
>     Return spill offset of 40 and 20.  Aligned to 16 bytes for n32.  */
>  
> diff --git a/libgcc/config/mips/crtn.S b/libgcc/config/mips/crtn.S
> index d80c342..6a13b46 100644
> --- a/libgcc/config/mips/crtn.S
> +++ b/libgcc/config/mips/crtn.S
> @@ -21,6 +21,12 @@ 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 "config.h"
> +#if HAVE_LD_MIPS_GNUSTACK
> +/* An executable stack is *not* required for these functions.  */
> +        .section .note.GNU-stack,"",%progbits
> +#endif
> +
>  /* 4 slots for argument spill area.  1 for cpreturn, 1 for stack.
>     Return spill offset of 40 and 20.  Aligned to 16 bytes for n32.  */
>  
> diff --git a/libgcc/config/mips/mips16.S b/libgcc/config/mips/mips16.S
> index 5080f86..b8f6df8 100644
> --- a/libgcc/config/mips/mips16.S
> +++ b/libgcc/config/mips/mips16.S
> @@ -48,6 +48,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>     values using the soft-float calling convention, but do the actual
>     operation using the hard floating point instructions.  */
>  
> +#include "config.h"
> +#if HAVE_LD_MIPS_GNUSTACK
> +/* An executable stack is *not* required for these functions.  */
> +        .section .note.GNU-stack,"",%progbits
> +	.previous
> +#endif
> +
>  #if defined _MIPS_SIM && (_MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIO64)
>  
>  /* This file contains 32-bit assembly code.  */
> diff --git a/libgcc/config/mips/vr4120-div.S b/libgcc/config/mips/vr4120-div.S
> index 9954bc3..262de67 100644
> --- a/libgcc/config/mips/vr4120-div.S
> +++ b/libgcc/config/mips/vr4120-div.S
> @@ -26,6 +26,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>     -mfix-vr4120.  div and ddiv do not give the correct result when one
>     of the operands is negative.  */
>  
> +#include "config.h"
> +#if HAVE_LD_MIPS_GNUSTACK
> +/* An executable stack is *not* required for these functions.  */
> +        .section .note.GNU-stack,"",%progbits
> +#endif
> +	.previous
> +
>  	.set	nomips16
>  
>  #define DIV								\
>

Patch
diff mbox

diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index ea18ad6..c3eefc0 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -20194,6 +20194,11 @@  mips_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
 #undef TARGET_HARD_REGNO_SCRATCH_OK
 #define TARGET_HARD_REGNO_SCRATCH_OK mips_hard_regno_scratch_ok
 
+#if HAVE_LD_MIPS_GNUSTACK
+#undef TARGET_ASM_FILE_END
+#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
+#endif
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-mips.h"
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 0a626e9..9b8190e 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -4562,6 +4562,29 @@  pointers into PC-relative form.])
       AC_MSG_ERROR(
 	[Requesting --with-nan= requires assembler support for -mnan=])
     fi
+
+    AC_CACHE_CHECK([linker for GNU-stack ABI support],
+      [gcc_cv_ld_mips_gnustack],
+      [gcc_cv_ld_mips_gnustack=no
+       if test x$gcc_cv_as != x \
+	       -a x$gcc_cv_ld != x \
+	       -a x$gcc_cv_readelf != x ; then
+	 cat > conftest.s <<EOF
+.section .note.GNU-stack,"",%progbits
+EOF
+	 if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \
+	    && $gcc_cv_ld -o conftest conftest.o > /dev/null 2>&1; then
+	   abi_version=`$gcc_cv_readelf -h conftest 2>&1 | grep "ABI Version:" | cut -d: -f2 | tr -d '[[:space:]]'`
+	   if test "$abi_version" -ge 5; then
+	     gcc_cv_ld_mips_gnustack=yes
+	   fi
+	 fi
+       fi
+       rm -f conftest.s conftest.o conftest])
+    if test x$gcc_cv_ld_mips_gnustack = xyes; then
+	    AC_DEFINE(HAVE_LD_MIPS_GNUSTACK, 1,
+      [Define if your linker can handle PT_GNU_STACK segments correctly.])
+    fi
     ;;
     s390*-*-*)
     gcc_GAS_CHECK_FEATURE([.gnu_attribute support],
diff --git a/libgcc/config/mips/crti.S b/libgcc/config/mips/crti.S
index 8521d3c..aa85d94 100644
--- a/libgcc/config/mips/crti.S
+++ b/libgcc/config/mips/crti.S
@@ -21,6 +21,12 @@  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 "config.h"
+#if HAVE_LD_MIPS_GNUSTACK
+/* An executable stack is *not* required for these functions.  */
+	.section .note.GNU-stack,"",%progbits
+#endif
+
 /* 4 slots for argument spill area.  1 for cpreturn, 1 for stack.
    Return spill offset of 40 and 20.  Aligned to 16 bytes for n32.  */
 
diff --git a/libgcc/config/mips/crtn.S b/libgcc/config/mips/crtn.S
index d80c342..6a13b46 100644
--- a/libgcc/config/mips/crtn.S
+++ b/libgcc/config/mips/crtn.S
@@ -21,6 +21,12 @@  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 "config.h"
+#if HAVE_LD_MIPS_GNUSTACK
+/* An executable stack is *not* required for these functions.  */
+        .section .note.GNU-stack,"",%progbits
+#endif
+
 /* 4 slots for argument spill area.  1 for cpreturn, 1 for stack.
    Return spill offset of 40 and 20.  Aligned to 16 bytes for n32.  */
 
diff --git a/libgcc/config/mips/mips16.S b/libgcc/config/mips/mips16.S
index 5080f86..b8f6df8 100644
--- a/libgcc/config/mips/mips16.S
+++ b/libgcc/config/mips/mips16.S
@@ -48,6 +48,13 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    values using the soft-float calling convention, but do the actual
    operation using the hard floating point instructions.  */
 
+#include "config.h"
+#if HAVE_LD_MIPS_GNUSTACK
+/* An executable stack is *not* required for these functions.  */
+        .section .note.GNU-stack,"",%progbits
+	.previous
+#endif
+
 #if defined _MIPS_SIM && (_MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIO64)
 
 /* This file contains 32-bit assembly code.  */
diff --git a/libgcc/config/mips/vr4120-div.S b/libgcc/config/mips/vr4120-div.S
index 9954bc3..262de67 100644
--- a/libgcc/config/mips/vr4120-div.S
+++ b/libgcc/config/mips/vr4120-div.S
@@ -26,6 +26,13 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    -mfix-vr4120.  div and ddiv do not give the correct result when one
    of the operands is negative.  */
 
+#include "config.h"
+#if HAVE_LD_MIPS_GNUSTACK
+/* An executable stack is *not* required for these functions.  */
+        .section .note.GNU-stack,"",%progbits
+#endif
+	.previous
+
 	.set	nomips16
 
 #define DIV								\