https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86486

--- Comment #4 from Tamar Christina <tnfchris at gcc dot gnu.org> ---
Author: tnfchris
Date: Mon Oct  1 13:00:58 2018
New Revision: 264751

URL: https://gcc.gnu.org/viewcvs?rev=264751&root=gcc&view=rev
Log:
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.


Added:
    trunk/gcc/testsuite/gcc.target/aarch64/stack-check-14.c
    trunk/gcc/testsuite/gcc.target/aarch64/stack-check-15.c
    trunk/gcc/testsuite/gcc.target/aarch64/stack-check-alloca-1.c
    trunk/gcc/testsuite/gcc.target/aarch64/stack-check-alloca-10.c
    trunk/gcc/testsuite/gcc.target/aarch64/stack-check-alloca-2.c
    trunk/gcc/testsuite/gcc.target/aarch64/stack-check-alloca-3.c
    trunk/gcc/testsuite/gcc.target/aarch64/stack-check-alloca-4.c
    trunk/gcc/testsuite/gcc.target/aarch64/stack-check-alloca-5.c
    trunk/gcc/testsuite/gcc.target/aarch64/stack-check-alloca-6.c
    trunk/gcc/testsuite/gcc.target/aarch64/stack-check-alloca-7.c
    trunk/gcc/testsuite/gcc.target/aarch64/stack-check-alloca-8.c
    trunk/gcc/testsuite/gcc.target/aarch64/stack-check-alloca-9.c
    trunk/gcc/testsuite/gcc.target/aarch64/stack-check-alloca.h
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/aarch64/aarch64.c
    trunk/gcc/config/aarch64/aarch64.h
    trunk/gcc/testsuite/ChangeLog

Reply via email to