Ensure that outgoing argument size is at least 8 bytes when alloca and stack-clash

Programming / Compilers / GCC - tnfchris [138bc75d-0d04-0410-961f-82ee72b054a4] - 1 October 2018 13:00 EDT

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.

aad32f38bac Ensure that outgoing argument size is at least 8 bytes when alloca and stack-clash.
gcc/ChangeLog | 10 +++++++++
gcc/config/aarch64/aarch64.c | 18 ++++++++++++++++
gcc/config/aarch64/aarch64.h | 17 +++++++++++++++
gcc/testsuite/ChangeLog | 17 +++++++++++++++
gcc/testsuite/gcc.target/aarch64/stack-check-14.c | 24 ++++++++++++++++++++++
gcc/testsuite/gcc.target/aarch64/stack-check-15.c | 21 +++++++++++++++++++
.../gcc.target/aarch64/stack-check-alloca-1.c | 14 +++++++++++++
.../gcc.target/aarch64/stack-check-alloca-10.c | 12 +++++++++++
.../gcc.target/aarch64/stack-check-alloca-2.c | 10 +++++++++
.../gcc.target/aarch64/stack-check-alloca-3.c | 10 +++++++++
.../gcc.target/aarch64/stack-check-alloca-4.c | 11 ++++++++++
.../gcc.target/aarch64/stack-check-alloca-5.c | 11 ++++++++++
.../gcc.target/aarch64/stack-check-alloca-6.c | 11 ++++++++++
.../gcc.target/aarch64/stack-check-alloca-7.c | 11 ++++++++++
.../gcc.target/aarch64/stack-check-alloca-8.c | 13 ++++++++++++
.../gcc.target/aarch64/stack-check-alloca-9.c | 12 +++++++++++
.../gcc.target/aarch64/stack-check-alloca.h | 13 ++++++++++++
17 files changed, 235 insertions(+)

Upstream: gcc.gnu.org


  • Share