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 164824e7fdSDimitry Andric static bool GetBranchTargetEnforcement(MachineFunction &MF) { 174824e7fdSDimitry Andric const auto &Subtarget = MF.getSubtarget<ARMSubtarget>(); 184824e7fdSDimitry Andric if (!Subtarget.isMClass() || !Subtarget.hasV7Ops()) 194824e7fdSDimitry Andric return false; 204824e7fdSDimitry Andric 214824e7fdSDimitry Andric const Function &F = MF.getFunction(); 224824e7fdSDimitry Andric if (!F.hasFnAttribute("branch-target-enforcement")) { 234824e7fdSDimitry Andric if (const auto *BTE = mdconst::extract_or_null<ConstantInt>( 244824e7fdSDimitry Andric F.getParent()->getModuleFlag("branch-target-enforcement"))) 254824e7fdSDimitry Andric return BTE->getZExtValue(); 264824e7fdSDimitry Andric return false; 274824e7fdSDimitry Andric } 284824e7fdSDimitry Andric 294824e7fdSDimitry Andric const StringRef BTIEnable = 304824e7fdSDimitry Andric F.getFnAttribute("branch-target-enforcement").getValueAsString(); 314824e7fdSDimitry Andric assert(BTIEnable.equals_insensitive("true") || 324824e7fdSDimitry Andric BTIEnable.equals_insensitive("false")); 334824e7fdSDimitry Andric return BTIEnable.equals_insensitive("true"); 344824e7fdSDimitry Andric } 354824e7fdSDimitry Andric 364824e7fdSDimitry Andric // The pair returns values for the ARMFunctionInfo members 374824e7fdSDimitry Andric // SignReturnAddress and SignReturnAddressAll respectively. 384824e7fdSDimitry Andric static std::pair<bool, bool> GetSignReturnAddress(const Function &F) { 394824e7fdSDimitry Andric if (!F.hasFnAttribute("sign-return-address")) { 404824e7fdSDimitry Andric const Module &M = *F.getParent(); 414824e7fdSDimitry Andric if (const auto *Sign = mdconst::extract_or_null<ConstantInt>( 424824e7fdSDimitry Andric M.getModuleFlag("sign-return-address"))) { 434824e7fdSDimitry Andric if (Sign->getZExtValue()) { 444824e7fdSDimitry Andric if (const auto *All = mdconst::extract_or_null<ConstantInt>( 454824e7fdSDimitry Andric M.getModuleFlag("sign-return-address-all"))) 464824e7fdSDimitry Andric return {true, All->getZExtValue()}; 474824e7fdSDimitry Andric return {true, false}; 484824e7fdSDimitry Andric } 494824e7fdSDimitry Andric } 504824e7fdSDimitry Andric return {false, false}; 514824e7fdSDimitry Andric } 524824e7fdSDimitry Andric 534824e7fdSDimitry Andric StringRef Scope = F.getFnAttribute("sign-return-address").getValueAsString(); 544824e7fdSDimitry Andric if (Scope.equals("none")) 554824e7fdSDimitry Andric return {false, false}; 564824e7fdSDimitry Andric 574824e7fdSDimitry Andric if (Scope.equals("all")) 584824e7fdSDimitry Andric return {true, true}; 594824e7fdSDimitry Andric 604824e7fdSDimitry Andric assert(Scope.equals("non-leaf")); 614824e7fdSDimitry Andric return {true, false}; 624824e7fdSDimitry Andric } 634824e7fdSDimitry 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")), 684824e7fdSDimitry Andric IsCmseNSCall(MF.getFunction().hasFnAttribute("cmse_nonsecure_call")), 694824e7fdSDimitry Andric BranchTargetEnforcement(GetBranchTargetEnforcement(MF)) { 704824e7fdSDimitry Andric 714824e7fdSDimitry Andric const auto &Subtarget = MF.getSubtarget<ARMSubtarget>(); 724824e7fdSDimitry Andric if (Subtarget.isMClass() && Subtarget.hasV7Ops()) 734824e7fdSDimitry Andric std::tie(SignReturnAddress, SignReturnAddressAll) = 744824e7fdSDimitry Andric GetSignReturnAddress(MF.getFunction()); 754824e7fdSDimitry Andric } 76*81ad6265SDimitry Andric 77*81ad6265SDimitry Andric MachineFunctionInfo * 78*81ad6265SDimitry Andric ARMFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, 79*81ad6265SDimitry Andric const DenseMap<MachineBasicBlock *, MachineBasicBlock *> 80*81ad6265SDimitry Andric &Src2DstMBB) const { 81*81ad6265SDimitry Andric return DestMF.cloneInfo<ARMFunctionInfo>(*this); 82*81ad6265SDimitry Andric } 83