This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi, Due to popular demand :-), I'm again submitting the new stack checking implementation that we have been using at AdaCore for a few years now. Previous submissions: http://gcc.gnu.org/ml/gcc-patches/2006-03/msg01239.html http://gcc.gnu.org/ml/gcc-patches/2006-11/msg01846.html But, contrary to the above submissions, this one contains the full set of changes (modulo some adjustments in the Ada runtime and *-unwind.h files for non-Linux platforms). -fstack-check is broken in the 4.x series of compilers in the sense that you cannot recover from a stack overflow condition (for example in Ada). It's a regression from the 3.x series although there were bugs in that series too. Moreover, the original implementation comes with several drawbacks: - modified allocation strategy for large objects: they will always be allocated dynamically if their size exceeds a fixed threshold. - fixed limit on the size of the static frame of functions: when it is topped by a particular function, stack checking is not reliable and a warning is issued by the compiler. - inefficiency: because of both the modified allocation strategy and the generic implementation, the performances of the code are unnecessarily hampered. We are proposing a new implementation that eliminates the aforementioned drawbacks. It is based on partial support code in the architecture back-ends, modelled on what the Alpha back-end already has because of the requirement of the Tru64 ABI. We implemented it on Alpha/Tru64, x86/Linux, x86/Solaris, x86/FreeBSD, x86/Windows, x86/VxWorks, x86/LynxOS, x86-64/Linux, MIPS/IRIX (n32), SPARC/Solaris, SPARC64/Solaris, PA/HP-UX, PowerPC/AIX, PowerPC/VxWorks, PowerPC/LynxOS, IA-64/Linux and IA-64/HP-UX in 3.4.x, 4.1.x and 4.3.x based compilers. The new mechanism doesn't eliminate the old one, the option -fold-stack-check even makes it possible to select the latter when the former is available. On architectures without specific support code, -fstack-check is equivalent to -fold-stack-check. Tested on i586-suse-linux. Although the changes are mostly orthogonal to the rest of the compiler, suggestions are welcome as to what the best procedure for integrating this patch in the compiler would be. 2008-03-29 Eric Botcazou <ebotcazou@adacore.com> Tristan Gingold <gingold@adacore.com> Olivier Hainque <hainque@adacore.com> Jose Ruiz <ruiz@adacore.com> PR ada/20548 New stack checking implementation * common.opt (-fstack-check): Do not declare the variable here. (-fold-stack-check): New option. * doc/invoke.texi (Code Gen Options): Document it. * expr.h (STACK_CHECK_PROBE_INTERVAL): Delete. (STACK_CHECK_PROBE_INTERVAL_EXP): New macro. (STACK_CHECK_MAX_FRAME_SIZE): Adjust for above change. (STACK_OLD_CHECK_PROTECT): Likewise. (STACK_CHECK_PROTECT): Bump to 3 pages if DWARF-2 EH is used. (STACK_CHECK_STATIC_BUILTIN): New macro. (STACK_CHECK_PROBE_IOR): Likewise. (STACK_CHECK_MOVING_SP): Likewise. * system.h (STACK_CHECK_PROBE_INTERVAL): Poison it. * doc/tm.texi (Stack Checking): Delete STACK_CHECK_PROBE_INTERVAL. Document STACK_CHECK_PROBE_INTERVAL_EXP, STACK_CHECK_STATIC_BUILTIN, STACK_CHECK_PROBE_IOR and STACK_CHECK_MOVING_SP. * opts.c: Include expr.h. (common_handle_option) <OPT_fold_stack_check>: New case. <OPT_fstack_check>: Likewise. * calls.c (emit_library_call_value_1): Clear the ECF_NOTHROW flag if the libcall is LCT_MAY_THROW. (initialize_argument_information): Use TYPE_SIZE_UNIT consistently in the test for variable-sized types. Adjust for new behaviour of flag_stack_check. * explow.c: Include except.h. (anti_adjust_stack_and_probe): New function. (allocate_dynamic_stack_space): Do not take into account STACK_CHECK_MAX_FRAME_SIZE for static builtin stack checking. Do not directly allocate space if STACK_CHECK_MOVING_SP, instead invoke above function. (set_stack_check_libfunc): Delete. (stack_check_libfunc): Make public. (stack_check_symbol): New public variable. (emit_stack_probe): Deal with STACK_CHECK_PROBE_IOR. (PROBE_INTERVAL): New macro. (STACK_GROW_OPTAB): Likewise. (STACK_HIGH, STACK_LOW): Likewise. (probe_stack_range): Cope with SPARC_STACK_BIAS. Pass LCT_MAY_THROW to emit_library_call for the checking routine. Remove support code for dedicated pattern. Add support for stack limits provided by the stack_check_symbol variable. Fix loop condition in the small constant case. Rewrite in the general case to be immune to wrap-around. Make sure the address of probes is valid. Try to use [base + disp] addressing mode as much as possible. Do not include gt-explow.h. * function.c (gimplify_parameters): Use DECL_SIZE_UNIT in the test for variable-sized parameters. Treat all parameters whose size is greater than STACK_CHECK_MAX_VAR_SIZE as variable-sized if generic stack checking is enabled. * gimplify.c (gimplify_decl_expr): Treat non-static objects whose size is greater than STACK_CHECK_MAX_VAR_SIZE as variable-sized if generic stack checking is enabled. (expand_function_end): Adjust for new behaviour of flag_stack_check. * reload1.c (reload): Likewise. (init_elim_table): Set frame_pointer_needed if stack checking is enabled and STACK_CHECK_MOVING_SP. * rtlanal.c: Include expr.h. (may_trap_p_1) <MEM>: If STACK_CHECK_MOVING_SP, return 1 for volatile references to the stack pointer. * stmt.c (expand_decl): Assert that all automatic variables have fixed size at this point and remove dead code. * rtl.h (set_stack_check_libfunc): Delete. (stack_check_libfunc): Declare. (stack_check_symbol): Likewise. (libcall_type enum): Add LCT_MAY_THROW. * flags.h (stack_check_type): New enumeration type. (flag_stack_check): Change type to above. * toplev.c (flag_stack_check): Likewise. * tree.c (build_common_builtin_nodes): Do not set ECF_NOTHROW on __builtin_alloca if stack checking is enabled. * Makefile.in (rtlanal.o): Add dependency on EXPR_H. (explow.o): Remove gt-explow.h. * config/alpha/alpha.c (alpha_expand_prologue): If stack checking is enabled, probe up to frame_size + STACK_CHECK_PROTECT bytes. * config/i386/cygming.h (STACK_CHECK_STATIC_BUILTIN): Define to 1. * config/i386/freebsd.h (STACK_CHECK_STATIC_BUILTIN): Likewise. * config/i386/linux.h (STACK_CHECK_STATIC_BUILTIN): Likewise. (STACK_CHECK_MOVING_SP): Likewise. * config/i386/linux64.h (STACK_CHECK_STATIC_BUILTIN): Likewise. (STACK_CHECK_MOVING_SP): Likewise. * config/i386/lynx.h (STACK_CHECK_STATIC_BUILTIN): Likewise. * config/i386/sol2.h (STACK_CHECK_STATIC_BUILTIN): Likewise. * config/i386/vxworks.h (STACK_CHECK_STATIC_BUILTIN): Likewise. (STACK_CHECK_PROTECT): 8K is reserved in the stack to propagate exceptions reliably in case of stack overflow. * config/i386/vxworksae.h (STACK_CHECK_PROTECT): Redefine to 4K which is enough for executing a possible last chance handler. * config/i386/i386.h (STACK_CHECK_PROBE_IOR): Define to 1. * config/i386/i386.c (ix86_target_stack_probe): New function. (ix86_compute_frame_layout): Force use of push instructions to save registers if stack checking with probes is enabled. (ix86_eax_maybe_live_in_or_out): New function. (ix86_edx_maybe_live_in_or_out: Likewise. (ix86_ecx_maybe_live_in_or_out): Likewise. (get_scratch_register_on_entry): Likewise. (release_scratch_register_on_entry): Likewise. (output_probe_op): Likewise. (output_adjust_stack_and_probe_op): Likewise. (output_adjust_stack_and_probe): Likewise. (ix86_gen_adjust_stack_and_probe): Likewise. (ix86_adjust_stack_and_probe): Likewise. (output_cond_trap): Likewise. (output_probe_stack_range_op): Likewise. (ix86_gen_probe_stack_range): Likewise. (ix86_emit_probe_stack_range): Likewise. (ix86_expand_prologue): Emit stack checking code if static builtin stack checking is enabled. Test ix86_target_stack_probe instead of TARGET_STACK_PROBE. * config/i386/i386-protos.h (ix86_target_stack_probe): Declare. (output_adjust_stack_and_probe): Likewise. (output_cond_trap): Likewise. (output_probe_stack_range): Likewise. * config/i386/i386.md (UNSPECV_STACK_PROBE_INLINE): New constant. (allocate_stack_worker_32): Test ix86_target_stack_probe instead of TARGET_STACK_PROBE. (allocate_stack_worker_64): Likewise. (allocate_stack): Likewise. (adjust_stack_and_probe): New insn. (probe_stack_range): Likewise. (logical operation peepholes): Do not split stack checking probes. (cond_trap): New insn. * config/ia64/hpux.h (STACK_CHECK_STATIC_BUILTIN): Define to 1. (STACK_CHECK_PROTECT): Define. * config/ia64/linux.h (STACK_CHECK_STATIC_BUILTIN): Define to 1. * config/ia64/ia64.c (ia64_emit_probe_stack_range): New function. (output_probe_stack_range): Likewise. (ia64_expand_prologue): Invoke ia64_emit_probe_stack_range if static builtin stack checking is enabled. (rtx_needs_barrier): Return 1 for inline stack probes. (asm_insn_p): New predicate. (ia64_dfa_sched_reorder): Use it. (ia64_dfa_new_cycle): Likewise. (issue_nops_and_insn): Likewise. (bundling): Likewise. (final_emit_insn_group_barriers): Likewise. * config/ia64/ia64-protos.h (output_probe_stack_range): Declare. * config/ia64/ia64.md (UNSPECV_STACK_PROBE_INLINE): New constant. (probe_stack_range): New insn. * config/mips/iris6.h (STACK_CHECK_STATIC_BUILTIN): Define to 1. * config/mips/mips.c: Include except.h. (mips_emit_probe_stack_range): New function. (mips_output_probe_stack_range): Likewise. (mips_expand_prologue): Invoke mips_emit_probe_stack_range if static builtin stack checking is enabled. * config/mips/mips-protos.h (mips_output_probe_stack_range): Declare. * config/mips/mips.md (UNSPECV_STACK_PROBE_INLINE): New constant. (probe_stack_range): New insn. * config/pa/pa-hpux.h (STACK_CHECK_STATIC_BUILTIN): Define to 1. * config/pa/pa.c (pa_emit_probe_stack_range): New function. (output_probe_stack_range): Likewise. (hppa_expand_prologue): Invoke pa_emit_probe_stack_range if static builtin stack checking is enabled. * config/pa/pa-protos.h (output_probe_stack_range): Declare. * config/pa/pa.md (probe_stack_range): New insn. * config/rs6000/aix.h (STACK_CHECK_STATIC_BUILTIN): Define to 1. * config/rs6000/lynx.h (STACK_CHECK_STATIC_BUILTIN): Likewise. * config/rs6000/vxworks.h (STACK_CHECK_STATIC_BUILTIN): Likewise. (STACK_CHECK_PROTECT): 8K is reserved in the stack to propagate exceptions reliably in case of stack overflow. * config/rs6000/vxworksae.h (STACK_CHECK_PROTECT): Redefine to 4K which is enough for executing a possible last chance handler. * config/rs6000/rs6000.c (rs6000_emit_probe_stack_range): New function. (output_probe_stack_range): Likewise. (rs6000_emit_prologue): Invoke rs6000_emit_probe_stack_range if static builtin stack checking is enabled. * config/rs6000/rs6000-protos.h (output_probe_stack_range): Declare. * config/rs6000/rs6000.md (UNSPECV_STACK_PROBE_INLINE): New constant. (probe_stack_range): New insn. * config/sparc/sol2.h (STACK_CHECK_STATIC_BUILTIN): Define to 1. * config/sparc/sparc.c: Include except.h. (sparc_emit_probe_stack_range): New function. (build_big_number): Likewise. (output_probe_stack_range): Likewise. (sparc_expand_prologue): Invoke sparc_emit_probe_stack_range if static builtin stack checking is enabled. * config/sparc/sparc-protos.h (output_probe_stack_range): Declare. * config/sparc/sparc.md (UNSPECV_STACK_PROBE_INLINE): New constant. (probe_stack_range): New insn. ada/ * decl.c (gnat_to_gnu_entity): Use DECL_SIZE_UNIT consistently in the setjmp test. Adjust for new behaviour of flag_stack_check. * trans.c (gigi): Set stack_check_symbol to __gnat_stack_limit on selected platforms. * utils2.c (build_call_alloc_dealloc): Remove redundant test of flag_stack_check. Adjust for new behaviour of flag_stack_check. * init.c (HP-UX section): Use an alternate signal stack. (Linux section): Likewise on x86 and x86-64. * system-linux-x86_64.ads (Stack_Check_Probes): Set to true. * system-linux-x86.ads (Stack_Check_Probes): Set to true. testsuite/ * ada/acats/norun.lst: Remove c52103x, c52104x, c52104y, cb1010a, cb1010c and cb1010d. -- Eric Botcazou
Attachment:
gcc-44_stack-check.diff.gz
Description: GNU Zip compressed data
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |