LLVM: lib/Target/X86/X86IndirectBranchTracking.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

27

28using namespace llvm;

29

30#define DEBUG_TYPE "x86-indirect-branch-tracking"

31

34 cl::desc("Enable X86 indirect branch tracking pass."));

35

36STATISTIC(NumEndBranchAdded, "Number of ENDBR instructions added");

37

38namespace {

40public:

42

44 return "X86 Indirect Branch Tracking";

45 }

46

48

49private:

50 static char ID;

51

52

54

55

56 unsigned int EndbrOpcode = 0;

57

58

59

60

61

63};

64

65}

66

67char X86IndirectBranchTrackingPass::ID = 0;

68

70 return new X86IndirectBranchTrackingPass();

71}

72

73bool X86IndirectBranchTrackingPass::addENDBR(

75 assert(TII && "Target instruction info was not initialized");

76 assert((X86::ENDBR64 == EndbrOpcode || X86::ENDBR32 == EndbrOpcode) &&

77 "Unexpected Endbr opcode");

78

79

80

81 if (I == MBB.end() || I->getOpcode() != EndbrOpcode) {

83 ++NumEndBranchAdded;

84 return true;

85 }

86 return false;

87}

88

91 return false;

92 auto *CalleeFn = dyn_cast(MOp.getGlobal());

93 if (!CalleeFn)

94 return false;

96 return Attrs.hasFnAttr(Attribute::ReturnsTwice);

97}

98

99

102

103 if (F.doesNoCfCheck())

104 return false;

105

107

109 return true;

110

111 default:

112 return (F.hasAddressTaken() || F.hasLocalLinkage());

113 }

114}

115

116bool X86IndirectBranchTrackingPass::runOnMachineFunction(MachineFunction &MF) {

118

120

121 Metadata *isCFProtectionSupported = M->getModuleFlag("cf-protection-branch");

122

123

124

127#ifdef __CET__

128 bool isJITwithCET = TM->isJIT();

129#else

130 bool isJITwithCET = false;

131#endif

133 return false;

134

135

136 bool Changed = false;

137

139 EndbrOpcode = SubTarget.is64Bit() ? X86::ENDBR64 : X86::ENDBR32;

140

141

145 }

146

147 for (auto &MBB : MF) {

148

149

152

154 if (I->isCall() && I->getNumOperands() > 0 &&

156 Changed |= addENDBR(MBB, std::next(I));

157 }

158 }

159

160

161

162

163 if (TM->Options.ExceptionModel == ExceptionHandling::SjLj) {

165

167 if (I->isDebugInstr())

168 continue;

169 Changed |= addENDBR(MBB, I);

170 break;

171 } else if (I->isEHLabel()) {

172

173

174 MCSymbol *Sym = I->getOperand(0).getMCSymbol();

175 if (!MF.hasCallSiteLandingPad(Sym))

176 continue;

177 Changed |= addENDBR(MBB, std::next(I));

178 break;

179 }

180 }

183 if (I->isEHLabel())

184 continue;

185 Changed |= addENDBR(MBB, std::next(I));

186 break;

187 }

188 }

189 }

190 return Changed;

191}

const HexagonInstrInfo * TII

Module.h This file contains the declarations for the Module class.

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

static bool needsPrologueENDBR(MachineFunction &MF, const Module *M)

static bool IsCallReturnTwice(llvm::MachineOperand &MOp)

cl::opt< bool > IndirectBranchTracking("x86-indirect-branch-tracking", cl::init(false), cl::Hidden, cl::desc("Enable X86 indirect branch tracking pass."))

FunctionPass class - This class is used to implement most global optimizations.

Module * getParent()

Get the module that this global value is contained inside of...

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

bool isEHPad() const

Returns true if the block is a landing pad.

bool hasAddressTaken() const

Test whether this block is used as something other than the target of a terminator,...

DebugLoc findDebugLoc(instr_iterator MBBI)

Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.

MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...

virtual bool runOnMachineFunction(MachineFunction &MF)=0

runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

Function & getFunction()

Return the LLVM function that this machine code represents.

const TargetMachine & getTarget() const

getTarget - Return the target machine this machine code is compiled with

MachineOperand class - Representation of each machine instruction operand.

const GlobalValue * getGlobal() const

bool isGlobal() const

isGlobal - Tests if this is a MO_GlobalAddress operand.

A Module instance is used to store all the information related to an LLVM module.

virtual StringRef getPassName() const

getPassName - Return a nice clean name for a pass.

StringRef - Represent a constant reference to a string, i.e.

CodeModel::Model getCodeModel() const

Returns the code model.

const X86InstrInfo * getInstrInfo() const override

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)

Builder interface. Specify how to create the initial instruction itself.

FunctionPass * createX86IndirectBranchTrackingPass()

This pass inserts ENDBR instructions before indirect jump/call destinations as part of CET IBT mechan...