@@ -3060,6 +3060,39 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
30603060 if (TLI.useStackGuardXorFP ())
30613061 GuardVal = TLI.emitStackGuardXorFP (DAG, GuardVal, dl);
30623062
3063+ // If we're using function-based instrumentation, call the guard check
3064+ // function
3065+ if (SPD.shouldEmitFunctionBasedCheckStackProtector ()) {
3066+ // Get the guard check function from the target and verify it exists since
3067+ // we're using function-based instrumentation
3068+ const Function *GuardCheckFn = TLI.getSSPStackGuardCheck (M);
3069+ assert (GuardCheckFn && " Guard check function is null" );
3070+
3071+ // The target provides a guard check function to validate the guard value.
3072+ // Generate a call to that function with the content of the guard slot as
3073+ // argument.
3074+ FunctionType *FnTy = GuardCheckFn->getFunctionType ();
3075+ assert (FnTy->getNumParams () == 1 && " Invalid function signature" );
3076+
3077+ TargetLowering::ArgListTy Args;
3078+ TargetLowering::ArgListEntry Entry;
3079+ Entry.Node = GuardVal;
3080+ Entry.Ty = FnTy->getParamType (0 );
3081+ if (GuardCheckFn->hasParamAttribute (0 , Attribute::AttrKind::InReg))
3082+ Entry.IsInReg = true ;
3083+ Args.push_back (Entry);
3084+
3085+ TargetLowering::CallLoweringInfo CLI (DAG);
3086+ CLI.setDebugLoc (getCurSDLoc ())
3087+ .setChain (DAG.getEntryNode ())
3088+ .setCallee (GuardCheckFn->getCallingConv (), FnTy->getReturnType (),
3089+ getValue (GuardCheckFn), std::move (Args));
3090+
3091+ std::pair<SDValue, SDValue> Result = TLI.LowerCallTo (CLI);
3092+ DAG.setRoot (Result.second );
3093+ return ;
3094+ }
3095+
30633096 // If useLoadStackGuardNode returns true, generate LOAD_STACK_GUARD.
30643097 // Otherwise, emit a volatile load to retrieve the stack guard value.
30653098 SDValue Chain = DAG.getEntryNode ();
@@ -3107,9 +3140,11 @@ void SelectionDAGBuilder::visitSPDescriptorFailure(
31073140 const Module &M = *ParentBB->getParent ()->getFunction ().getParent ();
31083141 SDValue Chain;
31093142
3110- // Retrieve guard check function, nullptr if instrumentation is inlined.
3111- if (const Function *GuardCheckFn = TLI.getSSPStackGuardCheck (M)) {
3112-
3143+ // For -Oz builds with a guard check function, we use function-based
3144+ // instrumentation. Otherwise, if we have a guard check function, we call it
3145+ // in the failure block.
3146+ auto *GuardCheckFn = TLI.getSSPStackGuardCheck (M);
3147+ if (GuardCheckFn && !SPD.shouldEmitFunctionBasedCheckStackProtector ()) {
31133148 // First create the loads to the guard/stack slot for the comparison.
31143149 auto &DL = DAG.getDataLayout ();
31153150 EVT PtrTy = TLI.getFrameIndexTy (DL);
0 commit comments