$OpenBSD: patch-lib_Target_AArch64_AArch64FrameLowering_cpp,v 1.3 2019/07/06 15:06:36 jca Exp $

Add retguard for arm64.

Index: lib/Target/AArch64/AArch64FrameLowering.cpp
--- lib/Target/AArch64/AArch64FrameLowering.cpp.orig
+++ lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -95,6 +95,7 @@
 #include "AArch64InstrInfo.h"
 #include "AArch64MachineFunctionInfo.h"
 #include "AArch64RegisterInfo.h"
+#include "AArch64ReturnProtectorLowering.h"
 #include "AArch64Subtarget.h"
 #include "AArch64TargetMachine.h"
 #include "MCTargetDesc/AArch64AddressingModes.h"
@@ -1975,6 +1976,30 @@ void AArch64FrameLowering::determineCalleeSaves(Machin
                                 ? RegInfo->getBaseRegister()
                                 : (unsigned)AArch64::NoRegister;
 
+  unsigned SpillEstimate = SavedRegs.count();
+  for (unsigned i = 0; CSRegs[i]; ++i) {
+    unsigned Reg = CSRegs[i];
+    unsigned PairedReg = CSRegs[i ^ 1];
+    if (Reg == BasePointerReg)
+      SpillEstimate++;
+    if (produceCompactUnwindFrame(MF) && !SavedRegs.test(PairedReg))
+      SpillEstimate++;
+  }
+
+  if (MFI.hasReturnProtectorRegister() && MFI.getReturnProtectorNeedsStore()) {
+    SavedRegs.set(MFI.getReturnProtectorRegister());
+    SpillEstimate++;
+  }
+
+  SpillEstimate += 2; // Conservatively include FP+LR in the estimate
+  unsigned StackEstimate = MFI.estimateStackSize(MF) + 8 * SpillEstimate;
+
+  // The frame record needs to be created by saving the appropriate registers
+  if (hasFP(MF) || windowsRequiresStackProbe(MF, StackEstimate)) {
+    SavedRegs.set(AArch64::FP);
+    SavedRegs.set(AArch64::LR);
+  }
+
   unsigned ExtraCSSpill = 0;
   // Figure out which callee-saved registers to save/restore.
   for (unsigned i = 0; CSRegs[i]; ++i) {
@@ -2156,4 +2181,8 @@ unsigned AArch64FrameLowering::getWinEHFuncletFrameSiz
   // This is the amount of stack a funclet needs to allocate.
   return alignTo(CSSize + MF.getFrameInfo().getMaxCallFrameSize(),
                  getStackAlignment());
+}
+
+const ReturnProtectorLowering *AArch64FrameLowering::getReturnProtector() const {
+  return &RPL;
 }
