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 <dkova...@accesssoftek.com> Date: Mon, 1 Jul 2024 00:50:21 +0300 Subject: [PATCH 1/6] [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 <atrosine...@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 1b7cc82ea816e..4ed1ece22b7aa 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 fa0125f4b22a9..dc63545a47a86 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 f6115718e9f5f..ca634ed969d84 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 d6ce6581bb1a9..0b1e6d3356f68 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 <dkova...@accesssoftek.com> Date: Wed, 3 Jul 2024 12:52:18 +0300 Subject: [PATCH 2/6] 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 63134ab733e4b..3f9beb05215a9 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 <dkova...@accesssoftek.com> Date: Fri, 5 Jul 2024 02:05:38 +0300 Subject: [PATCH 3/6] 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 dc63545a47a86..b8b370cc3e405 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 <dkova...@accesssoftek.com> Date: Fri, 5 Jul 2024 15:48:19 +0300 Subject: [PATCH 4/6] 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 b8b370cc3e405..976c74b9b0ba2 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 0b1e6d3356f68..219842f6469a3 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 <dkova...@accesssoftek.com> Date: Fri, 5 Jul 2024 15:59:05 +0300 Subject: [PATCH 5/6] 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 219842f6469a3..dcaa96be72303 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}; >From 0ac47249cd78a54c0aefb6e9328edabdae30c93a Mon Sep 17 00:00:00 2001 From: Daniil Kovalev <dkova...@accesssoftek.com> Date: Fri, 12 Jul 2024 18:23:05 +0300 Subject: [PATCH 6/6] tmp --- clang/lib/Basic/Targets/AArch64.cpp | 9 ++- clang/lib/Basic/Targets/ARM.cpp | 3 + clang/lib/CodeGen/CodeGenModule.cpp | 2 + clang/lib/CodeGen/TargetInfo.h | 1 + clang/lib/Driver/ToolChain.cpp | 5 +- clang/lib/Driver/ToolChains/Arch/AArch64.cpp | 21 ++++++ clang/lib/Driver/ToolChains/Arch/AArch64.h | 3 + clang/lib/Driver/ToolChains/Clang.cpp | 31 +++++--- clang/lib/Driver/ToolChains/Linux.cpp | 3 + .../usr/include/aarch64-linux-gnu/.keep | 0 .../usr/include/aarch64-linux-pauthtest/.keep | 0 clang/test/Driver/aarch64-multilib-pauthabi.c | 4 ++ clang/test/Driver/aarch64-ptrauth.c | 71 +++++++++++++++---- .../llvm/TargetParser/ARMTargetParserCommon.h | 1 - llvm/include/llvm/TargetParser/Triple.h | 6 +- llvm/lib/TargetParser/ARMTargetParser.cpp | 2 + .../TargetParser/ARMTargetParserCommon.cpp | 27 ++----- llvm/lib/TargetParser/Triple.cpp | 3 + llvm/unittests/TargetParser/TripleTest.cpp | 6 ++ 19 files changed, 146 insertions(+), 52 deletions(-) create mode 100644 clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-gnu/.keep create mode 100644 clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-pauthtest/.keep create mode 100644 clang/test/Driver/aarch64-multilib-pauthabi.c diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 2692ddec26ff4..04ba0ef981a69 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -204,7 +204,8 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, StringRef AArch64TargetInfo::getABI() const { return ABI; } bool AArch64TargetInfo::setABI(const std::string &Name) { - if (Name != "aapcs" && Name != "aapcs-soft" && Name != "darwinpcs") + if (Name != "aapcs" && Name != "aapcs-soft" && Name != "darwinpcs" && + Name != "pauthtest") return false; ABI = Name; @@ -218,6 +219,12 @@ bool AArch64TargetInfo::validateTarget(DiagnosticsEngine &Diags) const { Diags.Report(diag::err_target_unsupported_abi_with_fpu) << ABI; return false; } + if (getTriple().getEnvironment() == llvm::Triple::PAuthTest && + getTriple().getOS() != llvm::Triple::Linux) { + Diags.Report(diag::err_target_unsupported_abi_for_triple) + << getTriple().getEnvironmentName() << getTriple().getTriple(); + return false; + } return true; } diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp index 7423626d7c3cb..340de5f0190d5 100644 --- a/clang/lib/Basic/Targets/ARM.cpp +++ b/clang/lib/Basic/Targets/ARM.cpp @@ -324,6 +324,9 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, case llvm::Triple::GNU: setABI("apcs-gnu"); break; + case llvm::Triple::PAuthTest: + setABI("pauthtest"); + break; default: if (IsNetBSD) setABI("apcs-gnu"); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 08cfa694cfb81..206156f2b1682 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -147,6 +147,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { return createWindowsAArch64TargetCodeGenInfo(CGM, AArch64ABIKind::Win64); else if (Target.getABI() == "aapcs-soft") Kind = AArch64ABIKind::AAPCSSoft; + else if (Target.getABI() == "pauthtest") + Kind = AArch64ABIKind::PAuthTest; return createAArch64TargetCodeGenInfo(CGM, Kind); } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index 0925609cc74aa..2f2138582ba1e 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -437,6 +437,7 @@ enum class AArch64ABIKind { DarwinPCS, Win64, AAPCSSoft, + PAuthTest, }; std::unique_ptr<TargetCodeGenInfo> diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 85ae4d2a26fee..20a555afb8092 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1031,11 +1031,12 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, } case llvm::Triple::aarch64: { llvm::Triple Triple = getTriple(); + tools::aarch64::setPAuthABIInTriple(getDriver(), Args, Triple); if (!Triple.isOSBinFormatMachO()) - return getTripleString(); + return Triple.getTriple(); if (Triple.isArm64e()) - return getTripleString(); + return Triple.getTriple(); // FIXME: older versions of ld64 expect the "arm64" component in the actual // triple string and query it to determine whether an LTO file can be diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index 5fbf38cdda12b..f083e40df1314 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -449,3 +449,24 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, if (Args.getLastArg(options::OPT_mno_bti_at_return_twice)) Features.push_back("+no-bti-at-return-twice"); } + +void aarch64::setPAuthABIInTriple(const Driver &D, const ArgList &Args, + llvm::Triple &Triple) { + Arg *ABIArg = Args.getLastArg(options::OPT_mabi_EQ); + bool HasPAuthABI = + ABIArg ? (StringRef(ABIArg->getValue()) == "pauthtest") : false; + + switch (Triple.getEnvironment()) { + case llvm::Triple::UnknownEnvironment: + if (HasPAuthABI) + Triple.setEnvironment(llvm::Triple::PAuthTest); + break; + case llvm::Triple::PAuthTest: + break; + default: + if (HasPAuthABI) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << ABIArg->getAsString(Args) << Triple.getTriple(); + break; + } +} diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.h b/clang/lib/Driver/ToolChains/Arch/AArch64.h index d47c402d4a42d..6d071167bd392 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.h +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.h @@ -28,6 +28,9 @@ void getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple, std::string getAArch64TargetCPU(const llvm::opt::ArgList &Args, const llvm::Triple &Triple, llvm::opt::Arg *&A); +void setPAuthABIInTriple(const Driver &D, const llvm::opt::ArgList &Args, + llvm::Triple &triple); + } // end namespace aarch64 } // end namespace target } // end namespace driver diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 636413fae3d1d..0c1efdc59dc5f 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1487,8 +1487,7 @@ 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) { +static void handlePAuthABI(const ArgList &DriverArgs, ArgStringList &CC1Args) { if (!DriverArgs.hasArg(options::OPT_fptrauth_intrinsics, options::OPT_fno_ptrauth_intrinsics)) CC1Args.push_back("-fptrauth-intrinsics"); @@ -1573,30 +1572,37 @@ 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); } CmdArgs.push_back( Args.MakeArgString(Twine("-msign-return-address=") + Scope)); - if (Scope != "none") + if (Scope != "none") { + if (Triple.getEnvironment() == llvm::Triple::PAuthTest) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getAsString(Args) << Triple.getTriple(); CmdArgs.push_back( Args.MakeArgString(Twine("-msign-return-address-key=") + Key)); - if (BranchProtectionPAuthLR) + } + if (BranchProtectionPAuthLR) { + if (Triple.getEnvironment() == llvm::Triple::PAuthTest) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getAsString(Args) << Triple.getTriple(); CmdArgs.push_back( Args.MakeArgString(Twine("-mbranch-protection-pauth-lr"))); + } if (IndirectBranches) CmdArgs.push_back("-mbranch-target-enforce"); - if (GuardedControlStack) + if (GuardedControlStack) { + if (Triple.getEnvironment() == llvm::Triple::PAuthTest) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getAsString(Args) << Triple.getTriple(); CmdArgs.push_back("-mguarded-control-stack"); + } } void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args, @@ -1740,6 +1746,8 @@ void RenderAArch64ABI(const llvm::Triple &Triple, const ArgList &Args, ABIName = A->getValue(); else if (Triple.isOSDarwin()) ABIName = "darwinpcs"; + else if (Triple.getEnvironment() == llvm::Triple::PAuthTest) + ABIName = "pauthtest"; else ABIName = "aapcs"; @@ -1776,6 +1784,9 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, // Enable/disable return address signing and indirect branch targets. CollectARMPACBTIOptions(getToolChain(), Args, CmdArgs, true /*isAArch64*/); + if (Triple.getEnvironment() == llvm::Triple::PAuthTest) + handlePAuthABI(Args, CmdArgs); + // Handle -msve_vector_bits=<bits> if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) { StringRef Val = A->getValue(); diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index 98a878e1d764d..2265138edbffb 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -86,6 +86,9 @@ std::string Linux::getMultiarchTriple(const Driver &D, case llvm::Triple::aarch64: if (IsAndroid) return "aarch64-linux-android"; + if (hasEffectiveTriple() && + getEffectiveTriple().getEnvironment() == llvm::Triple::PAuthTest) + return "aarch64-linux-pauthtest"; return "aarch64-linux-gnu"; case llvm::Triple::aarch64_be: return "aarch64_be-linux-gnu"; diff --git a/clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-gnu/.keep b/clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-gnu/.keep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-pauthtest/.keep b/clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-pauthtest/.keep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/clang/test/Driver/aarch64-multilib-pauthabi.c b/clang/test/Driver/aarch64-multilib-pauthabi.c new file mode 100644 index 0000000000000..3046cb856e83c --- /dev/null +++ b/clang/test/Driver/aarch64-multilib-pauthabi.c @@ -0,0 +1,4 @@ +// RUN: %clang --target=aarch64-linux-pauthtest --sysroot=%S/Inputs/multilib_aarch64_linux_tree -### -c %s 2>&1 | FileCheck %s +// RUN: %clang --target=aarch64-linux -mabi=pauthtest --sysroot=%S/Inputs/multilib_aarch64_linux_tree -### -c %s 2>&1 | FileCheck %s + +// CHECK: "-internal-externc-isystem" "{{.*}}/usr/include/aarch64-linux-pauthtest" diff --git a/clang/test/Driver/aarch64-ptrauth.c b/clang/test/Driver/aarch64-ptrauth.c index 976c74b9b0ba2..d13930e8f4b37 100644 --- a/clang/test/Driver/aarch64-ptrauth.c +++ b/clang/test/Driver/aarch64-ptrauth.c @@ -1,5 +1,7 @@ +// REQUIRES: aarch64-registered-target + // RUN: %clang -### -c --target=aarch64 %s 2>&1 | FileCheck %s --check-prefix NONE -// NONE: "-cc1" +// NONE: "-cc1" // NONE-NOT: "-fptrauth- // RUN: %clang -### -c --target=aarch64 \ @@ -13,14 +15,21 @@ // 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-linux -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI1 +// RUN: %clang -### -c --target=aarch64-linux-pauthtest %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI1 +// PAUTHABI1: "-cc1"{{.*}} "-triple" "aarch64-unknown-linux-pauthtest" +// PAUTHABI1-SAME: "-target-abi" "pauthtest" +// PAUTHABI1-SAME: "-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: %clang -### -c --target=aarch64 -mabi=pauthtest -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 +// RUN: %clang -### -c --target=aarch64-pauthtest -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: "-cc1" // PAUTHABI2-NOT: "-fptrauth- // RUN: not %clang -### -c --target=x86_64 -fptrauth-intrinsics -fptrauth-calls -fptrauth-returns -fptrauth-auth-traps \ @@ -34,16 +43,50 @@ // 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' +//// Only support PAuth ABI for Linux as for now. +// RUN: not %clang -c --target=aarch64-unknown -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=ERR2 +// RUN: not %clang -c --target=aarch64-unknown-pauthtest %s 2>&1 | FileCheck %s --check-prefix=ERR2 +// ERR2: error: ABI 'pauthtest' is not supported for 'aarch64-unknown-unknown-pauthtest' -// 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=' +//// PAuth ABI is encoded as environment part of the triple, so don't allow to explicitly set other environments. +// RUN: not %clang -c --target=aarch64-linux-gnu -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=ERR3 +// ERR3: error: unsupported option '-mabi=pauthtest' for target 'aarch64-unknown-linux-gnu' +// RUN: %clang -c --target=aarch64-linux-pauthtest -mabi=pauthtest %s -// RUN: not %clang -### -c --target=aarch64 -mbranch-protection=gcs+pauthabi %s 2>&1 | \ +//// The only branch protection option compatible with PAuthABI is BTI. +// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=pac-ret %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR4 +// RUN: not %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=pac-ret %s 2>&1 | \ // RUN: FileCheck %s --check-prefix=ERR4 -// ERR4: error: unsupported argument 'pauthabi+gcs' to option '-mbranch-protection=' +// ERR4: error: unsupported option '-mbranch-protection=pac-ret' for target 'aarch64-unknown-linux-pauthtest' + +// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=gcs %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR5 +// RUN: not %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=gcs %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR5 +// ERR5: error: unsupported option '-mbranch-protection=gcs' for target 'aarch64-unknown-linux-pauthtest' + +// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=standard %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR6 +// RUN: not %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=standard %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR6 +// ERR6: error: unsupported option '-mbranch-protection=standard' for target 'aarch64-unknown-linux-pauthtest' + +// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -msign-return-address=all %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR7 +// RUN: not %clang -### -c --target=aarch64-linux-pauthtest -msign-return-address=all %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR7 +// ERR7: error: unsupported option '-msign-return-address=all' for target 'aarch64-unknown-linux-pauthtest' + +// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -msign-return-address=non-leaf %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR8 +// RUN: not %clang -### -c --target=aarch64-linux-pauthtest -msign-return-address=non-leaf %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR8 +// ERR8: error: unsupported option '-msign-return-address=non-leaf' for target 'aarch64-unknown-linux-pauthtest' -// RUN: %clang -### -c --target=aarch64 -mbranch-protection=bti+pauthabi %s 2>&1 +// RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest -msign-return-address=none %s +// RUN: %clang -### -c --target=aarch64-linux-pauthtest -msign-return-address=none %s +// RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=bti %s +// RUN: %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=bti %s +// RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=none %s +// RUN: %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=none %s diff --git a/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h b/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h index ca634ed969d84..f6115718e9f5f 100644 --- a/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h +++ b/llvm/include/llvm/TargetParser/ARMTargetParserCommon.h @@ -43,7 +43,6 @@ struct ParsedBranchProtection { bool BranchTargetEnforcement; bool BranchProtectionPAuthLR; bool GuardedControlStack; - bool HasPauthABI; }; bool parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP, diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h index cb2be3bbd29f7..e504128714c55 100644 --- a/llvm/include/llvm/TargetParser/Triple.h +++ b/llvm/include/llvm/TargetParser/Triple.h @@ -266,7 +266,7 @@ class Triple { Cygnus, CoreCLR, Simulator, // Simulator variants of other systems, e.g., Apple's iOS - MacABI, // Mac Catalyst variant of Apple's iOS deployment target. + MacABI, // Mac Catalyst variant of Apple's iOS deployment target. // Shader Stages // The order of these values matters, and must be kept in sync with the @@ -290,7 +290,9 @@ class Triple { OpenCL, OpenHOS, - LastEnvironmentType = OpenHOS + PAuthTest, + + LastEnvironmentType = PAuthTest }; enum ObjectFormatType { UnknownObjectFormat, diff --git a/llvm/lib/TargetParser/ARMTargetParser.cpp b/llvm/lib/TargetParser/ARMTargetParser.cpp index 9d9917d86a368..1d31af587745f 100644 --- a/llvm/lib/TargetParser/ARMTargetParser.cpp +++ b/llvm/lib/TargetParser/ARMTargetParser.cpp @@ -562,6 +562,8 @@ StringRef ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) { case Triple::EABIHF: case Triple::EABI: return "aapcs"; + case Triple::PAuthTest: + return "pauthtest"; default: if (TT.isOSNetBSD()) return "apcs-gnu"; diff --git a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp index dcaa96be72303..d6ce6581bb1a9 100644 --- a/llvm/lib/TargetParser/ARMTargetParserCommon.cpp +++ b/llvm/lib/TargetParser/ARMTargetParserCommon.cpp @@ -134,14 +134,13 @@ ARM::EndianKind ARM::parseArchEndian(StringRef Arch) { } // Parse a branch protection specification, which has the form -// 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. +// 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. bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP, StringRef &Err, bool EnablePAuthLR) { - PBP = {"none", "a_key", false, false, false, false}; + PBP = {"none", "a_key", false, false, false}; if (Spec == "none") return true; // defaults are ok @@ -161,10 +160,6 @@ 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) { @@ -191,17 +186,5 @@ 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; } diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp index a54a02ac61d68..55911a7d71ac7 100644 --- a/llvm/lib/TargetParser/Triple.cpp +++ b/llvm/lib/TargetParser/Triple.cpp @@ -347,6 +347,8 @@ StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) { case OpenCL: return "opencl"; case OpenHOS: return "ohos"; + case PAuthTest: + return "pauthtest"; } llvm_unreachable("Invalid EnvironmentType!"); @@ -719,6 +721,7 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { .StartsWith("amplification", Triple::Amplification) .StartsWith("opencl", Triple::OpenCL) .StartsWith("ohos", Triple::OpenHOS) + .StartsWith("pauthtest", Triple::PAuthTest) .Default(Triple::UnknownEnvironment); } diff --git a/llvm/unittests/TargetParser/TripleTest.cpp b/llvm/unittests/TargetParser/TripleTest.cpp index f93dc3671197a..0aecfc64da208 100644 --- a/llvm/unittests/TargetParser/TripleTest.cpp +++ b/llvm/unittests/TargetParser/TripleTest.cpp @@ -1169,6 +1169,12 @@ TEST(TripleTest, ParsedIDs) { EXPECT_EQ(Triple::Serenity, T.getOS()); EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment()); + T = Triple("aarch64-unknown-linux-pauthtest"); + EXPECT_EQ(Triple::aarch64, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::PAuthTest, T.getEnvironment()); + T = Triple("huh"); EXPECT_EQ(Triple::UnknownArch, T.getArch()); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits