15
15
//
16
16
// ===----------------------------------------------------------------------===//
17
17
18
+ #include " llvm/CodeGen/ShadowStackGCLowering.h"
18
19
#include " llvm/ADT/SmallVector.h"
19
20
#include " llvm/ADT/StringExtras.h"
20
21
#include " llvm/Analysis/DomTreeUpdater.h"
22
+ #include " llvm/CodeGen/GCMetadata.h"
21
23
#include " llvm/CodeGen/Passes.h"
22
24
#include " llvm/IR/BasicBlock.h"
23
25
#include " llvm/IR/Constant.h"
@@ -50,7 +52,7 @@ using namespace llvm;
50
52
51
53
namespace {
52
54
53
- class ShadowStackGCLowering : public FunctionPass {
55
+ class ShadowStackGCLoweringImpl {
54
56
// / RootChain - This is the global linked-list that contains the chain of GC
55
57
// / roots.
56
58
GlobalVariable *Head = nullptr ;
@@ -64,13 +66,10 @@ class ShadowStackGCLowering : public FunctionPass {
64
66
std::vector<std::pair<CallInst *, AllocaInst *>> Roots;
65
67
66
68
public:
67
- static char ID;
68
-
69
- ShadowStackGCLowering ();
69
+ ShadowStackGCLoweringImpl () = default ;
70
70
71
- bool doInitialization (Module &M) override ;
72
- void getAnalysisUsage (AnalysisUsage &AU) const override ;
73
- bool runOnFunction (Function &F) override ;
71
+ bool doInitialization (Module &M);
72
+ bool runOnFunction (Function &F, DomTreeUpdater *DTU);
74
73
75
74
private:
76
75
bool IsNullValue (Value *V);
@@ -86,8 +85,51 @@ class ShadowStackGCLowering : public FunctionPass {
86
85
const char *Name);
87
86
};
88
87
88
+ class ShadowStackGCLowering : public FunctionPass {
89
+ ShadowStackGCLoweringImpl Impl;
90
+
91
+ public:
92
+ static char ID;
93
+
94
+ ShadowStackGCLowering ();
95
+
96
+ bool doInitialization (Module &M) override { return Impl.doInitialization (M); }
97
+ void getAnalysisUsage (AnalysisUsage &AU) const override {
98
+ AU.addPreserved <DominatorTreeWrapperPass>();
99
+ }
100
+ bool runOnFunction (Function &F) override {
101
+ std::optional<DomTreeUpdater> DTU;
102
+ if (auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
103
+ DTU.emplace (DTWP->getDomTree (), DomTreeUpdater::UpdateStrategy::Lazy);
104
+ return Impl.runOnFunction (F, DTU ? &*DTU : nullptr );
105
+ }
106
+ };
107
+
89
108
} // end anonymous namespace
90
109
110
+ PreservedAnalyses ShadowStackGCLoweringPass::run (Module &M,
111
+ ModuleAnalysisManager &MAM) {
112
+ auto &Map = MAM.getResult <CollectorMetadataAnalysis>(M);
113
+ if (Map.StrategyMap .contains (" shadow-stack" ))
114
+ return PreservedAnalyses::all ();
115
+
116
+ ShadowStackGCLoweringImpl Impl;
117
+ bool Changed = Impl.doInitialization (M);
118
+ for (auto &F : M) {
119
+ auto &FAM =
120
+ MAM.getResult <FunctionAnalysisManagerModuleProxy>(M).getManager ();
121
+ auto *DT = FAM.getCachedResult <DominatorTreeAnalysis>(F);
122
+ DomTreeUpdater DTU (DT, DomTreeUpdater::UpdateStrategy::Lazy);
123
+ Changed |= Impl.runOnFunction (F, DT ? &DTU : nullptr );
124
+ }
125
+
126
+ if (!Changed)
127
+ return PreservedAnalyses::all ();
128
+ PreservedAnalyses PA;
129
+ PA.preserve <DominatorTreeAnalysis>();
130
+ return PA;
131
+ }
132
+
91
133
char ShadowStackGCLowering::ID = 0 ;
92
134
char &llvm::ShadowStackGCLoweringID = ShadowStackGCLowering::ID;
93
135
@@ -104,7 +146,7 @@ ShadowStackGCLowering::ShadowStackGCLowering() : FunctionPass(ID) {
104
146
initializeShadowStackGCLoweringPass (*PassRegistry::getPassRegistry ());
105
147
}
106
148
107
- Constant *ShadowStackGCLowering ::GetFrameMap (Function &F) {
149
+ Constant *ShadowStackGCLoweringImpl ::GetFrameMap (Function &F) {
108
150
// doInitialization creates the abstract type of this value.
109
151
Type *VoidPtr = PointerType::getUnqual (F.getContext ());
110
152
@@ -158,7 +200,7 @@ Constant *ShadowStackGCLowering::GetFrameMap(Function &F) {
158
200
return ConstantExpr::getGetElementPtr (FrameMap->getType (), GV, GEPIndices);
159
201
}
160
202
161
- Type *ShadowStackGCLowering ::GetConcreteStackEntryType (Function &F) {
203
+ Type *ShadowStackGCLoweringImpl ::GetConcreteStackEntryType (Function &F) {
162
204
// doInitialization creates the generic version of this type.
163
205
std::vector<Type *> EltTys;
164
206
EltTys.push_back (StackEntryTy);
@@ -170,7 +212,7 @@ Type *ShadowStackGCLowering::GetConcreteStackEntryType(Function &F) {
170
212
171
213
// / doInitialization - If this module uses the GC intrinsics, find them now. If
172
214
// / not, exit fast.
173
- bool ShadowStackGCLowering ::doInitialization (Module &M) {
215
+ bool ShadowStackGCLoweringImpl ::doInitialization (Module &M) {
174
216
bool Active = false ;
175
217
for (Function &F : M) {
176
218
if (F.hasGC () && F.getGC () == " shadow-stack" ) {
@@ -224,13 +266,13 @@ bool ShadowStackGCLowering::doInitialization(Module &M) {
224
266
return true ;
225
267
}
226
268
227
- bool ShadowStackGCLowering ::IsNullValue (Value *V) {
269
+ bool ShadowStackGCLoweringImpl ::IsNullValue (Value *V) {
228
270
if (Constant *C = dyn_cast<Constant>(V))
229
271
return C->isNullValue ();
230
272
return false ;
231
273
}
232
274
233
- void ShadowStackGCLowering ::CollectRoots (Function &F) {
275
+ void ShadowStackGCLoweringImpl ::CollectRoots (Function &F) {
234
276
// FIXME: Account for original alignment. Could fragment the root array.
235
277
// Approach 1: Null initialize empty slots at runtime. Yuck.
236
278
// Approach 2: Emit a map of the array instead of just a count.
@@ -258,11 +300,10 @@ void ShadowStackGCLowering::CollectRoots(Function &F) {
258
300
Roots.insert (Roots.begin (), MetaRoots.begin (), MetaRoots.end ());
259
301
}
260
302
261
- GetElementPtrInst *ShadowStackGCLowering::CreateGEP (LLVMContext &Context,
262
- IRBuilder<> &B, Type *Ty,
263
- Value *BasePtr, int Idx,
264
- int Idx2,
265
- const char *Name) {
303
+ GetElementPtrInst *
304
+ ShadowStackGCLoweringImpl::CreateGEP (LLVMContext &Context, IRBuilder<> &B,
305
+ Type *Ty, Value *BasePtr, int Idx,
306
+ int Idx2, const char *Name) {
266
307
Value *Indices[] = {ConstantInt::get (Type::getInt32Ty (Context), 0 ),
267
308
ConstantInt::get (Type::getInt32Ty (Context), Idx),
268
309
ConstantInt::get (Type::getInt32Ty (Context), Idx2)};
@@ -273,9 +314,11 @@ GetElementPtrInst *ShadowStackGCLowering::CreateGEP(LLVMContext &Context,
273
314
return dyn_cast<GetElementPtrInst>(Val);
274
315
}
275
316
276
- GetElementPtrInst *ShadowStackGCLowering::CreateGEP (LLVMContext &Context,
277
- IRBuilder<> &B, Type *Ty, Value *BasePtr,
278
- int Idx, const char *Name) {
317
+ GetElementPtrInst *ShadowStackGCLoweringImpl::CreateGEP (LLVMContext &Context,
318
+ IRBuilder<> &B,
319
+ Type *Ty,
320
+ Value *BasePtr, int Idx,
321
+ const char *Name) {
279
322
Value *Indices[] = {ConstantInt::get (Type::getInt32Ty (Context), 0 ),
280
323
ConstantInt::get (Type::getInt32Ty (Context), Idx)};
281
324
Value *Val = B.CreateGEP (Ty, BasePtr, Indices, Name);
@@ -285,12 +328,9 @@ GetElementPtrInst *ShadowStackGCLowering::CreateGEP(LLVMContext &Context,
285
328
return dyn_cast<GetElementPtrInst>(Val);
286
329
}
287
330
288
- void ShadowStackGCLowering::getAnalysisUsage (AnalysisUsage &AU) const {
289
- AU.addPreserved <DominatorTreeWrapperPass>();
290
- }
291
-
292
331
// / runOnFunction - Insert code to maintain the shadow stack.
293
- bool ShadowStackGCLowering::runOnFunction (Function &F) {
332
+ bool ShadowStackGCLoweringImpl::runOnFunction (Function &F,
333
+ DomTreeUpdater *DTU) {
294
334
// Quick exit for functions that do not use the shadow stack GC.
295
335
if (!F.hasGC () || F.getGC () != " shadow-stack" )
296
336
return false ;
@@ -305,10 +345,6 @@ bool ShadowStackGCLowering::runOnFunction(Function &F) {
305
345
if (Roots.empty ())
306
346
return false ;
307
347
308
- std::optional<DomTreeUpdater> DTU;
309
- if (auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
310
- DTU.emplace (DTWP->getDomTree (), DomTreeUpdater::UpdateStrategy::Lazy);
311
-
312
348
// Build the constant map and figure the type of the shadow stack entry.
313
349
Value *FrameMap = GetFrameMap (F);
314
350
Type *ConcreteStackEntryTy = GetConcreteStackEntryType (F);
@@ -359,8 +395,7 @@ bool ShadowStackGCLowering::runOnFunction(Function &F) {
359
395
AtEntry.CreateStore (NewHeadVal, Head);
360
396
361
397
// For each instruction that escapes...
362
- EscapeEnumerator EE (F, " gc_cleanup" , /* HandleExceptions=*/ true ,
363
- DTU ? &*DTU : nullptr );
398
+ EscapeEnumerator EE (F, " gc_cleanup" , /* HandleExceptions=*/ true , DTU);
364
399
while (IRBuilder<> *AtExit = EE.Next ()) {
365
400
// Pop the entry from the shadow stack. Don't reuse CurrentHead from
366
401
// AtEntry, since that would make the value live for the entire function.
0 commit comments