summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp57
1 files changed, 56 insertions, 1 deletions
diff --git a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp
index 507c3e69b3a4..308d5e7889f2 100644
--- a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp
@@ -13,8 +13,63 @@ using namespace llvm;
void ARMFunctionInfo::anchor() {}
+static bool GetBranchTargetEnforcement(MachineFunction &MF) {
+ const auto &Subtarget = MF.getSubtarget<ARMSubtarget>();
+ if (!Subtarget.isMClass() || !Subtarget.hasV7Ops())
+ return false;
+
+ const Function &F = MF.getFunction();
+ if (!F.hasFnAttribute("branch-target-enforcement")) {
+ if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
+ F.getParent()->getModuleFlag("branch-target-enforcement")))
+ return BTE->getZExtValue();
+ return false;
+ }
+
+ const StringRef BTIEnable =
+ F.getFnAttribute("branch-target-enforcement").getValueAsString();
+ assert(BTIEnable.equals_insensitive("true") ||
+ BTIEnable.equals_insensitive("false"));
+ return BTIEnable.equals_insensitive("true");
+}
+
+// The pair returns values for the ARMFunctionInfo members
+// SignReturnAddress and SignReturnAddressAll respectively.
+static std::pair<bool, bool> GetSignReturnAddress(const Function &F) {
+ if (!F.hasFnAttribute("sign-return-address")) {
+ const Module &M = *F.getParent();
+ if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
+ M.getModuleFlag("sign-return-address"))) {
+ if (Sign->getZExtValue()) {
+ if (const auto *All = mdconst::extract_or_null<ConstantInt>(
+ M.getModuleFlag("sign-return-address-all")))
+ return {true, All->getZExtValue()};
+ return {true, false};
+ }
+ }
+ return {false, false};
+ }
+
+ StringRef Scope = F.getFnAttribute("sign-return-address").getValueAsString();
+ if (Scope.equals("none"))
+ return {false, false};
+
+ if (Scope.equals("all"))
+ return {true, true};
+
+ assert(Scope.equals("non-leaf"));
+ return {true, false};
+}
+
ARMFunctionInfo::ARMFunctionInfo(MachineFunction &MF)
: isThumb(MF.getSubtarget<ARMSubtarget>().isThumb()),
hasThumb2(MF.getSubtarget<ARMSubtarget>().hasThumb2()),
IsCmseNSEntry(MF.getFunction().hasFnAttribute("cmse_nonsecure_entry")),
- IsCmseNSCall(MF.getFunction().hasFnAttribute("cmse_nonsecure_call")) {}
+ IsCmseNSCall(MF.getFunction().hasFnAttribute("cmse_nonsecure_call")),
+ BranchTargetEnforcement(GetBranchTargetEnforcement(MF)) {
+
+ const auto &Subtarget = MF.getSubtarget<ARMSubtarget>();
+ if (Subtarget.isMClass() && Subtarget.hasV7Ops())
+ std::tie(SignReturnAddress, SignReturnAddressAll) =
+ GetSignReturnAddress(MF.getFunction());
+}