Ensure that outgoing argument size is at least 8 bytes when alloca and stack-clash.
authorTamar Christina <tamar.christina@arm.com>
Mon, 1 Oct 2018 13:00:58 +0000 (13:00 +0000)
committerTamar Christina <tnfchris@gcc.gnu.org>
Mon, 1 Oct 2018 13:00:58 +0000 (13:00 +0000)
commit8c6e3b2355b0cd245b0a4f802044d8fd885ea03e
tree46610e0ec89a849ce9e2145563dcea5383c311a3
parent2c25083e75fa265fd6cdd749a264951dc002d90b
Ensure that outgoing argument size is at least 8 bytes when alloca and stack-clash.

This patch adds a requirement that the number of outgoing arguments for a
function is at least 8 bytes when using stack-clash protection and alloca.

By using this condition we can avoid a check in the alloca code and so have
smaller and simpler code there.

A simplified version of the AArch64 stack frames is:

   +-----------------------+
   |                       |
   |                       |
   |                       |
   +-----------------------+
   |LR                     |
   +-----------------------+
   |FP                     |
   +-----------------------+
   |dynamic allocations    | ----  expanding area which will push the outgoing
   +-----------------------+       args down during each allocation.
   |padding                |
   +-----------------------+
   |outgoing stack args    | ---- safety buffer of 8 bytes (aligned)
   +-----------------------+

By always defining an outgoing argument, alloca(0) effectively is safe to probe
at $sp due to the reserved buffer being there.  It will never corrupt the stack.

This is also safe for alloca(x) where x is 0 or x % page_size == 0.  In the
former it is the same case as alloca(0) while the latter is safe because any
allocation pushes the outgoing stack args down:

   |FP                     |
   +-----------------------+
   |                       |
   |dynamic allocations    | ----  alloca (x)
   |                       |
   +-----------------------+
   |padding                |
   +-----------------------+
   |outgoing stack args    | ---- safety buffer of 8 bytes (aligned)
   +-----------------------+

Which means when you probe for the residual, if it's 0 you'll again just probe
in the outgoing stack args range, which we know is non-zero (at least 8 bytes).

gcc/

PR target/86486
* config/aarch64/aarch64.h (STACK_CLASH_MIN_BYTES_OUTGOING_ARGS,
STACK_DYNAMIC_OFFSET): New.
* config/aarch64/aarch64.c (aarch64_layout_frame):
Update outgoing args size.
(aarch64_stack_clash_protection_alloca_probe_range,
TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE): New.

gcc/testsuite/

PR target/86486
* gcc.target/aarch64/stack-check-alloca-1.c: New.
* gcc.target/aarch64/stack-check-alloca-10.c: New.
* gcc.target/aarch64/stack-check-alloca-2.c: New.
* gcc.target/aarch64/stack-check-alloca-3.c: New.
* gcc.target/aarch64/stack-check-alloca-4.c: New.
* gcc.target/aarch64/stack-check-alloca-5.c: New.
* gcc.target/aarch64/stack-check-alloca-6.c: New.
* gcc.target/aarch64/stack-check-alloca-7.c: New.
* gcc.target/aarch64/stack-check-alloca-8.c: New.
* gcc.target/aarch64/stack-check-alloca-9.c: New.
* gcc.target/aarch64/stack-check-alloca.h: New.
* gcc.target/aarch64/stack-check-14.c: New.
* gcc.target/aarch64/stack-check-15.c: New.

From-SVN: r264751
17 files changed:
gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/stack-check-14.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/stack-check-15.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/stack-check-alloca-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/stack-check-alloca-10.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/stack-check-alloca-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/stack-check-alloca-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/stack-check-alloca-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/stack-check-alloca-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/stack-check-alloca-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/stack-check-alloca-7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/stack-check-alloca-8.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/stack-check-alloca-9.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/stack-check-alloca.h [new file with mode: 0644]