[clang] [llvm] [PAC][Driver] Implement `-mbranch-protection=pauthabi` option (PR #97237)
Daniil Kovalev via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 5 05:59:46 PDT 2024
https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/97237
>From 3b4b1b1739b810d758e68f30c48b648963cff740 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Mon, 1 Jul 2024 00:50:21 +0300
Subject: [PATCH 1/5] [PAC][Driver] Implement `-mbranch-protection=pauthabi`
option
Enable the following ptrauth flags when `pauthabi` is passed as branch
protection:
- `intrinsics`;
- `calls`;
- `returns`;
- `auth-traps`;
- `vtable-pointer-address-discrimination`;
- `vtable-pointer-type-discrimination`;
- `init-fini`.
Co-authored-by: Anatoly Trosinenko <atrosinenko at accesssoftek.com>
---
clang/lib/Driver/ToolChains/Clang.cpp | 38 +++++++++++++++++++
clang/test/Driver/aarch64-ptrauth.c | 36 ++++++++++++++----
.../llvm/TargetParser/ARMTargetParserCommon.h | 1 +
.../TargetParser/ARMTargetParserCommon.cpp | 6 ++-
4 files changed, 72 insertions(+), 9 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 1b7cc82ea816ed..4ed1ece22b7aac 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1484,6 +1484,39 @@ void AddUnalignedAccessWarning(ArgStringList &CmdArgs) {
}
}
+static void handlePAuthABIOption(const ArgList &DriverArgs,
+ ArgStringList &CC1Args, const Driver &D) {
+ if (!DriverArgs.hasArg(options::OPT_fptrauth_intrinsics,
+ options::OPT_fno_ptrauth_intrinsics))
+ CC1Args.push_back("-fptrauth-intrinsics");
+
+ if (!DriverArgs.hasArg(options::OPT_fptrauth_calls,
+ options::OPT_fno_ptrauth_calls))
+ CC1Args.push_back("-fptrauth-calls");
+
+ if (!DriverArgs.hasArg(options::OPT_fptrauth_returns,
+ options::OPT_fno_ptrauth_returns))
+ CC1Args.push_back("-fptrauth-returns");
+
+ if (!DriverArgs.hasArg(options::OPT_fptrauth_auth_traps,
+ options::OPT_fno_ptrauth_auth_traps))
+ CC1Args.push_back("-fptrauth-auth-traps");
+
+ if (!DriverArgs.hasArg(
+ options::OPT_fptrauth_vtable_pointer_address_discrimination,
+ options::OPT_fno_ptrauth_vtable_pointer_address_discrimination))
+ CC1Args.push_back("-fptrauth-vtable-pointer-address-discrimination");
+
+ if (!DriverArgs.hasArg(
+ options::OPT_fptrauth_vtable_pointer_type_discrimination,
+ options::OPT_fno_ptrauth_vtable_pointer_type_discrimination))
+ CC1Args.push_back("-fptrauth-vtable-pointer-type-discrimination");
+
+ if (!DriverArgs.hasArg(options::OPT_fptrauth_init_fini,
+ options::OPT_fno_ptrauth_init_fini))
+ CC1Args.push_back("-fptrauth-init-fini");
+}
+
static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs, bool isAArch64) {
const Arg *A = isAArch64
@@ -1537,11 +1570,16 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
if (!isAArch64 && PBP.Key == "b_key")
D.Diag(diag::warn_unsupported_branch_protection)
<< "b-key" << A->getAsString(Args);
+ if (!isAArch64 && PBP.HasPauthABI)
+ D.Diag(diag::warn_unsupported_branch_protection)
+ << "pauthabi" << A->getAsString(Args);
Scope = PBP.Scope;
Key = PBP.Key;
BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
IndirectBranches = PBP.BranchTargetEnforcement;
GuardedControlStack = PBP.GuardedControlStack;
+ if (isAArch64 && PBP.HasPauthABI)
+ handlePAuthABIOption(Args, CmdArgs, D);
}
CmdArgs.push_back(
diff --git a/clang/test/Driver/aarch64-ptrauth.c b/clang/test/Driver/aarch64-ptrauth.c
index fa0125f4b22a9a..dc63545a47a866 100644
--- a/clang/test/Driver/aarch64-ptrauth.c
+++ b/clang/test/Driver/aarch64-ptrauth.c
@@ -13,13 +13,33 @@
// RUN: %s 2>&1 | FileCheck %s --check-prefix=ALL
// ALL: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini"
+// RUN: %clang -### -c --target=aarch64 -mbranch-protection=pauthabi %s 2>&1 | \
+// RUN: FileCheck %s --check-prefix=PAUTHABI1
+// PAUTHABI1: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini"
+
+// RUN: %clang -### -c --target=aarch64 -mbranch-protection=pauthabi -fno-ptrauth-intrinsics \
+// RUN: -fno-ptrauth-calls -fno-ptrauth-returns -fno-ptrauth-auth-traps \
+// RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fno-ptrauth-vtable-pointer-type-discrimination \
+// RUN: -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2
+// PAUTHABI2-NOT: "-fptrauth-intrinsics"
+// PAUTHABI2-NOT: "-fptrauth-calls"
+// PAUTHABI2-NOT: "-fptrauth-returns"
+// PAUTHABI2-NOT: "-fptrauth-auth-traps"
+// PAUTHABI2-NOT: "-fptrauth-vtable-pointer-address-discrimination"
+// PAUTHABI2-NOT: "-fptrauth-vtable-pointer-type-discrimination"
+// PAUTHABI2-NOT: "-fptrauth-init-fini"
+
// RUN: not %clang -### -c --target=x86_64 -fptrauth-intrinsics -fptrauth-calls -fptrauth-returns -fptrauth-auth-traps \
// RUN: -fptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-type-discrimination \
-// RUN: -fptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=ERR
-// ERR: error: unsupported option '-fptrauth-intrinsics' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-calls' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-returns' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-auth-traps' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-vtable-pointer-address-discrimination' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-vtable-pointer-type-discrimination' for target '{{.*}}'
-// ERR-NEXT: error: unsupported option '-fptrauth-init-fini' for target '{{.*}}'
+// RUN: -fptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=ERR1
+// ERR1: error: unsupported option '-fptrauth-intrinsics' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-calls' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-returns' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-auth-traps' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-vtable-pointer-address-discrimination' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-vtable-pointer-type-discrimination' for target '{{.*}}'
+// ERR1-NEXT: error: unsupported option '-fptrauth-init-fini' for target '{{.*}}'
+
+// RUN: not %clang -### -c --target=x86_64 -mbranch-protection=pauthabi %s 2>&1 | \
+// RUN: FileCheck %s --check-prefix=ERR2
+// ERR2: error: unsupported option '-mbranch-protection=' for target 'x86_64'
diff --git a/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h b/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h
index f6115718e9f5fd..ca634ed969d84b 100644
--- a/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h
+++ b/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h
@@ -43,6 +43,7 @@ struct ParsedBranchProtection {
bool BranchTargetEnforcement;
bool BranchProtectionPAuthLR;
bool GuardedControlStack;
+ bool HasPauthABI;
};
bool parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
diff --git a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
index d6ce6581bb1a92..0b1e6d3356f68f 100644
--- a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
+++ b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
@@ -140,7 +140,7 @@ ARM::EndianKind ARM::parseArchEndian(StringRef Arch) {
// an erroneous part of the spec.
bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
StringRef &Err, bool EnablePAuthLR) {
- PBP = {"none", "a_key", false, false, false};
+ PBP = {"none", "a_key", false, false, false, false};
if (Spec == "none")
return true; // defaults are ok
@@ -160,6 +160,10 @@ bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
PBP.BranchTargetEnforcement = true;
continue;
}
+ if (Opt == "pauthabi") {
+ PBP.HasPauthABI = true;
+ continue;
+ }
if (Opt == "pac-ret") {
PBP.Scope = "non-leaf";
for (; I + 1 != E; ++I) {
>From fcd090caac9ede6b915db991819298bed4a5d44e Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Wed, 3 Jul 2024 12:52:18 +0300
Subject: [PATCH 2/5] Address review comments
---
clang/lib/Driver/ToolChains/Clang.cpp | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 63134ab733e4be..3f9beb05215a99 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1484,8 +1484,11 @@ void AddUnalignedAccessWarning(ArgStringList &CmdArgs) {
}
}
+// Each combination of options here forms a signing schema, and in most cases
+// each signing schema is its own incompatible ABI. The default values of the
+// options represent the default signing schema.
static void handlePAuthABIOption(const ArgList &DriverArgs,
- ArgStringList &CC1Args, const Driver &D) {
+ ArgStringList &CC1Args) {
if (!DriverArgs.hasArg(options::OPT_fptrauth_intrinsics,
options::OPT_fno_ptrauth_intrinsics))
CC1Args.push_back("-fptrauth-intrinsics");
@@ -1579,7 +1582,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
IndirectBranches = PBP.BranchTargetEnforcement;
GuardedControlStack = PBP.GuardedControlStack;
if (isAArch64 && PBP.HasPauthABI)
- handlePAuthABIOption(Args, CmdArgs, D);
+ handlePAuthABIOption(Args, CmdArgs);
}
CmdArgs.push_back(
>From 1d81b91d88f4f93dc6cf9bbec0c5f7fb851f89ab Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Fri, 5 Jul 2024 02:05:38 +0300
Subject: [PATCH 3/5] Enhance test
---
clang/test/Driver/aarch64-ptrauth.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/clang/test/Driver/aarch64-ptrauth.c b/clang/test/Driver/aarch64-ptrauth.c
index dc63545a47a866..b8b370cc3e405c 100644
--- a/clang/test/Driver/aarch64-ptrauth.c
+++ b/clang/test/Driver/aarch64-ptrauth.c
@@ -21,13 +21,7 @@
// RUN: -fno-ptrauth-calls -fno-ptrauth-returns -fno-ptrauth-auth-traps \
// RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fno-ptrauth-vtable-pointer-type-discrimination \
// RUN: -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2
-// PAUTHABI2-NOT: "-fptrauth-intrinsics"
-// PAUTHABI2-NOT: "-fptrauth-calls"
-// PAUTHABI2-NOT: "-fptrauth-returns"
-// PAUTHABI2-NOT: "-fptrauth-auth-traps"
-// PAUTHABI2-NOT: "-fptrauth-vtable-pointer-address-discrimination"
-// PAUTHABI2-NOT: "-fptrauth-vtable-pointer-type-discrimination"
-// PAUTHABI2-NOT: "-fptrauth-init-fini"
+// PAUTHABI2-NOT: "-fptrauth-
// RUN: not %clang -### -c --target=x86_64 -fptrauth-intrinsics -fptrauth-calls -fptrauth-returns -fptrauth-auth-traps \
// RUN: -fptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-type-discrimination \
>From 3067c934a957eed21cb3ae73404675242425e5cb Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Fri, 5 Jul 2024 15:48:19 +0300
Subject: [PATCH 4/5] Allow `pauthabi+bti` and disallow other combinations with
`pauthabi`
---
clang/test/Driver/aarch64-ptrauth.c | 10 ++++++++++
llvm/lib/TargetParser/ARMTargetParserCommon.cpp | 12 ++++++++++++
2 files changed, 22 insertions(+)
diff --git a/clang/test/Driver/aarch64-ptrauth.c b/clang/test/Driver/aarch64-ptrauth.c
index b8b370cc3e405c..976c74b9b0ba22 100644
--- a/clang/test/Driver/aarch64-ptrauth.c
+++ b/clang/test/Driver/aarch64-ptrauth.c
@@ -37,3 +37,13 @@
// RUN: not %clang -### -c --target=x86_64 -mbranch-protection=pauthabi %s 2>&1 | \
// RUN: FileCheck %s --check-prefix=ERR2
// ERR2: error: unsupported option '-mbranch-protection=' for target 'x86_64'
+
+// RUN: not %clang -### -c --target=aarch64 -mbranch-protection=pauthabi+pac-ret %s 2>&1 | \
+// RUN: FileCheck %s --check-prefix=ERR3
+// ERR3: error: unsupported argument 'pauthabi+pac-ret' to option '-mbranch-protection='
+
+// RUN: not %clang -### -c --target=aarch64 -mbranch-protection=gcs+pauthabi %s 2>&1 | \
+// RUN: FileCheck %s --check-prefix=ERR4
+// ERR4: error: unsupported argument 'pauthabi+gcs' to option '-mbranch-protection='
+
+// RUN: %clang -### -c --target=aarch64 -mbranch-protection=bti+pauthabi %s 2>&1
diff --git a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
index 0b1e6d3356f68f..219842f6469a33 100644
--- a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
+++ b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
@@ -190,5 +190,17 @@ bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
return false;
}
+ if (!PBP.HasPauthABI)
+ return true;
+
+ if (PBP.Scope != "none") {
+ Err = "pauthabi+pac-ret";
+ return false;
+ }
+ if (PBP.GuardedControlStack) {
+ Err = "pauthabi+gcs";
+ return false;
+ }
+
return true;
}
>From 501a43b7486058a912893f2460fcf0500816cb35 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Fri, 5 Jul 2024 15:59:05 +0300
Subject: [PATCH 5/5] Update comment
---
llvm/lib/TargetParser/ARMTargetParserCommon.cpp | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
index 219842f6469a33..dcaa96be723034 100644
--- a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
+++ b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp
@@ -134,10 +134,11 @@ ARM::EndianKind ARM::parseArchEndian(StringRef Arch) {
}
// Parse a branch protection specification, which has the form
-// standard | none | [bti,pac-ret[+b-key,+leaf,+pc]*]
-// Returns true on success, with individual elements of the specification
-// returned in `PBP`. Returns false in error, with `Err` containing
-// an erroneous part of the spec.
+// standard | none | [bti,pac-ret[+b-key,+leaf,+pc]*,gcs,pauthabi]
+// Note: pauthabi is allowed with bti and disallowed with pac-ret and gcs.
+// Returns true on success, with individual elements of the
+// specification returned in `PBP`. Returns false in error, with `Err`
+// containing an erroneous part of the spec.
bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
StringRef &Err, bool EnablePAuthLR) {
PBP = {"none", "a_key", false, false, false, false};
More information about the cfe-commits
mailing list