diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -367,6 +367,21 @@ /// Return the OpenCL C or C++ version as a VersionTuple. VersionTuple getOpenCLVersionTuple() const; + + /// Check if return address signing is enabled. + bool hasSignReturnAddress() const { + return getSignReturnAddressScope() != SignReturnAddressScopeKind::None; + } + + /// Check if return address signing uses AKey. + bool isSignReturnAddressWithAKey() const { + return getSignReturnAddressKey() == SignReturnAddressKeyKind::AKey; + } + + /// Check if leaf functions are also signed. + bool isSignReturnAddressScopeAll() const { + return getSignReturnAddressScope() == SignReturnAddressScopeKind::All; + } }; /// Floating point control options diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -283,6 +283,27 @@ if ((FPU & NeonMode) && HasFP16FML) Builder.defineMacro("__ARM_FEATURE_FP16FML", "1"); + if (Opts.hasSignReturnAddress()) { + // Bitmask: + // 0: Protection using the A key + // 1: Protection using the B key + // 2: Protection including leaf functions + unsigned Value = 0; + + if (Opts.isSignReturnAddressWithAKey()) + Value |= (1 << 0); + else + Value |= (1 << 1); + + if (Opts.isSignReturnAddressScopeAll()) + Value |= (1 << 2); + + Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", std::to_string(Value)); + } + + if (Opts.BranchTargetEnforcement) + Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1"); + switch (ArchKind) { default: break; diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c --- a/clang/test/Preprocessor/aarch64-target-features.c +++ b/clang/test/Preprocessor/aarch64-target-features.c @@ -39,6 +39,8 @@ // CHECK-NOT: __ARM_SIZEOF_WCHAR_T 2 // CHECK-NOT: __ARM_FEATURE_SVE // CHECK-NOT: __ARM_FEATURE_DOTPROD +// CHECK-NOT: __ARM_FEATURE_PAC_DEFAULT +// CHECK-NOT: __ARM_FEATURE_BTI_DEFAULT // RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+crypto -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-CRYPTO %s // RUN: %clang -target arm64-none-linux-gnu -march=armv8-a+crypto -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-CRYPTO %s @@ -334,3 +336,33 @@ // ================== Check Memory Tagging Extensions (MTE). // RUN: %clang -target arm64-none-linux-gnu -march=armv8.5-a+memtag -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-MEMTAG %s // CHECK-MEMTAG: __ARM_FEATURE_MEMORY_TAGGING 1 + +// ================== Check Pointer Authentication Extension (PAuth). +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8.5-a -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=none -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=bti -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=standard -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret+b-key -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-BKEY %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret+leaf -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-ALL %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret+leaf+b-key -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-BKEY-ALL %s +// CHECK-PAUTH-OFF-NOT: __ARM_FEATURE_PAC_DEFAULT +// CHECK-PAUTH: #define __ARM_FEATURE_PAC_DEFAULT 1 +// CHECK-PAUTH-BKEY: #define __ARM_FEATURE_PAC_DEFAULT 2 +// CHECK-PAUTH-ALL: #define __ARM_FEATURE_PAC_DEFAULT 5 +// CHECK-PAUTH-BKEY-ALL: #define __ARM_FEATURE_PAC_DEFAULT 6 + +// ================== Check Branch Target Identification (BTI). +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8.5-a -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=none -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret+leaf -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret+b-key -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret+leaf+b-key -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=standard -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=bti -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret+bti -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI %s +// CHECK-BTI-OFF-NOT: __ARM_FEATURE_BTI_DEFAULT +// CHECK-BTI: #define __ARM_FEATURE_BTI_DEFAULT 1