summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormortimer <mortimer@openbsd.org>2019-10-25 00:40:56 +0000
committermortimer <mortimer@openbsd.org>2019-10-25 00:40:56 +0000
commit52446778f86252aa4533d0b08b871472df4e84f6 (patch)
tree973e0e48848d32e4e0a5f6621a935e6ccd828579
parentTest the old ioctl(2) for interface addresses SIOCSIFADDR, (diff)
downloadwireguard-openbsd-52446778f86252aa4533d0b08b871472df4e84f6.tar.xz
wireguard-openbsd-52446778f86252aa4533d0b08b871472df4e84f6.zip
Add retguard for octeon/mips64.
For this architecture we use separate retguard prologue and epilogue code for static or PIC code. In the PIC case we use some additional code before the retguard epilogue to recover the function start address and the GOT pointer in order to get the per-function random cookie. Much thanks to visa@ for suggestions and advice making it all work. ok deraadt@ visa@
-rw-r--r--gnu/llvm/lib/Target/Mips/CMakeLists.txt1
-rw-r--r--gnu/llvm/lib/Target/Mips/MipsAsmPrinter.cpp77
-rw-r--r--gnu/llvm/lib/Target/Mips/MipsFrameLowering.cpp9
-rw-r--r--gnu/llvm/lib/Target/Mips/MipsFrameLowering.h8
-rw-r--r--gnu/llvm/lib/Target/Mips/MipsInstrInfo.td25
-rw-r--r--gnu/llvm/lib/Target/Mips/MipsReturnProtectorLowering.cpp272
-rw-r--r--gnu/llvm/lib/Target/Mips/MipsReturnProtectorLowering.h46
-rw-r--r--gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp2
-rw-r--r--gnu/usr.bin/clang/Makefile.inc5
-rw-r--r--gnu/usr.bin/clang/libLLVMMipsCodeGen/Makefile3
10 files changed, 444 insertions, 4 deletions
diff --git a/gnu/llvm/lib/Target/Mips/CMakeLists.txt b/gnu/llvm/lib/Target/Mips/CMakeLists.txt
index b67fb46cf66..dbf01f85eee 100644
--- a/gnu/llvm/lib/Target/Mips/CMakeLists.txt
+++ b/gnu/llvm/lib/Target/Mips/CMakeLists.txt
@@ -47,6 +47,7 @@ add_llvm_target(MipsCodeGen
MipsPreLegalizerCombiner.cpp
MipsRegisterBankInfo.cpp
MipsRegisterInfo.cpp
+ MipsReturnProtectorLowering.cpp
MipsSEFrameLowering.cpp
MipsSEInstrInfo.cpp
MipsSEISelDAGToDAG.cpp
diff --git a/gnu/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/gnu/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
index 4a2c4a7239f..ade0ef82783 100644
--- a/gnu/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/gnu/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -241,6 +241,83 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
case Mips::PATCHABLE_TAIL_CALL:
LowerPATCHABLE_TAIL_CALL(*MI);
return;
+ case Mips::RETGUARD_GET_FUNCTION_ADDR:
+ {
+ MCSymbol *PCSym = OutContext.createTempSymbol();
+ MCSymbol *FuncSym = OutContext.lookupSymbol(MI->getMF()->getName());
+ if (FuncSym == nullptr)
+ llvm_unreachable("Function name has no symbol");
+
+ // Branch and link forward, calculate the distance
+ // from here to the start of the function, and fill the
+ // address in the given dest register
+ unsigned OUT = MI->getOperand(0).getReg();
+ unsigned IN1 = MI->getOperand(1).getReg();
+ unsigned IN2 = MI->getOperand(2).getReg();
+ MCSymbol *ReturnSym = MI->getOperand(3).getMCSymbol();
+
+ // Save the value of RA in IN1
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::OR64)
+ .addReg(IN1)
+ .addReg(Mips::RA_64)
+ .addReg(Mips::ZERO_64));
+ // BAL to get the PC into RA
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::BAL)
+ .addExpr(MCSymbolRefExpr::create(ReturnSym, OutContext)));
+ // NOP
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::SLL)
+ .addReg(Mips::ZERO_64)
+ .addReg(Mips::ZERO_64)
+ .addImm(0));
+
+ // Emit a symbol for "here/PC" because BAL will put
+ // the address of the instruction following the NOP into RA
+ // and we need this symbol to do the math
+ OutStreamer->EmitLabel(PCSym);
+
+ // Store PC in IN2
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::OR64)
+ .addReg(IN2)
+ .addReg(Mips::RA_64)
+ .addReg(Mips::ZERO_64));
+ // Restore original RA
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::OR64)
+ .addReg(Mips::RA_64)
+ .addReg(IN1)
+ .addReg(Mips::ZERO_64));
+ // Load the offset from PCSym to the start of the function
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::LUi64)
+ .addReg(IN1)
+ .addExpr(MipsMCExpr::create(MipsMCExpr::MipsExprKind::MEK_HI,
+ MCBinaryExpr::createSub(
+ MCSymbolRefExpr::create(PCSym, OutContext),
+ MCSymbolRefExpr::create(FuncSym, OutContext),
+ OutContext),
+ OutContext)));
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::DADDiu)
+ .addReg(IN1)
+ .addReg(IN1)
+ .addExpr(MipsMCExpr::create(MipsMCExpr::MipsExprKind::MEK_LO,
+ MCBinaryExpr::createSub(
+ MCSymbolRefExpr::create(PCSym, OutContext),
+ MCSymbolRefExpr::create(FuncSym, OutContext),
+ OutContext),
+ OutContext)));
+
+ // Sub distance from here to start of function
+ // to get address of the start of function
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::DSUBu)
+ .addReg(OUT)
+ .addReg(IN2)
+ .addReg(IN1));
+ return;
+ }
+ case Mips::RETGUARD_EMIT_SYMBOL:
+ {
+ MCSymbol *ReturnSym = MI->getOperand(0).getMCSymbol();
+ OutStreamer->EmitLabel(ReturnSym);
+ return;
+ }
}
if (EmitJalrReloc &&
diff --git a/gnu/llvm/lib/Target/Mips/MipsFrameLowering.cpp b/gnu/llvm/lib/Target/Mips/MipsFrameLowering.cpp
index 27a85970da6..54cac00577f 100644
--- a/gnu/llvm/lib/Target/Mips/MipsFrameLowering.cpp
+++ b/gnu/llvm/lib/Target/Mips/MipsFrameLowering.cpp
@@ -15,6 +15,7 @@
#include "MCTargetDesc/MipsBaseInfo.h"
#include "MipsInstrInfo.h"
#include "MipsMachineFunction.h"
+#include "MipsReturnProtectorLowering.h"
#include "MipsTargetMachine.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -123,6 +124,10 @@ uint64_t MipsFrameLowering::estimateStackSize(const MachineFunction &MF) const {
if (MFI.getObjectOffset(I) > 0)
Size += MFI.getObjectSize(I);
+ // Account for saving return protector register
+ if (MFI.getReturnProtectorNeeded())
+ Size += TRI.getSpillSize(*TRI.getMinimalPhysRegClass(Mips::T9_64));
+
// Conservatively assume all callee-saved registers will be saved.
for (const MCPhysReg *R = TRI.getCalleeSavedRegs(&MF); *R; ++R) {
unsigned RegSize = TRI.getSpillSize(*TRI.getMinimalPhysRegClass(*R));
@@ -150,3 +155,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
return MBB.erase(I);
}
+
+const ReturnProtectorLowering *MipsFrameLowering::getReturnProtector() const {
+ return &RPL;
+}
diff --git a/gnu/llvm/lib/Target/Mips/MipsFrameLowering.h b/gnu/llvm/lib/Target/Mips/MipsFrameLowering.h
index 0ead56eddd2..b86f31bd452 100644
--- a/gnu/llvm/lib/Target/Mips/MipsFrameLowering.h
+++ b/gnu/llvm/lib/Target/Mips/MipsFrameLowering.h
@@ -15,6 +15,7 @@
#define LLVM_LIB_TARGET_MIPS_MIPSFRAMELOWERING_H
#include "Mips.h"
+#include "MipsReturnProtectorLowering.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
namespace llvm {
@@ -25,8 +26,11 @@ protected:
const MipsSubtarget &STI;
public:
+
+ const MipsReturnProtectorLowering RPL;
+
explicit MipsFrameLowering(const MipsSubtarget &sti, unsigned Alignment)
- : TargetFrameLowering(StackGrowsDown, Alignment, 0, Alignment), STI(sti) {}
+ : TargetFrameLowering(StackGrowsDown, Alignment, 0, Alignment), STI(sti), RPL() {}
static const MipsFrameLowering *create(const MipsSubtarget &ST);
@@ -40,6 +44,8 @@ public:
return true;
}
+ const ReturnProtectorLowering *getReturnProtector() const override;
+
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
diff --git a/gnu/llvm/lib/Target/Mips/MipsInstrInfo.td b/gnu/llvm/lib/Target/Mips/MipsInstrInfo.td
index 447f7c395c3..e71478503d1 100644
--- a/gnu/llvm/lib/Target/Mips/MipsInstrInfo.td
+++ b/gnu/llvm/lib/Target/Mips/MipsInstrInfo.td
@@ -2022,6 +2022,31 @@ def LONG_BRANCH_ADDiu : PseudoSE<(outs GPR32Opnd:$dst),
def LONG_BRANCH_ADDiu2Op : PseudoSE<(outs GPR32Opnd:$dst),
(ins GPR32Opnd:$src, brtarget:$tgt), []>;
+// Pseudo instructions used by retguard. In order to calculste the PC
+// for PIC code, we use a pair of pseudos to get the function address
+// into T9, which is normally used to hold this value but is trashed
+// by function epilogue.
+let isCodeGenOnly = 1, hasNoSchedulingInfo = 1 in {
+
+ // Use BAL to get the PC into RA, then calculate the address of the
+ // current function and save this value in $rd. $rs and $rt are used
+ // as scratch registers and are trashed by this pseudo. $tgt is the
+ // symbol to branch to when calling BAL.
+ let Size = 32 in {
+ def RETGUARD_GET_FUNCTION_ADDR: PseudoSE<(outs GPR64:$rd),
+ (ins GPR64:$rs, GPR64:$rt, brtarget:$tgt), []>;
+ }
+
+ // Emit the symbol used for $tgt in RETGUARD_GET_FUNCTION_ADDR. We
+ // emit this symbol immediately before the usual function return, with
+ // the effect that the BAL branches to an immediate return and resumes
+ // execution through the rest of the RETGUARD epilogue. We pair BAL
+ // with RET to satisfy return branch predictors.
+ let Size = 0 in {
+ def RETGUARD_EMIT_SYMBOL: PseudoSE<(outs), (ins brtarget:$tgt), []>;
+ }
+}
+
//===----------------------------------------------------------------------===//
// Instruction definition
//===----------------------------------------------------------------------===//
diff --git a/gnu/llvm/lib/Target/Mips/MipsReturnProtectorLowering.cpp b/gnu/llvm/lib/Target/Mips/MipsReturnProtectorLowering.cpp
new file mode 100644
index 00000000000..e9d72d3a90a
--- /dev/null
+++ b/gnu/llvm/lib/Target/Mips/MipsReturnProtectorLowering.cpp
@@ -0,0 +1,272 @@
+//===-- MipsReturnProtectorLowering.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 Mips implementation of ReturnProtectorLowering
+// class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MCTargetDesc/MipsBaseInfo.h"
+#include "MipsInstrInfo.h"
+#include "MipsMachineFunction.h"
+#include "MipsReturnProtectorLowering.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 MipsReturnProtectorLowering::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();
+
+ const GlobalValue *FName = &MF.getFunction();
+
+ // Select some scratch registers
+ unsigned TempReg1 = Mips::AT_64;
+ unsigned TempReg2 = Mips::V0_64;
+ if (!MBB.isLiveIn(TempReg1))
+ MBB.addLiveIn(TempReg1);
+ if (!MBB.isLiveIn(TempReg2))
+ MBB.addLiveIn(TempReg2);
+
+ if (TM.isPositionIndependent()) {
+
+ if (!MBB.isLiveIn(Mips::T9_64))
+ MBB.addLiveIn(Mips::T9_64);
+
+ // TempReg1 loads the GOT pointer
+ // TempReg2 load the offset from GOT to random cookie pointer
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::LUi64), TempReg1)
+ .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::LUi64), TempReg2)
+ .addGlobalAddress(cookie, 0, MipsII::MO_GOT_HI16);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::DADDu), TempReg1)
+ .addReg(TempReg1)
+ .addReg(Mips::T9_64);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::DADDiu), TempReg2)
+ .addReg(TempReg2)
+ .addGlobalAddress(cookie, 0, MipsII::MO_GOT_LO16);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::DADDu), TempReg1)
+ .addReg(TempReg1)
+ .addReg(TempReg2);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::LD), REG)
+ .addReg(TempReg1)
+ .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::LD), REG)
+ .addReg(REG)
+ .addImm(0);
+ } else {
+ // TempReg1 loads the high 32 bits
+ // TempReg2 loads the low 32 bits
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::LUi64), TempReg1)
+ .addGlobalAddress(cookie, 0, MipsII::MO_HIGHEST);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::LUi64), TempReg2)
+ .addGlobalAddress(cookie, 0, MipsII::MO_ABS_HI);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::DADDiu), TempReg1)
+ .addReg(TempReg1)
+ .addGlobalAddress(cookie, 0, MipsII::MO_HIGHER);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::DSLL), TempReg1)
+ .addReg(TempReg1)
+ .addImm(32);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::DADDu), TempReg1)
+ .addReg(TempReg1)
+ .addReg(TempReg2);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::LD), REG)
+ .addReg(TempReg1)
+ .addGlobalAddress(cookie, 0, MipsII::MO_ABS_LO);
+ }
+
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::XOR64), REG)
+ .addReg(REG)
+ .addReg(Mips::RA_64);
+}
+
+void MipsReturnProtectorLowering::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();
+
+ const GlobalValue *FName = &MF.getFunction();
+
+ // Select some scratch registers
+ unsigned TempReg1 = Mips::T7_64;
+ unsigned TempReg2 = Mips::T8_64;
+ if (REG == Mips::T7_64 || REG == Mips::T8_64) {
+ TempReg1 = Mips::T5_64;
+ TempReg2 = Mips::T6_64;
+ }
+ if (!MBB.isLiveIn(TempReg1))
+ MBB.addLiveIn(TempReg1);
+ if (!MBB.isLiveIn(TempReg2))
+ MBB.addLiveIn(TempReg2);
+
+ // Undo the XOR to retrieve the random cookie
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::XOR64), REG)
+ .addReg(REG)
+ .addReg(Mips::RA_64);
+
+ // Load the random cookie
+ if (TM.isPositionIndependent()) {
+
+ if (!MBB.isLiveIn(Mips::T9_64))
+ MBB.addLiveIn(Mips::T9_64);
+
+ // T9 is trashed by this point, and we cannot trust saving
+ // the value from function entry on the stack, so calculate
+ // the address of the function entry using a pseudo
+ MCSymbol *BALTarget = MF.getContext().createTempSymbol();
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::RETGUARD_GET_FUNCTION_ADDR), Mips::T9_64)
+ .addReg(TempReg1)
+ .addReg(TempReg2)
+ .addSym(BALTarget);
+
+ // TempReg1 loads the GOT pointer
+ // TempReg2 load the offset from GOT to random cookie pointer
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::LUi64), TempReg1)
+ .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::LUi64), TempReg2)
+ .addGlobalAddress(cookie, 0, MipsII::MO_GOT_HI16);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::DADDu), TempReg1)
+ .addReg(TempReg1)
+ .addReg(Mips::T9_64);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::DADDiu), TempReg2)
+ .addReg(TempReg2)
+ .addGlobalAddress(cookie, 0, MipsII::MO_GOT_LO16);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::DADDu), TempReg1)
+ .addReg(TempReg1)
+ .addReg(TempReg2);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::LD), TempReg1)
+ .addReg(TempReg1)
+ .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::LD), TempReg1)
+ .addReg(TempReg1)
+ .addImm(0);
+ // Verify the random cookie
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::TNE))
+ .addReg(TempReg1)
+ .addReg(REG)
+ .addImm(0);
+ // Emit the BAL target symbol from above
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::RETGUARD_EMIT_SYMBOL))
+ .addSym(BALTarget);
+ } else {
+ // TempReg1 loads the high 32 bits
+ // TempReg2 loads the low 32 bits
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::LUi64), TempReg1)
+ .addGlobalAddress(cookie, 0, MipsII::MO_HIGHEST);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::LUi64), TempReg2)
+ .addGlobalAddress(cookie, 0, MipsII::MO_ABS_HI);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::DADDiu), TempReg1)
+ .addReg(TempReg1)
+ .addGlobalAddress(cookie, 0, MipsII::MO_HIGHER);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::DSLL), TempReg1)
+ .addReg(TempReg1)
+ .addImm(32);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::DADDu), TempReg1)
+ .addReg(TempReg1)
+ .addReg(TempReg2);
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::LD), TempReg1)
+ .addReg(TempReg1)
+ .addGlobalAddress(cookie, 0, MipsII::MO_ABS_LO);
+ // Verify the random cookie
+ BuildMI(MBB, MI, MBBDL, TII->get(Mips::TNE))
+ .addReg(TempReg1)
+ .addReg(REG)
+ .addImm(0);
+ }
+}
+
+bool MipsReturnProtectorLowering::opcodeIsReturn(unsigned opcode) const {
+ switch (opcode) {
+ case Mips::RetRA:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void MipsReturnProtectorLowering::fillTempRegisters(
+ MachineFunction &MF, std::vector<unsigned> &TempRegs) const {
+
+ const Function &F = MF.getFunction();
+
+ // long double arguments (f128) occupy two arg registers, so shift
+ // subsequent arguments down by one register
+ size_t shift_reg = 0;
+ for (const auto &arg : F.args()) {
+ if (arg.getType()->isFP128Ty())
+ shift_reg += 1;
+ }
+
+ if (!F.isVarArg()) {
+ // We can use any of the caller saved unused arg registers
+ switch (F.arg_size() + shift_reg) {
+ case 0:
+ // A0 is used to return f128 values in soft float
+ case 1:
+ TempRegs.push_back(Mips::A1_64);
+ LLVM_FALLTHROUGH;
+ case 2:
+ TempRegs.push_back(Mips::A2_64);
+ LLVM_FALLTHROUGH;
+ case 3:
+ TempRegs.push_back(Mips::A3_64);
+ LLVM_FALLTHROUGH;
+ case 4:
+ TempRegs.push_back(Mips::T0_64);
+ LLVM_FALLTHROUGH;
+ case 5:
+ TempRegs.push_back(Mips::T1_64);
+ LLVM_FALLTHROUGH;
+ case 6:
+ TempRegs.push_back(Mips::T2_64);
+ LLVM_FALLTHROUGH;
+ case 7:
+ TempRegs.push_back(Mips::T3_64);
+ LLVM_FALLTHROUGH;
+ case 8:
+ TempRegs.push_back(Mips::T4_64);
+ LLVM_FALLTHROUGH;
+ case 9:
+ TempRegs.push_back(Mips::T5_64);
+ LLVM_FALLTHROUGH;
+ case 10:
+ TempRegs.push_back(Mips::T6_64);
+ LLVM_FALLTHROUGH;
+ case 11:
+ TempRegs.push_back(Mips::T7_64);
+ LLVM_FALLTHROUGH;
+ case 12:
+ TempRegs.push_back(Mips::T8_64);
+ LLVM_FALLTHROUGH;
+ default:
+ break;
+ }
+ }
+ // For FastCC this is the only scratch reg that isn't V0 or T9
+ TempRegs.push_back(Mips::AT_64);
+}
diff --git a/gnu/llvm/lib/Target/Mips/MipsReturnProtectorLowering.h b/gnu/llvm/lib/Target/Mips/MipsReturnProtectorLowering.h
new file mode 100644
index 00000000000..677101cf950
--- /dev/null
+++ b/gnu/llvm/lib/Target/Mips/MipsReturnProtectorLowering.h
@@ -0,0 +1,46 @@
+//===-- MipsReturnProtectorLowering.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 Mips implementation of ReturnProtectorLowering
+// class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_MIPS_MIPSRETURNPROTECTORLOWERING_H
+#define LLVM_LIB_TARGET_MIPS_MIPSRETURNPROTECTORLOWERING_H
+
+#include "llvm/CodeGen/ReturnProtectorLowering.h"
+
+namespace llvm {
+
+class MipsReturnProtectorLowering : 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/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp b/gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp
index 78bf9acf5c9..760820d2ce0 100644
--- a/gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4561,6 +4561,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
if (RetProtector &&
((getToolChain().getArch() == llvm::Triple::x86_64) ||
+ (getToolChain().getArch() == llvm::Triple::mips64) ||
+ (getToolChain().getArch() == llvm::Triple::mips64el) ||
(getToolChain().getArch() == llvm::Triple::aarch64)) &&
!Args.hasArg(options::OPT_fno_stack_protector) &&
!Args.hasArg(options::OPT_pg)) {
diff --git a/gnu/usr.bin/clang/Makefile.inc b/gnu/usr.bin/clang/Makefile.inc
index f89abdd6330..d5839ada0e2 100644
--- a/gnu/usr.bin/clang/Makefile.inc
+++ b/gnu/usr.bin/clang/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.15 2019/07/11 11:31:09 visa Exp $
+# $OpenBSD: Makefile.inc,v 1.16 2019/10/25 00:40:56 mortimer Exp $
LLVM_SRCS?= ${.CURDIR}/../../../llvm
@@ -25,7 +25,8 @@ CPPFLAGS+= -DNDEBUG
# Disable some protections in the compiler to regain performance.
.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" || \
- ${MACHINE_ARCH} == "aarch64"
+ ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el" || \
+ ${MACHINE_ARCH} == "aarch64"
CXXFLAGS+= -fno-ret-protector
.endif
.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386"
diff --git a/gnu/usr.bin/clang/libLLVMMipsCodeGen/Makefile b/gnu/usr.bin/clang/libLLVMMipsCodeGen/Makefile
index f9a12e14d55..a6bcdc73498 100644
--- a/gnu/usr.bin/clang/libLLVMMipsCodeGen/Makefile
+++ b/gnu/usr.bin/clang/libLLVMMipsCodeGen/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.6 2019/06/23 22:07:41 patrick Exp $
+# $OpenBSD: Makefile,v 1.7 2019/10/25 00:40:56 mortimer Exp $
LIB= LLVMMipsCodeGen
NOPROFILE=
@@ -36,6 +36,7 @@ SRCS+= MicroMipsSizeReduction.cpp \
MipsPreLegalizerCombiner.cpp \
MipsRegisterBankInfo.cpp \
MipsRegisterInfo.cpp \
+ MipsReturnProtectorLowering.cpp \
MipsSEFrameLowering.cpp \
MipsSEInstrInfo.cpp \
MipsSEISelDAGToDAG.cpp \