Sebastian Pop <sebpop....@gmail.com> writes:
> Hi,
>
> On Fri, Aug 7, 2020 at 6:18 AM Richard Sandiford <rsand...@gcc.gnu.org> wrote:
>>
>> https://gcc.gnu.org/g:5380912a17ea09a8996720fb62b1a70c16c8f9f2
>>
>> commit r9-8794-g5380912a17ea09a8996720fb62b1a70c16c8f9f2
>> Author: Richard Sandiford <richard.sandif...@arm.com>
>> Date:   Fri Aug 7 12:17:37 2020 +0100
>
> could you please also apply this change to the gcc-8 branch?

I've now pushed the attached patch to GCC 8.  It's somewhat simpler
than the GCC 9+ version since GCC 8 didn't support the sysreg model.

Tested on aarch64-linux-gnu.

Thanks,
Richard


gcc/
        PR target/96191
        * config/aarch64/aarch64.md (stack_protect_test_<mode>): Set the
        CC register directly, instead of a GPR.  Replace the original GPR
        destination with an extra scratch register.  Zero out operand 3
        after use.
        (stack_protect_test): Update accordingly.

gcc/testsuite/
        PR target/96191
        * gcc.target/aarch64/stack-protector-1.c: New test.
        * gcc.target/aarch64/stack-protector-2.c: Likewise.

(cherry picked from commit fe1a26429038d7cd17abc53f96a6f3e2639b605f)
---
 gcc/config/aarch64/aarch64.md                 | 35 ++++----
 .../gcc.target/aarch64/stack-protector-1.c    | 89 +++++++++++++++++++
 .../gcc.target/aarch64/stack-protector-2.c    |  6 ++
 3 files changed, 110 insertions(+), 20 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-protector-1.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/stack-protector-2.c

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 9fc555c4006..ea1319c56a4 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -5995,35 +5995,30 @@
    (match_operand 2)]
   ""
 {
-  rtx result;
   machine_mode mode = GET_MODE (operands[0]);
 
-  result = gen_reg_rtx(mode);
-
   emit_insn ((mode == DImode
-             ? gen_stack_protect_test_di
-             : gen_stack_protect_test_si) (result,
-                                           operands[0],
-                                           operands[1]));
-
-  if (mode == DImode)
-    emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
-                                   result, const0_rtx, operands[2]));
-  else
-    emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
-                                   result, const0_rtx, operands[2]));
+            ? gen_stack_protect_test_di
+            : gen_stack_protect_test_si) (operands[0], operands[1]));
+
+  rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
+  emit_jump_insn (gen_condjump (gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx),
+                               cc_reg, operands[2]));
   DONE;
 })
 
+;; DO NOT SPLIT THIS PATTERN.  It is important for security reasons that the
+;; canary value does not live beyond the end of this sequence.
 (define_insn "stack_protect_test_<mode>"
-  [(set (match_operand:PTR 0 "register_operand" "=r")
-       (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
-                    (match_operand:PTR 2 "memory_operand" "m")]
-        UNSPEC_SP_TEST))
+  [(set (reg:CC CC_REGNUM)
+       (unspec:CC [(match_operand:PTR 0 "memory_operand" "m")
+                   (match_operand:PTR 1 "memory_operand" "m")]
+                  UNSPEC_SP_TEST))
+   (clobber (match_scratch:PTR 2 "=&r"))
    (clobber (match_scratch:PTR 3 "=&r"))]
   ""
-  "ldr\t%<w>3, %1\;ldr\t%<w>0, %2\;eor\t%<w>0, %<w>3, %<w>0"
-  [(set_attr "length" "12")
+  "ldr\t%<w>2, %0\;ldr\t%<w>3, %1\;subs\t%<w>2, %<w>2, %<w>3\;mov\t%3, 0"
+  [(set_attr "length" "16")
    (set_attr "type" "multiple")])
 
 ;; Write Floating-point Control Register.
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-protector-1.c 
b/gcc/testsuite/gcc.target/aarch64/stack-protector-1.c
new file mode 100644
index 00000000000..73e83bc413f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/stack-protector-1.c
@@ -0,0 +1,89 @@
+/* { dg-do run } */
+/* { dg-require-effective-target fstack_protector } */
+/* { dg-options "-fstack-protector-all -O2" } */
+
+extern volatile long *stack_chk_guard_ptr;
+
+volatile long *
+get_ptr (void)
+{
+  return stack_chk_guard_ptr;
+}
+
+void __attribute__ ((noipa))
+f (void)
+{
+  volatile int x;
+  x = 1;
+  x += 1;
+}
+
+#define CHECK(REG) "\tcmp\tx0, " #REG "\n\tbeq\t1f\n"
+
+asm (
+"      .pushsection .data\n"
+"      .align  3\n"
+"      .globl  stack_chk_guard_ptr\n"
+"stack_chk_guard_ptr:\n"
+#if __ILP32__
+"      .word   __stack_chk_guard\n"
+#else
+"      .xword  __stack_chk_guard\n"
+#endif
+"      .weak   __stack_chk_guard\n"
+"__stack_chk_guard:\n"
+"      .word   0xdead4321\n"
+"      .word   0xbeef8765\n"
+"      .text\n"
+"      .globl  main\n"
+"      .type   main, %function\n"
+"main:\n"
+"      bl      get_ptr\n"
+"      str     x0, [sp, #-16]!\n"
+"      bl      f\n"
+"      str     x0, [sp, #8]\n"
+"      ldr     x0, [sp]\n"
+#if __ILP32__
+"      ldr     w0, [x0]\n"
+#else
+"      ldr     x0, [x0]\n"
+#endif
+       CHECK (x1)
+       CHECK (x2)
+       CHECK (x3)
+       CHECK (x4)
+       CHECK (x5)
+       CHECK (x6)
+       CHECK (x7)
+       CHECK (x8)
+       CHECK (x9)
+       CHECK (x10)
+       CHECK (x11)
+       CHECK (x12)
+       CHECK (x13)
+       CHECK (x14)
+       CHECK (x15)
+       CHECK (x16)
+       CHECK (x17)
+       CHECK (x18)
+       CHECK (x19)
+       CHECK (x20)
+       CHECK (x21)
+       CHECK (x22)
+       CHECK (x23)
+       CHECK (x24)
+       CHECK (x25)
+       CHECK (x26)
+       CHECK (x27)
+       CHECK (x28)
+       CHECK (x29)
+       CHECK (x30)
+"      ldr     x1, [sp]\n"
+       CHECK (x1)
+"      mov     x0, #0\n"
+"      b       exit\n"
+"1:\n"
+"      b       abort\n"
+"      .size   main, .-main\n"
+"      .popsection"
+);
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-protector-2.c 
b/gcc/testsuite/gcc.target/aarch64/stack-protector-2.c
new file mode 100644
index 00000000000..266c36fdbc6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/stack-protector-2.c
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+/* { dg-require-effective-target fstack_protector } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-fstack-protector-all -O2 -fpic" } */
+
+#include "stack-protector-1.c"

Reply via email to