[PATCH] D156428: [AArch64][PtrAuth] Fix unwind state for tail calls

Oliver Stannard via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 27 06:43:48 PDT 2023


olista01 created this revision.
Herald added subscribers: hiraditya, kristof.beyls.
Herald added a project: All.
olista01 requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

When generating unwind tables for code which uses return-address
signing, we need to toggle the RA_SIGN_STATE DWARF register around any
tail-calls, because these require the return address to be authenticated
before the call, and could throw an exception. This is done using the
.cfi_negate_ra_state directive before the call, and .cfi_restore_state
at the start of the next basic block.

However, since D153098 <https://reviews.llvm.org/D153098>, the .cfi_restore_state isn't being inserted,
because the CFIFixup pass isn't being run. This re-enables that pass
when return-adress signing is enabled.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D156428

Files:
  llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
  llvm/test/CodeGen/AArch64/sign-return-address-cfi-negate-ra-state.ll


Index: llvm/test/CodeGen/AArch64/sign-return-address-cfi-negate-ra-state.ll
===================================================================
--- llvm/test/CodeGen/AArch64/sign-return-address-cfi-negate-ra-state.ll
+++ llvm/test/CodeGen/AArch64/sign-return-address-cfi-negate-ra-state.ll
@@ -5,7 +5,7 @@
 @.str = private unnamed_addr constant [15 x i8] c"some exception\00", align 1
 @_ZTIPKc = external dso_local constant ptr
 
-; CHECK: @_Z3fooi
+; CHECK-LABEL: @_Z3fooi
 ; CHECK-V8A: hint #25
 ; CHECK-V83A: paciasp
 ; CHECK-NEXT: .cfi_negate_ra_state
@@ -25,10 +25,59 @@
   ret i32 %0
 }
 
+; CHECK-LABEL: @_Z3bazi
+; In the prologue, sign the return address, toggle RA_SIGN_STATE to 1, and save
+; the unwind state.
+; CHECK-V8A:      hint #25
+; CHECK-V83A:     paciasp
+; CHECK-NEXT:     .cfi_negate_ra_state
+; CHECK:          .cfi_remember_state
+; To tail-call bar, authenticate the return address, and toggle RA_SIGN_STATE to 0.
+; CHECK-V8A:      hint #29
+; CHECK-V83A:     autiasp
+; CHECK-NEXT:     .cfi_negate_ra_state
+; CHECK-NEXT:     b       _Z3bari
+; To call quux, restore the unwind state, which sets RA_SIGN_STATE back to 1.
+; CHECK:          .cfi_restore_state
+; CHECK:          bl      _Z4quuxi
+; To return, authenticate the return address. v8.3-A can do this in one
+; instruction, so doesn't need any unwind opcodes.
+; CHECK-V83A:     retaa
+; CHECK-V8A:      hint    #29
+; CHECK-V8A-NEXT: .cfi_negate_ra_state
+; CHECK-V8A-NEXT: ret
+define hidden noundef i32 @_Z3bazi(i32 noundef %a) #0 {
+entry:
+  %tobool.not = icmp eq i32 %a, 0
+  br i1 %tobool.not, label %if.else, label %if.then
+
+if.then:                                          ; preds = %entry
+  %call = tail call noundef i32 @_Z3bari(i32 noundef 0)
+  %call1 = tail call noundef i32 @_Z3bari(i32 noundef %call)
+  br label %return
+
+if.else:                                          ; preds = %entry
+  %call2 = tail call noundef i32 @_Z4quuxi(i32 noundef 0)
+  %add = add nsw i32 %call2, 1
+  br label %return
+
+return:                                           ; preds = %if.else, %if.then
+  %retval.0 = phi i32 [ %call1, %if.then ], [ %add, %if.else ]
+  ret i32 %retval.0
+}
+
 declare dso_local ptr @__cxa_allocate_exception(i64)
 
 declare dso_local void @__cxa_throw(ptr, ptr, ptr)
 
+declare dso_local noundef i32 @_Z3bari(i32 noundef) local_unnamed_addr
+declare dso_local noundef i32 @_Z4quuxi(i32 noundef) local_unnamed_addr
+
 attributes #0 = { "sign-return-address"="all" }
 
 ;CHECK-DUMP: DW_CFA_AARCH64_negate_ra_state
+;CHECK-DUMP: DW_CFA_AARCH64_negate_ra_state
+;CHECK-DUMP: DW_CFA_remember_state
+;CHECK-DUMP: DW_CFA_AARCH64_negate_ra_state
+;CHECK-DUMP: DW_CFA_restore_state
+;CHECK-DUMP: DW_CFA_AARCH64_negate_ra_state
Index: llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -2271,6 +2271,13 @@
 }
 
 bool AArch64FrameLowering::enableCFIFixup(MachineFunction &MF) const {
+  const auto &MFI = *MF.getInfo<AArch64FunctionInfo>();
+
+  // Return-address signing requires CFIFixup to toggle the value of
+  // RA_SIGN_STATE around early-return tail calls
+  if (MFI.shouldSignReturnAddress(MF))
+    return true;
+
   return TargetFrameLowering::enableCFIFixup(MF) &&
          MF.getInfo<AArch64FunctionInfo>()->needsAsyncDwarfUnwindInfo(MF);
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D156428.544747.patch
Type: text/x-patch
Size: 3445 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230727/e16c7bf5/attachment.bin>


More information about the llvm-commits mailing list