diff --git a/clang/lib/Driver/ToolChains/Clang.h b/clang/lib/Driver/ToolChains/Clang.h --- a/clang/lib/Driver/ToolChains/Clang.h +++ b/clang/lib/Driver/ToolChains/Clang.h @@ -128,6 +128,8 @@ llvm::opt::ArgStringList &CmdArgs) const; void AddRISCVTargetArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; + void AddAArch64TargetArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; bool hasGoodDiagnostics() const override { return true; } bool hasIntegratedAssembler() const override { return false; } bool hasIntegratedCPP() const override { return false; } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -7015,6 +7015,29 @@ CmdArgs.push_back(ABIName.data()); } +void ClangAs::AddAArch64TargetArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + bool BranchTargetEnforce = false; + const auto &D = getToolChain().getDriver(); + + if (Arg *A = Args.getLastArg(options::OPT_mbranch_protection_EQ)) { + StringRef Err; + llvm::AArch64::ParsedBranchProtection PBP; + + if (!llvm::AArch64::parseBranchProtection(A->getValue(), PBP, Err)) { + D.Diag(diag::err_invalid_branch_protection) + << Err << A->getAsString(Args); + } else { + BranchTargetEnforce = PBP.BranchTargetEnforcement; + } + } + + if (Args.hasArg(options::OPT_mmark_bti_property) || BranchTargetEnforce) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-aarch64-mark-bti-property"); + } +} + void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, @@ -7193,10 +7216,7 @@ case llvm::Triple::aarch64: case llvm::Triple::aarch64_32: case llvm::Triple::aarch64_be: - if (Args.hasArg(options::OPT_mmark_bti_property)) { - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back("-aarch64-mark-bti-property"); - } + AddAArch64TargetArgs(Args, CmdArgs); break; case llvm::Triple::riscv32: diff --git a/clang/test/Driver/arm64-markbti.S b/clang/test/Driver/arm64-markbti.S --- a/clang/test/Driver/arm64-markbti.S +++ b/clang/test/Driver/arm64-markbti.S @@ -1,10 +1,12 @@ // REQUIRES: aarch64-registered-target -// When -mmark-bti-property is passed the generated file object gets BTI marking. +// When -mmark-bti-property or -mbranch-protection=bti is passed the generated file object gets BTI marking. // RUN: %clang -target arm64-linux-none -mmark-bti-property -c -o - %s | llvm-readobj -n - | FileCheck -check-prefix=CHECK -check-prefix=CHECK_GEN %s // RUN: %clang -target arm64-linux-none -DNOTE_PRESENT -c %s -o - | llvm-readobj -n - | FileCheck -check-prefix=CHECK -check-prefix=CHECK_PRESET %s // RUN: %clang -target arm64-linux-none -mmark-bti-property -DNOTE_PRESENT -c %s -o - | llvm-readobj -n - | FileCheck -check-prefix=CHECK -check-prefix=CHECK_PRESET %s // RUN: %clang -target arm64-linux-none -mmark-bti-property -DNOTE_PRESENT -c %s -o - 2>&1 | FileCheck -check-prefix=CHECK_WARNING %s +// RUN: %clang -target arm64-linux-none -mbranch-protection=bti -c -o - %s | llvm-readobj -n - | FileCheck -check-prefix=CHECK -check-prefix=CHECK_GEN %s +// RUN: %clang -target arm64-linux-none -mbranch-protection=bti -DNOTE_PRESENT -c %s -o - 2>&1 | FileCheck -check-prefix=CHECK_WARNING %s // // CHECK_WARNING: The .note.gnu.property is not emitted because it is already present. // CHECK: Name: .note.gnu.property