Skip to content

Commit

Permalink
[AArch64] Enable PAuthLR by default for standard
Browse files Browse the repository at this point in the history
 branch protection when the feature is available

Currently, LLVM implements the `standard` option as `bti+pac-ret`
for ARM and AArch64. Following discussions with the GNU
developemnt team within Arm it was decided to align the
behaviour of `standard` to match across the different compilers.

To ensure the behaviour is aligned. LLVM has been updated to
implement `standard` as `bti+pac-ret+pc` by default when
`+pauth-lr` is passed as part of the `-march` argument.
  • Loading branch information
Stylie777 committed Apr 30, 2024
1 parent b21ee48 commit 313c69e
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 4 deletions.
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
BranchProtectionInfo &BPI,
StringRef &Err) const {
llvm::ARM::ParsedBranchProtection PBP;
if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))
if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err, HasPAuthLR))
return false;

BPI.SignReturnAddr =
Expand Down
18 changes: 17 additions & 1 deletion clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1511,7 +1511,23 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
} else {
StringRef DiagMsg;
llvm::ARM::ParsedBranchProtection PBP;
if (!llvm::ARM::parseBranchProtection(A->getValue(), PBP, DiagMsg))

// To know if we need to enable PAuth-LR As part of the standard branch
// protection option, it needs to be determined if the feature has been
// activated in the `march` argument. This information is stored within the
// CmdArgs variable and can be found using a search.
if (isAArch64) {
auto isPAuthLR = [](const char *member) {
llvm::AArch64::ExtensionInfo pauthlr_extension =
llvm::AArch64::getExtensionByID(llvm::AArch64::AEK_PAUTHLR);
return (pauthlr_extension.Feature.compare(member) == 0);
};

if (std::any_of(CmdArgs.begin(), CmdArgs.end(), isPAuthLR))
EnablePAuthLR = true;
}
if (!llvm::ARM::parseBranchProtection(A->getValue(), PBP, DiagMsg,
EnablePAuthLR))
D.Diag(diag::err_drv_unsupported_option_argument)
<< A->getSpelling() << DiagMsg;
if (!isAArch64 && PBP.Key == "b_key")
Expand Down
4 changes: 4 additions & 0 deletions clang/test/Preprocessor/aarch64-target-features.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,9 @@
// ================== Check Armv9.5-A Pointer Authentication Enhancements(PAuth_LR).
// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-LR-OFF %s
// RUN: %clang -target arm64-none-linux-gnu -march=armv9.5-a -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-LR-OFF %s
// RUN: %clang -target arm64-none-linux-gnu -march=armv9.5-a -mbranch-protection=standard -x c -E -dM %s -o - | FileCheck -check-prefixes=CHECK-PAUTH-LR-OFF,CHECK-BRANCH-PROTECTION-NO-PC %s
// RUN: %clang -target arm64-none-linux-gnu -march=armv9.5-a+pauth-lr -mbranch-protection=standard -x c -E -dM %s -o - | FileCheck -check-prefixes=CHECK-PAUTH-LR,CHECK-BRANCH-PROTECTION-PC %s
// RUN: %clang -target arm64-none-linux-gnu -march=armv9.5-a+nopauth-lr -mbranch-protection=standard -x c -E -dM %s -o - | FileCheck -check-prefixes=CHECK-PAUTH-LR-OFF,CHECK-BRANCH-PROTECTION-NO-PC %s
// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a+pauth -mbranch-protection=none -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-LR-OFF %s
// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a+pauth-lr -mbranch-protection=none -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-LR %s
// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a+pauth-lr -mbranch-protection=bti -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-LR %s
Expand All @@ -636,6 +639,7 @@
// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a+pauth-lr -mbranch-protection=pac-ret+pc+b-key -x c -E -dM %s -o - | FileCheck -check-prefixes=CHECK-PAUTH-LR,CHECK-BRANCH-PROTECTION-PC-BKEY %s
// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a+pauth-lr -mbranch-protection=pac-ret+pc+leaf -x c -E -dM %s -o - | FileCheck -check-prefixes=CHECK-PAUTH-LR,CHECK-BRANCH-PROTECTION-PC-LEAF %s
// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a+pauth-lr -mbranch-protection=pac-ret+pc+leaf+b-key -x c -E -dM %s -o - | FileCheck -check-prefixes=CHECK-PAUTH-LR,CHECK-BRANCH-PROTECTION-PC-LEAF-BKEY %s
// CHECK-BRANCH-PROTECTION-NO-PC: #define __ARM_FEATURE_PAC_DEFAULT 1
// CHECK-BRANCH-PROTECTION-PC: #define __ARM_FEATURE_PAC_DEFAULT 9
// CHECK-BRANCH-PROTECTION-PC-BKEY: #define __ARM_FEATURE_PAC_DEFAULT 10
// CHECK-BRANCH-PROTECTION-PC-LEAF: #define __ARM_FEATURE_PAC_DEFAULT 13
Expand Down
5 changes: 5 additions & 0 deletions llvm/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ Changes to the AArch64 Backend
* Added support for Cortex-A78AE, Cortex-A520AE, Cortex-A720AE,
Neoverse-N3, Neoverse-V3 and Neoverse-V3AE CPUs.

* `-mbranch-protection=standard` now enables FEAT_PAuth_LR by
default when the feature is enabled. The new behaviour results
in `standard` being equal to `bti+pac-ret+pc` when `+pauth-lr`
is passed as part of `-mcpu=`options.

Changes to the AMDGPU Backend
-----------------------------

Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/TargetParser/ARMTargetParserCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ struct ParsedBranchProtection {
};

bool parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
StringRef &Err);
StringRef &Err, bool EnablePAuthLR = false);

} // namespace ARM
} // namespace llvm
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/TargetParser/ARMTargetParserCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ ARM::EndianKind ARM::parseArchEndian(StringRef Arch) {
// 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) {
StringRef &Err, bool EnablePAuthLR) {
PBP = {"none", "a_key", false, false, false};
if (Spec == "none")
return true; // defaults are ok
Expand All @@ -148,6 +148,7 @@ bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
PBP.Scope = "non-leaf";
PBP.BranchTargetEnforcement = true;
PBP.GuardedControlStack = true;
PBP.BranchProtectionPAuthLR = EnablePAuthLR;
return true;
}

Expand Down

0 comments on commit 313c69e

Please sign in to comment.