summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormortimer <mortimer@cvs.openbsd.org>2020-10-12 14:52:09 +0000
committermortimer <mortimer@cvs.openbsd.org>2020-10-12 14:52:09 +0000
commit570f86ea0446681932f07e5ac2b6183a7ebe8950 (patch)
treeb98b9af351a0e69a95a68f87b16818524d8821df
parentfc3e3ab2ad7cd3bb895c1c6f8c0d0c117502b586 (diff)
Add RETGUARD implementation for powerpc and powerpc64.
ok deraadt@ kettenis@
-rw-r--r--gnu/llvm/clang/lib/Driver/ToolChains/Clang.cpp4
-rw-r--r--gnu/llvm/llvm/lib/Target/PowerPC/CMakeLists.txt1
-rw-r--r--gnu/llvm/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp86
-rw-r--r--gnu/llvm/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp5
-rw-r--r--gnu/llvm/llvm/lib/Target/PowerPC/PPCFrameLowering.h4
-rw-r--r--gnu/llvm/llvm/lib/Target/PowerPC/PPCInstrInfo.td25
-rw-r--r--gnu/llvm/llvm/lib/Target/PowerPC/PPCReturnProtectorLowering.cpp285
-rw-r--r--gnu/llvm/llvm/lib/Target/PowerPC/PPCReturnProtectorLowering.h46
-rw-r--r--gnu/usr.bin/clang/libLLVMPowerPCCodeGen/Makefile3
9 files changed, 456 insertions, 3 deletions
diff --git a/gnu/llvm/clang/lib/Driver/ToolChains/Clang.cpp b/gnu/llvm/clang/lib/Driver/ToolChains/Clang.cpp
index 41d486c7046..c8e4003875a 100644
--- a/gnu/llvm/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/gnu/llvm/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5213,10 +5213,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
else if (A->getOption().matches(options::OPT_fret_protector))
RetProtector = 1;
}
+
if (RetProtector &&
((getToolChain().getArch() == llvm::Triple::x86_64) ||
(getToolChain().getArch() == llvm::Triple::mips64) ||
(getToolChain().getArch() == llvm::Triple::mips64el) ||
+ (getToolChain().getArch() == llvm::Triple::ppc) ||
+ (getToolChain().getArch() == llvm::Triple::ppc64) ||
+ (getToolChain().getArch() == llvm::Triple::ppc64le) ||
(getToolChain().getArch() == llvm::Triple::aarch64)) &&
!Args.hasArg(options::OPT_fno_stack_protector) &&
!Args.hasArg(options::OPT_pg)) {
diff --git a/gnu/llvm/llvm/lib/Target/PowerPC/CMakeLists.txt b/gnu/llvm/llvm/lib/Target/PowerPC/CMakeLists.txt
index 1893d6e32c9..24d709e0f33 100644
--- a/gnu/llvm/llvm/lib/Target/PowerPC/CMakeLists.txt
+++ b/gnu/llvm/llvm/lib/Target/PowerPC/CMakeLists.txt
@@ -35,6 +35,7 @@ add_llvm_target(PowerPCCodeGen
PPCMachineScheduler.cpp
PPCMIPeephole.cpp
PPCRegisterInfo.cpp
+ PPCReturnProtectorLowering.cpp
PPCQPXLoadSplat.cpp
PPCSubtarget.cpp
PPCTargetMachine.cpp
diff --git a/gnu/llvm/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/gnu/llvm/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 4311df5dbeb..db5cddda36f 100644
--- a/gnu/llvm/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/gnu/llvm/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -298,6 +298,11 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
switch (ExtraCode[0]) {
default: return true; // Unknown modifier.
+ case 'L': // A memory reference to the upper word of a double word op.
+ O << getDataLayout().getPointerSize() << "(";
+ printOperand(MI, OpNo, O);
+ O << ")";
+ return false;
case 'y': // A memory reference for an X-form instruction
{
const char *RegName = "r0";
@@ -309,7 +314,6 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
}
case 'U': // Print 'u' for update form.
case 'X': // Print 'x' for indexed form.
- {
// FIXME: Currently for PowerPC memory operands are always loaded
// into a register, so we never get an update or indexed form.
// This is bad even for offset forms, since even if we know we
@@ -319,7 +323,6 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
assert(MI->getOperand(OpNo).isReg());
return false;
}
- }
}
assert(MI->getOperand(OpNo).isReg());
@@ -675,6 +678,85 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return;
}
}
+ case PPC::RETGUARD_LOAD_PC: {
+ unsigned DEST = MI->getOperand(0).getReg();
+ unsigned LR = MI->getOperand(1).getReg();
+ MCSymbol *HereSym = MI->getOperand(2).getMCSymbol();
+
+ unsigned MTLR = PPC::MTLR;
+ unsigned MFLR = PPC::MFLR;
+ unsigned BL = PPC::BL;
+ if (Subtarget->isPPC64()) {
+ MTLR = PPC::MTLR8;
+ MFLR = PPC::MFLR8;
+ BL = PPC::BL8;
+ }
+
+ // Cache the current LR
+ EmitToStreamer(*OutStreamer, MCInstBuilder(MFLR)
+ .addReg(LR));
+
+ // Create the BL forward
+ const MCExpr *HereExpr = MCSymbolRefExpr::create(HereSym, OutContext);
+ EmitToStreamer(*OutStreamer, MCInstBuilder(BL)
+ .addExpr(HereExpr));
+ OutStreamer->EmitLabel(HereSym);
+
+ // Grab the result
+ EmitToStreamer(*OutStreamer, MCInstBuilder(MFLR)
+ .addReg(DEST));
+ // Restore LR
+ EmitToStreamer(*OutStreamer, MCInstBuilder(MTLR)
+ .addReg(LR));
+ return;
+ }
+ case PPC::RETGUARD_LOAD_GOT: {
+ if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
+ StringRef GOTName = (PL == PICLevel::SmallPIC ?
+ "_GLOBAL_OFFSET_TABLE_" : ".LTOC");
+ unsigned DEST = MI->getOperand(0).getReg();
+ unsigned HERE = MI->getOperand(1).getReg();
+ MCSymbol *HereSym = MI->getOperand(2).getMCSymbol();
+ MCSymbol *GOTSym = OutContext.getOrCreateSymbol(GOTName);
+ const MCExpr *HereExpr = MCSymbolRefExpr::create(HereSym, OutContext);
+ const MCExpr *GOTExpr = MCSymbolRefExpr::create(GOTSym, OutContext);
+
+ // Get offset from Here to GOT
+ const MCExpr *GOTDeltaExpr =
+ MCBinaryExpr::createSub(GOTExpr, HereExpr, OutContext);
+ const MCExpr *GOTDeltaHi =
+ PPCMCExpr::createHa(GOTDeltaExpr, false, OutContext);
+ const MCExpr *GOTDeltaLo =
+ PPCMCExpr::createLo(GOTDeltaExpr, false, OutContext);
+
+ EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
+ .addReg(DEST)
+ .addReg(HERE)
+ .addExpr(GOTDeltaHi));
+ EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
+ .addReg(DEST)
+ .addReg(DEST)
+ .addExpr(GOTDeltaLo));
+ }
+ return;
+ }
+ case PPC::RETGUARD_LOAD_COOKIE: {
+ unsigned DEST = MI->getOperand(0).getReg();
+ MCSymbol *CookieSym = getSymbol(MI->getOperand(1).getGlobal());
+ const MCExpr *CookieExprHa = MCSymbolRefExpr::create(
+ CookieSym, MCSymbolRefExpr::VK_PPC_HA, OutContext);
+ const MCExpr *CookieExprLo = MCSymbolRefExpr::create(
+ CookieSym, MCSymbolRefExpr::VK_PPC_LO, OutContext);
+
+ EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LIS)
+ .addReg(DEST)
+ .addExpr(CookieExprHa));
+ EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ)
+ .addReg(DEST)
+ .addExpr(CookieExprLo)
+ .addReg(DEST));
+ return;
+ }
case PPC::LWZtoc: {
assert(!IsDarwin && "TOC is an ELF/XCOFF construct.");
diff --git a/gnu/llvm/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp b/gnu/llvm/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
index 4c608520e26..5f4fdbc7667 100644
--- a/gnu/llvm/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
+++ b/gnu/llvm/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
@@ -14,6 +14,7 @@
#include "PPCInstrBuilder.h"
#include "PPCInstrInfo.h"
#include "PPCMachineFunctionInfo.h"
+#include "PPCReturnProtectorLowering.h"
#include "PPCSubtarget.h"
#include "PPCTargetMachine.h"
#include "llvm/ADT/Statistic.h"
@@ -2462,3 +2463,7 @@ bool PPCFrameLowering::enableShrinkWrapping(const MachineFunction &MF) const {
return (MF.getSubtarget<PPCSubtarget>().isSVR4ABI() &&
MF.getSubtarget<PPCSubtarget>().isPPC64());
}
+
+const ReturnProtectorLowering *PPCFrameLowering::getReturnProtector() const {
+ return &RPL;
+}
diff --git a/gnu/llvm/llvm/lib/Target/PowerPC/PPCFrameLowering.h b/gnu/llvm/llvm/lib/Target/PowerPC/PPCFrameLowering.h
index a5fbc9acbb2..ae039ee3996 100644
--- a/gnu/llvm/llvm/lib/Target/PowerPC/PPCFrameLowering.h
+++ b/gnu/llvm/llvm/lib/Target/PowerPC/PPCFrameLowering.h
@@ -12,6 +12,7 @@
#ifndef LLVM_LIB_TARGET_POWERPC_PPCFRAMELOWERING_H
#define LLVM_LIB_TARGET_POWERPC_PPCFRAMELOWERING_H
+#include "PPCReturnProtectorLowering.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/Target/TargetMachine.h"
@@ -170,6 +171,9 @@ public:
/// function prologue/epilogue.
bool canUseAsPrologue(const MachineBasicBlock &MBB) const override;
bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override;
+
+ const PPCReturnProtectorLowering RPL;
+ const ReturnProtectorLowering *getReturnProtector() const override;
};
} // End llvm namespace
diff --git a/gnu/llvm/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/gnu/llvm/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index b38ca3af63f..d4fa008c0d6 100644
--- a/gnu/llvm/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/gnu/llvm/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -1427,6 +1427,31 @@ let Defs = [LR] in
def MoveGOTtoLR : PPCEmitTimePseudo<(outs), (ins), "#MoveGOTtoLR", []>,
PPC970_Unit_BRU;
+// Pseudo instruction used by retguard.
+//
+// We need to get the PC into a register in order to calculate the address of
+// the retguard cookies. This pseudo will branch immediately forward to get PC
+// in LR, and then move LR into the destination register. The current value of
+// LR is saved and restored via the given temp register, which is trashed.
+let Size = 16 in {
+def RETGUARD_LOAD_PC : PPCEmitTimePseudo<(outs gprc:$dest), (ins gprc:$tmp),
+ "#RGLoadPC", []>;
+}
+
+// Once we have the PC in a register, we need to load the address of the GOT
+// into another register so we can then finally load the local offset of the
+// retguard symbol entry from the GOT and then the cookie value.
+let Size = 8 in {
+def RETGUARD_LOAD_GOT : PPCEmitTimePseudo<(outs gprc:$dest),
+ (ins gprc:$pc, calltarget:$sym), "RGLoadGOT", []>;
+}
+
+let Size = 8 in {
+// For static linkage, we can load the cookie directly
+def RETGUARD_LOAD_COOKIE : PPCEmitTimePseudo<(outs gprc:$dest),
+ (ins calltarget:$sym), "RGLoadCookie", []>;
+}
+
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7 in {
let isBarrier = 1 in {
let isPredicable = 1 in
diff --git a/gnu/llvm/llvm/lib/Target/PowerPC/PPCReturnProtectorLowering.cpp b/gnu/llvm/llvm/lib/Target/PowerPC/PPCReturnProtectorLowering.cpp
new file mode 100644
index 00000000000..ef7a9430adc
--- /dev/null
+++ b/gnu/llvm/llvm/lib/Target/PowerPC/PPCReturnProtectorLowering.cpp
@@ -0,0 +1,285 @@
+//===-- PPCReturnProtectorLowering.cpp --------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the PPC implementation of ReturnProtectorLowering
+// class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PPCInstrInfo.h"
+#include "PPCMachineFunctionInfo.h"
+#include "PPCReturnProtectorLowering.h"
+#include "PPCTargetMachine.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/IR/Function.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Target/TargetOptions.h"
+#include <cstdlib>
+
+using namespace llvm;
+
+void PPCReturnProtectorLowering::insertReturnProtectorPrologue(
+ MachineFunction &MF, MachineBasicBlock &MBB, GlobalVariable *cookie) const {
+
+ MachineBasicBlock::instr_iterator MI = MBB.instr_begin();
+ DebugLoc MBBDL = MBB.findDebugLoc(MI);
+ const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
+ const TargetMachine &TM = MF.getTarget();
+ unsigned REG = MF.getFrameInfo().getReturnProtectorRegister();
+ bool is64bit = MF.getSubtarget<PPCSubtarget>().isPPC64();
+ bool isELFv2 = MF.getSubtarget<PPCSubtarget>().isELFv2ABI();
+
+ unsigned LRReg = PPC::R0;
+ unsigned TOCReg = PPC::R2;
+ unsigned XOR = PPC::XOR;
+ unsigned LWZ = PPC::LWZ;
+ unsigned MFLR = PPC::MFLR;
+ if (is64bit) {
+ LRReg = PPC::X0;
+ TOCReg = PPC::X2;
+ XOR = PPC::XOR8;
+ LWZ = PPC::LWZ8;
+ MFLR = PPC::MFLR8;
+ }
+
+ if (!MBB.isLiveIn(LRReg))
+ MBB.addLiveIn(LRReg);
+
+ if (is64bit) {
+ // PIC and non-PIC is the same
+ if (!isELFv2)
+ llvm_unreachable("ppc64 retguard requires ELFv2");
+ // Get the return address into LRReg
+ BuildMI(MBB, MI, MBBDL, TII->get(MFLR), LRReg);
+ // Get the random cookie address into REG
+ BuildMI(MBB, MI, MBBDL, TII->get(PPC::ADDIStocHA8), REG)
+ .addReg(TOCReg)
+ .addGlobalAddress(cookie);
+ BuildMI(MBB, MI, MBBDL, TII->get(PPC::ADDItocL), REG)
+ .addReg(REG)
+ .addGlobalAddress(cookie);
+ // Now load the random cookie value
+ BuildMI(MBB, MI, MBBDL, TII->get(PPC::LWZ), REG)
+ .addImm(0)
+ .addReg(REG);
+ // XOR cookie ^ random = retguard cookie
+ BuildMI(MBB, MI, MBBDL, TII->get(XOR), REG)
+ .addReg(REG)
+ .addReg(LRReg);
+ } else {
+ // 32 bit
+ if (TM.isPositionIndependent()) {
+ MCSymbol *HereSym = MF.getContext().createTempSymbol();
+ // Get LR into a register, and get PC into another register
+ BuildMI(MBB, MI, MBBDL, TII->get(PPC::RETGUARD_LOAD_PC), REG)
+ .addReg(LRReg, RegState::Define)
+ .addSym(HereSym);
+ // Get the random cookie address into REG
+ BuildMI(MBB, MI, MBBDL, TII->get(PPC::RETGUARD_LOAD_GOT), REG)
+ .addReg(REG)
+ .addSym(HereSym);
+ BuildMI(MBB, MI, MBBDL, TII->get(PPC::LWZtoc), REG)
+ .addGlobalAddress(cookie, 0, 0)
+ .addReg(REG);
+ // Now load the random cookie value
+ BuildMI(MBB, MI, MBBDL, TII->get(PPC::LWZ), REG)
+ .addImm(0)
+ .addReg(REG);
+ // XOR cookie ^ random = retguard cookie
+ BuildMI(MBB, MI, MBBDL, TII->get(XOR), REG)
+ .addReg(REG)
+ .addReg(LRReg);
+ } else {
+ // Non-PIC prologue
+ // Load LR into a register
+ BuildMI(MBB, MI, MBBDL, TII->get(MFLR), LRReg);
+ // Load random cookie into another register
+ BuildMI(MBB, MI, MBBDL, TII->get(PPC::RETGUARD_LOAD_COOKIE), REG)
+ .addGlobalAddress(cookie);
+ // XOR cookie ^ random = retguard cookie
+ BuildMI(MBB, MI, MBBDL, TII->get(XOR), REG)
+ .addReg(REG)
+ .addReg(LRReg);
+ }
+ }
+}
+
+void PPCReturnProtectorLowering::insertReturnProtectorEpilogue(
+ MachineFunction &MF, MachineInstr &MI, GlobalVariable *cookie) const {
+
+ MachineBasicBlock &MBB = *MI.getParent();
+ DebugLoc MBBDL = MI.getDebugLoc();
+ const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
+ const TargetMachine &TM = MF.getTarget();
+ unsigned REG = MF.getFrameInfo().getReturnProtectorRegister();
+ bool is64bit = MF.getSubtarget<PPCSubtarget>().isPPC64();
+ bool isELFv2 = MF.getSubtarget<PPCSubtarget>().isELFv2ABI();
+
+ unsigned LRReg = PPC::R0;
+ unsigned TOCReg = PPC::R2;
+ unsigned RGReg = PPC::R12;
+ unsigned TRAP = PPC::TW;
+ unsigned XOR = PPC::XOR;
+ unsigned LWZ = PPC::LWZ;
+ unsigned MFLR = PPC::MFLR;
+ if (is64bit) {
+ LRReg = PPC::X0;
+ TOCReg = PPC::X2;
+ RGReg = PPC::X12;
+ TRAP = PPC::TD;
+ XOR = PPC::XOR8;
+ LWZ = PPC::LWZ8;
+ MFLR = PPC::MFLR8;
+ }
+
+ if (!MBB.isLiveIn(LRReg))
+ MBB.addLiveIn(LRReg);
+ if (!MBB.isLiveIn(RGReg))
+ MBB.addLiveIn(RGReg);
+
+ if (is64bit) {
+ // PIC and non-PIC is the same
+ if (!isELFv2)
+ llvm_unreachable("ppc64 retguard requires ELFv2");
+ // Get the return address into LRReg
+ BuildMI(MBB, MI, MBBDL, TII->get(MFLR), LRReg);
+ // XOR the LRReg with the retguard cookie value
+ BuildMI(MBB, MI, MBBDL, TII->get(XOR), REG)
+ .addReg(REG)
+ .addReg(LRReg);
+ // Get the random cookie address into RGReg
+ BuildMI(MBB, MI, MBBDL, TII->get(PPC::ADDIStocHA8), RGReg)
+ .addReg(TOCReg)
+ .addGlobalAddress(cookie);
+ BuildMI(MBB, MI, MBBDL, TII->get(PPC::ADDItocL), RGReg)
+ .addReg(RGReg)
+ .addGlobalAddress(cookie);
+ // Load the cookie random balue
+ BuildMI(MBB, MI, MBBDL, TII->get(PPC::LWZ), RGReg)
+ .addImm(0)
+ .addReg(RGReg);
+ // Trap if they don't compare
+ BuildMI(MBB, MI, MBBDL, TII->get(TRAP))
+ .addImm(24)
+ .addReg(REG)
+ .addReg(RGReg);
+ } else {
+ // 32 bit
+ if (TM.isPositionIndependent()) {
+ // Get the PC into RGReg and the LR value into LRReg
+ MCSymbol *HereSym = MF.getContext().createTempSymbol();
+ BuildMI(MBB, MI, MBBDL, TII->get(PPC::RETGUARD_LOAD_PC), RGReg)
+ .addReg(LRReg, RegState::Define)
+ .addSym(HereSym);
+ // XOR the LRReg with the retguard cookie value
+ BuildMI(MBB, MI, MBBDL, TII->get(XOR), REG)
+ .addReg(REG)
+ .addReg(LRReg);
+ // Get the random cookie address into RGReg
+ BuildMI(MBB, MI, MBBDL, TII->get(PPC::RETGUARD_LOAD_GOT), RGReg)
+ .addReg(RGReg)
+ .addSym(HereSym);
+ BuildMI(MBB, MI, MBBDL, TII->get(PPC::LWZtoc), RGReg)
+ .addGlobalAddress(cookie, 0, 0)
+ .addReg(RGReg);
+ // Load the cookie random balue
+ BuildMI(MBB, MI, MBBDL, TII->get(PPC::LWZ), RGReg)
+ .addImm(0)
+ .addReg(RGReg);
+ // Trap if they don't compare
+ BuildMI(MBB, MI, MBBDL, TII->get(TRAP))
+ .addImm(24)
+ .addReg(REG)
+ .addReg(RGReg);
+ } else {
+ // Get LR into a register
+ BuildMI(MBB, MI, MBBDL, TII->get(MFLR), LRReg);
+ // XOR the LR Reg with the retguard cookie value
+ BuildMI(MBB, MI, MBBDL, TII->get(XOR), REG)
+ .addReg(REG)
+ .addReg(LRReg);
+ BuildMI(MBB, MI, MBBDL, TII->get(PPC::RETGUARD_LOAD_COOKIE), RGReg)
+ .addGlobalAddress(cookie);
+ // Trap if they don't compare
+ BuildMI(MBB, MI, MBBDL, TII->get(TRAP))
+ .addImm(24)
+ .addReg(REG)
+ .addReg(RGReg);
+ }
+ }
+}
+
+bool PPCReturnProtectorLowering::opcodeIsReturn(unsigned opcode) const {
+ switch (opcode) {
+ case PPC::BLR:
+ case PPC::BCCLR:
+ case PPC::BCLR:
+ case PPC::BCLRn:
+ case PPC::BDZLR:
+ case PPC::BDNZLR:
+ case PPC::BDZLRp:
+ case PPC::BDNZLRp:
+ case PPC::BDZLRm:
+ case PPC::BDNZLRm:
+ case PPC::BLR8:
+ case PPC::BDZLR8:
+ case PPC::BDNZLR8:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void PPCReturnProtectorLowering::fillTempRegisters(
+ MachineFunction &MF, std::vector<unsigned> &TempRegs) const {
+
+ const Function &F = MF.getFunction();
+
+ bool is64bit = MF.getSubtarget<PPCSubtarget>().isPPC64();
+
+ // R0/R12 are also the hardcoded temp regs for the rest of
+ // frame lowering, so leave them alone.
+ //TempRegs.push_back(is64bit ? PPC::X0 : PPC::R0);
+ //TempRegs.push_back(is64bit ? PPC::X12 : PPC::R12);
+ // X11 is also the 'nest' param or environment pointer
+ TempRegs.push_back(is64bit ? PPC::X11 : PPC::R11);
+
+ if (!F.isVarArg()) {
+ // We can use any of the caller saved unused arg registers
+ switch (F.arg_size()) {
+ case 0: // X3/R3 are used to return
+ case 1: // X4/R4 are used to return
+ case 2:
+ TempRegs.push_back(is64bit ? PPC::X5 : PPC::R5);
+ LLVM_FALLTHROUGH;
+ case 3:
+ TempRegs.push_back(is64bit ? PPC::X6 : PPC::R6);
+ LLVM_FALLTHROUGH;
+ case 4:
+ TempRegs.push_back(is64bit ? PPC::X7 : PPC::R7);
+ LLVM_FALLTHROUGH;
+ case 5:
+ TempRegs.push_back(is64bit ? PPC::X8 : PPC::R8);
+ LLVM_FALLTHROUGH;
+ case 6:
+ TempRegs.push_back(is64bit ? PPC::X9 : PPC::R9);
+ LLVM_FALLTHROUGH;
+ case 7:
+ TempRegs.push_back(is64bit ? PPC::X10 : PPC::R10);
+ LLVM_FALLTHROUGH;
+ default:
+ break;
+ }
+ }
+}
diff --git a/gnu/llvm/llvm/lib/Target/PowerPC/PPCReturnProtectorLowering.h b/gnu/llvm/llvm/lib/Target/PowerPC/PPCReturnProtectorLowering.h
new file mode 100644
index 00000000000..94b99be9d63
--- /dev/null
+++ b/gnu/llvm/llvm/lib/Target/PowerPC/PPCReturnProtectorLowering.h
@@ -0,0 +1,46 @@
+//===-- PPCReturnProtectorLowering.h - --------------------- -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the PPC implementation of ReturnProtectorLowering
+// class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_PPC_MIPSRETURNPROTECTORLOWERING_H
+#define LLVM_LIB_TARGET_PPC_MIPSRETURNPROTECTORLOWERING_H
+
+#include "llvm/CodeGen/ReturnProtectorLowering.h"
+
+namespace llvm {
+
+class PPCReturnProtectorLowering : public ReturnProtectorLowering {
+public:
+ /// insertReturnProtectorPrologue/Epilogue - insert return protector
+ /// instrumentation in prologue or epilogue.
+ virtual void
+ insertReturnProtectorPrologue(MachineFunction &MF, MachineBasicBlock &MBB,
+ GlobalVariable *cookie) const override;
+ virtual void
+ insertReturnProtectorEpilogue(MachineFunction &MF, MachineInstr &MI,
+ GlobalVariable *cookie) const override;
+
+ /// opcodeIsReturn - Reuturn true is the given opcode is a return
+ /// instruction needing return protection, false otherwise.
+ virtual bool opcodeIsReturn(unsigned opcode) const override;
+
+ /// fillTempRegisters - Fill the list of available temp registers we can
+ /// use as a return protector register.
+ virtual void
+ fillTempRegisters(MachineFunction &MF,
+ std::vector<unsigned> &TempRegs) const override;
+};
+
+} // namespace llvm
+
+#endif
diff --git a/gnu/usr.bin/clang/libLLVMPowerPCCodeGen/Makefile b/gnu/usr.bin/clang/libLLVMPowerPCCodeGen/Makefile
index dd89f2615c5..89819217916 100644
--- a/gnu/usr.bin/clang/libLLVMPowerPCCodeGen/Makefile
+++ b/gnu/usr.bin/clang/libLLVMPowerPCCodeGen/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.7 2020/08/03 14:45:27 patrick Exp $
+# $OpenBSD: Makefile,v 1.8 2020/10/12 14:52:08 mortimer Exp $
LIB= LLVMPowerPCCodeGen
NOPROFILE=
@@ -31,6 +31,7 @@ SRCS+= PPCBoolRetToInt.cpp \
PPCQPXLoadSplat.cpp \
PPCReduceCRLogicals.cpp \
PPCRegisterInfo.cpp \
+ PPCReturnProtectorLowering.cpp \
PPCSubtarget.cpp \
PPCTargetMachine.cpp \
PPCTargetObjectFile.cpp \