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