From d75f90f1923454ae3dac50d69b90d907ac2607c6 Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Thu, 19 Aug 2004 22:10:52 +0000 Subject: [PATCH] 2004-08-18 Andreas Krebbel * 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 | 17 ++++++++++ gcc/config/s390/s390.c | 75 ++++++++++++++++++++++++++++++++++++++++++ gcc/config/s390/s390.h | 39 +++++++++++++++------- gcc/doc/invoke.texi | 31 ++++++++++++++++- 4 files changed, 150 insertions(+), 12 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4f832d42ac0..025d70e9642 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2004-08-18 Andreas Krebbel + + * 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 * unwind-dw2-fde.c (get_cie_encoding): Cast argument to strlen diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 02c245f6f33..f68879c5996 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -204,6 +204,16 @@ const char *s390_arch_string; /* for -march= */ 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)); diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index 02b1817c460..7dec84f454f 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -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. */ diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index db3677f946f..eadf22a3591 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 -- 2.30.2