Skip to content

Commit

Permalink
Fix up -fstack-protector on linux to use the segment
Browse files Browse the repository at this point in the history
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
  • Loading branch information
echristo committed Jul 6, 2010
1 parent 10d2f4d commit f7a0c7b
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 6 deletions.
8 changes: 8 additions & 0 deletions include/llvm/Target/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,14 @@ class TargetLowering {
/// getFunctionAlignment - Return the Log2 alignment of this function.
virtual unsigned getFunctionAlignment(const Function *) const = 0;

/// getStackCookieLocation - Return true if the target stores stack
/// protector cookies at a fixed offset in some non-standard address
/// space, and populates the address space and offset as
/// appropriate.
virtual bool getStackCookieLocation(unsigned &AddressSpace, unsigned &Offset) const {
return false;
}

//===--------------------------------------------------------------------===//
// TargetLowering Optimization Methods
//
Expand Down
17 changes: 15 additions & 2 deletions lib/CodeGen/StackProtector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ bool StackProtector::RequiresStackProtector() const {
bool StackProtector::InsertStackProtectors() {
BasicBlock *FailBB = 0; // The basic block to jump to if check fails.
AllocaInst *AI = 0; // Place on stack that stores the stack guard.
Constant *StackGuardVar = 0; // The stack guard variable.
Value *StackGuardVar = 0; // The stack guard variable.

for (Function::iterator I = F->begin(), E = F->end(); I != E; ) {
BasicBlock *BB = I++;
Expand All @@ -155,7 +155,20 @@ bool StackProtector::InsertStackProtectors() {
//
PointerType *PtrTy = PointerType::getUnqual(
Type::getInt8Ty(RI->getContext()));
StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy);

unsigned AddressSpace, Offset;
if (TLI->getStackCookieLocation(AddressSpace, Offset)) {
Constant *ASPtr = Constant::getNullValue(
PointerType::get(Type::getInt8Ty(RI->getContext()), AddressSpace));
APInt OffsetInt(32, Offset);
Constant *OffsetVal = Constant::getIntegerValue(
Type::getInt32Ty(RI->getContext()), OffsetInt);
StackGuardVar = ConstantExpr::getPointerCast(
ConstantExpr::getGetElementPtr(ASPtr, &OffsetVal, 1),
PointerType::get(PtrTy, AddressSpace));
} else {
StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy);
}

BasicBlock &Entry = F->getEntryBlock();
Instruction *InsPt = &Entry.front();
Expand Down
21 changes: 21 additions & 0 deletions lib/Target/X86/X86ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1189,6 +1189,27 @@ unsigned X86TargetLowering::getFunctionAlignment(const Function *F) const {
return F->hasFnAttr(Attribute::OptimizeForSize) ? 0 : 4;
}

bool X86TargetLowering::getStackCookieLocation(unsigned &AddressSpace,
unsigned &Offset) const {
if (!Subtarget->isTargetLinux())
return false;

if (Subtarget->is64Bit()) {
// %fs:0x28, unless we're using a Kernel code model, in which case it's %gs:
Offset = 0x28;
if (getTargetMachine().getCodeModel() == CodeModel::Kernel)
AddressSpace = 256;
else
AddressSpace = 257;
} else {
// %gs:0x14 on i386
Offset = 0x14;
AddressSpace = 256;
}
return true;
}


//===----------------------------------------------------------------------===//
// Return Value Calling Convention Implementation
//===----------------------------------------------------------------------===//
Expand Down
6 changes: 6 additions & 0 deletions lib/Target/X86/X86ISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,12 @@ namespace llvm {
/// getFunctionAlignment - Return the Log2 alignment of this function.
virtual unsigned getFunctionAlignment(const Function *F) const;

/// getStackCookieLocation - Return true if the target stores stack
/// protector cookies at a fixed offset in some non-standard address
/// space, and populates the address space and offset as
/// appropriate.
virtual bool getStackCookieLocation(unsigned &AddressSpace, unsigned &Offset) const;

private:
/// Subtarget - Keep a pointer to the X86Subtarget around so that we can
/// make the right decision when generating code for different targets.
Expand Down
25 changes: 25 additions & 0 deletions test/CodeGen/PowerPC/stack-protector.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
; RUN: llc -march=ppc32 < %s -o - | grep {__stack_chk_guard}
; RUN: llc -march=ppc32 < %s -o - | grep {__stack_chk_fail}

@"\01LC" = internal constant [11 x i8] c"buf == %s\0A\00" ; <[11 x i8]*> [#uses=1]

define void @test(i8* %a) nounwind ssp {
entry:
%a_addr = alloca i8* ; <i8**> [#uses=2]
%buf = alloca [8 x i8] ; <[8 x i8]*> [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
store i8* %a, i8** %a_addr
%buf1 = bitcast [8 x i8]* %buf to i8* ; <i8*> [#uses=1]
%0 = load i8** %a_addr, align 4 ; <i8*> [#uses=1]
%1 = call i8* @strcpy(i8* %buf1, i8* %0) nounwind ; <i8*> [#uses=0]
%buf2 = bitcast [8 x i8]* %buf to i8* ; <i8*> [#uses=1]
%2 = call i32 (i8*, ...)* @printf(i8* getelementptr ([11 x i8]* @"\01LC", i32 0, i32 0), i8* %buf2) nounwind ; <i32> [#uses=0]
br label %return

return: ; preds = %entry
ret void
}

declare i8* @strcpy(i8*, i8*) nounwind

declare i32 @printf(i8*, ...) nounwind
28 changes: 28 additions & 0 deletions test/CodeGen/X86/stack-protector-linux.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
; RUN: llc -mtriple=i386-pc-linux-gnu < %s -o - | grep %gs:
; RUN: llc -mtriple=x86_64-pc-linux-gnu < %s -o - | grep %fs:
; RUN: llc -code-model=kernel -mtriple=x86_64-pc-linux-gnu < %s -o - | grep %gs:
; RUN: llc -mtriple=x86_64-apple-darwin < %s -o - | grep {__stack_chk_guard}
; RUN: llc -mtriple=x86_64-apple-darwin < %s -o - | grep {__stack_chk_fail}

@"\01LC" = internal constant [11 x i8] c"buf == %s\0A\00" ; <[11 x i8]*> [#uses=1]

define void @test(i8* %a) nounwind ssp {
entry:
%a_addr = alloca i8* ; <i8**> [#uses=2]
%buf = alloca [8 x i8] ; <[8 x i8]*> [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
store i8* %a, i8** %a_addr
%buf1 = bitcast [8 x i8]* %buf to i8* ; <i8*> [#uses=1]
%0 = load i8** %a_addr, align 4 ; <i8*> [#uses=1]
%1 = call i8* @strcpy(i8* %buf1, i8* %0) nounwind ; <i8*> [#uses=0]
%buf2 = bitcast [8 x i8]* %buf to i8* ; <i8*> [#uses=1]
%2 = call i32 (i8*, ...)* @printf(i8* getelementptr ([11 x i8]* @"\01LC", i32 0, i32 0), i8* %buf2) nounwind ; <i32> [#uses=0]
br label %return

return: ; preds = %entry
ret void
}

declare i8* @strcpy(i8*, i8*) nounwind

declare i32 @printf(i8*, ...) nounwind
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
; RUN: llc < %s -o - | grep {__stack_chk_guard}
; RUN: llc < %s -o - | grep {__stack_chk_fail}
; RUN: llc -march=x86 < %s -o - | grep {__stack_chk_guard}
; RUN: llc -march=x86 < %s -o - | grep {__stack_chk_fail}

@"\01LC" = internal constant [11 x i8] c"buf == %s\0A\00" ; <[11 x i8]*> [#uses=1]

define void @test(i8* %a) nounwind ssp {
entry:
%a_addr = alloca i8* ; <i8**> [#uses=2]
%buf = alloca [8 x i8] ; <[8 x i8]*> [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
store i8* %a, i8** %a_addr
%buf1 = bitcast [8 x i8]* %buf to i8* ; <i8*> [#uses=1]
%0 = load i8** %a_addr, align 4 ; <i8*> [#uses=1]
%1 = call i8* @strcpy(i8* %buf1, i8* %0) nounwind ; <i8*> [#uses=0]
%buf2 = bitcast [8 x i8]* %buf to i8* ; <i8*> [#uses=1]
%buf2 = bitcast [8 x i8]* %buf to i8* ; <i8*> [#uses=1]
%2 = call i32 (i8*, ...)* @printf(i8* getelementptr ([11 x i8]* @"\01LC", i32 0, i32 0), i8* %buf2) nounwind ; <i32> [#uses=0]
br label %return

Expand Down

0 comments on commit f7a0c7b

Please sign in to comment.