Skip to content
Merged
95 changes: 78 additions & 17 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3037,8 +3037,9 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,

// First create the loads to the guard/stack slot for the comparison.
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
EVT PtrTy = TLI.getPointerTy(DAG.getDataLayout());
EVT PtrMemTy = TLI.getPointerMemTy(DAG.getDataLayout());
auto &DL = DAG.getDataLayout();
EVT PtrTy = TLI.getFrameIndexTy(DL);
EVT PtrMemTy = TLI.getPointerMemTy(DL, DL.getAllocaAddrSpace());

MachineFrameInfo &MFI = ParentBB->getParent()->getFrameInfo();
int FI = MFI.getStackProtectorIndex();
Expand All @@ -3047,8 +3048,8 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
SDLoc dl = getCurSDLoc();
SDValue StackSlotPtr = DAG.getFrameIndex(FI, PtrTy);
const Module &M = *ParentBB->getParent()->getFunction().getParent();
Align Align =
DAG.getDataLayout().getPrefTypeAlign(PointerType::get(M.getContext(), 0));
Align Align = DL.getPrefTypeAlign(
PointerType::get(M.getContext(), DL.getAllocaAddrSpace()));

// Generate code to load the content of the guard slot.
SDValue GuardVal = DAG.getLoad(
Expand All @@ -3059,8 +3060,14 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
if (TLI.useStackGuardXorFP())
GuardVal = TLI.emitStackGuardXorFP(DAG, GuardVal, dl);

// Retrieve guard check function, nullptr if instrumentation is inlined.
if (const Function *GuardCheckFn = TLI.getSSPStackGuardCheck(M)) {
// If we're using function-based instrumentation, call the guard check
// function
if (SPD.shouldEmitFunctionBasedCheckStackProtector()) {
// Get the guard check function from the target and verify it exists since
// we're using function-based instrumentation
const Function *GuardCheckFn = TLI.getSSPStackGuardCheck(M);
assert(GuardCheckFn && "Guard check function is null");

// The target provides a guard check function to validate the guard value.
// Generate a call to that function with the content of the guard slot as
// argument.
Expand Down Expand Up @@ -3101,10 +3108,9 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
}

// Perform the comparison via a getsetcc.
SDValue Cmp = DAG.getSetCC(dl, TLI.getSetCCResultType(DAG.getDataLayout(),
*DAG.getContext(),
Guard.getValueType()),
Guard, GuardVal, ISD::SETNE);
SDValue Cmp = DAG.getSetCC(
dl, TLI.getSetCCResultType(DL, *DAG.getContext(), Guard.getValueType()),
Guard, GuardVal, ISD::SETNE);

// If the guard/stackslot do not equal, branch to failure MBB.
SDValue BrCond = DAG.getNode(ISD::BRCOND, dl,
Expand All @@ -3126,14 +3132,69 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
/// For a high level explanation of how this fits into the stack protector
/// generation see the comment on the declaration of class
/// StackProtectorDescriptor.
void
SelectionDAGBuilder::visitSPDescriptorFailure(StackProtectorDescriptor &SPD) {
void SelectionDAGBuilder::visitSPDescriptorFailure(
StackProtectorDescriptor &SPD) {

const TargetLowering &TLI = DAG.getTargetLoweringInfo();
TargetLowering::MakeLibCallOptions CallOptions;
CallOptions.setDiscardResult(true);
SDValue Chain = TLI.makeLibCall(DAG, RTLIB::STACKPROTECTOR_CHECK_FAIL,
MVT::isVoid, {}, CallOptions, getCurSDLoc())
.second;
MachineBasicBlock *ParentBB = SPD.getParentMBB();
const Module &M = *ParentBB->getParent()->getFunction().getParent();
SDValue Chain;

// For -Oz builds with a guard check function, we use function-based
// instrumentation. Otherwise, if we have a guard check function, we call it
// in the failure block.
auto *GuardCheckFn = TLI.getSSPStackGuardCheck(M);
if (GuardCheckFn && !SPD.shouldEmitFunctionBasedCheckStackProtector()) {
// First create the loads to the guard/stack slot for the comparison.
auto &DL = DAG.getDataLayout();
EVT PtrTy = TLI.getFrameIndexTy(DL);
EVT PtrMemTy = TLI.getPointerMemTy(DL, DL.getAllocaAddrSpace());

MachineFrameInfo &MFI = ParentBB->getParent()->getFrameInfo();
int FI = MFI.getStackProtectorIndex();

SDLoc dl = getCurSDLoc();
SDValue StackSlotPtr = DAG.getFrameIndex(FI, PtrTy);
Align Align = DL.getPrefTypeAlign(
PointerType::get(M.getContext(), DL.getAllocaAddrSpace()));

// Generate code to load the content of the guard slot.
SDValue GuardVal = DAG.getLoad(
PtrMemTy, dl, DAG.getEntryNode(), StackSlotPtr,
MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI), Align,
MachineMemOperand::MOVolatile);

if (TLI.useStackGuardXorFP())
GuardVal = TLI.emitStackGuardXorFP(DAG, GuardVal, dl);

// The target provides a guard check function to validate the guard value.
// Generate a call to that function with the content of the guard slot as
// argument.
FunctionType *FnTy = GuardCheckFn->getFunctionType();
assert(FnTy->getNumParams() == 1 && "Invalid function signature");

TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
Entry.Node = GuardVal;
Entry.Ty = FnTy->getParamType(0);
if (GuardCheckFn->hasParamAttribute(0, Attribute::AttrKind::InReg))
Entry.IsInReg = true;
Args.push_back(Entry);

TargetLowering::CallLoweringInfo CLI(DAG);
CLI.setDebugLoc(getCurSDLoc())
.setChain(DAG.getEntryNode())
.setCallee(GuardCheckFn->getCallingConv(), FnTy->getReturnType(),
getValue(GuardCheckFn), std::move(Args));

Chain = TLI.LowerCallTo(CLI).second;
} else {
TargetLowering::MakeLibCallOptions CallOptions;
CallOptions.setDiscardResult(true);
Chain = TLI.makeLibCall(DAG, RTLIB::STACKPROTECTOR_CHECK_FAIL, MVT::isVoid,
{}, CallOptions, getCurSDLoc())
.second;
}

// Emit a trap instruction if we are required to do so.
const TargetOptions &TargetOpts = DAG.getTarget().Options;
Expand Down
8 changes: 3 additions & 5 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1877,7 +1877,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {

if (SP->shouldEmitSDCheck(*LLVMBB)) {
bool FunctionBasedInstrumentation =
TLI->getSSPStackGuardCheck(*Fn.getParent());
TLI->getSSPStackGuardCheck(*Fn.getParent()) && Fn.hasMinSize();
SDB->SPDescriptor.initialize(LLVMBB, FuncInfo->getMBB(LLVMBB),
FunctionBasedInstrumentation);
}
Expand Down Expand Up @@ -1950,8 +1950,7 @@ SelectionDAGISel::FinishBasicBlock() {

// Add load and check to the basicblock.
FuncInfo->MBB = ParentMBB;
FuncInfo->InsertPt =
findSplitPointForStackProtector(ParentMBB, *TII);
FuncInfo->InsertPt = findSplitPointForStackProtector(ParentMBB, *TII);
SDB->visitSPDescriptorParent(SDB->SPDescriptor, ParentMBB);
CurDAG->setRoot(SDB->getRoot());
SDB->clear();
Expand All @@ -1973,8 +1972,7 @@ SelectionDAGISel::FinishBasicBlock() {
findSplitPointForStackProtector(ParentMBB, *TII);

// Splice the terminator of ParentMBB into SuccessMBB.
SuccessMBB->splice(SuccessMBB->end(), ParentMBB,
SplitPoint,
SuccessMBB->splice(SuccessMBB->end(), ParentMBB, SplitPoint,
ParentMBB->end());

// Add compare/jump on neq/jump to the parent BB.
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/Target/X86/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ set(sources
X86VZeroUpper.cpp
X86WinEHState.cpp
X86WinEHUnwindV2.cpp
X86WinFixupBufferSecurityCheck.cpp
X86InsertWait.cpp
GISel/X86CallLowering.cpp
GISel/X86InstructionSelector.cpp
Expand Down
4 changes: 0 additions & 4 deletions llvm/lib/Target/X86/X86.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@ FunctionPass *createX86OptimizeLEAs();
/// Return a pass that transforms setcc + movzx pairs into xor + setcc.
FunctionPass *createX86FixupSetCC();

/// Return a pass that transform inline buffer security check into seperate bb
FunctionPass *createX86WinFixupBufferSecurityCheckPass();

/// Return a pass that avoids creating store forward block issues in the hardware.
FunctionPass *createX86AvoidStoreForwardingBlocks();

Expand Down Expand Up @@ -195,7 +192,6 @@ void initializeX86ExpandPseudoPass(PassRegistry &);
void initializeX86FastPreTileConfigPass(PassRegistry &);
void initializeX86FastTileConfigPass(PassRegistry &);
void initializeX86FixupSetCCPassPass(PassRegistry &);
void initializeX86WinFixupBufferSecurityCheckPassPass(PassRegistry &);
void initializeX86FlagsCopyLoweringPassPass(PassRegistry &);
void initializeX86LoadValueInjectionLoadHardeningPassPass(PassRegistry &);
void initializeX86LoadValueInjectionRetHardeningPassPass(PassRegistry &);
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/Target/X86/X86TargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,6 @@ bool X86PassConfig::addPreISel() {
void X86PassConfig::addPreRegAlloc() {
if (getOptLevel() != CodeGenOptLevel::None) {
addPass(&LiveRangeShrinkID);
addPass(createX86WinFixupBufferSecurityCheckPass());
addPass(createX86FixupSetCC());
addPass(createX86OptimizeLEAs());
addPass(createX86CallFrameOptimization());
Expand Down
Loading
Loading