2004-08-18 Andreas Krebbel <krebbel1@de.ibm.com>
authorAndreas Krebbel <krebbel1@de.ibm.com>
Thu, 19 Aug 2004 22:10:52 +0000 (22:10 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Thu, 19 Aug 2004 22:10:52 +0000 (22:10 +0000)
* config/s390/s390.md (s390_warn_framesize_string)
(s390_warn_dynamic_string, s390_stack_size_string)
(s390_stack_guard_string): New global string variables.
(s390_warn_framesize, s390_warn_dynamicstack_p, s390_stack_size)
(s390_stack_guard): New global variables.
(override_options): Added checks for the new options.
(s390_emit_prologue): Emit stack check and trap code and perform
compile time stack size checking.

* config/s390/s390.h (TARGET_OPTIONS): Added new options
"warn-framesize", "warn-dynamicstack", "stack-size" and
"stack-guard".

* doc/invoke.texi: Added documentation for the new options.

From-SVN: r86284

gcc/ChangeLog
gcc/config/s390/s390.c
gcc/config/s390/s390.h
gcc/doc/invoke.texi

index 4f832d42ac06882b055d2a8be71063874979a108..025d70e9642abc75564fa907d4e9bad624a196c6 100644 (file)
@@ -1,3 +1,20 @@
+2004-08-18  Andreas Krebbel  <krebbel1@de.ibm.com>
+
+       * config/s390/s390.md (s390_warn_framesize_string)
+       (s390_warn_dynamic_string, s390_stack_size_string)
+       (s390_stack_guard_string): New global string variables.
+       (s390_warn_framesize, s390_warn_dynamicstack_p, s390_stack_size)
+       (s390_stack_guard): New global variables.
+       (override_options): Added checks for the new options.
+       (s390_emit_prologue): Emit stack check and trap code and perform
+       compile time stack size checking.
+       
+       * config/s390/s390.h (TARGET_OPTIONS): Added new options 
+       "warn-framesize", "warn-dynamicstack", "stack-size" and
+       "stack-guard".
+
+       * doc/invoke.texi: Added documentation for the new options.
+
 2004-08-19  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * unwind-dw2-fde.c (get_cie_encoding): Cast argument to strlen
index 02c245f6f33b35b5dbcd2e34a3b081ba072d0f13..f68879c59963448954cd19301ba90e665029cb01 100644 (file)
@@ -204,6 +204,16 @@ const char *s390_arch_string;              /* for -march=<xxx> */
 const char *s390_backchain_string = ""; /* "" no-backchain ,"1" backchain,
                                           "2" kernel-backchain */
 
+const char *s390_warn_framesize_string;
+const char *s390_warn_dynamicstack_string;
+const char *s390_stack_size_string;
+const char *s390_stack_guard_string;
+
+HOST_WIDE_INT s390_warn_framesize = 0;
+bool s390_warn_dynamicstack_p = 0;
+HOST_WIDE_INT s390_stack_size = 0;
+HOST_WIDE_INT s390_stack_guard = 0;
+
 /* The following structure is embedded in the machine 
    specific part of struct function.  */
 
@@ -1147,6 +1157,44 @@ override_options (void)
     error ("z/Architecture mode not supported on %s.", s390_arch_string);
   if (TARGET_64BIT && !TARGET_ZARCH)
     error ("64-bit ABI not supported in ESA/390 mode.");
+
+  if (s390_warn_framesize_string)
+    {
+      if (sscanf (s390_warn_framesize_string, HOST_WIDE_INT_PRINT_DEC,
+                 &s390_warn_framesize) != 1)
+       error ("invalid value for -mwarn-framesize");
+    }
+
+  if (s390_warn_dynamicstack_string)
+    s390_warn_dynamicstack_p = 1;
+  
+  if (s390_stack_size_string)
+    {
+      if (sscanf (s390_stack_size_string, HOST_WIDE_INT_PRINT_DEC, 
+                 &s390_stack_size) != 1)
+       error ("invalid value for -mstack-size");
+      
+      if (exact_log2 (s390_stack_size) == -1)
+       error ("stack size must be an exact power of 2");
+      
+      if (s390_stack_guard_string)
+       {
+         if (sscanf (s390_stack_guard_string, HOST_WIDE_INT_PRINT_DEC, 
+                     &s390_stack_guard) != 1)
+           error ("invalid value for -mstack-guard");
+         
+         if (s390_stack_guard >= s390_stack_size)
+           error ("stack size must be greater than the stack guard value");
+         if (exact_log2 (s390_stack_guard) == -1)
+           error ("stack guard value must be an exact power of 2");
+       }
+      else
+       error ("-mstack-size implies use of -mstack-guard");
+    }
+  
+  if (s390_stack_guard_string && !s390_stack_size_string)
+    error ("-mstack-guard implies use of -mstack-size"); 
 }
 
 /* Map for smallest class containing reg regno.  */
@@ -6269,6 +6317,33 @@ s390_emit_prologue (void)
     {
       rtx frame_off = GEN_INT (-cfun_frame_layout.frame_size);
 
+      if (s390_stack_size)
+       {
+         HOST_WIDE_INT stack_check_mask = ((s390_stack_size - 1)
+                                           & ~(s390_stack_guard - 1));
+         rtx t = gen_rtx_AND (Pmode, stack_pointer_rtx,
+                              GEN_INT (stack_check_mask));
+
+         if (TARGET_64BIT)
+           gen_cmpdi (t, const0_rtx);
+         else
+           gen_cmpsi (t, const0_rtx);
+
+         emit_insn (gen_conditional_trap (gen_rtx_EQ (CCmode, 
+                                                      gen_rtx_REG (CCmode, 
+                                                                   CC_REGNUM),
+                                                      const0_rtx),
+                                          const0_rtx));
+       }
+
+      if (s390_warn_framesize > 0 
+         && cfun_frame_layout.frame_size >= s390_warn_framesize)
+       warning ("frame size of `%s' is " HOST_WIDE_INT_PRINT_DEC " bytes", 
+                current_function_name (), cfun_frame_layout.frame_size);
+
+      if (s390_warn_dynamicstack_p && cfun->calls_alloca)
+       warning ("`%s' uses dynamic stack allocation", current_function_name ());
+
       /* Save incoming stack pointer into temp reg.  */
       if (cfun_frame_layout.save_backchain_p || next_fpr)
        insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
index 02b1817c460f45392e75cd3ddcf370a879a3272b..7dec84f454fad85b0f9eafade51391fdf67589bc 100644 (file)
@@ -62,6 +62,11 @@ extern const char *s390_arch_string;
 
 extern const char *s390_backchain_string;
 
+extern const char *s390_warn_framesize_string;
+extern const char *s390_warn_dynamicstack_string;
+extern const char *s390_stack_size_string;
+extern const char *s390_stack_guard_string;
+
 #define TARGET_CPU_IEEE_FLOAT \
        (s390_arch_flags & PF_IEEE_FLOAT)
 #define TARGET_CPU_ZARCH \
@@ -142,17 +147,29 @@ extern int target_flags;
   { "fused-madd",   -256, N_("enable fused multiply/add instructions")}, \
   { "", TARGET_DEFAULT, 0 } }
 
-#define TARGET_OPTIONS                                          \
-{ { "tune=",            &s390_tune_string,                      \
-    N_("Schedule code for given CPU"), 0},                      \
-  { "arch=",            &s390_arch_string,                      \
-    N_("Generate code for given CPU"), 0},                      \
-  { "backchain",        &s390_backchain_string,                 \
-    N_("Set backchain"), "1"},                                  \
-  { "no-backchain",     &s390_backchain_string,                 \
-    N_("Do not set backchain"), ""},                            \
-  { "kernel-backchain", &s390_backchain_string,                 \
-    N_("Set backchain appropriate for the linux kernel"), "2"}, \
+#define TARGET_OPTIONS                                                         \
+{ { "tune=",            &s390_tune_string,                                     \
+    N_("Schedule code for given CPU"), 0},                                     \
+  { "arch=",            &s390_arch_string,                                     \
+    N_("Generate code for given CPU"), 0},                                     \
+  { "backchain",        &s390_backchain_string,                                \
+    N_("Set backchain"), "1"},                                                 \
+  { "no-backchain",     &s390_backchain_string,                                \
+    N_("Do not set backchain"), ""},                                           \
+  { "kernel-backchain", &s390_backchain_string,                                \
+    N_("Set backchain appropriate for the linux kernel"), "2"},                \
+  { "warn-framesize=",   &s390_warn_framesize_string,                          \
+    N_("Warn if a single function's framesize exceeds the given framesize"),   \
+       0},                                                                     \
+  { "warn-dynamicstack", &s390_warn_dynamicstack_string,                       \
+    N_("Warn if a function uses alloca or creates an array with dynamic size"),\
+       0},                                                                     \
+  { "stack-size=",       &s390_stack_size_string,                              \
+    N_("Emit extra code in the function prologue in order to trap if the stack"\
+       "size exceeds the given limit"), 0},                                    \
+  { "stack-guard=",      &s390_stack_guard_string,                             \
+    N_("Set the max. number of bytes which has to be left to stack size "      \
+       "before a trap instruction is triggered"), 0},                          \
 }
 
 /* Support for configure-time defaults.  */
index db3677f946ff9d1b9ed516c66cf805b8d7082425..eadf22a3591f147bb8d5efcaa94753f6403d0824 100644 (file)
@@ -620,7 +620,8 @@ See RS/6000 and PowerPC Options.
 -mhard-float  -msoft-float  -mbackchain  -mno-backchain -mkernel-backchain @gol
 -msmall-exec  -mno-small-exec  -mmvcle -mno-mvcle @gol
 -m64  -m31  -mdebug  -mno-debug  -mesa  -mzarch @gol
--mtpf-trace -mno-tpf-trace  -mfused-madd  -mno-fused-madd}
+-mtpf-trace -mno-tpf-trace  -mfused-madd  -mno-fused-madd @gol
+-mwarn-framesize  -mwarn-dynamicstack  -mstack-size -mstack-guard}
 
 @emph{SH Options}
 @gccoptlist{-m1  -m2  -m2e  -m3  -m3e @gol
@@ -10593,6 +10594,34 @@ when compiling for the TPF OS.
 Generate code that uses (does not use) the floating point multiply and
 accumulate instructions.  These instructions are generated by default if
 hardware floating point is used.
+
+@item -mwarn-framesize=@var{framesize}
+@opindex mwarn-framesize
+Emit a warning if the current function exceeds the given frame size.  Because
+this is a compile time check it doesn't need to be a real problem when the program
+runs.  It is intended to identify functions which most probably cause 
+a stack overflow.  It is useful to be used in an environment with limited stack 
+size e.g. the linux kernel.
+
+@item -mwarn-dynamicstack
+@opindex mwarn-dynamicstack
+Emit a warning if the function calls alloca or uses dynamically
+sized arrays.  This is generally a bad idea with a limited stack size.
+
+@item -mstack-guard=@var{stack-guard}
+@item -mstack-size=@var{stack-size}
+@opindex mstack-guard
+@opindex mstack-size
+These arguments always have to be used in conjunction.  If they are present the s390
+back end emits additional instructions in the function prologue which trigger a trap
+if the stack size is @var{stack-guard} bytes above the @var{stack-size} 
+(remember that the stack on s390 grows downward).  These options are intended to 
+be used to help debugging stack overflow problems.  The additionally emitted code 
+cause only little overhead and hence can also be used in production like systems 
+without greater performance degradation.  The given values have to be exact 
+powers of 2 and @var{stack-size} has to be greater than @var{stack-guard}.
+In order to be efficient the extra code makes the assumption that the stack starts
+at an address aligned to the value given by @var{stack-size}.
 @end table
 
 @node SH Options