xref: /llvm-project/bolt/include/bolt/Passes/RetpolineInsertion.h (revision a5f3d1a803020167bd9d494a8a3921e7dcc1550a)
1 //===- bolt/Passes/RetpolineInsertion.h -------------------------*- C++ -*-===//
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 #ifndef BOLT_PASSES_RETPOLINE_INSERTION_H
10 #define BOLT_PASSES_RETPOLINE_INSERTION_H
11 
12 #include "bolt/Passes/BinaryPasses.h"
13 #include <string>
14 #include <unordered_map>
15 
16 namespace llvm {
17 namespace bolt {
18 
19 struct IndirectBranchInfo {
20 private:
21   bool IsMem = false;
22   bool IsCall = false;
23   bool IsTailCall = false;
24 
25 public:
26   IndirectBranchInfo(MCInst &Inst, MCPlusBuilder &MIB);
isMemIndirectBranchInfo27   bool isMem() const { return IsMem; }
isRegIndirectBranchInfo28   bool isReg() const { return !IsMem; }
isCallIndirectBranchInfo29   bool isCall() const { return IsCall; }
isJumpIndirectBranchInfo30   bool isJump() const { return !IsCall; }
isTailCallIndirectBranchInfo31   bool isTailCall() const { return IsTailCall; }
32 
33   using MemOpInfo = MCPlusBuilder::X86MemOperand;
34 
35   union {
36     // Register branch information
37     MCPhysReg BranchReg;
38 
39     // Memory branch information
40     MemOpInfo Memory;
41   };
42 };
43 
44 class RetpolineInsertion : public BinaryFunctionPass {
45 private:
46   std::unordered_map<std::string, BinaryFunction *> CreatedRetpolines;
47 
48   BinaryFunction *getOrCreateRetpoline(BinaryContext &BC,
49                                        const IndirectBranchInfo &BrInfo,
50                                        bool R11Available);
51 
52 public:
53   /// Register r11 availability options
54   enum AvailabilityOptions : char {
55     ALWAYS = 0, ///  r11 available before calls and jumps
56     ABI = 1,    ///  r11 available before calls
57     NEVER = 2   ///  r11 not available
58   };
59 
RetpolineInsertion(const cl::opt<bool> & PrintPass)60   explicit RetpolineInsertion(const cl::opt<bool> &PrintPass)
61       : BinaryFunctionPass(PrintPass) {}
62 
getName()63   const char *getName() const override { return "retpoline-insertion"; }
64 
65   Error runOnFunctions(BinaryContext &BC) override;
66 };
67 
68 } // namespace bolt
69 } // namespace llvm
70 
71 #endif // BOLT_PASSES_RETPOLINE_INSERTION_H
72