0From: Alexandre Oliva <oliva@adacore.com>

strub: introduce STACK_ADDRESS_OFFSET

Since STACK_POINTER_OFFSET is not necessarily at the boundary between
caller- and callee-owned stack, as desired by
__builtin_stack_address(), and using it as if it were or not causes
problems, introduce a new macro so that ports can define it suitably,
without modifying STACK_POINTER_OFFSET.


for  gcc/ChangeLog

	PR middle-end/112917
	PR middle-end/113100
	* builtins.cc (expand_builtin_stack_address): Use
	STACK_ADDRESS_OFFSET.
	* doc/extend.texi (__builtin_stack_address): Adjust.
	* config/sparc/sparc.h (STACK_ADDRESS_OFFSET): Define.
	* doc/tm.texi.in (STACK_ADDRESS_OFFSET): Document.
	* doc/tm.texi: Rebuilt.
This commit is contained in:
Alexandre Oliva 2024-01-31 00:13:36 -03:00 committed by Alexandre Oliva
parent 35de88e2ed
commit 320fb976e9
5 changed files with 68 additions and 4 deletions

View file

@ -5450,7 +5450,7 @@ expand_builtin_stack_address ()
rtx ret = convert_to_mode (ptr_mode, copy_to_reg (stack_pointer_rtx),
STACK_UNSIGNED);
#ifdef SPARC_STACK_BOUNDARY_HACK
#ifdef STACK_ADDRESS_OFFSET
/* Unbias the stack pointer, bringing it to the boundary between the
stack area claimed by the active function calling this builtin,
and stack ranges that could get clobbered if it called another
@ -5477,8 +5477,7 @@ expand_builtin_stack_address ()
(caller) function's active area as well, whereas those pushed or
allocated temporarily for a call are regarded as part of the
callee's stack range, rather than the caller's. */
if (SPARC_STACK_BOUNDARY_HACK)
ret = plus_constant (ptr_mode, ret, STACK_POINTER_OFFSET);
ret = plus_constant (ptr_mode, ret, STACK_ADDRESS_OFFSET);
#endif
return force_reg (ptr_mode, ret);

View file

@ -734,6 +734,13 @@ along with GCC; see the file COPYING3. If not see
parameter regs. */
#define STACK_POINTER_OFFSET (FIRST_PARM_OFFSET(0) + SPARC_STACK_BIAS)
/* Unbias the stack pointer if needed, and move past the register save area,
that is never in use while a function is active, so that it is regarded as a
callee save area rather than as part of the function's own stack area. This
enables __strub_leave() to do a better job of clearing the stack frame of a
previously-called sibling. */
#define STACK_ADDRESS_OFFSET STACK_POINTER_OFFSET
/* Base register for access to local variables of the function. */
#define HARD_FRAME_POINTER_REGNUM 30

View file

@ -12799,7 +12799,7 @@ situations.
@deftypefn {Built-in Function} {void *} __builtin_stack_address ()
This function returns the stack pointer register, offset by
@code{STACK_POINTER_OFFSET}.
@code{STACK_ADDRESS_OFFSET} if that's defined.
Conceptually, the returned address returned by this built-in function is
the boundary between the stack area allocated for use by its caller, and

View file

@ -3456,6 +3456,35 @@ or type, otherwise return false. The default implementation always returns
true.
@end deftypefn
@defmac STACK_ADDRESS_OFFSET
Offset from the stack pointer register to the boundary address between
the stack area claimed by an active function, and stack ranges that
could get clobbered if it called another function. It should NOT
encompass any stack red zone, that is used in leaf functions.
This value is added to the stack pointer register to compute the address
returned by @code{__builtin_stack_address}, and this is its only use.
If this macro is not defined, no offset is added. Defining it like
@code{STACK_POINTER_OFFSET} may be appropriate for many machines, but
not all.
On SPARC, for example, the register save area is *not* considered active
or used by the active function, but rather as akin to the area in which
call-preserved registers are saved by callees, so the stack address is
above that area, even though the (unbiased) stack pointer points below
it. This enables @code{__strub_leave} to clear what would otherwise
overlap with its own register save area.
On PowerPC, @code{STACK_POINTER_OFFSET} also reserves space for a save
area, but that area is used by the caller rather than the callee, so the
boundary address is below it.
If the address is computed too high or too low, parts of a stack range
that should be scrubbed may be left unscrubbed, scrubbing may corrupt
active portions of the stack frame, and stack ranges may be
doubly-scrubbed by caller and callee.
@end defmac
@defmac TARGET_STRUB_USE_DYNAMIC_ARRAY
If defined to nonzero, @code{__strub_leave} will allocate a dynamic
array covering the stack range that needs scrubbing before clearing it.

View file

@ -2688,6 +2688,35 @@ may reduce the size of debug information on some ports.
@hook TARGET_HAVE_STRUB_SUPPORT_FOR
@defmac STACK_ADDRESS_OFFSET
Offset from the stack pointer register to the boundary address between
the stack area claimed by an active function, and stack ranges that
could get clobbered if it called another function. It should NOT
encompass any stack red zone, that is used in leaf functions.
This value is added to the stack pointer register to compute the address
returned by @code{__builtin_stack_address}, and this is its only use.
If this macro is not defined, no offset is added. Defining it like
@code{STACK_POINTER_OFFSET} may be appropriate for many machines, but
not all.
On SPARC, for example, the register save area is *not* considered active
or used by the active function, but rather as akin to the area in which
call-preserved registers are saved by callees, so the stack address is
above that area, even though the (unbiased) stack pointer points below
it. This enables @code{__strub_leave} to clear what would otherwise
overlap with its own register save area.
On PowerPC, @code{STACK_POINTER_OFFSET} also reserves space for a save
area, but that area is used by the caller rather than the callee, so the
boundary address is below it.
If the address is computed too high or too low, parts of a stack range
that should be scrubbed may be left unscrubbed, scrubbing may corrupt
active portions of the stack frame, and stack ranges may be
doubly-scrubbed by caller and callee.
@end defmac
@defmac TARGET_STRUB_USE_DYNAMIC_ARRAY
If defined to nonzero, @code{__strub_leave} will allocate a dynamic
array covering the stack range that needs scrubbing before clearing it.