[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