]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rs6000: Compute rop_hash_save_offset for non-Altivec compiles [PR115389]
authorPeter Bergner <bergner@linux.ibm.com>
Fri, 14 Jun 2024 19:36:20 +0000 (14:36 -0500)
committerPeter Bergner <bergner@linux.ibm.com>
Wed, 24 Jul 2024 01:28:12 +0000 (20:28 -0500)
We currently only compute the offset for the ROP hash save location in
the stack frame for Altivec compiles.  For non-Altivec compiles when we
emit ROP mitigation instructions, we use a default offset of zero which
corresponds to the backchain save location which will get clobbered on
any call.  The fix is to compute the ROP hash save location for all
compiles.

2024-06-14  Peter Bergner  <bergner@linux.ibm.com>

gcc/
PR target/115389
* config/rs6000/rs6000-logue.cc (rs6000_stack_info): Compute
rop_hash_save_offset for non-Altivec compiles.

gcc/testsuite
PR target/115389
* gcc.target/powerpc/pr115389.c: New test.

(cherry picked from commit c70eea0dba5f223d49c80cfb3e80e87b74330aac)

gcc/config/rs6000/rs6000-logue.cc
gcc/testsuite/gcc.target/powerpc/pr115389.c [new file with mode: 0644]

index 270f415737577e6363e7e00048e07d91551d192c..3894bd23d179c6dc31a0f2b48da3dc0c5efb4594 100644 (file)
@@ -821,17 +821,16 @@ rs6000_stack_info (void)
          gcc_assert (info->altivec_size == 0
                      || info->altivec_save_offset % 16 == 0);
 
-         /* Adjust for AltiVec case.  */
-         info->ehrd_offset = info->altivec_save_offset - ehrd_size;
-
          /* Adjust for ROP protection.  */
          info->rop_hash_save_offset
            = info->altivec_save_offset - info->rop_hash_size;
-         info->ehrd_offset -= info->rop_hash_size;
        }
       else
-       info->ehrd_offset = info->gp_save_offset - ehrd_size;
+         /* Adjust for ROP protection.  */
+         info->rop_hash_save_offset
+           = info->gp_save_offset - info->rop_hash_size;
 
+      info->ehrd_offset = info->rop_hash_save_offset - ehrd_size;
       info->ehcr_offset = info->ehrd_offset - ehcr_size;
       info->cr_save_offset = reg_size; /* first word when 64-bit.  */
       info->lr_save_offset = 2*reg_size;
diff --git a/gcc/testsuite/gcc.target/powerpc/pr115389.c b/gcc/testsuite/gcc.target/powerpc/pr115389.c
new file mode 100644 (file)
index 0000000..a091ee8
--- /dev/null
@@ -0,0 +1,17 @@
+/* PR target/115389 */
+/* { dg-do assemble } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10 -mrop-protect -mno-vsx -mno-altivec -mabi=no-altivec -save-temps" } */
+/* { dg-require-effective-target rop_ok } */
+
+/* Verify we do not emit invalid offsets for our ROP insns.  */
+
+extern void foo (void);
+long
+bar (void)
+{
+  foo ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler-times {\mhashst\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mhashchk\M} 1 } } */