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   struct MemOpInfo {
34     unsigned BaseRegNum;
35     int64_t ScaleValue;
36     unsigned IndexRegNum;
37     int64_t DispValue;
38     unsigned SegRegNum;
39     const MCExpr *DispExpr{nullptr};
40   };
41 
42   union {
43     // Register branch information
44     MCPhysReg BranchReg;
45 
46     // Memory branch information
47     MemOpInfo Memory;
48   };
49 };
50 
51 class RetpolineInsertion : public BinaryFunctionPass {
52 private:
53   std::unordered_map<std::string, BinaryFunction *> CreatedRetpolines;
54 
55   BinaryFunction *getOrCreateRetpoline(BinaryContext &BC,
56                                        const IndirectBranchInfo &BrInfo,
57                                        bool R11Available);
58 
59 public:
60   /// Register r11 availability options
61   enum AvailabilityOptions : char {
62     ALWAYS = 0, ///  r11 available before calls and jumps
63     ABI = 1,    ///  r11 available before calls
64     NEVER = 2   ///  r11 not available
65   };
66 
RetpolineInsertion(const cl::opt<bool> & PrintPass)67   explicit RetpolineInsertion(const cl::opt<bool> &PrintPass)
68       : BinaryFunctionPass(PrintPass) {}
69 
getName()70   const char *getName() const override { return "retpoline-insertion"; }
71 
72   void runOnFunctions(BinaryContext &BC) override;
73 };
74 
75 } // namespace bolt
76 } // namespace llvm
77 
78 #endif // BOLT_PASSES_RETPOLINE_INSERTION_H
79