@@ -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,51 @@ 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
+ 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