[v2,3/4] aarch64 testsuite: explain expectections for pr94515* tests

Message ID 20240918140535.1538392-4-matthieu.longo@arm.com
State Committed
Commit fb475d3f25943beffac8e9c0c78247bad75287a1
Headers
Series dwarf2: add hooks for architecture-specific CFIs |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Test passed

Commit Message

Matthieu Longo Sept. 18, 2024, 2:05 p.m. UTC
  gcc/testsuite/ChangeLog:

        * g++.target/aarch64/pr94515-1.C: Improve test documentation.
        * g++.target/aarch64/pr94515-2.C: Same.
---
 gcc/testsuite/g++.target/aarch64/pr94515-1.C |  8 ++++
 gcc/testsuite/g++.target/aarch64/pr94515-2.C | 39 +++++++++++++++++---
 2 files changed, 41 insertions(+), 6 deletions(-)
  

Patch

diff --git a/gcc/testsuite/g++.target/aarch64/pr94515-1.C b/gcc/testsuite/g++.target/aarch64/pr94515-1.C
index d5c114a83a8..359039e1753 100644
--- a/gcc/testsuite/g++.target/aarch64/pr94515-1.C
+++ b/gcc/testsuite/g++.target/aarch64/pr94515-1.C
@@ -15,12 +15,20 @@  void unwind (void)
 __attribute__((noinline, noipa, target("branch-protection=pac-ret")))
 int test (int z)
 {
+  // paciasp -> cfi_negate_ra_state: RA_no_signing -> RA_signing_SP
   if (z) {
     asm volatile ("":::"x20","x21");
     unwind ();
+    // autiasp -> cfi_negate_ra_state: RA_signing_SP -> RA_no_signing
     return 1;
   } else {
+    // 2nd cfi_negate_ra_state because the CFI directives are processed linearily.
+    // At this point, the unwinder would believe that the address is not signed
+    // due to the previous return. That's why the compiler has to emit second
+    // cfi_negate_ra_state to mean that the return address is still signed.
+    // cfi_negate_ra_state: RA_no_signing -> RA_signing_SP
     unwind ();
+    // autiasp -> cfi_negate_ra_state: RA_signing_SP -> RA_no_signing
     return 2;
   }
 }
diff --git a/gcc/testsuite/g++.target/aarch64/pr94515-2.C b/gcc/testsuite/g++.target/aarch64/pr94515-2.C
index f4a3333beed..bdb65411a08 100644
--- a/gcc/testsuite/g++.target/aarch64/pr94515-2.C
+++ b/gcc/testsuite/g++.target/aarch64/pr94515-2.C
@@ -6,6 +6,7 @@ 
 volatile int zero = 0;
 int global = 0;
 
+/* This is a leaf function, so no .cfi_negate_ra_state directive is expected.  */
 __attribute__((noinline))
 int bar(void)
 {
@@ -13,29 +14,55 @@  int bar(void)
   return 0;
 }
 
+/* This function does not return normally, so the address is signed but no
+ * authentication code is emitted. It means that only one CFI directive is
+ * supposed to be emitted at signing time.  */
 __attribute__((noinline, noreturn))
 void unwind (void)
 {
   throw 42;
 }
 
+/* This function has several return instructions, and alternates different RA
+ * states. 4 .cfi_negate_ra_state and a .cfi_remember_state/.cfi_restore_state
+ * should be emitted.
+ *
+ * Expected layout:
+ *   A: path to return 0 without assignment to global
+ *   B: global=y + branch back into A
+ *   C: return 2
+ *   D: unwind
+ * Which gives with return pointer authentication:
+ *   A: sign -> authenticate [2 negate_ra_states + remember_state for B]
+ *   B: signed [restore_state]
+ *   C: unsigned [negate_ra_state]
+ *   D: signed [negate_ra_state]
+ */
 __attribute__((noinline, noipa))
 int test(int x)
 {
-  if (x==1) return 2; /* This return path may not use the stack.  */
+  // This return path may not use the stack. This means that the return address
+  // won't be signed.
+  if (x==1) return 2;
+
+  // All the return paths of the code below must have RA mangle state set, and
+  // the return address must be signed.
   int y = bar();
   if (y > global) global=y;
-  if (y==3) unwind(); /* This return path must have RA mangle state set.  */
-  return 0;
+  if (y==3) unwind(); // authentication of the return address is not required.
+  return 0; // authentication of the return address is required.
 }
 
+/* This function requires only 2 .cfi_negate_ra_state.  */
 int main ()
 {
+  // paciasp -> cfi_negate_ra_state: RA_no_signing -> RA_signing_SP
   try {
     test (zero);
-    __builtin_abort ();
+    __builtin_abort (); // authentication of the return address is not required.
   } catch (...) {
+    // autiasp -> cfi_negate_ra_state: RA_signing_SP -> RA_no_signing
     return 0;
   }
-  __builtin_abort ();
-}
+  __builtin_abort (); // authentication of the return address is not required.
+}
\ No newline at end of file