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
anchor()14 void ARMFunctionInfo::anchor() {}
15
GetBranchTargetEnforcement(const Function & F,const ARMSubtarget * Subtarget)16 static bool GetBranchTargetEnforcement(const Function &F,
17 const ARMSubtarget *Subtarget) {
18 if (!Subtarget->isMClass() || !Subtarget->hasV7Ops())
19 return false;
20
21 if (!F.hasFnAttribute("branch-target-enforcement")) {
22 if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
23 F.getParent()->getModuleFlag("branch-target-enforcement")))
24 return BTE->getZExtValue();
25 return false;
26 }
27
28 const StringRef BTIEnable =
29 F.getFnAttribute("branch-target-enforcement").getValueAsString();
30 assert(BTIEnable.equals_insensitive("true") ||
31 BTIEnable.equals_insensitive("false"));
32 return BTIEnable.equals_insensitive("true");
33 }
34
35 // The pair returns values for the ARMFunctionInfo members
36 // SignReturnAddress and SignReturnAddressAll respectively.
GetSignReturnAddress(const Function & F)37 static std::pair<bool, bool> GetSignReturnAddress(const Function &F) {
38 if (!F.hasFnAttribute("sign-return-address")) {
39 const Module &M = *F.getParent();
40 if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
41 M.getModuleFlag("sign-return-address"))) {
42 if (Sign->getZExtValue()) {
43 if (const auto *All = mdconst::extract_or_null<ConstantInt>(
44 M.getModuleFlag("sign-return-address-all")))
45 return {true, All->getZExtValue()};
46 return {true, false};
47 }
48 }
49 return {false, false};
50 }
51
52 StringRef Scope = F.getFnAttribute("sign-return-address").getValueAsString();
53 if (Scope.equals("none"))
54 return {false, false};
55
56 if (Scope.equals("all"))
57 return {true, true};
58
59 assert(Scope.equals("non-leaf"));
60 return {true, false};
61 }
62
ARMFunctionInfo(const Function & F,const ARMSubtarget * Subtarget)63 ARMFunctionInfo::ARMFunctionInfo(const Function &F,
64 const ARMSubtarget *Subtarget)
65 : isThumb(Subtarget->isThumb()), hasThumb2(Subtarget->hasThumb2()),
66 IsCmseNSEntry(F.hasFnAttribute("cmse_nonsecure_entry")),
67 IsCmseNSCall(F.hasFnAttribute("cmse_nonsecure_call")),
68 BranchTargetEnforcement(GetBranchTargetEnforcement(F, Subtarget)) {
69 if (Subtarget->isMClass() && Subtarget->hasV7Ops())
70 std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F);
71 }
72
73 MachineFunctionInfo *
clone(BumpPtrAllocator & Allocator,MachineFunction & DestMF,const DenseMap<MachineBasicBlock *,MachineBasicBlock * > & Src2DstMBB) const74 ARMFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
75 const DenseMap<MachineBasicBlock *, MachineBasicBlock *>
76 &Src2DstMBB) const {
77 return DestMF.cloneInfo<ARMFunctionInfo>(*this);
78 }
79