LLVM 24.0.0git
CFGuardLongjmp.cpp
Go to the documentation of this file.
1//===-- CFGuardLongjmp.cpp - Longjmp symbols for CFGuard --------*- 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/// \file
10/// This file contains a machine function pass to insert a symbol after each
11/// call to _setjmp and store this in the MachineFunction's LongjmpTargets
12/// vector. This will be used to emit the table of valid longjmp targets used
13/// by Control Flow Guard.
14///
15//===----------------------------------------------------------------------===//
16
18#include "llvm/ADT/Statistic.h"
26#include "llvm/CodeGen/Passes.h"
27#include "llvm/IR/Analysis.h"
28#include "llvm/IR/Module.h"
30#include "llvm/Pass.h"
31
32using namespace llvm;
33
34#define DEBUG_TYPE "cfguard-longjmp"
35
36STATISTIC(CFGuardLongjmpTargets,
37 "Number of Control Flow Guard longjmp targets");
38
39namespace {
40
41/// MachineFunction pass to insert a symbol after each call to _setjmp and store
42/// this in the MachineFunction's LongjmpTargets vector.
43class CFGuardLongjmpLegacy : public MachineFunctionPass {
44public:
45 static char ID;
46
47 CFGuardLongjmpLegacy() : MachineFunctionPass(ID) {}
48
49 StringRef getPassName() const override {
50 return "Control Flow Guard longjmp targets";
51 }
52
53 bool runOnMachineFunction(MachineFunction &MF) override;
54
55 void getAnalysisUsage(AnalysisUsage &AU) const override {
56 AU.setPreservesCFG();
58 }
59};
60
61} // end anonymous namespace
62
63char CFGuardLongjmpLegacy::ID = 0;
64
65INITIALIZE_PASS(CFGuardLongjmpLegacy, "CFGuardLongjmp",
66 "Insert symbols at valid longjmp targets for /guard:cf", false,
67 false)
69 return new CFGuardLongjmpLegacy();
70}
71
73
74 // Skip modules for which the cfguard flag is not set.
77 return false;
78
79 // Skip functions that do not have calls to _setjmp.
81 return false;
82
84
85 // Iterate over all instructions in the function and add calls to functions
86 // that return twice to the list of targets.
87 for (MachineBasicBlock &MBB : MF) {
88 for (MachineInstr &MI : MBB) {
89
90 // Skip instructions that are not calls.
91 if (!MI.isCall() || MI.getNumOperands() < 1)
92 continue;
93
94 // Iterate over operands to find calls to global functions.
95 for (MachineOperand &MO : MI.operands()) {
96 if (!MO.isGlobal())
97 continue;
98
99 auto *F = dyn_cast<Function>(MO.getGlobal());
100 if (!F)
101 continue;
102
103 // If the instruction calls a function that returns twice, add
104 // it to the list of targets.
105 if (F->hasFnAttribute(Attribute::ReturnsTwice)) {
106 SetjmpCalls.push_back(&MI);
107 break;
108 }
109 }
110 }
111 }
112
113 if (SetjmpCalls.empty())
114 return false;
115
116 unsigned SetjmpNum = 0;
117
118 // For each possible target, create a new symbol and insert it immediately
119 // after the call to setjmp. Add this symbol to the MachineFunction's list
120 // of longjmp targets.
121 for (MachineInstr *Setjmp : SetjmpCalls) {
122 SmallString<128> SymbolName;
123 raw_svector_ostream(SymbolName) << "$cfgsj_" << MF.getName() << SetjmpNum++;
124 MCSymbol *SjSymbol = MF.getContext().getOrCreateSymbol(SymbolName);
125
126 Setjmp->setPostInstrSymbol(MF, SjSymbol);
127 MF.addLongjmpTarget(SjSymbol);
128 CFGuardLongjmpTargets++;
129 }
130
131 return true;
132}
133
134bool CFGuardLongjmpLegacy::runOnMachineFunction(MachineFunction &MF) {
136}
137
138PreservedAnalyses
MachineBasicBlock & MBB
static bool runCFGuardLongjmpOnMachineFunction(MachineFunction &MF)
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:278
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
bool callsFunctionThatReturnsTwice() const
callsFunctionThatReturnsTwice - Return true if the function has a call to setjmp or other function th...
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
void addLongjmpTarget(MCSymbol *Target)
Add the specified symbol to the list of valid longjmp targets for Windows Control Flow Guard.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MCContext & getContext() const
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
ControlFlowGuardMode getControlFlowGuardMode() const
Gets the Control Flow Guard mode.
Definition Module.cpp:1026
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A raw_ostream that writes to an SmallVector or SmallString.
Pass manager infrastructure for declaring and invalidating analyses.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI FunctionPass * createCFGuardLongjmpLegacyPass()
Creates CFGuard longjmp target identification pass.
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.