2004-08-18 Andreas Krebbel <krebbel1@de.ibm.com>
authoruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 19 Aug 2004 22:10:52 +0000 (22:10 +0000)
committeruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@86284 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 4f832d4..025d70e 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 02c245f..f68879c 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 02b1817..7dec84f 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 db3677f..eadf22a 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