Skip to content

Commit 1f7f268

Browse files
authored
StackProtector: use isInTailCallPosition to verify tail call position (#68997)
The issue is caused by [D133860](https://reviews.llvm.org/D133860). The guard would be inserted in wrong place in some cases, like the test case showed below. This patch fixed the issue by using `isInTailCallPosition()` to verify whether the tail call is in right position.
1 parent 5715510 commit 1f7f268

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed

llvm/lib/CodeGen/StackProtector.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/Analysis/BranchProbabilityInfo.h"
2121
#include "llvm/Analysis/MemoryLocation.h"
2222
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
23+
#include "llvm/CodeGen/Analysis.h"
2324
#include "llvm/CodeGen/Passes.h"
2425
#include "llvm/CodeGen/TargetLowering.h"
2526
#include "llvm/CodeGen/TargetPassConfig.h"
@@ -625,18 +626,11 @@ bool InsertStackProtectors(const TargetMachine *TM, Function *F,
625626
HasIRCheck = true;
626627

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

641635
// Generate epilogue instrumentation. The epilogue intrumentation can be
642636
// function-based or inlined depending on which mechanism the target is

llvm/test/CodeGen/X86/tailcc-ssp.ll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,24 @@ define void @tailcall_unrelated_frame() sspreq {
101101
tail call void @bar()
102102
ret void
103103
}
104+
105+
declare void @callee()
106+
define void @caller() sspreq {
107+
; WINDOWS-LABEL: caller:
108+
; WINDOWS: callq callee
109+
; WINDOWS: callq callee
110+
; WINDOWS: cmpq __security_cookie(%rip), %rcx
111+
; WINDOWS: jne
112+
; WINDOWS: callq __security_check_cookie
113+
114+
; LINUX-LABEL: caller:
115+
; LINUX: callq callee@PLT
116+
; LINUX: callq callee@PLT
117+
; LINUX: cmpq
118+
; LINUX: jne
119+
; LINUX: callq __stack_chk_fail@PLT
120+
121+
tail call void @callee()
122+
call void @callee()
123+
ret void
124+
}

0 commit comments

Comments
 (0)