diff options
author | Ties Stuij <ties.stuij@arm.com> | 2021-12-01 10:22:19 +0000 |
---|---|---|
committer | Ties Stuij <ties.stuij@arm.com> | 2021-12-01 10:37:16 +0000 |
commit | e3b2f0226bc09f16d5cdba9b94d1db3f15ee7d4a (patch) | |
tree | 7a81fa15d02f269f62fecce7fdae5ad8faab2191 /llvm/lib/Support/TargetParser.cpp | |
parent | 6d41de380f223c8da02fd4d6a7f7dd1e7a404a24 (diff) | |
download | llvm-e3b2f0226bc09f16d5cdba9b94d1db3f15ee7d4a.zip llvm-e3b2f0226bc09f16d5cdba9b94d1db3f15ee7d4a.tar.gz llvm-e3b2f0226bc09f16d5cdba9b94d1db3f15ee7d4a.tar.bz2 |
[clang][ARM] PACBTI-M frontend support
Handle branch protection option on the commandline as well as a function
attribute. One patch for both mechanisms, as they use the same underlying
parsing mechanism.
These are recorded in a set of LLVM IR module-level attributes like we do for
AArch64 PAC/BTI (see https://reviews.llvm.org/D85649):
- command-line options are "translated" to module-level LLVM IR
attributes (metadata).
- functions have PAC/BTI specific attributes iff the
__attribute__((target("branch-protection=...))) was used in the function
declaration.
- command-line option -mbranch-protection to armclang targeting Arm,
following this grammar:
branch-protection ::= "-mbranch-protection=" <protection>
protection ::= "none" | "standard" | "bti" [ "+" <pac-ret-clause> ]
| <pac-ret-clause> [ "+" "bti"]
pac-ret-clause ::= "pac-ret" [ "+" <pac-ret-option> ]
pac-ret-option ::= "leaf" ["+" "b-key"] | "b-key" ["+" "leaf"]
b-key is simply a placeholder to make it consistent with AArch64's
version. In Arm, however, it triggers a warning informing that b-key is
unsupported and a-key will be selected instead.
- Handle _attribute_((target(("branch-protection=..."))) for AArch32 with the
same grammer as the commandline options.
This patch is part of a series that adds support for the PACBTI-M extension of
the Armv8.1-M architecture, as detailed here:
https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/armv8-1-m-pointer-authentication-and-branch-target-identification-extension
The PACBTI-M specification can be found in the Armv8-M Architecture Reference
Manual:
https://developer.arm.com/documentation/ddi0553/latest
The following people contributed to this patch:
- Momchil Velikov
- Victor Campos
- Ties Stuij
Reviewed By: vhscampos
Differential Revision: https://reviews.llvm.org/D112421
Diffstat (limited to 'llvm/lib/Support/TargetParser.cpp')
-rw-r--r-- | llvm/lib/Support/TargetParser.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/llvm/lib/Support/TargetParser.cpp b/llvm/lib/Support/TargetParser.cpp index 1dadce4..4acc23d 100644 --- a/llvm/lib/Support/TargetParser.cpp +++ b/llvm/lib/Support/TargetParser.cpp @@ -333,3 +333,51 @@ bool getCPUFeaturesExceptStdExt(CPUKind Kind, } // namespace RISCV } // namespace llvm + +// Parse a branch protection specification, which has the form +// standard | none | [bti,pac-ret[+b-key,+leaf]*] +// 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) { + PBP = {"none", "a_key", false}; + if (Spec == "none") + return true; // defaults are ok + + if (Spec == "standard") { + PBP.Scope = "non-leaf"; + PBP.BranchTargetEnforcement = true; + return true; + } + + SmallVector<StringRef, 4> Opts; + Spec.split(Opts, "+"); + for (int I = 0, E = Opts.size(); I != E; ++I) { + StringRef Opt = Opts[I].trim(); + if (Opt == "bti") { + PBP.BranchTargetEnforcement = true; + continue; + } + if (Opt == "pac-ret") { + PBP.Scope = "non-leaf"; + for (; I + 1 != E; ++I) { + StringRef PACOpt = Opts[I + 1].trim(); + if (PACOpt == "leaf") + PBP.Scope = "all"; + else if (PACOpt == "b-key") + PBP.Key = "b_key"; + else + break; + } + continue; + } + if (Opt == "") + Err = "<empty>"; + else + Err = Opt; + return false; + } + + return true; +} |