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