blob: 5cfa5dd5f569795bf3afc0f785bab97e47a9270f [file] [log] [blame]
//===- bolt/Passes/RetpolineInsertion.h -------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef BOLT_PASSES_RETPOLINE_INSERTION_H
#define BOLT_PASSES_RETPOLINE_INSERTION_H
#include "bolt/Passes/BinaryPasses.h"
#include <string>
#include <unordered_map>
namespace llvm {
namespace bolt {
struct IndirectBranchInfo {
private:
bool IsMem = false;
bool IsCall = false;
bool IsTailCall = false;
public:
IndirectBranchInfo(MCInst &Inst, MCPlusBuilder &MIB);
bool isMem() const { return IsMem; }
bool isReg() const { return !IsMem; }
bool isCall() const { return IsCall; }
bool isJump() const { return !IsCall; }
bool isTailCall() const { return IsTailCall; }
struct MemOpInfo {
unsigned BaseRegNum;
int64_t ScaleValue;
unsigned IndexRegNum;
int64_t DispValue;
unsigned SegRegNum;
const MCExpr *DispExpr{nullptr};
};
union {
// Register branch information
MCPhysReg BranchReg;
// Memory branch information
MemOpInfo Memory;
};
};
class RetpolineInsertion : public BinaryFunctionPass {
private:
std::unordered_map<std::string, BinaryFunction *> CreatedRetpolines;
BinaryFunction *getOrCreateRetpoline(BinaryContext &BC,
const IndirectBranchInfo &BrInfo,
bool R11Available);
public:
/// Register r11 availability options
enum AvailabilityOptions : char {
ALWAYS = 0, /// r11 available before calls and jumps
ABI = 1, /// r11 available before calls
NEVER = 2 /// r11 not available
};
explicit RetpolineInsertion(const cl::opt<bool> &PrintPass)
: BinaryFunctionPass(PrintPass) {}
const char *getName() const override { return "retpoline-insertion"; }
void runOnFunctions(BinaryContext &BC) override;
};
} // namespace bolt
} // namespace llvm
#endif // BOLT_PASSES_RETPOLINE_INSERTION_H