@@ -3037,8 +3037,9 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
3037
3037
3038
3038
// First create the loads to the guard/stack slot for the comparison.
3039
3039
const TargetLowering &TLI = DAG.getTargetLoweringInfo ();
3040
- EVT PtrTy = TLI.getPointerTy (DAG.getDataLayout ());
3041
- EVT PtrMemTy = TLI.getPointerMemTy (DAG.getDataLayout ());
3040
+ auto &DL = DAG.getDataLayout ();
3041
+ EVT PtrTy = TLI.getFrameIndexTy (DL);
3042
+ EVT PtrMemTy = TLI.getPointerMemTy (DL, DL.getAllocaAddrSpace ());
3042
3043
3043
3044
MachineFrameInfo &MFI = ParentBB->getParent ()->getFrameInfo ();
3044
3045
int FI = MFI.getStackProtectorIndex ();
@@ -3047,8 +3048,8 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
3047
3048
SDLoc dl = getCurSDLoc ();
3048
3049
SDValue StackSlotPtr = DAG.getFrameIndex (FI, PtrTy);
3049
3050
const Module &M = *ParentBB->getParent ()->getFunction ().getParent ();
3050
- Align Align =
3051
- DAG. getDataLayout (). getPrefTypeAlign ( PointerType::get (M.getContext (), 0 ));
3051
+ Align Align = DL. getPrefTypeAlign (
3052
+ PointerType::get (M.getContext (), DL. getAllocaAddrSpace () ));
3052
3053
3053
3054
// Generate code to load the content of the guard slot.
3054
3055
SDValue GuardVal = DAG.getLoad (
@@ -3059,8 +3060,14 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
3059
3060
if (TLI.useStackGuardXorFP ())
3060
3061
GuardVal = TLI.emitStackGuardXorFP (DAG, GuardVal, dl);
3061
3062
3062
- // Retrieve guard check function, nullptr if instrumentation is inlined.
3063
- if (const Function *GuardCheckFn = TLI.getSSPStackGuardCheck (M)) {
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
+
3064
3071
// The target provides a guard check function to validate the guard value.
3065
3072
// Generate a call to that function with the content of the guard slot as
3066
3073
// argument.
@@ -3101,10 +3108,9 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
3101
3108
}
3102
3109
3103
3110
// Perform the comparison via a getsetcc.
3104
- SDValue Cmp = DAG.getSetCC (dl, TLI.getSetCCResultType (DAG.getDataLayout (),
3105
- *DAG.getContext (),
3106
- Guard.getValueType ()),
3107
- Guard, GuardVal, ISD::SETNE);
3111
+ SDValue Cmp = DAG.getSetCC (
3112
+ dl, TLI.getSetCCResultType (DL, *DAG.getContext (), Guard.getValueType ()),
3113
+ Guard, GuardVal, ISD::SETNE);
3108
3114
3109
3115
// If the guard/stackslot do not equal, branch to failure MBB.
3110
3116
SDValue BrCond = DAG.getNode (ISD::BRCOND, dl,
@@ -3126,14 +3132,69 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
3126
3132
// / For a high level explanation of how this fits into the stack protector
3127
3133
// / generation see the comment on the declaration of class
3128
3134
// / StackProtectorDescriptor.
3129
- void
3130
- SelectionDAGBuilder::visitSPDescriptorFailure (StackProtectorDescriptor &SPD) {
3135
+ void SelectionDAGBuilder::visitSPDescriptorFailure (
3136
+ StackProtectorDescriptor &SPD) {
3137
+
3131
3138
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 ;
3139
+ MachineBasicBlock *ParentBB = SPD.getParentMBB ();
3140
+ const Module &M = *ParentBB->getParent ()->getFunction ().getParent ();
3141
+ SDValue Chain;
3142
+
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 ()) {
3148
+ // First create the loads to the guard/stack slot for the comparison.
3149
+ auto &DL = DAG.getDataLayout ();
3150
+ EVT PtrTy = TLI.getFrameIndexTy (DL);
3151
+ EVT PtrMemTy = TLI.getPointerMemTy (DL, DL.getAllocaAddrSpace ());
3152
+
3153
+ MachineFrameInfo &MFI = ParentBB->getParent ()->getFrameInfo ();
3154
+ int FI = MFI.getStackProtectorIndex ();
3155
+
3156
+ SDLoc dl = getCurSDLoc ();
3157
+ SDValue StackSlotPtr = DAG.getFrameIndex (FI, PtrTy);
3158
+ Align Align = DL.getPrefTypeAlign (
3159
+ PointerType::get (M.getContext (), DL.getAllocaAddrSpace ()));
3160
+
3161
+ // Generate code to load the content of the guard slot.
3162
+ SDValue GuardVal = DAG.getLoad (
3163
+ PtrMemTy, dl, DAG.getEntryNode (), StackSlotPtr,
3164
+ MachinePointerInfo::getFixedStack (DAG.getMachineFunction (), FI), Align,
3165
+ MachineMemOperand::MOVolatile);
3166
+
3167
+ if (TLI.useStackGuardXorFP ())
3168
+ GuardVal = TLI.emitStackGuardXorFP (DAG, GuardVal, dl);
3169
+
3170
+ // The target provides a guard check function to validate the guard value.
3171
+ // Generate a call to that function with the content of the guard slot as
3172
+ // argument.
3173
+ FunctionType *FnTy = GuardCheckFn->getFunctionType ();
3174
+ assert (FnTy->getNumParams () == 1 && " Invalid function signature" );
3175
+
3176
+ TargetLowering::ArgListTy Args;
3177
+ TargetLowering::ArgListEntry Entry;
3178
+ Entry.Node = GuardVal;
3179
+ Entry.Ty = FnTy->getParamType (0 );
3180
+ if (GuardCheckFn->hasParamAttribute (0 , Attribute::AttrKind::InReg))
3181
+ Entry.IsInReg = true ;
3182
+ Args.push_back (Entry);
3183
+
3184
+ TargetLowering::CallLoweringInfo CLI (DAG);
3185
+ CLI.setDebugLoc (getCurSDLoc ())
3186
+ .setChain (DAG.getEntryNode ())
3187
+ .setCallee (GuardCheckFn->getCallingConv (), FnTy->getReturnType (),
3188
+ getValue (GuardCheckFn), std::move (Args));
3189
+
3190
+ Chain = TLI.LowerCallTo (CLI).second ;
3191
+ } else {
3192
+ TargetLowering::MakeLibCallOptions CallOptions;
3193
+ CallOptions.setDiscardResult (true );
3194
+ Chain = TLI.makeLibCall (DAG, RTLIB::STACKPROTECTOR_CHECK_FAIL, MVT::isVoid,
3195
+ {}, CallOptions, getCurSDLoc ())
3196
+ .second ;
3197
+ }
3137
3198
3138
3199
// Emit a trap instruction if we are required to do so.
3139
3200
const TargetOptions &TargetOpts = DAG.getTarget ().Options ;
0 commit comments