Skip to content

Commit 22662a0

Browse files
committed
Inline stack guard check on Windows
1 parent f045996 commit 22662a0

File tree

6 files changed

+228
-95
lines changed

6 files changed

+228
-95
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 59 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3059,33 +3059,6 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
30593059
if (TLI.useStackGuardXorFP())
30603060
GuardVal = TLI.emitStackGuardXorFP(DAG, GuardVal, dl);
30613061

3062-
// Retrieve guard check function, nullptr if instrumentation is inlined.
3063-
if (const Function *GuardCheckFn = TLI.getSSPStackGuardCheck(M)) {
3064-
// The target provides a guard check function to validate the guard value.
3065-
// Generate a call to that function with the content of the guard slot as
3066-
// argument.
3067-
FunctionType *FnTy = GuardCheckFn->getFunctionType();
3068-
assert(FnTy->getNumParams() == 1 && "Invalid function signature");
3069-
3070-
TargetLowering::ArgListTy Args;
3071-
TargetLowering::ArgListEntry Entry;
3072-
Entry.Node = GuardVal;
3073-
Entry.Ty = FnTy->getParamType(0);
3074-
if (GuardCheckFn->hasParamAttribute(0, Attribute::AttrKind::InReg))
3075-
Entry.IsInReg = true;
3076-
Args.push_back(Entry);
3077-
3078-
TargetLowering::CallLoweringInfo CLI(DAG);
3079-
CLI.setDebugLoc(getCurSDLoc())
3080-
.setChain(DAG.getEntryNode())
3081-
.setCallee(GuardCheckFn->getCallingConv(), FnTy->getReturnType(),
3082-
getValue(GuardCheckFn), std::move(Args));
3083-
3084-
std::pair<SDValue, SDValue> Result = TLI.LowerCallTo(CLI);
3085-
DAG.setRoot(Result.second);
3086-
return;
3087-
}
3088-
30893062
// If useLoadStackGuardNode returns true, generate LOAD_STACK_GUARD.
30903063
// Otherwise, emit a volatile load to retrieve the stack guard value.
30913064
SDValue Chain = DAG.getEntryNode();
@@ -3126,14 +3099,66 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
31263099
/// For a high level explanation of how this fits into the stack protector
31273100
/// generation see the comment on the declaration of class
31283101
/// StackProtectorDescriptor.
3129-
void
3130-
SelectionDAGBuilder::visitSPDescriptorFailure(StackProtectorDescriptor &SPD) {
3102+
void SelectionDAGBuilder::visitSPDescriptorFailure(
3103+
StackProtectorDescriptor &SPD) {
3104+
31313105
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
3132-
TargetLowering::MakeLibCallOptions CallOptions;
3133-
CallOptions.setDiscardResult(true);
3134-
SDValue Chain = TLI.makeLibCall(DAG, RTLIB::STACKPROTECTOR_CHECK_FAIL,
3135-
MVT::isVoid, {}, CallOptions, getCurSDLoc())
3136-
.second;
3106+
MachineBasicBlock *ParentBB = SPD.getParentMBB();
3107+
const Module &M = *ParentBB->getParent()->getFunction().getParent();
3108+
SDValue Chain;
3109+
3110+
// Retrieve guard check function, nullptr if instrumentation is inlined.
3111+
if (const Function *GuardCheckFn = TLI.getSSPStackGuardCheck(M)) {
3112+
3113+
// First create the loads to the guard/stack slot for the comparison.
3114+
EVT PtrTy = TLI.getPointerTy(DAG.getDataLayout());
3115+
EVT PtrMemTy = TLI.getPointerMemTy(DAG.getDataLayout());
3116+
3117+
MachineFrameInfo &MFI = ParentBB->getParent()->getFrameInfo();
3118+
int FI = MFI.getStackProtectorIndex();
3119+
3120+
SDLoc dl = getCurSDLoc();
3121+
SDValue StackSlotPtr = DAG.getFrameIndex(FI, PtrTy);
3122+
Align Align = DAG.getDataLayout().getPrefTypeAlign(
3123+
PointerType::get(M.getContext(), 0));
3124+
3125+
// Generate code to load the content of the guard slot.
3126+
SDValue GuardVal = DAG.getLoad(
3127+
PtrMemTy, dl, DAG.getEntryNode(), StackSlotPtr,
3128+
MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI), Align,
3129+
MachineMemOperand::MOVolatile);
3130+
3131+
if (TLI.useStackGuardXorFP())
3132+
GuardVal = TLI.emitStackGuardXorFP(DAG, GuardVal, dl);
3133+
3134+
// The target provides a guard check function to validate the guard value.
3135+
// Generate a call to that function with the content of the guard slot as
3136+
// argument.
3137+
FunctionType *FnTy = GuardCheckFn->getFunctionType();
3138+
assert(FnTy->getNumParams() == 1 && "Invalid function signature");
3139+
3140+
TargetLowering::ArgListTy Args;
3141+
TargetLowering::ArgListEntry Entry;
3142+
Entry.Node = GuardVal;
3143+
Entry.Ty = FnTy->getParamType(0);
3144+
if (GuardCheckFn->hasParamAttribute(0, Attribute::AttrKind::InReg))
3145+
Entry.IsInReg = true;
3146+
Args.push_back(Entry);
3147+
3148+
TargetLowering::CallLoweringInfo CLI(DAG);
3149+
CLI.setDebugLoc(getCurSDLoc())
3150+
.setChain(DAG.getEntryNode())
3151+
.setCallee(GuardCheckFn->getCallingConv(), FnTy->getReturnType(),
3152+
getValue(GuardCheckFn), std::move(Args));
3153+
3154+
Chain = TLI.LowerCallTo(CLI).second;
3155+
} else {
3156+
TargetLowering::MakeLibCallOptions CallOptions;
3157+
CallOptions.setDiscardResult(true);
3158+
Chain = TLI.makeLibCall(DAG, RTLIB::STACKPROTECTOR_CHECK_FAIL, MVT::isVoid,
3159+
{}, CallOptions, getCurSDLoc())
3160+
.second;
3161+
}
31373162

31383163
// Emit a trap instruction if we are required to do so.
31393164
const TargetOptions &TargetOpts = DAG.getTarget().Options;

llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1881,12 +1881,9 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
18811881
FastIS->recomputeInsertPt();
18821882
}
18831883

1884-
if (SP->shouldEmitSDCheck(*LLVMBB)) {
1885-
bool FunctionBasedInstrumentation =
1886-
TLI->getSSPStackGuardCheck(*Fn.getParent());
1884+
if (SP->shouldEmitSDCheck(*LLVMBB))
18871885
SDB->SPDescriptor.initialize(LLVMBB, FuncInfo->getMBB(LLVMBB),
1888-
FunctionBasedInstrumentation);
1889-
}
1886+
false);
18901887

18911888
if (Begin != BI)
18921889
++NumDAGBlocks;
@@ -1948,24 +1945,7 @@ SelectionDAGISel::FinishBasicBlock() {
19481945
PHI.addReg(FuncInfo->PHINodesToUpdate[i].second).addMBB(FuncInfo->MBB);
19491946
}
19501947

1951-
// Handle stack protector.
1952-
if (SDB->SPDescriptor.shouldEmitFunctionBasedCheckStackProtector()) {
1953-
// The target provides a guard check function. There is no need to
1954-
// generate error handling code or to split current basic block.
1955-
MachineBasicBlock *ParentMBB = SDB->SPDescriptor.getParentMBB();
1956-
1957-
// Add load and check to the basicblock.
1958-
FuncInfo->MBB = ParentMBB;
1959-
FuncInfo->InsertPt =
1960-
findSplitPointForStackProtector(ParentMBB, *TII);
1961-
SDB->visitSPDescriptorParent(SDB->SPDescriptor, ParentMBB);
1962-
CurDAG->setRoot(SDB->getRoot());
1963-
SDB->clear();
1964-
CodeGenAndEmitDAG();
1965-
1966-
// Clear the Per-BB State.
1967-
SDB->SPDescriptor.resetPerBBState();
1968-
} else if (SDB->SPDescriptor.shouldEmitStackProtector()) {
1948+
if (SDB->SPDescriptor.shouldEmitStackProtector()) {
19691949
MachineBasicBlock *ParentMBB = SDB->SPDescriptor.getParentMBB();
19701950
MachineBasicBlock *SuccessMBB = SDB->SPDescriptor.getSuccessMBB();
19711951

@@ -1979,8 +1959,7 @@ SelectionDAGISel::FinishBasicBlock() {
19791959
findSplitPointForStackProtector(ParentMBB, *TII);
19801960

19811961
// Splice the terminator of ParentMBB into SuccessMBB.
1982-
SuccessMBB->splice(SuccessMBB->end(), ParentMBB,
1983-
SplitPoint,
1962+
SuccessMBB->splice(SuccessMBB->end(), ParentMBB, SplitPoint,
19841963
ParentMBB->end());
19851964

19861965
// Add compare/jump on neq/jump to the parent BB.

llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-stack-protector-windows.ll

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,23 @@ define void @caller() sspreq {
1717
; CHECK-NEXT: ldr x8, [x8, :lo12:__security_cookie]
1818
; CHECK-NEXT: str x8, [sp, #8]
1919
; CHECK-NEXT: bl callee
20-
; CHECK-NEXT: ldr x0, [sp, #8]
21-
; CHECK-NEXT: bl __security_check_cookie
20+
; CHECK-NEXT: adrp x8, __security_cookie
21+
; CHECK-NEXT: ldr x9, [sp, #8]
22+
; CHECK-NEXT: ldr x8, [x8, :lo12:__security_cookie]
23+
; CHECK-NEXT: cmp x8, x9
24+
; CHECK-NEXT: b.ne .LBB0_2
25+
; CHECK-NEXT: // %bb.1: // %entry
2226
; CHECK-NEXT: .seh_startepilogue
2327
; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload
2428
; CHECK-NEXT: .seh_save_reg x30, 16
2529
; CHECK-NEXT: add sp, sp, #32
2630
; CHECK-NEXT: .seh_stackalloc 32
2731
; CHECK-NEXT: .seh_endepilogue
2832
; CHECK-NEXT: ret
33+
; CHECK-NEXT: .LBB0_2: // %entry
34+
; CHECK-NEXT: ldr x0, [sp, #8]
35+
; CHECK-NEXT: bl __security_check_cookie
36+
; CHECK-NEXT: brk #0x1
2937
; CHECK-NEXT: .seh_endfunclet
3038
; CHECK-NEXT: .seh_endproc
3139
entry:

0 commit comments

Comments
 (0)