10b57cec5SDimitry Andric //===-- ARMMachineFunctionInfo.cpp - ARM machine function info ------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "ARMMachineFunctionInfo.h" 100b57cec5SDimitry Andric #include "ARMSubtarget.h" 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric using namespace llvm; 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric void ARMFunctionInfo::anchor() {} 150b57cec5SDimitry Andric 16*4824e7fdSDimitry Andric static bool GetBranchTargetEnforcement(MachineFunction &MF) { 17*4824e7fdSDimitry Andric const auto &Subtarget = MF.getSubtarget<ARMSubtarget>(); 18*4824e7fdSDimitry Andric if (!Subtarget.isMClass() || !Subtarget.hasV7Ops()) 19*4824e7fdSDimitry Andric return false; 20*4824e7fdSDimitry Andric 21*4824e7fdSDimitry Andric const Function &F = MF.getFunction(); 22*4824e7fdSDimitry Andric if (!F.hasFnAttribute("branch-target-enforcement")) { 23*4824e7fdSDimitry Andric if (const auto *BTE = mdconst::extract_or_null<ConstantInt>( 24*4824e7fdSDimitry Andric F.getParent()->getModuleFlag("branch-target-enforcement"))) 25*4824e7fdSDimitry Andric return BTE->getZExtValue(); 26*4824e7fdSDimitry Andric return false; 27*4824e7fdSDimitry Andric } 28*4824e7fdSDimitry Andric 29*4824e7fdSDimitry Andric const StringRef BTIEnable = 30*4824e7fdSDimitry Andric F.getFnAttribute("branch-target-enforcement").getValueAsString(); 31*4824e7fdSDimitry Andric assert(BTIEnable.equals_insensitive("true") || 32*4824e7fdSDimitry Andric BTIEnable.equals_insensitive("false")); 33*4824e7fdSDimitry Andric return BTIEnable.equals_insensitive("true"); 34*4824e7fdSDimitry Andric } 35*4824e7fdSDimitry Andric 36*4824e7fdSDimitry Andric // The pair returns values for the ARMFunctionInfo members 37*4824e7fdSDimitry Andric // SignReturnAddress and SignReturnAddressAll respectively. 38*4824e7fdSDimitry Andric static std::pair<bool, bool> GetSignReturnAddress(const Function &F) { 39*4824e7fdSDimitry Andric if (!F.hasFnAttribute("sign-return-address")) { 40*4824e7fdSDimitry Andric const Module &M = *F.getParent(); 41*4824e7fdSDimitry Andric if (const auto *Sign = mdconst::extract_or_null<ConstantInt>( 42*4824e7fdSDimitry Andric M.getModuleFlag("sign-return-address"))) { 43*4824e7fdSDimitry Andric if (Sign->getZExtValue()) { 44*4824e7fdSDimitry Andric if (const auto *All = mdconst::extract_or_null<ConstantInt>( 45*4824e7fdSDimitry Andric M.getModuleFlag("sign-return-address-all"))) 46*4824e7fdSDimitry Andric return {true, All->getZExtValue()}; 47*4824e7fdSDimitry Andric return {true, false}; 48*4824e7fdSDimitry Andric } 49*4824e7fdSDimitry Andric } 50*4824e7fdSDimitry Andric return {false, false}; 51*4824e7fdSDimitry Andric } 52*4824e7fdSDimitry Andric 53*4824e7fdSDimitry Andric StringRef Scope = F.getFnAttribute("sign-return-address").getValueAsString(); 54*4824e7fdSDimitry Andric if (Scope.equals("none")) 55*4824e7fdSDimitry Andric return {false, false}; 56*4824e7fdSDimitry Andric 57*4824e7fdSDimitry Andric if (Scope.equals("all")) 58*4824e7fdSDimitry Andric return {true, true}; 59*4824e7fdSDimitry Andric 60*4824e7fdSDimitry Andric assert(Scope.equals("non-leaf")); 61*4824e7fdSDimitry Andric return {true, false}; 62*4824e7fdSDimitry Andric } 63*4824e7fdSDimitry Andric 640b57cec5SDimitry Andric ARMFunctionInfo::ARMFunctionInfo(MachineFunction &MF) 650b57cec5SDimitry Andric : isThumb(MF.getSubtarget<ARMSubtarget>().isThumb()), 665ffd83dbSDimitry Andric hasThumb2(MF.getSubtarget<ARMSubtarget>().hasThumb2()), 675ffd83dbSDimitry Andric IsCmseNSEntry(MF.getFunction().hasFnAttribute("cmse_nonsecure_entry")), 68*4824e7fdSDimitry Andric IsCmseNSCall(MF.getFunction().hasFnAttribute("cmse_nonsecure_call")), 69*4824e7fdSDimitry Andric BranchTargetEnforcement(GetBranchTargetEnforcement(MF)) { 70*4824e7fdSDimitry Andric 71*4824e7fdSDimitry Andric const auto &Subtarget = MF.getSubtarget<ARMSubtarget>(); 72*4824e7fdSDimitry Andric if (Subtarget.isMClass() && Subtarget.hasV7Ops()) 73*4824e7fdSDimitry Andric std::tie(SignReturnAddress, SignReturnAddressAll) = 74*4824e7fdSDimitry Andric GetSignReturnAddress(MF.getFunction()); 75*4824e7fdSDimitry Andric } 76