[front-end,build-machinery,opt-framework] Allow setting of stack-clash via configure options. [Patch (4/6)]

Message ID 20180711112233.GA15865@arm.com
State New
Headers show
Series
  • [front-end,build-machinery,opt-framework] Allow setting of stack-clash via configure options. [Patch (4/6)]
Related show

Commit Message

Tamar Christina July 11, 2018, 11:22 a.m.
Hi All,

This patch defines a configure option to allow the setting of the default
guard size via configure flags when building the target.

The new flag is:

 * --with-stack-clash-protection-guard-size=<num>

The value of configured based params are set very early on and allow the
target to validate or reject the values as it sees fit.

To do this the values for the parameter get set by configure through CPP defines.
In case the back-end wants to know if a value was set or not the original default
value is also passed down as a define.

This allows a target to check if a param was changed by the user at configure time.

Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu and no issues.
Both targets were tested with stack clash on and off by default.

Ok for trunk?

Thanks,
Tamar

gcc/
2018-07-11  Tamar Christina  <tamar.christina@arm.com>

	PR target/86486
	* configure.ac: Add stack-clash-protection-guard-size.
	* config.in (DEFAULT_STK_CLASH_GUARD_SIZE, STK_CLASH_GUARD_SIZE_DEFAULT,
	STK_CLASH_GUARD_SIZE_MAX, STK_CLASH_GUARD_SIZE_MIN): New.
	* params.def (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE): Use it.
	* configure: Regenerate.
	* Makefile.in (params.list, params.options): Add include dir for CPP.
	* params-list.h: Include auto-host.h
	* params-options.h: Likewise.

--

Comments

Jeff Law July 11, 2018, 7:21 p.m. | #1
On 07/11/2018 05:22 AM, Tamar Christina wrote:
> Hi All,
> 
> This patch defines a configure option to allow the setting of the default
> guard size via configure flags when building the target.
> 
> The new flag is:
> 
>  * --with-stack-clash-protection-guard-size=<num>
> 
> The value of configured based params are set very early on and allow the
> target to validate or reject the values as it sees fit.
> 
> To do this the values for the parameter get set by configure through CPP defines.
> In case the back-end wants to know if a value was set or not the original default
> value is also passed down as a define.
> 
> This allows a target to check if a param was changed by the user at configure time.
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu and no issues.
> Both targets were tested with stack clash on and off by default.
> 
> Ok for trunk?
> 
> Thanks,
> Tamar
> 
> gcc/
> 2018-07-11  Tamar Christina  <tamar.christina@arm.com>
> 
> 	PR target/86486
> 	* configure.ac: Add stack-clash-protection-guard-size.
> 	* config.in (DEFAULT_STK_CLASH_GUARD_SIZE, STK_CLASH_GUARD_SIZE_DEFAULT,
> 	STK_CLASH_GUARD_SIZE_MAX, STK_CLASH_GUARD_SIZE_MIN): New.
> 	* params.def (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE): Use it.
> 	* configure: Regenerate.
> 	* Makefile.in (params.list, params.options): Add include dir for CPP.
> 	* params-list.h: Include auto-host.h
> 	* params-options.h: Likewise.
> 
Something seems wrong here.

What's the purpose of including auto-host in params-list and
params-options?  It seems like you're putting a property of the target
(guard size) into the wrong place (auto-host.h).

It's also a bit unclear to me why this is necessary at all.  Are we
planning to support both the 4k and 64k guards?  My goal (once the guard
was configurable) was never for supporting multiple sizes on a target
but instead to allow experimentation to find the right default.

Jeff
Tamar Christina July 12, 2018, 5:45 p.m. | #2
Hi Jeff,

The 07/11/2018 20:21, Jeff Law wrote:
> On 07/11/2018 05:22 AM, Tamar Christina wrote:
> > Hi All,
> > 
> > This patch defines a configure option to allow the setting of the default
> > guard size via configure flags when building the target.
> > 
> > The new flag is:
> > 
> >  * --with-stack-clash-protection-guard-size=<num>
> > 
> > The value of configured based params are set very early on and allow the
> > target to validate or reject the values as it sees fit.
> > 
> > To do this the values for the parameter get set by configure through CPP defines.
> > In case the back-end wants to know if a value was set or not the original default
> > value is also passed down as a define.
> > 
> > This allows a target to check if a param was changed by the user at configure time.
> > 
> > Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu and no issues.
> > Both targets were tested with stack clash on and off by default.
> > 
> > Ok for trunk?
> > 
> > Thanks,
> > Tamar
> > 
> > gcc/
> > 2018-07-11  Tamar Christina  <tamar.christina@arm.com>
> > 
> > 	PR target/86486
> > 	* configure.ac: Add stack-clash-protection-guard-size.
> > 	* config.in (DEFAULT_STK_CLASH_GUARD_SIZE, STK_CLASH_GUARD_SIZE_DEFAULT,
> > 	STK_CLASH_GUARD_SIZE_MAX, STK_CLASH_GUARD_SIZE_MIN): New.
> > 	* params.def (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE): Use it.
> > 	* configure: Regenerate.
> > 	* Makefile.in (params.list, params.options): Add include dir for CPP.
> > 	* params-list.h: Include auto-host.h
> > 	* params-options.h: Likewise.
> > 
> Something seems wrong here.
> 
> What's the purpose of including auto-host in params-list and
> params-options?  It seems like you're putting a property of the target
> (guard size) into the wrong place (auto-host.h).
> 

The reason for this is because there's a test gcc.dg/params/blocksort-part.c
that uses these params-options to generate test cases to perform parameter
validation. However because now the params.def file can contain a CPP
macro these would then fail.

CPP is already called to create params-options and params-list so the easiest
way to fix this test was just to include auto-host which would get it the values
from configure.

This test is probably not needed anymore after my second patch series as parameters
are validated by the front-end now, so they can never go out of range.

> It's also a bit unclear to me why this is necessary at all.  Are we
> planning to support both the 4k and 64k guards?  My goal (once the guard
> was configurable) was never for supporting multiple sizes on a target
> but instead to allow experimentation to find the right default.
> 

I will get back to you on this one.

Thanks,
Tamar

> Jeff

--

Patch

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index d8f3e8861189604035b248b69bc484443f334c1c..f2fcab8e1c91bac4fac1b7162659165f74c6795b 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3469,13 +3469,13 @@  installdirs:
 
 params.list: s-params.list; @true
 s-params.list: $(srcdir)/params-list.h $(srcdir)/params.def
-	$(CPP) $(srcdir)/params-list.h | sed 's/^#.*//;/^$$/d' > tmp-params.list
+	$(CPP) -I$(objdir) $(srcdir)/params-list.h | sed 's/^#.*//;/^$$/d' > tmp-params.list
 	$(SHELL) $(srcdir)/../move-if-change tmp-params.list params.list
 	$(STAMP) s-params.list
 
 params.options: s-params.options; @true
 s-params.options: $(srcdir)/params-options.h $(srcdir)/params.def
-	$(CPP) $(srcdir)/params-options.h | sed 's/^#.*//;/^$$/d' > tmp-params.options
+	$(CPP) -I$(objdir) $(srcdir)/params-options.h | sed 's/^#.*//;/^$$/d' > tmp-params.options
 	$(SHELL) $(srcdir)/../move-if-change tmp-params.options params.options
 	$(STAMP) s-params.options
 
diff --git a/gcc/config.in b/gcc/config.in
index 2856e72d627df537a301a6c7ab6b5bbb75f6b43f..bf593b5231adef0a6fc71b259597afa76e862607 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -55,6 +55,12 @@ 
 #endif
 
 
+/* Define to larger than zero set the default stack clash protector size. */
+#ifndef USED_FOR_TARGET
+#undef DEFAULT_STK_CLASH_GUARD_SIZE
+#endif
+
+
 /* Define if you want to use __cxa_atexit, rather than atexit, to register C++
    destructors for local statics and global objects. This is essential for
    fully standards-compliant handling of destructors, but requires
@@ -2148,6 +2154,24 @@ 
 #endif
 
 
+/* Set the stack clash guard size default value. */
+#ifndef USED_FOR_TARGET
+#undef STK_CLASH_GUARD_SIZE_DEFAULT
+#endif
+
+
+/* Set the stack clash guard size maximum value. */
+#ifndef USED_FOR_TARGET
+#undef STK_CLASH_GUARD_SIZE_MAX
+#endif
+
+
+/* Set the stack clash guard size minimum value. */
+#ifndef USED_FOR_TARGET
+#undef STK_CLASH_GUARD_SIZE_MIN
+#endif
+
+
 /* Define if you can safely include both <string.h> and <strings.h>. */
 #ifndef USED_FOR_TARGET
 #undef STRING_WITH_STRINGS
diff --git a/gcc/configure b/gcc/configure
index 60d373982fd38fe51c285e2b02941754d1b833d6..35cf0c724b4f14152205153337379e0ae3a0d501 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -905,6 +905,7 @@  enable_valgrind_annotations
 with_stabs
 enable_multilib
 enable_multiarch
+with_stack_clash_protection_guard_size
 enable___cxa_atexit
 enable_decimal_float
 enable_fixed_point
@@ -1724,6 +1725,8 @@  Optional Packages:
   --with-gnu-as           arrange to work with GNU as
   --with-as               arrange to use the specified as (full pathname)
   --with-stabs            arrange to use stabs instead of host debug format
+  --with-stack-clash-protection-guard-size=size
+                          Set the default stack clash protection guard size.
   --with-dwarf2           force the default debug format to be DWARF 2
   --with-specs=SPECS      add SPECS to driver command-line processing
   --with-pkgversion=PKG   Use PKG in the version string in place of "GCC"
@@ -7436,6 +7439,51 @@  $as_echo "$enable_multiarch$ma_msg_suffix" >&6; }
 
 
 
+# default stack clash protection guard size
+# These are kept here and passed down to params.def.  This way we don't have to
+# worry about keeping them in sync.
+stk_clash_min=12
+stk_clash_max=30
+stk_clash_default=12
+
+# Keep the default value when the option is not used to 0, this allows us to
+# distinguish between the cases where the user specifially set a value via
+# configure and when the normal default value is used.
+
+# Check whether --with-stack-clash-protection-guard-size was given.
+if test "${with_stack_clash_protection_guard_size+set}" = set; then :
+  withval=$with_stack_clash_protection_guard_size; DEFAULT_STK_CLASH_GUARD_SIZE="$with_stack_clash_protection_guard_size"
+else
+  DEFAULT_STK_CLASH_GUARD_SIZE=0
+fi
+
+if test $DEFAULT_STK_CLASH_GUARD_SIZE -ne 0 \
+     && (test $DEFAULT_STK_CLASH_GUARD_SIZE -lt $stk_clash_min \
+	 || test $DEFAULT_STK_CLASH_GUARD_SIZE -gt $stk_clash_max); then
+  as_fn_error "Invalid value $DEFAULT_STK_CLASH_GUARD_SIZE for --with-stack-clash-protection-guard-size. Must be between $stk_clash_min and $stk_clash_max." "$LINENO" 5
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_STK_CLASH_GUARD_SIZE $DEFAULT_STK_CLASH_GUARD_SIZE
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define STK_CLASH_GUARD_SIZE_MIN $stk_clash_min
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define STK_CLASH_GUARD_SIZE_MAX $stk_clash_max
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define STK_CLASH_GUARD_SIZE_DEFAULT $stk_clash_default
+_ACEOF
+
+
 # Enable __cxa_atexit for C++.
 # Check whether --enable-__cxa_atexit was given.
 if test "${enable___cxa_atexit+set}" = set; then :
@@ -18448,7 +18496,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 18451 "configure"
+#line 18499 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -18554,7 +18602,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 18557 "configure"
+#line 18605 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 010ecd2ccf609ded1f4d2849a2acc13aba43b55b..77d30825df113fc1f18b86d6a5294c13be9aeb65 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -811,6 +811,36 @@  AC_MSG_RESULT($enable_multiarch$ma_msg_suffix)
 AC_SUBST(with_cpu)
 AC_SUBST(with_float)
 
+# default stack clash protection guard size
+# These are kept here and passed down to params.def.  This way we don't have to
+# worry about keeping them in sync.
+stk_clash_min=12
+stk_clash_max=30
+stk_clash_default=12
+
+# Keep the default value when the option is not used to 0, this allows us to
+# distinguish between the cases where the user specifially set a value via
+# configure and when the normal default value is used.
+AC_ARG_WITH(stack-clash-protection-guard-size,
+[AS_HELP_STRING([--with-stack-clash-protection-guard-size=size], [Set the default stack clash protection guard size.])],
+[DEFAULT_STK_CLASH_GUARD_SIZE="$with_stack_clash_protection_guard_size"], [DEFAULT_STK_CLASH_GUARD_SIZE=0])
+if test $DEFAULT_STK_CLASH_GUARD_SIZE -ne 0 \
+     && (test $DEFAULT_STK_CLASH_GUARD_SIZE -lt $stk_clash_min \
+	 || test $DEFAULT_STK_CLASH_GUARD_SIZE -gt $stk_clash_max); then
+  AC_MSG_ERROR(m4_normalize([
+		Invalid value $DEFAULT_STK_CLASH_GUARD_SIZE for --with-stack-clash-protection-guard-size. \
+		Must be between $stk_clash_min and $stk_clash_max.]))
+fi
+
+AC_DEFINE_UNQUOTED(DEFAULT_STK_CLASH_GUARD_SIZE, $DEFAULT_STK_CLASH_GUARD_SIZE,
+	[Define to larger than zero set the default stack clash protector size.])
+AC_DEFINE_UNQUOTED(STK_CLASH_GUARD_SIZE_MIN, $stk_clash_min,
+	[Set the stack clash guard size minimum value.])
+AC_DEFINE_UNQUOTED(STK_CLASH_GUARD_SIZE_MAX, $stk_clash_max,
+	[Set the stack clash guard size maximum value.])
+AC_DEFINE_UNQUOTED(STK_CLASH_GUARD_SIZE_DEFAULT, $stk_clash_default,
+	[Set the stack clash guard size default value.])
+
 # Enable __cxa_atexit for C++.
 AC_ARG_ENABLE(__cxa_atexit,
 [AS_HELP_STRING([--enable-__cxa_atexit], [enable __cxa_atexit for C++])],
diff --git a/gcc/params-list.h b/gcc/params-list.h
index 4889c39a180abb3d0efaaf12e148deb1d011f65f..e58eb50cea356deb85e232da6e3200d6168ac686 100644
--- a/gcc/params-list.h
+++ b/gcc/params-list.h
@@ -17,6 +17,8 @@  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/>.  */
 
+#include "auto-host.h"
+
 #define DEFPARAM(enumerator, option, nocmsgid, default, min, max) \
   enumerator,
 #define DEFPARAMENUM5(enumerator, option, nocmsgid, default, \
diff --git a/gcc/params-options.h b/gcc/params-options.h
index e9ac2e73522ddb6c199ed0af462ebc7e4777d676..ea678ed46ce5d21af0b9bc9e27f358406589a564 100644
--- a/gcc/params-options.h
+++ b/gcc/params-options.h
@@ -17,6 +17,8 @@  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/>.  */
 
+#include "auto-host.h"
+
 #define DEFPARAM(enumerator, option, nocmsgid, default, min, max) \
   option=default,min,max
 #define DEFPARAMENUM5(enumerator, option, nocmsgid, default, \
diff --git a/gcc/params.def b/gcc/params.def
index a3906c268814bdc3a813416a60b9f666d1568f0a..d4e0461844dc958cebaefaa9004fd98c78c31419 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -213,10 +213,14 @@  DEFPARAM(PARAM_STACK_FRAME_GROWTH,
 	 "Maximal stack frame growth due to inlining (in percent).",
 	 1000, 0, 0)
 
+/* These values are stored in configure.ac, update them there to keep everything
+   in sync.  */
 DEFPARAM(PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE,
 	 "stack-clash-protection-guard-size",
 	 "Size of the stack guard expressed as a power of two.",
-	 12, 12, 30)
+	 DEFAULT_STK_CLASH_GUARD_SIZE ? DEFAULT_STK_CLASH_GUARD_SIZE : STK_CLASH_GUARD_SIZE_DEFAULT,
+	 STK_CLASH_GUARD_SIZE_MIN,
+	 STK_CLASH_GUARD_SIZE_MAX)
 
 DEFPARAM(PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL,
 	 "stack-clash-protection-probe-interval",