LLVM  14.0.0git
ARMSLSHardening.cpp
Go to the documentation of this file.
1 //===- ARMSLSHardening.cpp - Harden Straight Line Missspeculation ---------===//
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 // This file contains a pass to insert code to mitigate against side channel
10 // vulnerabilities that may happen under straight line miss-speculation.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "ARM.h"
15 #include "ARMInstrInfo.h"
16 #include "ARMSubtarget.h"
24 #include "llvm/IR/DebugLoc.h"
25 #include <cassert>
26 
27 using namespace llvm;
28 
29 #define DEBUG_TYPE "arm-sls-hardening"
30 
31 #define ARM_SLS_HARDENING_NAME "ARM sls hardening pass"
32 
33 namespace {
34 
35 class ARMSLSHardening : public MachineFunctionPass {
36 public:
37  const TargetInstrInfo *TII;
38  const ARMSubtarget *ST;
39 
40  static char ID;
41 
42  ARMSLSHardening() : MachineFunctionPass(ID) {
44  }
45 
46  bool runOnMachineFunction(MachineFunction &Fn) override;
47 
48  StringRef getPassName() const override { return ARM_SLS_HARDENING_NAME; }
49 
50  void getAnalysisUsage(AnalysisUsage &AU) const override {
51  AU.setPreservesCFG();
53  }
54 
55 private:
56  bool hardenReturnsAndBRs(MachineBasicBlock &MBB) const;
57  bool hardenIndirectCalls(MachineBasicBlock &MBB) const;
59  ConvertIndirectCallToIndirectJump(MachineBasicBlock &MBB,
61 };
62 
63 } // end anonymous namespace
64 
65 char ARMSLSHardening::ID = 0;
66 
67 INITIALIZE_PASS(ARMSLSHardening, "arm-sls-hardening",
68  ARM_SLS_HARDENING_NAME, false, false)
69 
70 static void insertSpeculationBarrier(const ARMSubtarget *ST,
75  assert(MBBI != MBB.begin() &&
76  "Must not insert SpeculationBarrierEndBB as only instruction in MBB.");
77  assert(std::prev(MBBI)->isBarrier() &&
78  "SpeculationBarrierEndBB must only follow unconditional control flow "
79  "instructions.");
80  assert(std::prev(MBBI)->isTerminator() &&
81  "SpeculationBarrierEndBB must only follow terminators.");
82  const TargetInstrInfo *TII = ST->getInstrInfo();
83  assert(ST->hasDataBarrier() || ST->hasSB());
84  bool ProduceSB = ST->hasSB() && !AlwaysUseISBDSB;
85  unsigned BarrierOpc =
86  ProduceSB ? (ST->isThumb() ? ARM::t2SpeculationBarrierSBEndBB
87  : ARM::SpeculationBarrierSBEndBB)
88  : (ST->isThumb() ? ARM::t2SpeculationBarrierISBDSBEndBB
89  : ARM::SpeculationBarrierISBDSBEndBB);
90  if (MBBI == MBB.end() || !isSpeculationBarrierEndBBOpcode(MBBI->getOpcode()))
91  BuildMI(MBB, MBBI, DL, TII->get(BarrierOpc));
92 }
93 
94 bool ARMSLSHardening::runOnMachineFunction(MachineFunction &MF) {
95  ST = &MF.getSubtarget<ARMSubtarget>();
96  TII = MF.getSubtarget().getInstrInfo();
97 
98  bool Modified = false;
99  for (auto &MBB : MF) {
100  Modified |= hardenReturnsAndBRs(MBB);
101  Modified |= hardenIndirectCalls(MBB);
102  }
103 
104  return Modified;
105 }
106 
107 bool ARMSLSHardening::hardenReturnsAndBRs(MachineBasicBlock &MBB) const {
108  if (!ST->hardenSlsRetBr())
109  return false;
110  assert(!ST->isThumb1Only());
111  bool Modified = false;
114  for (; MBBI != E; MBBI = NextMBBI) {
115  MachineInstr &MI = *MBBI;
116  NextMBBI = std::next(MBBI);
118  assert(MI.isTerminator());
120  insertSpeculationBarrier(ST, MBB, std::next(MBBI), MI.getDebugLoc());
121  Modified = true;
122  }
123  }
124  return Modified;
125 }
126 
127 static const char SLSBLRNamePrefix[] = "__llvm_slsblr_thunk_";
128 
129 static const struct ThunkNameRegMode {
130  const char* Name;
132  bool isThumb;
133 } SLSBLRThunks[] = {
134  {"__llvm_slsblr_thunk_arm_r0", ARM::R0, false},
135  {"__llvm_slsblr_thunk_arm_r1", ARM::R1, false},
136  {"__llvm_slsblr_thunk_arm_r2", ARM::R2, false},
137  {"__llvm_slsblr_thunk_arm_r3", ARM::R3, false},
138  {"__llvm_slsblr_thunk_arm_r4", ARM::R4, false},
139  {"__llvm_slsblr_thunk_arm_r5", ARM::R5, false},
140  {"__llvm_slsblr_thunk_arm_r6", ARM::R6, false},
141  {"__llvm_slsblr_thunk_arm_r7", ARM::R7, false},
142  {"__llvm_slsblr_thunk_arm_r8", ARM::R8, false},
143  {"__llvm_slsblr_thunk_arm_r9", ARM::R9, false},
144  {"__llvm_slsblr_thunk_arm_r10", ARM::R10, false},
145  {"__llvm_slsblr_thunk_arm_r11", ARM::R11, false},
146  {"__llvm_slsblr_thunk_arm_sp", ARM::SP, false},
147  {"__llvm_slsblr_thunk_arm_pc", ARM::PC, false},
148  {"__llvm_slsblr_thunk_thumb_r0", ARM::R0, true},
149  {"__llvm_slsblr_thunk_thumb_r1", ARM::R1, true},
150  {"__llvm_slsblr_thunk_thumb_r2", ARM::R2, true},
151  {"__llvm_slsblr_thunk_thumb_r3", ARM::R3, true},
152  {"__llvm_slsblr_thunk_thumb_r4", ARM::R4, true},
153  {"__llvm_slsblr_thunk_thumb_r5", ARM::R5, true},
154  {"__llvm_slsblr_thunk_thumb_r6", ARM::R6, true},
155  {"__llvm_slsblr_thunk_thumb_r7", ARM::R7, true},
156  {"__llvm_slsblr_thunk_thumb_r8", ARM::R8, true},
157  {"__llvm_slsblr_thunk_thumb_r9", ARM::R9, true},
158  {"__llvm_slsblr_thunk_thumb_r10", ARM::R10, true},
159  {"__llvm_slsblr_thunk_thumb_r11", ARM::R11, true},
160  {"__llvm_slsblr_thunk_thumb_sp", ARM::SP, true},
161  {"__llvm_slsblr_thunk_thumb_pc", ARM::PC, true},
162 };
163 
164 namespace {
165 struct SLSBLRThunkInserter : ThunkInserter<SLSBLRThunkInserter> {
166  const char *getThunkPrefix() { return SLSBLRNamePrefix; }
167  bool mayUseThunk(const MachineFunction &MF) {
168  ComdatThunks &= !MF.getSubtarget<ARMSubtarget>().hardenSlsNoComdat();
169  // FIXME: This could also check if there are any indirect calls in the
170  // function to more accurately reflect if a thunk will be needed.
171  return MF.getSubtarget<ARMSubtarget>().hardenSlsBlr();
172  }
173  void insertThunks(MachineModuleInfo &MMI);
174  void populateThunk(MachineFunction &MF);
175 
176 private:
177  bool ComdatThunks = true;
178 };
179 } // namespace
180 
181 void SLSBLRThunkInserter::insertThunks(MachineModuleInfo &MMI) {
182  // FIXME: It probably would be possible to filter which thunks to produce
183  // based on which registers are actually used in indirect calls in this
184  // function. But would that be a worthwhile optimization?
185  for (auto T : SLSBLRThunks)
186  createThunkFunction(MMI, T.Name, ComdatThunks);
187 }
188 
189 void SLSBLRThunkInserter::populateThunk(MachineFunction &MF) {
190  // FIXME: How to better communicate Register number, rather than through
191  // name and lookup table?
192  assert(MF.getName().startswith(getThunkPrefix()));
193  auto ThunkIt = llvm::find_if(
194  SLSBLRThunks, [&MF](auto T) { return T.Name == MF.getName(); });
195  assert(ThunkIt != std::end(SLSBLRThunks));
196  Register ThunkReg = ThunkIt->Reg;
197  bool isThumb = ThunkIt->isThumb;
198 
199  const TargetInstrInfo *TII = MF.getSubtarget<ARMSubtarget>().getInstrInfo();
200  MachineBasicBlock *Entry = &MF.front();
201  Entry->clear();
202 
203  // These thunks need to consist of the following instructions:
204  // __llvm_slsblr_thunk_(arm/thumb)_rN:
205  // bx rN
206  // barrierInsts
207  Entry->addLiveIn(ThunkReg);
208  if (isThumb)
209  BuildMI(Entry, DebugLoc(), TII->get(ARM::tBX))
210  .addReg(ThunkReg)
211  .add(predOps(ARMCC::AL));
212  else
213  BuildMI(Entry, DebugLoc(), TII->get(ARM::BX))
214  .addReg(ThunkReg);
215 
216  // Make sure the thunks do not make use of the SB extension in case there is
217  // a function somewhere that will call to it that for some reason disabled
218  // the SB extension locally on that function, even though it's enabled for
219  // the module otherwise. Therefore set AlwaysUseISBSDB to true.
220  insertSpeculationBarrier(&MF.getSubtarget<ARMSubtarget>(), *Entry,
221  Entry->end(), DebugLoc(), true /*AlwaysUseISBDSB*/);
222 }
223 
224 MachineBasicBlock &ARMSLSHardening::ConvertIndirectCallToIndirectJump(
226  // Transform an indirect call to an indirect jump as follows:
227  // Before:
228  // |-----------------------------|
229  // | ... |
230  // | instI |
231  // | BLX rN |
232  // | instJ |
233  // | ... |
234  // |-----------------------------|
235  //
236  // After:
237  // |---------- -------------------------|
238  // | ... |
239  // | instI |
240  // | *call* __llvm_slsblr_thunk_mode_xN |
241  // | instJ |
242  // | ... |
243  // |--------------------------------------|
244  //
245  // __llvm_slsblr_thunk_mode_xN:
246  // |-----------------------------|
247  // | BX rN |
248  // | barrierInsts |
249  // |-----------------------------|
250  //
251  // The __llvm_slsblr_thunk_mode_xN thunks are created by the
252  // SLSBLRThunkInserter.
253  // This function merely needs to transform an indirect call to a direct call
254  // to __llvm_slsblr_thunk_xN.
256  assert(isIndirectCall(IndirectCall) && !IndirectCall.isReturn());
257  int RegOpIdxOnIndirectCall = -1;
258  bool isThumb;
259  switch (IndirectCall.getOpcode()) {
260  case ARM::BLX: // !isThumb2
261  case ARM::BLX_noip: // !isThumb2
262  isThumb = false;
263  RegOpIdxOnIndirectCall = 0;
264  break;
265  case ARM::tBLXr: // isThumb2
266  case ARM::tBLXr_noip: // isThumb2
267  isThumb = true;
268  RegOpIdxOnIndirectCall = 2;
269  break;
270  default:
271  llvm_unreachable("unhandled Indirect Call");
272  }
273 
274  Register Reg = IndirectCall.getOperand(RegOpIdxOnIndirectCall).getReg();
275  // Since linkers are allowed to clobber R12 on function calls, the above
276  // mitigation only works if the original indirect call instruction was not
277  // using R12. Code generation before must make sure that no indirect call
278  // using R12 was produced if the mitigation is enabled.
279  // Also, the transformation is incorrect if the indirect call uses LR, so
280  // also have to avoid that.
281  assert(Reg != ARM::R12 && Reg != ARM::LR);
282  bool RegIsKilled = IndirectCall.getOperand(RegOpIdxOnIndirectCall).isKill();
283 
284  DebugLoc DL = IndirectCall.getDebugLoc();
285 
286  MachineFunction &MF = *MBBI->getMF();
287  auto ThunkIt = llvm::find_if(SLSBLRThunks, [Reg, isThumb](auto T) {
288  return T.Reg == Reg && T.isThumb == isThumb;
289  });
290  assert(ThunkIt != std::end(SLSBLRThunks));
291  Module *M = MF.getFunction().getParent();
292  const GlobalValue *GV = cast<GlobalValue>(M->getNamedValue(ThunkIt->Name));
293 
294  MachineInstr *BL =
295  isThumb ? BuildMI(MBB, MBBI, DL, TII->get(ARM::tBL))
296  .addImm(IndirectCall.getOperand(0).getImm())
297  .addReg(IndirectCall.getOperand(1).getReg())
298  .addGlobalAddress(GV)
299  : BuildMI(MBB, MBBI, DL, TII->get(ARM::BL)).addGlobalAddress(GV);
300 
301  // Now copy the implicit operands from IndirectCall to BL and copy other
302  // necessary info.
303  // However, both IndirectCall and BL instructions implictly use SP and
304  // implicitly define LR. Blindly copying implicit operands would result in SP
305  // and LR operands to be present multiple times. While this may not be too
306  // much of an issue, let's avoid that for cleanliness, by removing those
307  // implicit operands from the BL created above before we copy over all
308  // implicit operands from the IndirectCall.
309  int ImpLROpIdx = -1;
310  int ImpSPOpIdx = -1;
311  for (unsigned OpIdx = BL->getNumExplicitOperands();
312  OpIdx < BL->getNumOperands(); OpIdx++) {
313  MachineOperand Op = BL->getOperand(OpIdx);
314  if (!Op.isReg())
315  continue;
316  if (Op.getReg() == ARM::LR && Op.isDef())
317  ImpLROpIdx = OpIdx;
318  if (Op.getReg() == ARM::SP && !Op.isDef())
319  ImpSPOpIdx = OpIdx;
320  }
321  assert(ImpLROpIdx != -1);
322  assert(ImpSPOpIdx != -1);
323  int FirstOpIdxToRemove = std::max(ImpLROpIdx, ImpSPOpIdx);
324  int SecondOpIdxToRemove = std::min(ImpLROpIdx, ImpSPOpIdx);
325  BL->RemoveOperand(FirstOpIdxToRemove);
326  BL->RemoveOperand(SecondOpIdxToRemove);
327  // Now copy over the implicit operands from the original IndirectCall
328  BL->copyImplicitOps(MF, IndirectCall);
329  MF.moveCallSiteInfo(&IndirectCall, BL);
330  // Also add the register called in the IndirectCall as being used in the
331  // called thunk.
332  BL->addOperand(MachineOperand::CreateReg(Reg, false /*isDef*/, true /*isImp*/,
333  RegIsKilled /*isKill*/));
334  // Remove IndirectCallinstruction
335  MBB.erase(MBBI);
336  return MBB;
337 }
338 
339 bool ARMSLSHardening::hardenIndirectCalls(MachineBasicBlock &MBB) const {
340  if (!ST->hardenSlsBlr())
341  return false;
342  bool Modified = false;
345  for (; MBBI != E; MBBI = NextMBBI) {
346  MachineInstr &MI = *MBBI;
347  NextMBBI = std::next(MBBI);
348  // Tail calls are both indirect calls and "returns".
349  // They are also indirect jumps, so should be handled by sls-harden-retbr,
350  // rather than sls-harden-blr.
351  if (isIndirectCall(MI) && !MI.isReturn()) {
352  ConvertIndirectCallToIndirectJump(MBB, MBBI);
353  Modified = true;
354  }
355  }
356  return Modified;
357 }
358 
359 
360 
362  return new ARMSLSHardening();
363 }
364 
365 namespace {
366 class ARMIndirectThunks : public MachineFunctionPass {
367 public:
368  static char ID;
369 
370  ARMIndirectThunks() : MachineFunctionPass(ID) {}
371 
372  StringRef getPassName() const override { return "ARM Indirect Thunks"; }
373 
374  bool doInitialization(Module &M) override;
375  bool runOnMachineFunction(MachineFunction &MF) override;
376 
377  void getAnalysisUsage(AnalysisUsage &AU) const override {
381  }
382 
383 private:
384  std::tuple<SLSBLRThunkInserter> TIs;
385 
386  // FIXME: When LLVM moves to C++17, these can become folds
387  template <typename... ThunkInserterT>
388  static void initTIs(Module &M,
389  std::tuple<ThunkInserterT...> &ThunkInserters) {
390  (void)std::initializer_list<int>{
391  (std::get<ThunkInserterT>(ThunkInserters).init(M), 0)...};
392  }
393  template <typename... ThunkInserterT>
394  static bool runTIs(MachineModuleInfo &MMI, MachineFunction &MF,
395  std::tuple<ThunkInserterT...> &ThunkInserters) {
396  bool Modified = false;
397  (void)std::initializer_list<int>{
398  Modified |= std::get<ThunkInserterT>(ThunkInserters).run(MMI, MF)...};
399  return Modified;
400  }
401 };
402 
403 } // end anonymous namespace
404 
405 char ARMIndirectThunks::ID = 0;
406 
408  return new ARMIndirectThunks();
409 }
410 
411 bool ARMIndirectThunks::doInitialization(Module &M) {
412  initTIs(M, TIs);
413  return false;
414 }
415 
416 bool ARMIndirectThunks::runOnMachineFunction(MachineFunction &MF) {
417  LLVM_DEBUG(dbgs() << getPassName() << '\n');
418  auto &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
419  return runTIs(MMI, MF, TIs);
420 }
ARMSubtarget.h
llvm::StringRef::startswith
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:286
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
MachineInstr.h
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
AlwaysUseISBDSB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc bool AlwaysUseISBDSB
Definition: ARMSLSHardening.cpp:74
llvm::MachineOperand::CreateReg
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
Definition: MachineOperand.h:791
llvm::ARMSubtarget
Definition: ARMSubtarget.h:46
T
llvm::MachineInstrBuilder::add
const MachineInstrBuilder & add(const MachineOperand &MO) const
Definition: MachineInstrBuilder.h:224
llvm::TargetSubtargetInfo::getInstrInfo
virtual const TargetInstrInfo * getInstrInfo() const
Definition: TargetSubtargetInfo.h:92
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
ThunkNameRegMode::Name
const char * Name
Definition: ARMSLSHardening.cpp:130
MachineBasicBlock.h
R4
#define R4(n)
llvm::MachineFunction::moveCallSiteInfo
void moveCallSiteInfo(const MachineInstr *Old, const MachineInstr *New)
Move the call site info from Old to \New call site info.
Definition: MachineFunction.cpp:949
llvm::sys::path::end
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:233
llvm::HexagonInstrInfo::isPredicated
bool isPredicated(const MachineInstr &MI) const override
Returns true if the instruction is already predicated.
Definition: HexagonInstrInfo.cpp:1580
llvm::ARCISD::BL
@ BL
Definition: ARCISelLowering.h:34
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:102
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::MachineBasicBlock::erase
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
Definition: MachineBasicBlock.cpp:1304
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::PseudoProbeType::IndirectCall
@ IndirectCall
R2
#define R2(n)
ThunkNameRegMode
Definition: ARMSLSHardening.cpp:129
llvm::MachineFunction::front
const MachineBasicBlock & front() const
Definition: MachineFunction.h:828
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition: TargetInstrInfo.h:97
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::initializeARMSLSHardeningPass
void initializeARMSLSHardeningPass(PassRegistry &)
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
false
Definition: StackSlotColoring.cpp:142
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
llvm::MachineModuleInfo
This class contains meta information specific to a module.
Definition: MachineModuleInfo.h:78
IndirectThunks.h
LoopDeletionResult::Modified
@ Modified
DebugLoc.h
isThumb
static bool isThumb(const MCSubtargetInfo &STI)
Definition: ARMAsmPrinter.cpp:470
INITIALIZE_PASS
INITIALIZE_PASS(ARMSLSHardening, "arm-sls-hardening", ARM_SLS_HARDENING_NAME, false, false) static void insertSpeculationBarrier(const ARMSubtarget *ST
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::ARMCC::AL
@ AL
Definition: ARMBaseInfo.h:45
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:634
llvm::GlobalValue
Definition: GlobalValue.h:44
ARM_SLS_HARDENING_NAME
#define ARM_SLS_HARDENING_NAME
Definition: ARMSLSHardening.cpp:31
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
MBB
MachineBasicBlock & MBB
Definition: ARMSLSHardening.cpp:71
llvm::GlobalValue::getParent
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:578
llvm::MachineModuleInfoWrapperPass
Definition: MachineModuleInfo.h:279
const
aarch64 promote const
Definition: AArch64PromoteConstant.cpp:232
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
MachineFunctionPass.h
llvm::MachineFunction::getName
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Definition: MachineFunction.cpp:542
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: ARMSLSHardening.cpp:73
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:97
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
R6
#define R6(n)
ThunkNameRegMode::Reg
Register Reg
Definition: ARMSLSHardening.cpp:131
ARM.h
llvm::MachineFunction
Definition: MachineFunction.h:234
llvm::MachineBasicBlock::getFirstTerminator
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
Definition: MachineBasicBlock.cpp:242
llvm::createARMSLSHardeningPass
FunctionPass * createARMSLSHardeningPass()
Definition: ARMSLSHardening.cpp:361
llvm::min
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:357
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:253
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
llvm::AnalysisUsage::addPreserved
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Definition: PassAnalysisSupport.h:98
ARMInstrInfo.h
llvm::isIndirectCall
static bool isIndirectCall(const MachineInstr &MI)
Definition: ARMBaseInstrInfo.h:653
llvm::createARMIndirectThunks
FunctionPass * createARMIndirectThunks()
Definition: ARMSLSHardening.cpp:407
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::find_if
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1578
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:600
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:324
llvm::ThunkInserter
Definition: IndirectThunks.h:24
llvm::MachineInstrBuilder::addGlobalAddress
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:177
llvm::isIndirectControlFlowNotComingBack
static bool isIndirectControlFlowNotComingBack(const MachineInstr &MI)
Definition: ARMBaseInstrInfo.h:701
SLSBLRThunks
static const struct ThunkNameRegMode SLSBLRThunks[]
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:268
MachineInstrBuilder.h
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:328
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
MachineOperand.h
MBBI
MachineBasicBlock MachineBasicBlock::iterator MBBI
Definition: ARMSLSHardening.cpp:72
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
llvm::predOps
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
Definition: ARMBaseInstrInfo.h:540
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
ThunkNameRegMode::isThumb
bool isThumb
Definition: ARMSLSHardening.cpp:132
llvm::isSpeculationBarrierEndBBOpcode
static bool isSpeculationBarrierEndBBOpcode(int Opc)
Definition: ARMBaseInstrInfo.h:707
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
MachineFunction.h
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:270
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37