[PATCH] New -fstack-check implementation (1/n)

Eric Botcazou ebotcazou@adacore.com
Mon Mar 20 08:00:00 GMT 2006


Hi,

-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).  This is 
a regression from the 3.x series although there were bugs in that series too.

Moreover, the original implementation of -fstack-check 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 of -fstack-check that eliminates the 
aforementioned drawback.  It is based on partial support code in the 
architecture back-ends, modelled on what the Alpha back-end already features 
because of the requirement of stack checking by the Tru64 ABI.  We have 
implemented it on Alpha/Tru64, x86/Linux, x86/Solaris, x86/FreeBSD, 
x86/Windows, x86-64/Linux, MIPS/IRIX, SPARC/Solaris, PA/HP-UX, PowerPC/AIX, 
and IA-64/Linux in a 3.4.x based compiler and are in the process of porting 
it to 4.1.x.

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.

This first patch contains the generic implementation of the new mechanism and 
also repairs the old one, so the 3 ACATS tests that require stack checking 
(c52103x c52104x c52104y) will pass even with the old mechanism on platforms 
that are capable of unwinding through signal handlers.  We'll also submit a 
few new *-unwind.h files for non-Linux platforms.

Bootstrapped/regtested on x86_64-suse-linux, OK for mainline?


2006-03-20  Eric Botcazou  <ebotcazou@adacore.com>

	PR ada/20548
	* 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_CHECK_STATIC_BUILTIN): New macro.
	(STACK_OLD_CHECK_PROTECT): Likewise.
	(STACK_CHECK_PROTECT): Bump to 3 pages if DWARF-2 EH is used.
	* system.h (STACK_CHECK_PROBE_INTERVAL): Poison it.
	* doc/tm.texi (Stack Checking): Delete STACK_CHECK_PROBE_INTERVAL
	entry.  Add new entries for STACK_CHECK_PROBE_INTERVAL_EXP and
	STACK_CHECK_STATIC_BUILTIN.
	* 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.
	* 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.
	(expand_function_end): Adjust for new behaviour of flag_stack_check.
	* reload1.c (reload): Likewise.
	* stmt.c (expand_decl): Assert that all automatic variables have
	fixed size at this point and remove dead code.
	* gimplify.c (gimplify_decl_expr): Use more stringent test on
	DECL_SIZE_UNIT to detect variable-sized objects.  Treat all
	objects whose size is greater than STACK_CHECK_MAX_VAR_SIZE
	as variable-sized if generic stack checking is enabled.
	* explow.c: Include except.h.
	(allocate_dynamic_stack_space): Do not take into account
	STACK_CHECK_MAX_FRAME_SIZE for static builtin stack checking.
	(set_stack_check_libfunc): Delete.
	(stack_check_libfunc): Make public.
	(PROBE_INTERVAL): New macro.
	(STACK_GROW_OPTAB): 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 MD pattern.  Fix loop condition in the small constant case.
	Rewrite in the general case to be immune to wrap-around.
	Do not include gt-explow.h.
	* Makefile.in (explow.o): Remove gt-explow.h.
	(list of gt files): Likewise.
	* rtl.h (set_stack_check_libfunc): Delete.
	(stack_check_libfunc): Declare.
	(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.

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): For targets that do not use probes, initialize
	stack_check_libfunc here...
	(gnat_init_stmt_group): ...and not there.
	* utils2.c (build_call_alloc_dealloc): Remove redundant test of
 	flag_stack_check.  Adjust for new behaviour of flag_stack_check.

testsuite/

	* ada/acats/norun.lst: Remove c52103x, c52104x and c52104y.


-- 
Eric Botcazou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gcc-42_stack-check_generic.diff
Type: text/x-diff
Size: 34994 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20060320/5c5ddbcb/attachment.bin>


More information about the Gcc-patches mailing list