llvm.org GIT mirror llvm / 80a320d
Update in response to feedback from Chris: - Use enums instead of magic numbers. - Rework algorithm to use the bytes size from the target to determine when to emit stack protectors. - Get rid of "propolice" in any comments. - Renamed an option to its expanded form. - Other miscellanenous changes. More changes will come after this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58723 91177308-0d34-0410-b5e6-96231b3b80d8 Bill Wendling 11 years ago
3 changed file(s) with 60 addition(s) and 33 deletion(s). Raw diff Collapse all Expand all
2222 class FunctionPass;
2323 class PassInfo;
2424 class TargetMachine;
25 class TargetLowering;
2526 class RegisterCoalescer;
27
28 /// StackProtectorLevel - An enumeration for when to determin when to turn
29 /// stack smashing protection (SSP) on.
30 namespace SSP {
31 enum StackProtectorLevel {
32 OFF, // Stack protectors are off.
33 SOME, // Stack protectors on only for functions that require them.
34 ALL // Stack protectors on for all functions.
35 };
36 } // end SSP namespace
2637
2738 /// createUnreachableBlockEliminationPass - The LLVM code generator does not
2839 /// work well with unreachable basic blocks (what live ranges make sense for a
192203 FunctionPass *createStackSlotColoringPass();
193204
194205 /// createStackProtectorPass - This pass adds stack protectors to functions.
195 FunctionPass *createStackProtectorPass(int Level);
206 FunctionPass *createStackProtectorPass(SSP::StackProtectorLevel lvl,
207 const TargetLowering *tli);
196208
197209 } // End llvm namespace
198210
6060 cl::desc("Enable the experimental \"fast\" instruction selector"));
6161
6262 // Enable stack protectors.
63 static cl::opt
64 EnableStackProtector("enable-stack-protector", cl::init(0),
65 cl::desc("Use ProPolice as a stack protection method."));
63 static cl::opt
64 EnableStackProtector("enable-stack-protector",
65 cl::desc("Stack canary protection level: (default: off)"),
66 cl::init(SSP::OFF),
67 cl::values(clEnumValN(SSP::ALL, "all",
68 "All functions get stack protectors."),
69 clEnumValN(SSP::SOME, "some",
70 "Only functions requiring stack protectors get them."),
71 clEnumValN(SSP::OFF, "off",
72 "No functions get stack protectors."),
73 clEnumValEnd));
6674
6775 FileModel::Model
6876 LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
169177 if (!Fast)
170178 PM.add(createCodeGenPreparePass(getTargetLowering()));
171179
172 PM.add(createStackProtectorPass(EnableStackProtector));
180 if (EnableStackProtector != SSP::OFF)
181 PM.add(createStackProtectorPass(EnableStackProtector, getTargetLowering()));
173182
174183 if (PrintISelInput)
175184 PM.add(createPrintFunctionPass("\n\n"
66 //
77 //===----------------------------------------------------------------------===//
88 //
9 // This pass inserts stack protectors into functions which need them. The stack
10 // protectors this uses are the type that ProPolice used. A variable with a
11 // random value in it is stored onto the stack before the local variables are
12 // allocated. Upon exitting the block, the stored value is checked. If it's
9 // This pass inserts stack protectors into functions which need them. A variable
10 // with a random value in it is stored onto the stack before the local variables
11 // are allocated. Upon exiting the block, the stored value is checked. If it's
1312 // changed, then there was some sort of violation and the program aborts.
1413 //
1514 //===----------------------------------------------------------------------===//
2423 #include "llvm/Pass.h"
2524 #include "llvm/ADT/APInt.h"
2625 #include "llvm/Support/CommandLine.h"
26 #include "llvm/Target/TargetData.h"
27 #include "llvm/Target/TargetLowering.h"
2728 using namespace llvm;
2829
2930 // Enable stack protectors.
3031 static cl::opt
31 SSPBufferSize("ssp-buffer-size", cl::init(8),
32 SSPBufferSize("stack-protector-buffer-size", cl::init(8),
3233 cl::desc("The lower bound for a buffer to be considered for "
3334 "stack smashing protection."));
3435
3536 namespace {
3637 class VISIBILITY_HIDDEN StackProtector : public FunctionPass {
37 // Level == 0 -- Stack protectors are off.
38 // Level == 1 -- Stack protectors are on only for some functions.
39 // Level == 2 -- Stack protectors are on for all functions.
40 int Level;
38 /// Level - The level of stack protection.
39 SSP::StackProtectorLevel Level;
40
41 /// TLI - Keep a pointer of a TargetLowering to consult for determining
42 /// target type sizes.
43 const TargetLowering *TLI;
4144
4245 /// FailBB - Holds the basic block to jump to when the stack protector check
4346 /// fails.
6972
7073 /// RequiresStackProtector - Check whether or not this function needs a
7174 /// stack protector based upon the stack protector level.
72 bool RequiresStackProtector();
75 bool RequiresStackProtector() const;
7376 public:
7477 static char ID; // Pass identification, replacement for typeid.
75 StackProtector(int lvl = 0) : FunctionPass(&ID), Level(lvl), FailBB(0) {}
78 StackProtector() : FunctionPass(&ID), Level(SSP::OFF), TLI(0), FailBB(0) {}
79 StackProtector(SSP::StackProtectorLevel lvl, const TargetLowering *tli)
80 : FunctionPass(&ID), Level(lvl), TLI(tli), FailBB(0) {}
7681
7782 virtual bool runOnFunction(Function &Fn);
7883 };
8287 static RegisterPass
8388 X("stack-protector", "Insert stack protectors");
8489
85 FunctionPass *llvm::createStackProtectorPass(int lvl) {
86 return new StackProtector(lvl);
90 FunctionPass *llvm::createStackProtectorPass(SSP::StackProtectorLevel lvl,
91 const TargetLowering *tli) {
92 return new StackProtector(lvl, tli);
8793 }
8894
8995 bool StackProtector::runOnFunction(Function &Fn) {
118124
119125 StackProtFrameSlot = new AllocaInst(PointerType::getUnqual(Type::Int8Ty),
120126 "StackProt_Frame", &InsertPt);
121 LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", true, &InsertPt);
122 new StoreInst(LI, StackProtFrameSlot, true, &InsertPt);
127 LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, &InsertPt);
128 new StoreInst(LI, StackProtFrameSlot, false, &InsertPt);
123129 }
124130
125131 /// InsertStackProtectorEpilogue - Insert code before the return instructions
134140 ReturnBBs.reserve(F->size());
135141
136142 for (; I != E; ++I)
137 if (isa((*I).getTerminator()))
143 if (isa(I->getTerminator()))
138144 ReturnBBs.push_back(I);
139145
140146 if (ReturnBBs.empty()) return; // Odd, but could happen. . .
187193 FailBB = BasicBlock::Create("CallStackCheckFailBlk", F);
188194 std::vector Params;
189195 Constant *StackChkFail =
190 M->getOrInsertFunction("__stack_chk_fail",
191 FunctionType::get(Type::VoidTy, Params, false));
196 M->getOrInsertFunction("__stack_chk_fail", Type::VoidTy, NULL);
192197 CallInst::Create(StackChkFail, "", FailBB);
193198 new UnreachableInst(FailBB);
194199 }
195200
196201 /// RequiresStackProtector - Check whether or not this function needs a stack
197202 /// protector based upon the stack protector level.
198 bool StackProtector::RequiresStackProtector() {
203 bool StackProtector::RequiresStackProtector() const {
199204 switch (Level) {
200205 default: return false;
201 case 2: return true;
202 case 1: {
206 case SSP::ALL: return true;
207 case SSP::SOME: {
203208 // If the size of the local variables allocated on the stack is greater than
204209 // SSPBufferSize, then we require a stack protector.
205210 uint64_t StackSize = 0;
211 const TargetData *TD = TLI->getTargetData();
206212
207213 for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
208214 BasicBlock *BB = I;
209215
210216 for (BasicBlock::iterator
211217 II = BB->begin(), IE = BB->end(); II != IE; ++II)
212 if (AllocaInst *AI = dyn_cast(II))
218 if (AllocaInst *AI = dyn_cast(II)) {
213219 if (ConstantInt *CI = dyn_cast(AI->getArraySize())) {
220 uint64_t Bytes = TD->getTypeSizeInBits(AI->getAllocatedType()) / 8;
214221 const APInt &Size = CI->getValue();
215 StackSize += Size.getZExtValue() * 8;
222 StackSize += Bytes * Size.getZExtValue();
223
224 if (SSPBufferSize <= StackSize)
225 return true;
216226 }
227 }
217228 }
218
219 if (SSPBufferSize <= StackSize)
220 return true;
221229
222230 return false;
223231 }
224232 }
225233 }
226
227 // [EOF] StackProtector.cpp