[clang] [llvm] [PAC][Driver] Implement `-mbranch-protection=pauthabi` option (PR #97237)

Daniil Kovalev via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 4 16:15:23 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/3] [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/3] 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/3] 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 \



More information about the cfe-commits mailing list