Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 4 additions & 10 deletions llvm/lib/CodeGen/StackProtector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetPassConfig.h"
Expand Down Expand Up @@ -625,18 +626,11 @@ bool InsertStackProtectors(const TargetMachine *TM, Function *F,
HasIRCheck = true;

// If we're instrumenting a block with a tail call, the check has to be
// inserted before the call rather than between it and the return. The
// verifier guarantees that a tail call is either directly before the
// return or with a single correct bitcast of the return value in between so
// we don't need to worry about many situations here.
// inserted before the call rather than between it and the return.
Instruction *Prev = CheckLoc->getPrevNonDebugInstruction();
if (Prev && isa<CallInst>(Prev) && cast<CallInst>(Prev)->isTailCall())
CheckLoc = Prev;
else if (Prev) {
Prev = Prev->getPrevNonDebugInstruction();
if (Prev && isa<CallInst>(Prev) && cast<CallInst>(Prev)->isTailCall())
if (auto *CI = dyn_cast_if_present<CallInst>(Prev))
if (CI->isTailCall() && isInTailCallPosition(*CI, *TM))
CheckLoc = Prev;
}

// Generate epilogue instrumentation. The epilogue intrumentation can be
// function-based or inlined depending on which mechanism the target is
Expand Down
21 changes: 21 additions & 0 deletions llvm/test/CodeGen/X86/tailcc-ssp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,24 @@ define void @tailcall_unrelated_frame() sspreq {
tail call void @bar()
ret void
}

declare void @callee()
define void @caller() sspreq {
; WINDOWS-LABEL: caller:
; WINDOWS: callq callee
; WINDOWS: callq callee
; WINDOWS: cmpq __security_cookie(%rip), %rcx
; WINDOWS: jne
; WINDOWS: callq __security_check_cookie

; LINUX-LABEL: caller:
; LINUX: callq callee@PLT
; LINUX: callq callee@PLT
; LINUX: cmpq
; LINUX: jne
; LINUX: callq __stack_chk_fail@PLT

tail call void @callee()
call void @callee()
ret void
}