diff options
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 95 |
1 files changed, 78 insertions, 17 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index e6a1dc9..c63eb7f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -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(); @@ -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( @@ -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. @@ -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, @@ -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; |