@@ -64,6 +64,90 @@ static cl::opt<bool> EnableSelectionDAGSP("enable-selectiondag-sp",
64
64
static cl::opt<bool > DisableCheckNoReturn (" disable-check-noreturn-call" ,
65
65
cl::init (false ), cl::Hidden);
66
66
67
+ // / InsertStackProtectors - Insert code into the prologue and epilogue of the
68
+ // / function.
69
+ // /
70
+ // / - The prologue code loads and stores the stack guard onto the stack.
71
+ // / - The epilogue checks the value stored in the prologue against the original
72
+ // / value. It calls __stack_chk_fail if they differ.
73
+ static bool InsertStackProtectors (const TargetMachine *TM, Function *F,
74
+ DomTreeUpdater *DTU, bool &HasPrologue,
75
+ bool &HasIRCheck);
76
+
77
+ // / CreateFailBB - Create a basic block to jump to when the stack protector
78
+ // / check fails.
79
+ static BasicBlock *CreateFailBB (Function *F, const Triple &Trip);
80
+
81
+ bool SSPLayoutInfo::shouldEmitSDCheck (const BasicBlock &BB) const {
82
+ return HasPrologue && !HasIRCheck && isa<ReturnInst>(BB.getTerminator ());
83
+ }
84
+
85
+ void SSPLayoutInfo::copyToMachineFrameInfo (MachineFrameInfo &MFI) const {
86
+ if (Layout.empty ())
87
+ return ;
88
+
89
+ for (int I = 0 , E = MFI.getObjectIndexEnd (); I != E; ++I) {
90
+ if (MFI.isDeadObjectIndex (I))
91
+ continue ;
92
+
93
+ const AllocaInst *AI = MFI.getObjectAllocation (I);
94
+ if (!AI)
95
+ continue ;
96
+
97
+ SSPLayoutMap::const_iterator LI = Layout.find (AI);
98
+ if (LI == Layout.end ())
99
+ continue ;
100
+
101
+ MFI.setObjectSSPLayout (I, LI->second );
102
+ }
103
+ }
104
+
105
+ SSPLayoutInfo SSPLayoutAnalysis::run (Function &F,
106
+ FunctionAnalysisManager &FAM) {
107
+
108
+ SSPLayoutInfo Info;
109
+ Info.RequireStackProtector =
110
+ SSPLayoutAnalysis::requiresStackProtector (&F, &Info.Layout );
111
+ Info.SSPBufferSize = F.getFnAttributeAsParsedInteger (
112
+ " stack-protector-buffer-size" , SSPLayoutInfo::DefaultSSPBufferSize);
113
+ return Info;
114
+ }
115
+
116
+ AnalysisKey SSPLayoutAnalysis::Key;
117
+
118
+ PreservedAnalyses StackProtectorPass::run (Function &F,
119
+ FunctionAnalysisManager &FAM) {
120
+ auto &Info = FAM.getResult <SSPLayoutAnalysis>(F);
121
+ auto *DT = FAM.getCachedResult <DominatorTreeAnalysis>(F);
122
+ DomTreeUpdater DTU (DT, DomTreeUpdater::UpdateStrategy::Lazy);
123
+
124
+ if (!Info.RequireStackProtector )
125
+ return PreservedAnalyses::all ();
126
+
127
+ // TODO(etienneb): Functions with funclets are not correctly supported now.
128
+ // Do nothing if this is funclet-based personality.
129
+ if (F.hasPersonalityFn ()) {
130
+ EHPersonality Personality = classifyEHPersonality (F.getPersonalityFn ());
131
+ if (isFuncletEHPersonality (Personality))
132
+ return PreservedAnalyses::all ();
133
+ }
134
+
135
+ ++NumFunProtected;
136
+ bool Changed = InsertStackProtectors (TM, &F, DT ? &DTU : nullptr ,
137
+ Info.HasPrologue , Info.HasIRCheck );
138
+ #ifdef EXPENSIVE_CHECKS
139
+ assert ((!DT || DT->verify (DominatorTree::VerificationLevel::Full)) &&
140
+ " Failed to maintain validity of domtree!" );
141
+ #endif
142
+
143
+ if (!Changed)
144
+ return PreservedAnalyses::all ();
145
+ PreservedAnalyses PA;
146
+ PA.preserve <SSPLayoutAnalysis>();
147
+ PA.preserve <DominatorTreeAnalysis>();
148
+ return PA;
149
+ }
150
+
67
151
char StackProtector::ID = 0 ;
68
152
69
153
StackProtector::StackProtector () : FunctionPass(ID) {
@@ -90,14 +174,12 @@ bool StackProtector::runOnFunction(Function &Fn) {
90
174
if (auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
91
175
DTU.emplace (DTWP->getDomTree (), DomTreeUpdater::UpdateStrategy::Lazy);
92
176
TM = &getAnalysis<TargetPassConfig>().getTM <TargetMachine>();
93
- Trip = TM->getTargetTriple ();
94
- TLI = TM->getSubtargetImpl (Fn)->getTargetLowering ();
95
- HasPrologue = false ;
96
- HasIRCheck = false ;
97
-
98
- SSPBufferSize = Fn.getFnAttributeAsParsedInteger (
99
- " stack-protector-buffer-size" , DefaultSSPBufferSize);
100
- if (!requiresStackProtector (F, &Layout))
177
+ LayoutInfo.HasPrologue = false ;
178
+ LayoutInfo.HasIRCheck = false ;
179
+
180
+ LayoutInfo.SSPBufferSize = Fn.getFnAttributeAsParsedInteger (
181
+ " stack-protector-buffer-size" , SSPLayoutInfo::DefaultSSPBufferSize);
182
+ if (!requiresStackProtector (F, &LayoutInfo.Layout ))
101
183
return false ;
102
184
103
185
// TODO(etienneb): Functions with funclets are not correctly supported now.
@@ -109,7 +191,9 @@ bool StackProtector::runOnFunction(Function &Fn) {
109
191
}
110
192
111
193
++NumFunProtected;
112
- bool Changed = InsertStackProtectors ();
194
+ bool Changed =
195
+ InsertStackProtectors (TM, F, DTU ? &*DTU : nullptr ,
196
+ LayoutInfo.HasPrologue , LayoutInfo.HasIRCheck );
113
197
#ifdef EXPENSIVE_CHECKS
114
198
assert ((!DTU ||
115
199
DTU->getDomTree ().verify (DominatorTree::VerificationLevel::Full)) &&
@@ -284,7 +368,8 @@ static const CallInst *findStackProtectorIntrinsic(Function &F) {
284
368
// / functions with aggregates that contain any buffer regardless of type and
285
369
// / size, and functions that contain stack-based variables that have had their
286
370
// / address taken.
287
- bool StackProtector::requiresStackProtector (Function *F, SSPLayoutMap *Layout) {
371
+ bool SSPLayoutAnalysis::requiresStackProtector (Function *F,
372
+ SSPLayoutMap *Layout) {
288
373
Module *M = F->getParent ();
289
374
bool Strong = false ;
290
375
bool NeedsProtector = false ;
@@ -295,7 +380,7 @@ bool StackProtector::requiresStackProtector(Function *F, SSPLayoutMap *Layout) {
295
380
SmallPtrSet<const PHINode *, 16 > VisitedPHIs;
296
381
297
382
unsigned SSPBufferSize = F->getFnAttributeAsParsedInteger (
298
- " stack-protector-buffer-size" , DefaultSSPBufferSize);
383
+ " stack-protector-buffer-size" , SSPLayoutInfo:: DefaultSSPBufferSize);
299
384
300
385
if (F->hasFnAttribute (Attribute::SafeStack))
301
386
return false ;
@@ -460,13 +545,12 @@ static bool CreatePrologue(Function *F, Module *M, Instruction *CheckLoc,
460
545
return SupportsSelectionDAGSP;
461
546
}
462
547
463
- // / InsertStackProtectors - Insert code into the prologue and epilogue of the
464
- // / function.
465
- // /
466
- // / - The prologue code loads and stores the stack guard onto the stack.
467
- // / - The epilogue checks the value stored in the prologue against the original
468
- // / value. It calls __stack_chk_fail if they differ.
469
- bool StackProtector::InsertStackProtectors () {
548
+ bool InsertStackProtectors (const TargetMachine *TM, Function *F,
549
+ DomTreeUpdater *DTU, bool &HasPrologue,
550
+ bool &HasIRCheck) {
551
+ auto *M = F->getParent ();
552
+ auto *TLI = TM->getSubtargetImpl (*F)->getTargetLowering ();
553
+
470
554
// If the target wants to XOR the frame pointer into the guard value, it's
471
555
// impossible to emit the check in IR, so the target *must* support stack
472
556
// protection in SDAG.
@@ -574,7 +658,7 @@ bool StackProtector::InsertStackProtectors() {
574
658
// merge pass will merge together all of the various BB into one including
575
659
// fail BB generated by the stack protector pseudo instruction.
576
660
if (!FailBB)
577
- FailBB = CreateFailBB ();
661
+ FailBB = CreateFailBB (F, TM-> getTargetTriple () );
578
662
579
663
IRBuilder<> B (CheckLoc);
580
664
Value *Guard = getStackGuard (TLI, M, B);
@@ -589,8 +673,7 @@ bool StackProtector::InsertStackProtectors() {
589
673
SuccessProb.getNumerator ());
590
674
591
675
SplitBlockAndInsertIfThen (Cmp, CheckLoc,
592
- /* Unreachable=*/ false , Weights,
593
- DTU ? &*DTU : nullptr ,
676
+ /* Unreachable=*/ false , Weights, DTU,
594
677
/* LI=*/ nullptr , /* ThenBlock=*/ FailBB);
595
678
596
679
auto *BI = cast<BranchInst>(Cmp->getParent ()->getTerminator ());
@@ -608,9 +691,8 @@ bool StackProtector::InsertStackProtectors() {
608
691
return HasPrologue;
609
692
}
610
693
611
- // / CreateFailBB - Create a basic block to jump to when the stack protector
612
- // / check fails.
613
- BasicBlock *StackProtector::CreateFailBB () {
694
+ BasicBlock *CreateFailBB (Function *F, const Triple &Trip) {
695
+ auto *M = F->getParent ();
614
696
LLVMContext &Context = F->getContext ();
615
697
BasicBlock *FailBB = BasicBlock::Create (Context, " CallStackCheckFailBlk" , F);
616
698
IRBuilder<> B (FailBB);
@@ -633,27 +715,3 @@ BasicBlock *StackProtector::CreateFailBB() {
633
715
B.CreateUnreachable ();
634
716
return FailBB;
635
717
}
636
-
637
- bool StackProtector::shouldEmitSDCheck (const BasicBlock &BB) const {
638
- return HasPrologue && !HasIRCheck && isa<ReturnInst>(BB.getTerminator ());
639
- }
640
-
641
- void StackProtector::copyToMachineFrameInfo (MachineFrameInfo &MFI) const {
642
- if (Layout.empty ())
643
- return ;
644
-
645
- for (int I = 0 , E = MFI.getObjectIndexEnd (); I != E; ++I) {
646
- if (MFI.isDeadObjectIndex (I))
647
- continue ;
648
-
649
- const AllocaInst *AI = MFI.getObjectAllocation (I);
650
- if (!AI)
651
- continue ;
652
-
653
- SSPLayoutMap::const_iterator LI = Layout.find (AI);
654
- if (LI == Layout.end ())
655
- continue ;
656
-
657
- MFI.setObjectSSPLayout (I, LI->second );
658
- }
659
- }
0 commit comments