@@ -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,51 @@ 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+ unsigned FI = MFI.getStackProtectorIndex ();
4058+ int64_t SPStart = MFI.getObjectOffset (FI);
4059+ int64_t SPEnd = SPStart + MFI.getObjectSize (FI);
4060+ for (unsigned I = 0 , E = MFI.getObjectIndexEnd (); I != E; ++I) {
4061+ if (I == FI)
4062+ continue ;
4063+ if (MFI.isDeadObjectIndex (I))
4064+ continue ;
4065+ // FIXME: Skip non-default stack objects, as some targets may place them
4066+ // above the stack protector. This is a workaround for the fact that
4067+ // backends such as AArch64 may place SVE stack objects *above* the stack
4068+ // protector.
4069+ if (MFI.getStackID (I) != TargetStackID::Default)
4070+ continue ;
4071+ // Skip variable-sized objects because they do not have a fixed offset.
4072+ if (MFI.isVariableSizedObjectIndex (I))
4073+ continue ;
4074+ // FIXME: Skip spill slots which may be allocated above the stack protector.
4075+ // Ideally this would only skip callee-saved registers, but we don't have
4076+ // that information here. For example, spill-slots used for scavenging are
4077+ // not described in CalleeSavedInfo.
4078+ if (MFI.isSpillSlotObjectIndex (I))
4079+ continue ;
4080+ int64_t ObjStart = MFI.getObjectOffset (I);
4081+ int64_t ObjEnd = ObjStart + MFI.getObjectSize (I);
4082+ if (SPStart < ObjEnd && ObjStart < SPEnd) {
4083+ report (" Stack protector overlaps with another stack object" , MF);
4084+ break ;
4085+ }
4086+ if ((StackGrowsDown && SPStart <= ObjStart) ||
4087+ (!StackGrowsDown && SPStart >= ObjStart)) {
4088+ report (" Stack protector is not the top-most object on the stack" , MF);
4089+ break ;
4090+ }
4091+ }
4092+ }
0 commit comments