@@ -353,6 +353,8 @@ struct MachineVerifier {
353353 LaneBitmask LaneMask = LaneBitmask::getNone());
354354
355355 void verifyStackFrame ();
356+ // Check that the stack protector is the top-most object in the stack.
357+ void verifyStackProtector ();
356358
357359 void verifySlotIndexes () const ;
358360 void verifyProperties (const MachineFunction &MF);
@@ -709,8 +711,10 @@ void MachineVerifier::visitMachineFunctionBefore() {
709711 // Check that the register use lists are sane.
710712 MRI->verifyUseLists ();
711713
712- if (!MF->empty ())
714+ if (!MF->empty ()) {
713715 verifyStackFrame ();
716+ verifyStackProtector ();
717+ }
714718}
715719
716720void
@@ -4038,3 +4042,49 @@ void MachineVerifier::verifyStackFrame() {
40384042 }
40394043 }
40404044}
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