-
Notifications
You must be signed in to change notification settings - Fork 12.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[AArch64][PAC][clang][ELF] Support PAuth ABI core info #85235
Conversation
da135fa
to
435c7ea
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
435c7ea
to
4283e2e
Compare
Define the following clang driver flags: - `-fptrauth-intrinsics`: `PointerAuth.intrinsics()` in `LangOptions`, `ptrauth_intrinsics` preprocessor feature; - `-fptrauth-calls`: `PointerAuth.calls()` in `LangOptions`, `ptrauth_calls` and and `ptrauth_member_function_pointer_type_discrimination` preprocessor features; - `-fptrauth-returns`: `PointerAuth.returns()` in `LangOptions`, `ptrauth_returns` preprocessor feature; - `-fptrauth-auth-traps`: `PointerAuth.authTraps()` in `LangOptions`; - `-fptrauth-vtable-pointer-address-discrimination`: `PointerAuth.vtptrAddressDiscrimination()` in `LangOptions`, `ptrauth_vtable_pointer_address_discrimination` preprocessor feature; - `-fptrauth-vtable-pointer-type-discrimination`: `PointerAuth.vtptrTypeDiscrimination()` in `LangOptions`, `ptrauth_vtable_pointer_type_discrimination` preprocessor feature; - `-fptrauth-init-fini`: `PointerAuth.initFini()` in `LangOptions`, `ptrauth_init_fini` preprocessor feature. The patch only defines the flags and having corresponding `LangOptions` set does not affect codegen yet. Co-authored-by: Ahmed Bougacha <[email protected]>
Emit PAuth ABI compatibility tag values as llvm module flags: - `aarch64-elf-pauthabi-platform` - `aarch64-elf-pauthabi-version`
4283e2e
to
9924f57
Compare
@llvm/pr-subscribers-clang-codegen Author: Daniil Kovalev (kovdan01) ChangesDepends on #85231 Emit PAuth ABI compatibility tag values as llvm module flags:
For platform 0x10000002 (llvm_linux), the version value bits correspond to the following LangOptions defined in #85232:
Full diff: https://github.com/llvm/llvm-project/pull/85235.diff 9 Files Affected:
diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def
index eeed5f4751f2f4..1c6236aa4f9748 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -102,6 +102,12 @@ FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread))
FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow))
FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
FEATURE(ptrauth_intrinsics, LangOpts.PointerAuthIntrinsics)
+FEATURE(ptrauth_calls, LangOpts.PointerAuthCalls)
+FEATURE(ptrauth_returns, LangOpts.PointerAuthReturns)
+FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtrAddressDiscrimination)
+FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination)
+FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls)
+FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
FEATURE(swiftasynccc,
PP.getTargetInfo().checkCallingConvention(CC_SwiftAsync) ==
clang::TargetInfo::CCCR_OK)
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 8ef6700ecdc78e..4b99e70298462f 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -162,6 +162,12 @@ LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template t
LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library features")
LANGOPT(PointerAuthIntrinsics, 1, 0, "pointer authentication intrinsics")
+LANGOPT(PointerAuthCalls , 1, 0, "function pointer authentication")
+LANGOPT(PointerAuthReturns, 1, 0, "return pointer authentication")
+LANGOPT(PointerAuthAuthTraps, 1, 0, "pointer authentication failure traps")
+LANGOPT(PointerAuthVTPtrAddressDiscrimination, 1, 0, "incorporate address discrimination in authenticated vtable pointers")
+LANGOPT(PointerAuthVTPtrTypeDiscrimination, 1, 0, "incorporate type discrimination in authenticated vtable pointers")
+LANGOPT(PointerAuthInitFini, 1, 0, "sign function pointers in init/fini arrays")
LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes")
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 29c226f4bd8da7..e624eed2a15316 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4110,8 +4110,26 @@ let Group = f_Group in {
let Visibility = [ClangOption,CC1Option] in {
def fptrauth_intrinsics : Flag<["-"], "fptrauth-intrinsics">,
HelpText<"Enable pointer authentication intrinsics">;
+ def fptrauth_calls : Flag<["-"], "fptrauth-calls">,
+ HelpText<"Enable signing and authentication of all indirect calls">;
+ def fptrauth_returns : Flag<["-"], "fptrauth-returns">,
+ HelpText<"Enable signing and authentication of return addresses">;
+ def fptrauth_auth_traps : Flag<["-"], "fptrauth-auth-traps">,
+ HelpText<"Enable traps on authentication failures">;
+ def fptrauth_vtable_pointer_address_discrimination : Flag<["-"], "fptrauth-vtable-pointer-address-discrimination">,
+ HelpText<"Enable address discrimination of vtable pointers">;
+ def fptrauth_vtable_pointer_type_discrimination : Flag<["-"], "fptrauth-vtable-pointer-type-discrimination">,
+ HelpText<"Enable type discrimination of vtable pointers">;
+ def fptrauth_init_fini : Flag<["-"], "fptrauth-init-fini">,
+ HelpText<"Enable signing of function pointers in init/fini arrays">;
}
def fno_ptrauth_intrinsics : Flag<["-"], "fno-ptrauth-intrinsics">;
+ def fno_ptrauth_calls : Flag<["-"], "fno-ptrauth-calls">;
+ def fno_ptrauth_returns : Flag<["-"], "fno-ptrauth-returns">;
+ def fno_ptrauth_auth_traps : Flag<["-"], "fno-ptrauth-auth-traps">;
+ def fno_ptrauth_vtable_pointer_address_discrimination : Flag<["-"], "fno-ptrauth-vtable-pointer-address-discrimination">;
+ def fno_ptrauth_vtable_pointer_type_discrimination : Flag<["-"], "fno-ptrauth-vtable-pointer-type-discrimination">;
+ def fno_ptrauth_init_fini : Flag<["-"], "fno-ptrauth-init-fini">;
}
def fenable_matrix : Flag<["-"], "fenable-matrix">, Group<f_Group>,
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 8ceecff28cbc63..a35fdf6fa7072b 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -53,6 +53,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
#include "llvm/IR/AttributeMask.h"
#include "llvm/IR/CallingConv.h"
@@ -1187,6 +1188,36 @@ void CodeGenModule::Release() {
if (!LangOpts.isSignReturnAddressWithAKey())
getModule().addModuleFlag(llvm::Module::Min,
"sign-return-address-with-bkey", 1);
+
+ if (getTriple().isOSLinux() && getTriple().isOSBinFormatELF()) {
+ using namespace llvm::ELF;
+ uint64_t PAuthABIVersion =
+ (LangOpts.PointerAuthIntrinsics
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INTRINSICS) |
+ (LangOpts.PointerAuthCalls
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_CALLS) |
+ (LangOpts.PointerAuthReturns
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_RETURNS) |
+ (LangOpts.PointerAuthAuthTraps
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_AUTHTRAPS) |
+ (LangOpts.PointerAuthVTPtrAddressDiscrimination
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRADDRDISCR) |
+ (LangOpts.PointerAuthVTPtrTypeDiscrimination
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRTYPEDISCR) |
+ (LangOpts.PointerAuthInitFini
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI);
+ static_assert(AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI ==
+ AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST,
+ "Update when new enum items are defined");
+ if (PAuthABIVersion != 0) {
+ getModule().addModuleFlag(llvm::Module::Error,
+ "aarch64-elf-pauthabi-platform",
+ AARCH64_PAUTH_PLATFORM_LLVM_LINUX);
+ getModule().addModuleFlag(llvm::Module::Error,
+ "aarch64-elf-pauthabi-version",
+ PAuthABIVersion);
+ }
+ }
}
if (CodeGenOpts.StackClashProtector)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 055884d275ce1b..04ca9e08591f9a 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7203,6 +7203,33 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_ptrauth_intrinsics, false))
CmdArgs.push_back("-fptrauth-intrinsics");
+ if (Args.hasFlag(options::OPT_fptrauth_calls, options::OPT_fno_ptrauth_calls,
+ false))
+ CmdArgs.push_back("-fptrauth-calls");
+
+ if (Args.hasFlag(options::OPT_fptrauth_returns,
+ options::OPT_fno_ptrauth_returns, false))
+ CmdArgs.push_back("-fptrauth-returns");
+
+ if (Args.hasFlag(options::OPT_fptrauth_auth_traps,
+ options::OPT_fno_ptrauth_auth_traps, false))
+ CmdArgs.push_back("-fptrauth-auth-traps");
+
+ if (Args.hasFlag(
+ options::OPT_fptrauth_vtable_pointer_address_discrimination,
+ options::OPT_fno_ptrauth_vtable_pointer_address_discrimination,
+ false))
+ CmdArgs.push_back("-fptrauth-vtable-pointer-address-discrimination");
+
+ if (Args.hasFlag(options::OPT_fptrauth_vtable_pointer_type_discrimination,
+ options::OPT_fno_ptrauth_vtable_pointer_type_discrimination,
+ false))
+ CmdArgs.push_back("-fptrauth-vtable-pointer-type-discrimination");
+
+ if (Args.hasFlag(options::OPT_fptrauth_init_fini,
+ options::OPT_fno_ptrauth_init_fini, false))
+ CmdArgs.push_back("-fptrauth-init-fini");
+
// -fsigned-bitfields is default, and clang doesn't yet support
// -funsigned-bitfields.
if (!Args.hasFlag(options::OPT_fsigned_bitfields,
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 2a21a9d619dc0b..8f921c65a56377 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3297,11 +3297,31 @@ static void GeneratePointerAuthArgs(const LangOptions &Opts,
ArgumentConsumer Consumer) {
if (Opts.PointerAuthIntrinsics)
GenerateArg(Consumer, OPT_fptrauth_intrinsics);
+ if (Opts.PointerAuthCalls)
+ GenerateArg(Consumer, OPT_fptrauth_calls);
+ if (Opts.PointerAuthReturns)
+ GenerateArg(Consumer, OPT_fptrauth_returns);
+ if (Opts.PointerAuthAuthTraps)
+ GenerateArg(Consumer, OPT_fptrauth_auth_traps);
+ if (Opts.PointerAuthVTPtrAddressDiscrimination)
+ GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_address_discrimination);
+ if (Opts.PointerAuthVTPtrTypeDiscrimination)
+ GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_type_discrimination);
+ if (Opts.PointerAuthInitFini)
+ GenerateArg(Consumer, OPT_fptrauth_init_fini);
}
static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args,
DiagnosticsEngine &Diags) {
Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics);
+ Opts.PointerAuthCalls = Args.hasArg(OPT_fptrauth_calls);
+ Opts.PointerAuthReturns = Args.hasArg(OPT_fptrauth_returns);
+ Opts.PointerAuthAuthTraps = Args.hasArg(OPT_fptrauth_auth_traps);
+ Opts.PointerAuthVTPtrAddressDiscrimination =
+ Args.hasArg(OPT_fptrauth_vtable_pointer_address_discrimination);
+ Opts.PointerAuthVTPtrTypeDiscrimination =
+ Args.hasArg(OPT_fptrauth_vtable_pointer_type_discrimination);
+ Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini);
}
/// Check if input file kind and language standard are compatible.
diff --git a/clang/test/CodeGen/aarch64-elf-pauthabi.c b/clang/test/CodeGen/aarch64-elf-pauthabi.c
new file mode 100644
index 00000000000000..8f3e2d9b274b5a
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-elf-pauthabi.c
@@ -0,0 +1,61 @@
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-auth-traps \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini %s | \
+// RUN: FileCheck %s --check-prefix=ALL
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-intrinsics %s | FileCheck %s --check-prefix=INTRIN
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-calls %s | FileCheck %s --check-prefix=CALL
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-returns %s | FileCheck %s --check-prefix=RET
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-auth-traps %s | FileCheck %s --check-prefix=TRAP
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-calls -fptrauth-vtable-pointer-address-discrimination %s | \
+// RUN: FileCheck %s --check-prefix=VPTRADDR
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-calls -fptrauth-vtable-pointer-type-discrimination %s | \
+// RUN: FileCheck %s --check-prefix=VPTRTYPE
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-calls -fptrauth-init-fini %s | \
+// RUN: FileCheck %s --check-prefix=INITFINI
+
+// REQUIRES: aarch64-registered-target
+
+// ALL: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// ALL: !{i32 1, !"aarch64-elf-pauthabi-version", i32 127}
+
+// INTRIN: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// INTRIN: !{i32 1, !"aarch64-elf-pauthabi-version", i32 1}
+
+// CALL: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// CALL: !{i32 1, !"aarch64-elf-pauthabi-version", i32 2}
+
+// RET: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// RET: !{i32 1, !"aarch64-elf-pauthabi-version", i32 4}
+
+// TRAP: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// TRAP: !{i32 1, !"aarch64-elf-pauthabi-version", i32 8}
+
+// VPTRADDR: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// VPTRADDR: !{i32 1, !"aarch64-elf-pauthabi-version", i32 18}
+
+// VPTRTYPE: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// VPTRTYPE: !{i32 1, !"aarch64-elf-pauthabi-version", i32 34}
+
+// INITFINI: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// INITFINI: !{i32 1, !"aarch64-elf-pauthabi-version", i32 66}
+
+void foo() {}
diff --git a/clang/test/Driver/ptrauth.c b/clang/test/Driver/ptrauth.c
new file mode 100644
index 00000000000000..2336a5d551b014
--- /dev/null
+++ b/clang/test/Driver/ptrauth.c
@@ -0,0 +1,32 @@
+// Check that we can manually enable specific ptrauth features.
+
+// RUN: %clang -target aarch64 -c %s -### 2>&1 | FileCheck %s --check-prefix NONE
+// NONE: "-cc1"
+// NONE-NOT: "-fptrauth-intrinsics"
+// NONE-NOT: "-fptrauth-calls"
+// NONE-NOT: "-fptrauth-returns"
+// NONE-NOT: "-fptrauth-auth-traps"
+// NONE-NOT: "-fptrauth-vtable-pointer-address-discrimination"
+// NONE-NOT: "-fptrauth-vtable-pointer-type-discrimination"
+// NONE-NOT: "-fptrauth-init-fini"
+
+// RUN: %clang -target aarch64 -fptrauth-intrinsics -c %s -### 2>&1 | FileCheck %s --check-prefix INTRIN
+// INTRIN: "-cc1"{{.*}} {{.*}} "-fptrauth-intrinsics"
+
+// RUN: %clang -target aarch64 -fptrauth-calls -c %s -### 2>&1 | FileCheck %s --check-prefix CALL
+// CALL: "-cc1"{{.*}} {{.*}} "-fptrauth-calls"
+
+// RUN: %clang -target aarch64 -fptrauth-returns -c %s -### 2>&1 | FileCheck %s --check-prefix RETURN
+// RETURN: "-cc1"{{.*}} {{.*}} "-fptrauth-returns"
+
+// RUN: %clang -target aarch64 -fptrauth-auth-traps -c %s -### 2>&1 | FileCheck %s --check-prefix TRAPS
+// TRAPS: "-cc1"{{.*}} {{.*}} "-fptrauth-auth-traps"
+
+// RUN: %clang -target aarch64 -fptrauth-vtable-pointer-address-discrimination -c %s -### 2>&1 | FileCheck %s --check-prefix VPTR_ADDR_DISCR
+// VPTR_ADDR_DISCR: "-cc1"{{.*}} {{.*}} "-fptrauth-vtable-pointer-address-discrimination"
+
+// RUN: %clang -target aarch64 -fptrauth-vtable-pointer-type-discrimination -c %s -### 2>&1 | FileCheck %s --check-prefix VPTR_TYPE_DISCR
+// VPTR_TYPE_DISCR: "-cc1"{{.*}} {{.*}} "-fptrauth-vtable-pointer-type-discrimination"
+
+// RUN: %clang -target aarch64 -fptrauth-init-fini -c %s -### 2>&1 | FileCheck %s --check-prefix INITFINI
+// INITFINI: "-cc1"{{.*}} {{.*}} "-fptrauth-init-fini"
diff --git a/clang/test/Preprocessor/ptrauth_feature.c b/clang/test/Preprocessor/ptrauth_feature.c
index e45c6ea90fd11f..80e239110ffc7b 100644
--- a/clang/test/Preprocessor/ptrauth_feature.c
+++ b/clang/test/Preprocessor/ptrauth_feature.c
@@ -1,5 +1,59 @@
-// RUN: %clang_cc1 %s -E -triple=arm64-- | FileCheck %s --check-prefixes=NOINTRIN
-// RUN: %clang_cc1 %s -E -triple=arm64-- -fptrauth-intrinsics | FileCheck %s --check-prefixes=INTRIN
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=NOINTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,NOCALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,NORETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,NOVPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,NOINITFINI
#if __has_feature(ptrauth_intrinsics)
// INTRIN: has_ptrauth_intrinsics
@@ -8,3 +62,52 @@ void has_ptrauth_intrinsics() {}
// NOINTRIN: no_ptrauth_intrinsics
void no_ptrauth_intrinsics() {}
#endif
+
+#if __has_feature(ptrauth_calls)
+// CALLS: has_ptrauth_calls
+void has_ptrauth_calls() {}
+#else
+// NOCALLS: no_ptrauth_calls
+void no_ptrauth_calls() {}
+#endif
+
+// This is always enabled when ptrauth_calls is enabled
+#if __has_feature(ptrauth_member_function_pointer_type_discrimination)
+// CALLS: has_ptrauth_member_function_pointer_type_discrimination
+void has_ptrauth_member_function_pointer_type_discrimination() {}
+#else
+// NOCALLS: no_ptrauth_member_function_pointer_type_discrimination
+void no_ptrauth_member_function_pointer_type_discrimination() {}
+#endif
+
+#if __has_feature(ptrauth_returns)
+// RETS: has_ptrauth_returns
+void has_ptrauth_returns() {}
+#else
+// NORETS: no_ptrauth_returns
+void no_ptrauth_returns() {}
+#endif
+
+#if __has_feature(ptrauth_vtable_pointer_address_discrimination)
+// VPTR_ADDR_DISCR: has_ptrauth_vtable_pointer_address_discrimination
+void has_ptrauth_vtable_pointer_address_discrimination() {}
+#else
+// NOVPTR_ADDR_DISCR: no_ptrauth_vtable_pointer_address_discrimination
+void no_ptrauth_vtable_pointer_address_discrimination() {}
+#endif
+
+#if __has_feature(ptrauth_vtable_pointer_type_discrimination)
+// VPTR_TYPE_DISCR: has_ptrauth_vtable_pointer_type_discrimination
+void has_ptrauth_vtable_pointer_type_discrimination() {}
+#else
+// NOVPTR_TYPE_DISCR: no_ptrauth_vtable_pointer_type_discrimination
+void no_ptrauth_vtable_pointer_type_discrimination() {}
+#endif
+
+#if __has_feature(ptrauth_init_fini)
+// INITFINI: has_ptrauth_init_fini
+void has_ptrauth_init_fini() {}
+#else
+// NOINITFINI: no_ptrauth_init_fini
+void no_ptrauth_init_fini() {}
+#endif
|
@llvm/pr-subscribers-clang Author: Daniil Kovalev (kovdan01) ChangesDepends on #85231 Emit PAuth ABI compatibility tag values as llvm module flags:
For platform 0x10000002 (llvm_linux), the version value bits correspond to the following LangOptions defined in #85232:
Full diff: https://github.com/llvm/llvm-project/pull/85235.diff 9 Files Affected:
diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def
index eeed5f4751f2f4..1c6236aa4f9748 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -102,6 +102,12 @@ FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread))
FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow))
FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
FEATURE(ptrauth_intrinsics, LangOpts.PointerAuthIntrinsics)
+FEATURE(ptrauth_calls, LangOpts.PointerAuthCalls)
+FEATURE(ptrauth_returns, LangOpts.PointerAuthReturns)
+FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtrAddressDiscrimination)
+FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination)
+FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls)
+FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
FEATURE(swiftasynccc,
PP.getTargetInfo().checkCallingConvention(CC_SwiftAsync) ==
clang::TargetInfo::CCCR_OK)
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 8ef6700ecdc78e..4b99e70298462f 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -162,6 +162,12 @@ LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template t
LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library features")
LANGOPT(PointerAuthIntrinsics, 1, 0, "pointer authentication intrinsics")
+LANGOPT(PointerAuthCalls , 1, 0, "function pointer authentication")
+LANGOPT(PointerAuthReturns, 1, 0, "return pointer authentication")
+LANGOPT(PointerAuthAuthTraps, 1, 0, "pointer authentication failure traps")
+LANGOPT(PointerAuthVTPtrAddressDiscrimination, 1, 0, "incorporate address discrimination in authenticated vtable pointers")
+LANGOPT(PointerAuthVTPtrTypeDiscrimination, 1, 0, "incorporate type discrimination in authenticated vtable pointers")
+LANGOPT(PointerAuthInitFini, 1, 0, "sign function pointers in init/fini arrays")
LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes")
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 29c226f4bd8da7..e624eed2a15316 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4110,8 +4110,26 @@ let Group = f_Group in {
let Visibility = [ClangOption,CC1Option] in {
def fptrauth_intrinsics : Flag<["-"], "fptrauth-intrinsics">,
HelpText<"Enable pointer authentication intrinsics">;
+ def fptrauth_calls : Flag<["-"], "fptrauth-calls">,
+ HelpText<"Enable signing and authentication of all indirect calls">;
+ def fptrauth_returns : Flag<["-"], "fptrauth-returns">,
+ HelpText<"Enable signing and authentication of return addresses">;
+ def fptrauth_auth_traps : Flag<["-"], "fptrauth-auth-traps">,
+ HelpText<"Enable traps on authentication failures">;
+ def fptrauth_vtable_pointer_address_discrimination : Flag<["-"], "fptrauth-vtable-pointer-address-discrimination">,
+ HelpText<"Enable address discrimination of vtable pointers">;
+ def fptrauth_vtable_pointer_type_discrimination : Flag<["-"], "fptrauth-vtable-pointer-type-discrimination">,
+ HelpText<"Enable type discrimination of vtable pointers">;
+ def fptrauth_init_fini : Flag<["-"], "fptrauth-init-fini">,
+ HelpText<"Enable signing of function pointers in init/fini arrays">;
}
def fno_ptrauth_intrinsics : Flag<["-"], "fno-ptrauth-intrinsics">;
+ def fno_ptrauth_calls : Flag<["-"], "fno-ptrauth-calls">;
+ def fno_ptrauth_returns : Flag<["-"], "fno-ptrauth-returns">;
+ def fno_ptrauth_auth_traps : Flag<["-"], "fno-ptrauth-auth-traps">;
+ def fno_ptrauth_vtable_pointer_address_discrimination : Flag<["-"], "fno-ptrauth-vtable-pointer-address-discrimination">;
+ def fno_ptrauth_vtable_pointer_type_discrimination : Flag<["-"], "fno-ptrauth-vtable-pointer-type-discrimination">;
+ def fno_ptrauth_init_fini : Flag<["-"], "fno-ptrauth-init-fini">;
}
def fenable_matrix : Flag<["-"], "fenable-matrix">, Group<f_Group>,
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 8ceecff28cbc63..a35fdf6fa7072b 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -53,6 +53,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
#include "llvm/IR/AttributeMask.h"
#include "llvm/IR/CallingConv.h"
@@ -1187,6 +1188,36 @@ void CodeGenModule::Release() {
if (!LangOpts.isSignReturnAddressWithAKey())
getModule().addModuleFlag(llvm::Module::Min,
"sign-return-address-with-bkey", 1);
+
+ if (getTriple().isOSLinux() && getTriple().isOSBinFormatELF()) {
+ using namespace llvm::ELF;
+ uint64_t PAuthABIVersion =
+ (LangOpts.PointerAuthIntrinsics
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INTRINSICS) |
+ (LangOpts.PointerAuthCalls
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_CALLS) |
+ (LangOpts.PointerAuthReturns
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_RETURNS) |
+ (LangOpts.PointerAuthAuthTraps
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_AUTHTRAPS) |
+ (LangOpts.PointerAuthVTPtrAddressDiscrimination
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRADDRDISCR) |
+ (LangOpts.PointerAuthVTPtrTypeDiscrimination
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRTYPEDISCR) |
+ (LangOpts.PointerAuthInitFini
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI);
+ static_assert(AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI ==
+ AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST,
+ "Update when new enum items are defined");
+ if (PAuthABIVersion != 0) {
+ getModule().addModuleFlag(llvm::Module::Error,
+ "aarch64-elf-pauthabi-platform",
+ AARCH64_PAUTH_PLATFORM_LLVM_LINUX);
+ getModule().addModuleFlag(llvm::Module::Error,
+ "aarch64-elf-pauthabi-version",
+ PAuthABIVersion);
+ }
+ }
}
if (CodeGenOpts.StackClashProtector)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 055884d275ce1b..04ca9e08591f9a 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7203,6 +7203,33 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_ptrauth_intrinsics, false))
CmdArgs.push_back("-fptrauth-intrinsics");
+ if (Args.hasFlag(options::OPT_fptrauth_calls, options::OPT_fno_ptrauth_calls,
+ false))
+ CmdArgs.push_back("-fptrauth-calls");
+
+ if (Args.hasFlag(options::OPT_fptrauth_returns,
+ options::OPT_fno_ptrauth_returns, false))
+ CmdArgs.push_back("-fptrauth-returns");
+
+ if (Args.hasFlag(options::OPT_fptrauth_auth_traps,
+ options::OPT_fno_ptrauth_auth_traps, false))
+ CmdArgs.push_back("-fptrauth-auth-traps");
+
+ if (Args.hasFlag(
+ options::OPT_fptrauth_vtable_pointer_address_discrimination,
+ options::OPT_fno_ptrauth_vtable_pointer_address_discrimination,
+ false))
+ CmdArgs.push_back("-fptrauth-vtable-pointer-address-discrimination");
+
+ if (Args.hasFlag(options::OPT_fptrauth_vtable_pointer_type_discrimination,
+ options::OPT_fno_ptrauth_vtable_pointer_type_discrimination,
+ false))
+ CmdArgs.push_back("-fptrauth-vtable-pointer-type-discrimination");
+
+ if (Args.hasFlag(options::OPT_fptrauth_init_fini,
+ options::OPT_fno_ptrauth_init_fini, false))
+ CmdArgs.push_back("-fptrauth-init-fini");
+
// -fsigned-bitfields is default, and clang doesn't yet support
// -funsigned-bitfields.
if (!Args.hasFlag(options::OPT_fsigned_bitfields,
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 2a21a9d619dc0b..8f921c65a56377 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3297,11 +3297,31 @@ static void GeneratePointerAuthArgs(const LangOptions &Opts,
ArgumentConsumer Consumer) {
if (Opts.PointerAuthIntrinsics)
GenerateArg(Consumer, OPT_fptrauth_intrinsics);
+ if (Opts.PointerAuthCalls)
+ GenerateArg(Consumer, OPT_fptrauth_calls);
+ if (Opts.PointerAuthReturns)
+ GenerateArg(Consumer, OPT_fptrauth_returns);
+ if (Opts.PointerAuthAuthTraps)
+ GenerateArg(Consumer, OPT_fptrauth_auth_traps);
+ if (Opts.PointerAuthVTPtrAddressDiscrimination)
+ GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_address_discrimination);
+ if (Opts.PointerAuthVTPtrTypeDiscrimination)
+ GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_type_discrimination);
+ if (Opts.PointerAuthInitFini)
+ GenerateArg(Consumer, OPT_fptrauth_init_fini);
}
static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args,
DiagnosticsEngine &Diags) {
Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics);
+ Opts.PointerAuthCalls = Args.hasArg(OPT_fptrauth_calls);
+ Opts.PointerAuthReturns = Args.hasArg(OPT_fptrauth_returns);
+ Opts.PointerAuthAuthTraps = Args.hasArg(OPT_fptrauth_auth_traps);
+ Opts.PointerAuthVTPtrAddressDiscrimination =
+ Args.hasArg(OPT_fptrauth_vtable_pointer_address_discrimination);
+ Opts.PointerAuthVTPtrTypeDiscrimination =
+ Args.hasArg(OPT_fptrauth_vtable_pointer_type_discrimination);
+ Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini);
}
/// Check if input file kind and language standard are compatible.
diff --git a/clang/test/CodeGen/aarch64-elf-pauthabi.c b/clang/test/CodeGen/aarch64-elf-pauthabi.c
new file mode 100644
index 00000000000000..8f3e2d9b274b5a
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-elf-pauthabi.c
@@ -0,0 +1,61 @@
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-auth-traps \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini %s | \
+// RUN: FileCheck %s --check-prefix=ALL
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-intrinsics %s | FileCheck %s --check-prefix=INTRIN
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-calls %s | FileCheck %s --check-prefix=CALL
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-returns %s | FileCheck %s --check-prefix=RET
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-auth-traps %s | FileCheck %s --check-prefix=TRAP
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-calls -fptrauth-vtable-pointer-address-discrimination %s | \
+// RUN: FileCheck %s --check-prefix=VPTRADDR
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-calls -fptrauth-vtable-pointer-type-discrimination %s | \
+// RUN: FileCheck %s --check-prefix=VPTRTYPE
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-calls -fptrauth-init-fini %s | \
+// RUN: FileCheck %s --check-prefix=INITFINI
+
+// REQUIRES: aarch64-registered-target
+
+// ALL: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// ALL: !{i32 1, !"aarch64-elf-pauthabi-version", i32 127}
+
+// INTRIN: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// INTRIN: !{i32 1, !"aarch64-elf-pauthabi-version", i32 1}
+
+// CALL: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// CALL: !{i32 1, !"aarch64-elf-pauthabi-version", i32 2}
+
+// RET: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// RET: !{i32 1, !"aarch64-elf-pauthabi-version", i32 4}
+
+// TRAP: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// TRAP: !{i32 1, !"aarch64-elf-pauthabi-version", i32 8}
+
+// VPTRADDR: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// VPTRADDR: !{i32 1, !"aarch64-elf-pauthabi-version", i32 18}
+
+// VPTRTYPE: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// VPTRTYPE: !{i32 1, !"aarch64-elf-pauthabi-version", i32 34}
+
+// INITFINI: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// INITFINI: !{i32 1, !"aarch64-elf-pauthabi-version", i32 66}
+
+void foo() {}
diff --git a/clang/test/Driver/ptrauth.c b/clang/test/Driver/ptrauth.c
new file mode 100644
index 00000000000000..2336a5d551b014
--- /dev/null
+++ b/clang/test/Driver/ptrauth.c
@@ -0,0 +1,32 @@
+// Check that we can manually enable specific ptrauth features.
+
+// RUN: %clang -target aarch64 -c %s -### 2>&1 | FileCheck %s --check-prefix NONE
+// NONE: "-cc1"
+// NONE-NOT: "-fptrauth-intrinsics"
+// NONE-NOT: "-fptrauth-calls"
+// NONE-NOT: "-fptrauth-returns"
+// NONE-NOT: "-fptrauth-auth-traps"
+// NONE-NOT: "-fptrauth-vtable-pointer-address-discrimination"
+// NONE-NOT: "-fptrauth-vtable-pointer-type-discrimination"
+// NONE-NOT: "-fptrauth-init-fini"
+
+// RUN: %clang -target aarch64 -fptrauth-intrinsics -c %s -### 2>&1 | FileCheck %s --check-prefix INTRIN
+// INTRIN: "-cc1"{{.*}} {{.*}} "-fptrauth-intrinsics"
+
+// RUN: %clang -target aarch64 -fptrauth-calls -c %s -### 2>&1 | FileCheck %s --check-prefix CALL
+// CALL: "-cc1"{{.*}} {{.*}} "-fptrauth-calls"
+
+// RUN: %clang -target aarch64 -fptrauth-returns -c %s -### 2>&1 | FileCheck %s --check-prefix RETURN
+// RETURN: "-cc1"{{.*}} {{.*}} "-fptrauth-returns"
+
+// RUN: %clang -target aarch64 -fptrauth-auth-traps -c %s -### 2>&1 | FileCheck %s --check-prefix TRAPS
+// TRAPS: "-cc1"{{.*}} {{.*}} "-fptrauth-auth-traps"
+
+// RUN: %clang -target aarch64 -fptrauth-vtable-pointer-address-discrimination -c %s -### 2>&1 | FileCheck %s --check-prefix VPTR_ADDR_DISCR
+// VPTR_ADDR_DISCR: "-cc1"{{.*}} {{.*}} "-fptrauth-vtable-pointer-address-discrimination"
+
+// RUN: %clang -target aarch64 -fptrauth-vtable-pointer-type-discrimination -c %s -### 2>&1 | FileCheck %s --check-prefix VPTR_TYPE_DISCR
+// VPTR_TYPE_DISCR: "-cc1"{{.*}} {{.*}} "-fptrauth-vtable-pointer-type-discrimination"
+
+// RUN: %clang -target aarch64 -fptrauth-init-fini -c %s -### 2>&1 | FileCheck %s --check-prefix INITFINI
+// INITFINI: "-cc1"{{.*}} {{.*}} "-fptrauth-init-fini"
diff --git a/clang/test/Preprocessor/ptrauth_feature.c b/clang/test/Preprocessor/ptrauth_feature.c
index e45c6ea90fd11f..80e239110ffc7b 100644
--- a/clang/test/Preprocessor/ptrauth_feature.c
+++ b/clang/test/Preprocessor/ptrauth_feature.c
@@ -1,5 +1,59 @@
-// RUN: %clang_cc1 %s -E -triple=arm64-- | FileCheck %s --check-prefixes=NOINTRIN
-// RUN: %clang_cc1 %s -E -triple=arm64-- -fptrauth-intrinsics | FileCheck %s --check-prefixes=INTRIN
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=NOINTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,NOCALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,NORETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,NOVPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,NOINITFINI
#if __has_feature(ptrauth_intrinsics)
// INTRIN: has_ptrauth_intrinsics
@@ -8,3 +62,52 @@ void has_ptrauth_intrinsics() {}
// NOINTRIN: no_ptrauth_intrinsics
void no_ptrauth_intrinsics() {}
#endif
+
+#if __has_feature(ptrauth_calls)
+// CALLS: has_ptrauth_calls
+void has_ptrauth_calls() {}
+#else
+// NOCALLS: no_ptrauth_calls
+void no_ptrauth_calls() {}
+#endif
+
+// This is always enabled when ptrauth_calls is enabled
+#if __has_feature(ptrauth_member_function_pointer_type_discrimination)
+// CALLS: has_ptrauth_member_function_pointer_type_discrimination
+void has_ptrauth_member_function_pointer_type_discrimination() {}
+#else
+// NOCALLS: no_ptrauth_member_function_pointer_type_discrimination
+void no_ptrauth_member_function_pointer_type_discrimination() {}
+#endif
+
+#if __has_feature(ptrauth_returns)
+// RETS: has_ptrauth_returns
+void has_ptrauth_returns() {}
+#else
+// NORETS: no_ptrauth_returns
+void no_ptrauth_returns() {}
+#endif
+
+#if __has_feature(ptrauth_vtable_pointer_address_discrimination)
+// VPTR_ADDR_DISCR: has_ptrauth_vtable_pointer_address_discrimination
+void has_ptrauth_vtable_pointer_address_discrimination() {}
+#else
+// NOVPTR_ADDR_DISCR: no_ptrauth_vtable_pointer_address_discrimination
+void no_ptrauth_vtable_pointer_address_discrimination() {}
+#endif
+
+#if __has_feature(ptrauth_vtable_pointer_type_discrimination)
+// VPTR_TYPE_DISCR: has_ptrauth_vtable_pointer_type_discrimination
+void has_ptrauth_vtable_pointer_type_discrimination() {}
+#else
+// NOVPTR_TYPE_DISCR: no_ptrauth_vtable_pointer_type_discrimination
+void no_ptrauth_vtable_pointer_type_discrimination() {}
+#endif
+
+#if __has_feature(ptrauth_init_fini)
+// INITFINI: has_ptrauth_init_fini
+void has_ptrauth_init_fini() {}
+#else
+// NOINITFINI: no_ptrauth_init_fini
+void no_ptrauth_init_fini() {}
+#endif
|
@llvm/pr-subscribers-clang-driver Author: Daniil Kovalev (kovdan01) ChangesDepends on #85231 Emit PAuth ABI compatibility tag values as llvm module flags:
For platform 0x10000002 (llvm_linux), the version value bits correspond to the following LangOptions defined in #85232:
Full diff: https://github.com/llvm/llvm-project/pull/85235.diff 9 Files Affected:
diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def
index eeed5f4751f2f4..1c6236aa4f9748 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -102,6 +102,12 @@ FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread))
FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow))
FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
FEATURE(ptrauth_intrinsics, LangOpts.PointerAuthIntrinsics)
+FEATURE(ptrauth_calls, LangOpts.PointerAuthCalls)
+FEATURE(ptrauth_returns, LangOpts.PointerAuthReturns)
+FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtrAddressDiscrimination)
+FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination)
+FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls)
+FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
FEATURE(swiftasynccc,
PP.getTargetInfo().checkCallingConvention(CC_SwiftAsync) ==
clang::TargetInfo::CCCR_OK)
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 8ef6700ecdc78e..4b99e70298462f 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -162,6 +162,12 @@ LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template t
LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library features")
LANGOPT(PointerAuthIntrinsics, 1, 0, "pointer authentication intrinsics")
+LANGOPT(PointerAuthCalls , 1, 0, "function pointer authentication")
+LANGOPT(PointerAuthReturns, 1, 0, "return pointer authentication")
+LANGOPT(PointerAuthAuthTraps, 1, 0, "pointer authentication failure traps")
+LANGOPT(PointerAuthVTPtrAddressDiscrimination, 1, 0, "incorporate address discrimination in authenticated vtable pointers")
+LANGOPT(PointerAuthVTPtrTypeDiscrimination, 1, 0, "incorporate type discrimination in authenticated vtable pointers")
+LANGOPT(PointerAuthInitFini, 1, 0, "sign function pointers in init/fini arrays")
LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes")
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 29c226f4bd8da7..e624eed2a15316 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4110,8 +4110,26 @@ let Group = f_Group in {
let Visibility = [ClangOption,CC1Option] in {
def fptrauth_intrinsics : Flag<["-"], "fptrauth-intrinsics">,
HelpText<"Enable pointer authentication intrinsics">;
+ def fptrauth_calls : Flag<["-"], "fptrauth-calls">,
+ HelpText<"Enable signing and authentication of all indirect calls">;
+ def fptrauth_returns : Flag<["-"], "fptrauth-returns">,
+ HelpText<"Enable signing and authentication of return addresses">;
+ def fptrauth_auth_traps : Flag<["-"], "fptrauth-auth-traps">,
+ HelpText<"Enable traps on authentication failures">;
+ def fptrauth_vtable_pointer_address_discrimination : Flag<["-"], "fptrauth-vtable-pointer-address-discrimination">,
+ HelpText<"Enable address discrimination of vtable pointers">;
+ def fptrauth_vtable_pointer_type_discrimination : Flag<["-"], "fptrauth-vtable-pointer-type-discrimination">,
+ HelpText<"Enable type discrimination of vtable pointers">;
+ def fptrauth_init_fini : Flag<["-"], "fptrauth-init-fini">,
+ HelpText<"Enable signing of function pointers in init/fini arrays">;
}
def fno_ptrauth_intrinsics : Flag<["-"], "fno-ptrauth-intrinsics">;
+ def fno_ptrauth_calls : Flag<["-"], "fno-ptrauth-calls">;
+ def fno_ptrauth_returns : Flag<["-"], "fno-ptrauth-returns">;
+ def fno_ptrauth_auth_traps : Flag<["-"], "fno-ptrauth-auth-traps">;
+ def fno_ptrauth_vtable_pointer_address_discrimination : Flag<["-"], "fno-ptrauth-vtable-pointer-address-discrimination">;
+ def fno_ptrauth_vtable_pointer_type_discrimination : Flag<["-"], "fno-ptrauth-vtable-pointer-type-discrimination">;
+ def fno_ptrauth_init_fini : Flag<["-"], "fno-ptrauth-init-fini">;
}
def fenable_matrix : Flag<["-"], "fenable-matrix">, Group<f_Group>,
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 8ceecff28cbc63..a35fdf6fa7072b 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -53,6 +53,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
#include "llvm/IR/AttributeMask.h"
#include "llvm/IR/CallingConv.h"
@@ -1187,6 +1188,36 @@ void CodeGenModule::Release() {
if (!LangOpts.isSignReturnAddressWithAKey())
getModule().addModuleFlag(llvm::Module::Min,
"sign-return-address-with-bkey", 1);
+
+ if (getTriple().isOSLinux() && getTriple().isOSBinFormatELF()) {
+ using namespace llvm::ELF;
+ uint64_t PAuthABIVersion =
+ (LangOpts.PointerAuthIntrinsics
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INTRINSICS) |
+ (LangOpts.PointerAuthCalls
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_CALLS) |
+ (LangOpts.PointerAuthReturns
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_RETURNS) |
+ (LangOpts.PointerAuthAuthTraps
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_AUTHTRAPS) |
+ (LangOpts.PointerAuthVTPtrAddressDiscrimination
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRADDRDISCR) |
+ (LangOpts.PointerAuthVTPtrTypeDiscrimination
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRTYPEDISCR) |
+ (LangOpts.PointerAuthInitFini
+ << AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI);
+ static_assert(AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI ==
+ AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST,
+ "Update when new enum items are defined");
+ if (PAuthABIVersion != 0) {
+ getModule().addModuleFlag(llvm::Module::Error,
+ "aarch64-elf-pauthabi-platform",
+ AARCH64_PAUTH_PLATFORM_LLVM_LINUX);
+ getModule().addModuleFlag(llvm::Module::Error,
+ "aarch64-elf-pauthabi-version",
+ PAuthABIVersion);
+ }
+ }
}
if (CodeGenOpts.StackClashProtector)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 055884d275ce1b..04ca9e08591f9a 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7203,6 +7203,33 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_ptrauth_intrinsics, false))
CmdArgs.push_back("-fptrauth-intrinsics");
+ if (Args.hasFlag(options::OPT_fptrauth_calls, options::OPT_fno_ptrauth_calls,
+ false))
+ CmdArgs.push_back("-fptrauth-calls");
+
+ if (Args.hasFlag(options::OPT_fptrauth_returns,
+ options::OPT_fno_ptrauth_returns, false))
+ CmdArgs.push_back("-fptrauth-returns");
+
+ if (Args.hasFlag(options::OPT_fptrauth_auth_traps,
+ options::OPT_fno_ptrauth_auth_traps, false))
+ CmdArgs.push_back("-fptrauth-auth-traps");
+
+ if (Args.hasFlag(
+ options::OPT_fptrauth_vtable_pointer_address_discrimination,
+ options::OPT_fno_ptrauth_vtable_pointer_address_discrimination,
+ false))
+ CmdArgs.push_back("-fptrauth-vtable-pointer-address-discrimination");
+
+ if (Args.hasFlag(options::OPT_fptrauth_vtable_pointer_type_discrimination,
+ options::OPT_fno_ptrauth_vtable_pointer_type_discrimination,
+ false))
+ CmdArgs.push_back("-fptrauth-vtable-pointer-type-discrimination");
+
+ if (Args.hasFlag(options::OPT_fptrauth_init_fini,
+ options::OPT_fno_ptrauth_init_fini, false))
+ CmdArgs.push_back("-fptrauth-init-fini");
+
// -fsigned-bitfields is default, and clang doesn't yet support
// -funsigned-bitfields.
if (!Args.hasFlag(options::OPT_fsigned_bitfields,
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 2a21a9d619dc0b..8f921c65a56377 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3297,11 +3297,31 @@ static void GeneratePointerAuthArgs(const LangOptions &Opts,
ArgumentConsumer Consumer) {
if (Opts.PointerAuthIntrinsics)
GenerateArg(Consumer, OPT_fptrauth_intrinsics);
+ if (Opts.PointerAuthCalls)
+ GenerateArg(Consumer, OPT_fptrauth_calls);
+ if (Opts.PointerAuthReturns)
+ GenerateArg(Consumer, OPT_fptrauth_returns);
+ if (Opts.PointerAuthAuthTraps)
+ GenerateArg(Consumer, OPT_fptrauth_auth_traps);
+ if (Opts.PointerAuthVTPtrAddressDiscrimination)
+ GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_address_discrimination);
+ if (Opts.PointerAuthVTPtrTypeDiscrimination)
+ GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_type_discrimination);
+ if (Opts.PointerAuthInitFini)
+ GenerateArg(Consumer, OPT_fptrauth_init_fini);
}
static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args,
DiagnosticsEngine &Diags) {
Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics);
+ Opts.PointerAuthCalls = Args.hasArg(OPT_fptrauth_calls);
+ Opts.PointerAuthReturns = Args.hasArg(OPT_fptrauth_returns);
+ Opts.PointerAuthAuthTraps = Args.hasArg(OPT_fptrauth_auth_traps);
+ Opts.PointerAuthVTPtrAddressDiscrimination =
+ Args.hasArg(OPT_fptrauth_vtable_pointer_address_discrimination);
+ Opts.PointerAuthVTPtrTypeDiscrimination =
+ Args.hasArg(OPT_fptrauth_vtable_pointer_type_discrimination);
+ Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini);
}
/// Check if input file kind and language standard are compatible.
diff --git a/clang/test/CodeGen/aarch64-elf-pauthabi.c b/clang/test/CodeGen/aarch64-elf-pauthabi.c
new file mode 100644
index 00000000000000..8f3e2d9b274b5a
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-elf-pauthabi.c
@@ -0,0 +1,61 @@
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-auth-traps \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini %s | \
+// RUN: FileCheck %s --check-prefix=ALL
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-intrinsics %s | FileCheck %s --check-prefix=INTRIN
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-calls %s | FileCheck %s --check-prefix=CALL
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-returns %s | FileCheck %s --check-prefix=RET
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-auth-traps %s | FileCheck %s --check-prefix=TRAP
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-calls -fptrauth-vtable-pointer-address-discrimination %s | \
+// RUN: FileCheck %s --check-prefix=VPTRADDR
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-calls -fptrauth-vtable-pointer-type-discrimination %s | \
+// RUN: FileCheck %s --check-prefix=VPTRTYPE
+
+// RUN: %clang -target aarch64-linux -S -emit-llvm -o - \
+// RUN: -fptrauth-calls -fptrauth-init-fini %s | \
+// RUN: FileCheck %s --check-prefix=INITFINI
+
+// REQUIRES: aarch64-registered-target
+
+// ALL: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// ALL: !{i32 1, !"aarch64-elf-pauthabi-version", i32 127}
+
+// INTRIN: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// INTRIN: !{i32 1, !"aarch64-elf-pauthabi-version", i32 1}
+
+// CALL: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// CALL: !{i32 1, !"aarch64-elf-pauthabi-version", i32 2}
+
+// RET: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// RET: !{i32 1, !"aarch64-elf-pauthabi-version", i32 4}
+
+// TRAP: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// TRAP: !{i32 1, !"aarch64-elf-pauthabi-version", i32 8}
+
+// VPTRADDR: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// VPTRADDR: !{i32 1, !"aarch64-elf-pauthabi-version", i32 18}
+
+// VPTRTYPE: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// VPTRTYPE: !{i32 1, !"aarch64-elf-pauthabi-version", i32 34}
+
+// INITFINI: !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+// INITFINI: !{i32 1, !"aarch64-elf-pauthabi-version", i32 66}
+
+void foo() {}
diff --git a/clang/test/Driver/ptrauth.c b/clang/test/Driver/ptrauth.c
new file mode 100644
index 00000000000000..2336a5d551b014
--- /dev/null
+++ b/clang/test/Driver/ptrauth.c
@@ -0,0 +1,32 @@
+// Check that we can manually enable specific ptrauth features.
+
+// RUN: %clang -target aarch64 -c %s -### 2>&1 | FileCheck %s --check-prefix NONE
+// NONE: "-cc1"
+// NONE-NOT: "-fptrauth-intrinsics"
+// NONE-NOT: "-fptrauth-calls"
+// NONE-NOT: "-fptrauth-returns"
+// NONE-NOT: "-fptrauth-auth-traps"
+// NONE-NOT: "-fptrauth-vtable-pointer-address-discrimination"
+// NONE-NOT: "-fptrauth-vtable-pointer-type-discrimination"
+// NONE-NOT: "-fptrauth-init-fini"
+
+// RUN: %clang -target aarch64 -fptrauth-intrinsics -c %s -### 2>&1 | FileCheck %s --check-prefix INTRIN
+// INTRIN: "-cc1"{{.*}} {{.*}} "-fptrauth-intrinsics"
+
+// RUN: %clang -target aarch64 -fptrauth-calls -c %s -### 2>&1 | FileCheck %s --check-prefix CALL
+// CALL: "-cc1"{{.*}} {{.*}} "-fptrauth-calls"
+
+// RUN: %clang -target aarch64 -fptrauth-returns -c %s -### 2>&1 | FileCheck %s --check-prefix RETURN
+// RETURN: "-cc1"{{.*}} {{.*}} "-fptrauth-returns"
+
+// RUN: %clang -target aarch64 -fptrauth-auth-traps -c %s -### 2>&1 | FileCheck %s --check-prefix TRAPS
+// TRAPS: "-cc1"{{.*}} {{.*}} "-fptrauth-auth-traps"
+
+// RUN: %clang -target aarch64 -fptrauth-vtable-pointer-address-discrimination -c %s -### 2>&1 | FileCheck %s --check-prefix VPTR_ADDR_DISCR
+// VPTR_ADDR_DISCR: "-cc1"{{.*}} {{.*}} "-fptrauth-vtable-pointer-address-discrimination"
+
+// RUN: %clang -target aarch64 -fptrauth-vtable-pointer-type-discrimination -c %s -### 2>&1 | FileCheck %s --check-prefix VPTR_TYPE_DISCR
+// VPTR_TYPE_DISCR: "-cc1"{{.*}} {{.*}} "-fptrauth-vtable-pointer-type-discrimination"
+
+// RUN: %clang -target aarch64 -fptrauth-init-fini -c %s -### 2>&1 | FileCheck %s --check-prefix INITFINI
+// INITFINI: "-cc1"{{.*}} {{.*}} "-fptrauth-init-fini"
diff --git a/clang/test/Preprocessor/ptrauth_feature.c b/clang/test/Preprocessor/ptrauth_feature.c
index e45c6ea90fd11f..80e239110ffc7b 100644
--- a/clang/test/Preprocessor/ptrauth_feature.c
+++ b/clang/test/Preprocessor/ptrauth_feature.c
@@ -1,5 +1,59 @@
-// RUN: %clang_cc1 %s -E -triple=arm64-- | FileCheck %s --check-prefixes=NOINTRIN
-// RUN: %clang_cc1 %s -E -triple=arm64-- -fptrauth-intrinsics | FileCheck %s --check-prefixes=INTRIN
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=NOINTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,NOCALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,NORETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-type-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,NOVPTR_ADDR_DISCR,VPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-init-fini | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,NOVPTR_TYPE_DISCR,INITFINI
+
+// RUN: %clang_cc1 -E %s -triple=aarch64 \
+// RUN: -fptrauth-intrinsics \
+// RUN: -fptrauth-calls \
+// RUN: -fptrauth-returns \
+// RUN: -fptrauth-vtable-pointer-address-discrimination \
+// RUN: -fptrauth-vtable-pointer-type-discrimination | \
+// RUN: FileCheck %s --check-prefixes=INTRIN,CALLS,RETS,VPTR_ADDR_DISCR,VPTR_TYPE_DISCR,NOINITFINI
#if __has_feature(ptrauth_intrinsics)
// INTRIN: has_ptrauth_intrinsics
@@ -8,3 +62,52 @@ void has_ptrauth_intrinsics() {}
// NOINTRIN: no_ptrauth_intrinsics
void no_ptrauth_intrinsics() {}
#endif
+
+#if __has_feature(ptrauth_calls)
+// CALLS: has_ptrauth_calls
+void has_ptrauth_calls() {}
+#else
+// NOCALLS: no_ptrauth_calls
+void no_ptrauth_calls() {}
+#endif
+
+// This is always enabled when ptrauth_calls is enabled
+#if __has_feature(ptrauth_member_function_pointer_type_discrimination)
+// CALLS: has_ptrauth_member_function_pointer_type_discrimination
+void has_ptrauth_member_function_pointer_type_discrimination() {}
+#else
+// NOCALLS: no_ptrauth_member_function_pointer_type_discrimination
+void no_ptrauth_member_function_pointer_type_discrimination() {}
+#endif
+
+#if __has_feature(ptrauth_returns)
+// RETS: has_ptrauth_returns
+void has_ptrauth_returns() {}
+#else
+// NORETS: no_ptrauth_returns
+void no_ptrauth_returns() {}
+#endif
+
+#if __has_feature(ptrauth_vtable_pointer_address_discrimination)
+// VPTR_ADDR_DISCR: has_ptrauth_vtable_pointer_address_discrimination
+void has_ptrauth_vtable_pointer_address_discrimination() {}
+#else
+// NOVPTR_ADDR_DISCR: no_ptrauth_vtable_pointer_address_discrimination
+void no_ptrauth_vtable_pointer_address_discrimination() {}
+#endif
+
+#if __has_feature(ptrauth_vtable_pointer_type_discrimination)
+// VPTR_TYPE_DISCR: has_ptrauth_vtable_pointer_type_discrimination
+void has_ptrauth_vtable_pointer_type_discrimination() {}
+#else
+// NOVPTR_TYPE_DISCR: no_ptrauth_vtable_pointer_type_discrimination
+void no_ptrauth_vtable_pointer_type_discrimination() {}
+#endif
+
+#if __has_feature(ptrauth_init_fini)
+// INITFINI: has_ptrauth_init_fini
+void has_ptrauth_init_fini() {}
+#else
+// NOINITFINI: no_ptrauth_init_fini
+void no_ptrauth_init_fini() {}
+#endif
|
clang/test/Driver/ptrauth.c
Outdated
@@ -0,0 +1,32 @@ | |||
// Check that we can manually enable specific ptrauth features. | |||
|
|||
// RUN: %clang -target aarch64 -c %s -### 2>&1 | FileCheck %s --check-prefix NONE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--target=
for new tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, thanks, see f80f4bd
clang/test/Driver/ptrauth.c
Outdated
// NONE-NOT: "-fptrauth-init-fini" | ||
|
||
// RUN: %clang -target aarch64 -fptrauth-intrinsics -c %s -### 2>&1 | FileCheck %s --check-prefix INTRIN | ||
// INTRIN: "-cc1"{{.*}} {{.*}} "-fptrauth-intrinsics" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{{.*}} {{.*}}
=> {{.*}}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, thanks, see f80f4bd
@@ -0,0 +1,61 @@ | |||
// REQUIRES: aarch64-registered-target |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most clang/test/CodeGen tests don't need registered-target. You can check this by removing AArch64 from LLVM_TARGETS_TO_BUILD
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensured that it's not needed and deleted in 2fd8f66, thanks
clang/test/Driver/ptrauth.c
Outdated
|
||
// RUN: %clang --target=aarch64 -c %s -### 2>&1 | FileCheck %s --check-prefix NONE | ||
// NONE: "-cc1" | ||
// NONE-NOT: "-fptrauth-intrinsics" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// NONE-NOT: "-fptrauth-
to rule them all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, thanks, see 4fd37cf
clang/test/Driver/ptrauth.c
Outdated
@@ -0,0 +1,32 @@ | |||
// Check that we can manually enable specific ptrauth features. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aarch64-ptrauth.c is more conventional for such target-specific features
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -7203,6 +7203,33 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, | |||
options::OPT_fno_ptrauth_intrinsics, false)) | |||
CmdArgs.push_back("-fptrauth-intrinsics"); | |||
|
|||
if (Args.hasFlag(options::OPT_fptrauth_calls, options::OPT_fno_ptrauth_calls, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be added in Clang::AddAArch64TargetArgs and use addOptInFlag. See 6ff6191
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Fixed in 68bf805
@MaskRay Would be glad to see your feedback since issues you mentioned previously seem to be resolved (see my answers in threads you opened). Would be happy to also see feedback from everyone else interested. |
@MaskRay A kind reminder regarding the PR - please let me know if latest updates address your previous comments and if there are other issues still present. |
@MaskRay Please see fixes for your previous comments in several latest commits. Would be glad to see new feedback on the PR. Note: the buildkite failure on Windows is flang-related and not related to these changes. |
@@ -0,0 +1,59 @@ | |||
// RUN: %clang --target=aarch64-linux -S -emit-llvm -o - \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We prefer %clang_cc1
for codegen tests. %clang
is not used in clang/test/Driver
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, thanks, see fdb26a1
clang/test/Driver/aarch64-ptrauth.c
Outdated
// RUN: %clang -### -c --target=aarch64 -fno-ptrauth-intrinsics -fptrauth-intrinsics %s 2>&1 | FileCheck %s --check-prefix=INTRIN | ||
// INTRIN: "-cc1"{{.*}} "-fptrauth-intrinsics" | ||
|
||
// RUN: not %clang -### -c --target=x86_64 -fptrauth-intrinsics %s 2>&1 | FileCheck %s --check-prefix=ERR | ||
// ERR: error: unsupported option '-fptrauth-intrinsics' for target '{{.*}}' | ||
// RUN: %clang -### -c --target=aarch64 -fno-ptrauth-calls -fptrauth-calls %s 2>&1 | FileCheck %s --check-prefix=CALL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The overhead of additional RUN lines perhaps overweigh
the additional value testing each -fptrauth-*
individually. Perhaps pack more on the same %clang
RUN line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've measured timings on my machine, and we can potentially save about 0.1s if combine some of the RUN lines. It's noticeable, but there are tests like aarch64-fixed-x-register.c which contain a lot more similar RUN lines which can also be combined and we could save even more if enhance them.
I suggest to merge this PR "as is" and probably submitting a subsequent PR which makes this test and some similar ones "lighter" if it's a big concern. As for me, keeping all the RUN lines can protect us from dummy typos and they probably are worth the time spent on them - but I don't mind combining the RUN lines if the extra overhead bothers many people.
Please let me know if this approach is OK for you and I can merge the PR. If the clang driver test timings look too bad, I can also submit a corresponding issue so the context of the discussion is not lost.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there is some value separating tests for codegen but the value is largely diminished for driver.
For driver, the code looks like Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_returns, options::OPT_fno_ptrauth_returns);
. We don't repeat OPT_fptrauth_returns
twice, so it's very difficult to make a typo mistake...
So for driver, I'd hope that some grouping is made. If that's extra trouble to you, you can submit this as is and I will simplify it a bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this makes sense. Given that, I've combined 7 RUN lines for individual options into a single RUN line (so the file contains 3 RUN lines total now). See b0f9a19.
@@ -1796,6 +1796,26 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, | |||
|
|||
Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_intrinsics, | |||
options::OPT_fno_ptrauth_intrinsics); | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd delete blank lines for these similar OPT_fptrauth_*
lines. Deleting extra blank lines makes the grouping (OPT_fptrauth_*
code is together) clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deleted, see b0f9a19
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will need a rebase (or merge main) as -S -emit-llvm
tests have errors.
clang/lib/CodeGen/CodeGenModule.cpp
Outdated
@@ -1190,6 +1191,36 @@ void CodeGenModule::Release() { | |||
if (!LangOpts.isSignReturnAddressWithAKey()) | |||
getModule().addModuleFlag(llvm::Module::Min, | |||
"sign-return-address-with-bkey", 1); | |||
|
|||
if (getTriple().isOSLinux() && getTriple().isOSBinFormatELF()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Linux implies ELF. You can remove getTriple().isOSBinFormatELF()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, but I'll leave an assertion against ELF here. Theoretically, we might have non-ELF binary format on Linux, while the Linux itself seems to have deprecated COFF and a.out support and llvm does not seem to support them as well. This assertion makes sense to me since (a) it makes things clear that we want to check both Linux and ELF (b) this will notify us if in future we have binary formats other than ELF supported on Linux.
See 37a4d9d
@@ -0,0 +1,59 @@ | |||
// RUN: %clang_cc1 -triple aarch64-linux -S -emit-llvm -o - \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-S
should be removed. I've cleaned up the whole clang/test suite.
After #91140 this will lead to an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, thanks, see 37a4d9d
Depends on #87545
Emit PAuth ABI compatibility tag values as llvm module flags:
aarch64-elf-pauthabi-platform
aarch64-elf-pauthabi-version
For platform 0x10000002 (llvm_linux), the version value bits correspond to the following LangOptions defined in #85232:
PointerAuthIntrinsics
;PointerAuthCalls
;PointerAuthReturns
;PointerAuthAuthTraps
;PointerAuthVTPtrAddressDiscrimination
;PointerAuthVTPtrTypeDiscrimination
;PointerAuthInitFini
.