llvm.org GIT mirror llvm / f7a0c7b
Fix up -fstack-protector on linux to use the segment registers. Split out testcases per architecture and os now. Patch from Nelson Elhage. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107640 91177308-0d34-0410-b5e6-96231b3b80d8 Eric Christopher 9 years ago
8 changed file(s) with 128 addition(s) and 27 deletion(s). Raw diff Collapse all Expand all
748748 /// getFunctionAlignment - Return the Log2 alignment of this function.
749749 virtual unsigned getFunctionAlignment(const Function *) const = 0;
750750
751 /// getStackCookieLocation - Return true if the target stores stack
752 /// protector cookies at a fixed offset in some non-standard address
753 /// space, and populates the address space and offset as
754 /// appropriate.
755 virtual bool getStackCookieLocation(unsigned &AddressSpace, unsigned &Offset) const {
756 return false;
757 }
758
751759 //===--------------------------------------------------------------------===//
752760 // TargetLowering Optimization Methods
753761 //
135135 bool StackProtector::InsertStackProtectors() {
136136 BasicBlock *FailBB = 0; // The basic block to jump to if check fails.
137137 AllocaInst *AI = 0; // Place on stack that stores the stack guard.
138 Constant *StackGuardVar = 0; // The stack guard variable.
138 Value *StackGuardVar = 0; // The stack guard variable.
139139
140140 for (Function::iterator I = F->begin(), E = F->end(); I != E; ) {
141141 BasicBlock *BB = I++;
154154 //
155155 PointerType *PtrTy = PointerType::getUnqual(
156156 Type::getInt8Ty(RI->getContext()));
157 StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy);
157
158 unsigned AddressSpace, Offset;
159 if (TLI->getStackCookieLocation(AddressSpace, Offset)) {
160 Constant *ASPtr = Constant::getNullValue(
161 PointerType::get(Type::getInt8Ty(RI->getContext()), AddressSpace));
162 APInt OffsetInt(32, Offset);
163 Constant *OffsetVal = Constant::getIntegerValue(
164 Type::getInt32Ty(RI->getContext()), OffsetInt);
165 StackGuardVar = ConstantExpr::getPointerCast(
166 ConstantExpr::getGetElementPtr(ASPtr, &OffsetVal, 1),
167 PointerType::get(PtrTy, AddressSpace));
168 } else {
169 StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy);
170 }
158171
159172 BasicBlock &Entry = F->getEntryBlock();
160173 Instruction *InsPt = &Entry.front();
11871187 unsigned X86TargetLowering::getFunctionAlignment(const Function *F) const {
11881188 return F->hasFnAttr(Attribute::OptimizeForSize) ? 0 : 4;
11891189 }
1190
1191 bool X86TargetLowering::getStackCookieLocation(unsigned &AddressSpace,
1192 unsigned &Offset) const {
1193 if (!Subtarget->isTargetLinux())
1194 return false;
1195
1196 if (Subtarget->is64Bit()) {
1197 // %fs:0x28, unless we're using a Kernel code model, in which case it's %gs:
1198 Offset = 0x28;
1199 if (getTargetMachine().getCodeModel() == CodeModel::Kernel)
1200 AddressSpace = 256;
1201 else
1202 AddressSpace = 257;
1203 } else {
1204 // %gs:0x14 on i386
1205 Offset = 0x14;
1206 AddressSpace = 256;
1207 }
1208 return true;
1209 }
1210
11901211
11911212 //===----------------------------------------------------------------------===//
11921213 // Return Value Calling Convention Implementation
591591
592592 /// getFunctionAlignment - Return the Log2 alignment of this function.
593593 virtual unsigned getFunctionAlignment(const Function *F) const;
594
595 /// getStackCookieLocation - Return true if the target stores stack
596 /// protector cookies at a fixed offset in some non-standard address
597 /// space, and populates the address space and offset as
598 /// appropriate.
599 virtual bool getStackCookieLocation(unsigned &AddressSpace, unsigned &Offset) const;
594600
595601 private:
596602 /// Subtarget - Keep a pointer to the X86Subtarget around so that we can
+0
-25
test/CodeGen/Generic/stack-protector.ll less more
None ; RUN: llc < %s -o - | grep {__stack_chk_guard}
1 ; RUN: llc < %s -o - | grep {__stack_chk_fail}
2
3 @"\01LC" = internal constant [11 x i8] c"buf == %s\0A\00" ; <[11 x i8]*> [#uses=1]
4
5 define void @test(i8* %a) nounwind ssp {
6 entry:
7 %a_addr = alloca i8* ; [#uses=2]
8 %buf = alloca [8 x i8] ; <[8 x i8]*> [#uses=2]
9 %"alloca point" = bitcast i32 0 to i32 ; [#uses=0]
10 store i8* %a, i8** %a_addr
11 %buf1 = bitcast [8 x i8]* %buf to i8* ; [#uses=1]
12 %0 = load i8** %a_addr, align 4 ; [#uses=1]
13 %1 = call i8* @strcpy(i8* %buf1, i8* %0) nounwind ; [#uses=0]
14 %buf2 = bitcast [8 x i8]* %buf to i8* ; [#uses=1]
15 %2 = call i32 (i8*, ...)* @printf(i8* getelementptr ([11 x i8]* @"\01LC", i32 0, i32 0), i8* %buf2) nounwind ; [#uses=0]
16 br label %return
17
18 return: ; preds = %entry
19 ret void
20 }
21
22 declare i8* @strcpy(i8*, i8*) nounwind
23
24 declare i32 @printf(i8*, ...) nounwind
0 ; RUN: llc -march=ppc32 < %s -o - | grep {__stack_chk_guard}
1 ; RUN: llc -march=ppc32 < %s -o - | grep {__stack_chk_fail}
2
3 @"\01LC" = internal constant [11 x i8] c"buf == %s\0A\00" ; <[11 x i8]*> [#uses=1]
4
5 define void @test(i8* %a) nounwind ssp {
6 entry:
7 %a_addr = alloca i8* ; [#uses=2]
8 %buf = alloca [8 x i8] ; <[8 x i8]*> [#uses=2]
9 %"alloca point" = bitcast i32 0 to i32 ; [#uses=0]
10 store i8* %a, i8** %a_addr
11 %buf1 = bitcast [8 x i8]* %buf to i8* ; [#uses=1]
12 %0 = load i8** %a_addr, align 4 ; [#uses=1]
13 %1 = call i8* @strcpy(i8* %buf1, i8* %0) nounwind ; [#uses=0]
14 %buf2 = bitcast [8 x i8]* %buf to i8* ; [#uses=1]
15 %2 = call i32 (i8*, ...)* @printf(i8* getelementptr ([11 x i8]* @"\01LC", i32 0, i32 0), i8* %buf2) nounwind ; [#uses=0]
16 br label %return
17
18 return: ; preds = %entry
19 ret void
20 }
21
22 declare i8* @strcpy(i8*, i8*) nounwind
23
24 declare i32 @printf(i8*, ...) nounwind
0 ; RUN: llc -mtriple=i386-pc-linux-gnu < %s -o - | grep %gs:
1 ; RUN: llc -mtriple=x86_64-pc-linux-gnu < %s -o - | grep %fs:
2 ; RUN: llc -code-model=kernel -mtriple=x86_64-pc-linux-gnu < %s -o - | grep %gs:
3 ; RUN: llc -mtriple=x86_64-apple-darwin < %s -o - | grep {__stack_chk_guard}
4 ; RUN: llc -mtriple=x86_64-apple-darwin < %s -o - | grep {__stack_chk_fail}
5
6 @"\01LC" = internal constant [11 x i8] c"buf == %s\0A\00" ; <[11 x i8]*> [#uses=1]
7
8 define void @test(i8* %a) nounwind ssp {
9 entry:
10 %a_addr = alloca i8* ; [#uses=2]
11 %buf = alloca [8 x i8] ; <[8 x i8]*> [#uses=2]
12 %"alloca point" = bitcast i32 0 to i32 ; [#uses=0]
13 store i8* %a, i8** %a_addr
14 %buf1 = bitcast [8 x i8]* %buf to i8* ; [#uses=1]
15 %0 = load i8** %a_addr, align 4 ; [#uses=1]
16 %1 = call i8* @strcpy(i8* %buf1, i8* %0) nounwind ; [#uses=0]
17 %buf2 = bitcast [8 x i8]* %buf to i8* ; [#uses=1]
18 %2 = call i32 (i8*, ...)* @printf(i8* getelementptr ([11 x i8]* @"\01LC", i32 0, i32 0), i8* %buf2) nounwind ; [#uses=0]
19 br label %return
20
21 return: ; preds = %entry
22 ret void
23 }
24
25 declare i8* @strcpy(i8*, i8*) nounwind
26
27 declare i32 @printf(i8*, ...) nounwind
0 ; RUN: llc -march=x86 < %s -o - | grep {__stack_chk_guard}
1 ; RUN: llc -march=x86 < %s -o - | grep {__stack_chk_fail}
2
3 @"\01LC" = internal constant [11 x i8] c"buf == %s\0A\00" ; <[11 x i8]*> [#uses=1]
4
5 define void @test(i8* %a) nounwind ssp {
6 entry:
7 %a_addr = alloca i8* ; [#uses=2]
8 %buf = alloca [8 x i8] ; <[8 x i8]*> [#uses=2]
9 %"alloca point" = bitcast i32 0 to i32 ; [#uses=0]
10 store i8* %a, i8** %a_addr
11 %buf1 = bitcast [8 x i8]* %buf to i8* ; [#uses=1]
12 %0 = load i8** %a_addr, align 4 ; [#uses=1]
13 %1 = call i8* @strcpy(i8* %buf1, i8* %0) nounwind ; [#uses=0]
14 %buf2 = bitcast [8 x i8]* %buf to i8* ; [#uses=1]
15 %2 = call i32 (i8*, ...)* @printf(i8* getelementptr ([11 x i8]* @"\01LC", i32 0, i32 0), i8* %buf2) nounwind ; [#uses=0]
16 br label %return
17
18 return: ; preds = %entry
19 ret void
20 }
21
22 declare i8* @strcpy(i8*, i8*) nounwind
23
24 declare i32 @printf(i8*, ...) nounwind