@@ -353,6 +353,8 @@ struct MachineVerifier {
353
353
LaneBitmask LaneMask = LaneBitmask::getNone());
354
354
355
355
void verifyStackFrame ();
356
+ // Check that the stack protector is the top-most object in the stack.
357
+ void verifyStackProtector ();
356
358
357
359
void verifySlotIndexes () const ;
358
360
void verifyProperties (const MachineFunction &MF);
@@ -709,8 +711,10 @@ void MachineVerifier::visitMachineFunctionBefore() {
709
711
// Check that the register use lists are sane.
710
712
MRI->verifyUseLists ();
711
713
712
- if (!MF->empty ())
714
+ if (!MF->empty ()) {
713
715
verifyStackFrame ();
716
+ verifyStackProtector ();
717
+ }
714
718
}
715
719
716
720
void
@@ -4038,3 +4042,49 @@ void MachineVerifier::verifyStackFrame() {
4038
4042
}
4039
4043
}
4040
4044
}
4045
+
4046
+ void MachineVerifier::verifyStackProtector () {
4047
+ const MachineFrameInfo &MFI = MF->getFrameInfo ();
4048
+ if (!MFI.hasStackProtectorIndex ())
4049
+ return ;
4050
+ // Only applicable when the offsets of frame objects have been determined,
4051
+ // which is indicated by a non-zero stack size.
4052
+ if (!MFI.getStackSize ())
4053
+ return ;
4054
+ const TargetFrameLowering &TFI = *MF->getSubtarget ().getFrameLowering ();
4055
+ bool StackGrowsDown =
4056
+ TFI.getStackGrowthDirection () == TargetFrameLowering::StackGrowsDown;
4057
+ // Collect the frame indices of the callee-saved registers which are spilled
4058
+ // to the stack. These are the registers that are stored above the stack
4059
+ // protector.
4060
+ SmallSet<unsigned , 4 > CalleeSavedFrameIndices;
4061
+ if (MFI.isCalleeSavedInfoValid ()) {
4062
+ for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo ()) {
4063
+ if (!Info.isSpilledToReg ())
4064
+ CalleeSavedFrameIndices.insert (Info.getFrameIdx ());
4065
+ }
4066
+ }
4067
+ unsigned FI = MFI.getStackProtectorIndex ();
4068
+ int64_t SPStart = MFI.getObjectOffset (FI);
4069
+ int64_t SPEnd = SPStart + MFI.getObjectSize (FI);
4070
+ for (unsigned I = 0 , E = MFI.getObjectIndexEnd (); I != E; ++I) {
4071
+ if (I == FI)
4072
+ continue ;
4073
+ // Variable-sized objects do not have a fixed offset.
4074
+ if (MFI.isVariableSizedObjectIndex (I))
4075
+ continue ;
4076
+ if (CalleeSavedFrameIndices.contains (I))
4077
+ continue ;
4078
+ int64_t ObjStart = MFI.getObjectOffset (I);
4079
+ int64_t ObjEnd = ObjStart + MFI.getObjectSize (I);
4080
+ if (SPStart < ObjEnd && ObjStart < SPEnd) {
4081
+ report (" Stack protector overlaps with another stack object" , MF);
4082
+ break ;
4083
+ }
4084
+ if ((StackGrowsDown && SPStart <= ObjStart) ||
4085
+ (!StackGrowsDown && SPStart >= ObjStart)) {
4086
+ report (" Stack protector is not the top-most object on the stack" , MF);
4087
+ break ;
4088
+ }
4089
+ }
4090
+ }
0 commit comments