summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--distrib/amd64/ramdiskA/Makefile.inc4
-rw-r--r--gnu/llvm/include/llvm/CodeGen/MachineFrameInfo.h13
-rw-r--r--gnu/llvm/include/llvm/CodeGen/Passes.h3
-rw-r--r--gnu/llvm/include/llvm/CodeGen/TargetFrameLowering.h18
-rw-r--r--gnu/llvm/include/llvm/InitializePasses.h1
-rw-r--r--gnu/llvm/lib/CodeGen/CMakeLists.txt1
-rw-r--r--gnu/llvm/lib/CodeGen/PrologEpilogInserter.cpp40
-rw-r--r--gnu/llvm/lib/CodeGen/ReturnProtectorPass.cpp61
-rw-r--r--gnu/llvm/lib/CodeGen/TargetPassConfig.cpp2
-rw-r--r--gnu/llvm/lib/Target/X86/X86FrameLowering.cpp198
-rw-r--r--gnu/llvm/lib/Target/X86/X86FrameLowering.h13
-rw-r--r--gnu/llvm/lib/Target/X86/X86InstrCompiler.td15
-rw-r--r--gnu/llvm/lib/Target/X86/X86MCInstLower.cpp10
-rw-r--r--gnu/llvm/tools/clang/include/clang/Driver/CC1Options.td2
-rw-r--r--gnu/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def3
-rw-r--r--gnu/llvm/tools/clang/lib/CodeGen/CGCall.cpp3
-rw-r--r--gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp7
-rw-r--r--gnu/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp2
-rw-r--r--gnu/usr.bin/clang/Makefile.inc5
-rw-r--r--gnu/usr.bin/clang/libLLVMCodeGen/Makefile3
-rw-r--r--share/mk/bsd.lib.mk4
21 files changed, 400 insertions, 8 deletions
diff --git a/distrib/amd64/ramdiskA/Makefile.inc b/distrib/amd64/ramdiskA/Makefile.inc
index a2e02e30819..5248f4d1264 100644
--- a/distrib/amd64/ramdiskA/Makefile.inc
+++ b/distrib/amd64/ramdiskA/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.6 2017/08/13 15:41:30 jasper Exp $
+# $OpenBSD: Makefile.inc,v 1.7 2018/06/06 00:14:29 mortimer Exp $
TOP= ${.CURDIR}/..
@@ -75,7 +75,7 @@ bsd.rd: mr.fs bsd rdsetroot
bsd:
cd ${.CURDIR}/../../../sys/arch/amd64/compile/${RAMDISK} && \
- su ${BUILDUSER} -c '${MAKE} config && ${MAKE} clean && env COPTS=-Oz ${MAKE}'
+ su ${BUILDUSER} -c '${MAKE} config && ${MAKE} clean && env COPTS="-Oz -fno-ret-protector" ${MAKE}'
cp -p ${.CURDIR}/../../../sys/arch/amd64/compile/${RAMDISK}/obj/bsd bsd
mr.fs: instbin
diff --git a/gnu/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/gnu/llvm/include/llvm/CodeGen/MachineFrameInfo.h
index f887517217e..ad18d16ee70 100644
--- a/gnu/llvm/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/gnu/llvm/include/llvm/CodeGen/MachineFrameInfo.h
@@ -237,6 +237,11 @@ class MachineFrameInfo {
/// The frame index for the stack protector.
int StackProtectorIdx = -1;
+ /// The register to use for the return protector temp register
+ unsigned ReturnProtectorTempRegister = 0;
+ /// Set to true if using return protectors
+ bool ReturnProtector = false;
+
/// The frame index for the function context. Used for SjLj exceptions.
int FunctionContextIdx = -1;
@@ -314,6 +319,14 @@ public:
void setStackProtectorIndex(int I) { StackProtectorIdx = I; }
bool hasStackProtectorIndex() const { return StackProtectorIdx != -1; }
+ /// Return the temporary register for the return protector cookie calculation
+ int getReturnProtectorTempRegister() const { return ReturnProtectorTempRegister; }
+ void setReturnProtectorTempRegister(unsigned I) { ReturnProtectorTempRegister = I; }
+ bool hasReturnProtectorTempRegister() const { return ReturnProtectorTempRegister != 0; }
+ /// Return the return protector level
+ void setReturnProtector(bool I) { ReturnProtector = I; }
+ bool hasReturnProtector() const { return ReturnProtector; }
+
/// Return the index for the function context object.
/// This object is used for SjLj exceptions.
int getFunctionContextIndex() const { return FunctionContextIdx; }
diff --git a/gnu/llvm/include/llvm/CodeGen/Passes.h b/gnu/llvm/include/llvm/CodeGen/Passes.h
index 064526b1efa..d02eadd4e3c 100644
--- a/gnu/llvm/include/llvm/CodeGen/Passes.h
+++ b/gnu/llvm/include/llvm/CodeGen/Passes.h
@@ -307,6 +307,9 @@ namespace llvm {
///
FunctionPass *createStackProtectorPass();
+ // createReturnProtectorPass - This pass add return protectors to functions.
+ FunctionPass *createReturnProtectorPass();
+
/// createMachineVerifierPass - This pass verifies cenerated machine code
/// instructions for correctness.
///
diff --git a/gnu/llvm/include/llvm/CodeGen/TargetFrameLowering.h b/gnu/llvm/include/llvm/CodeGen/TargetFrameLowering.h
index 61f1cf07bcf..e07aaddc076 100644
--- a/gnu/llvm/include/llvm/CodeGen/TargetFrameLowering.h
+++ b/gnu/llvm/include/llvm/CodeGen/TargetFrameLowering.h
@@ -165,6 +165,24 @@ public:
virtual void emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const = 0;
+ /// determineReturnProtectorTempRegister - Find a register that can be used
+ /// during function prologue / epilogue to store the return protector cookie
+ virtual bool determineReturnProtectorTempRegister(MachineFunction &MF,
+ const SmallVector<MachineBasicBlock *, 4> &SaveBlocks,
+ const SmallVector<MachineBasicBlock *, 4> &RestoreBlocks) const {
+ return false;
+ }
+
+ /// insertReturnProtectorPrologue/Epilogue - Insert ret-protector code
+ virtual void insertReturnProtectorPrologue(MachineFunction &MF,
+ MachineBasicBlock &MBB) const
+ {}
+ virtual bool insertReturnProtectorEpilogue(MachineFunction &MF,
+ MachineBasicBlock &MBB) const
+ {
+ return false;
+ }
+
/// Replace a StackProbe stub (if any) with the actual probe code inline
virtual void inlineStackProbe(MachineFunction &MF,
MachineBasicBlock &PrologueMBB) const {}
diff --git a/gnu/llvm/include/llvm/InitializePasses.h b/gnu/llvm/include/llvm/InitializePasses.h
index 4c79333f5d2..8ec56344bad 100644
--- a/gnu/llvm/include/llvm/InitializePasses.h
+++ b/gnu/llvm/include/llvm/InitializePasses.h
@@ -321,6 +321,7 @@ void initializeRegionViewerPass(PassRegistry&);
void initializeRegisterCoalescerPass(PassRegistry&);
void initializeRenameIndependentSubregsPass(PassRegistry&);
void initializeResetMachineFunctionPass(PassRegistry&);
+void initializeReturnProtectorPass(PassRegistry&);
void initializeReversePostOrderFunctionAttrsLegacyPassPass(PassRegistry&);
void initializeRewriteStatepointsForGCLegacyPassPass(PassRegistry &);
void initializeRewriteSymbolsLegacyPassPass(PassRegistry&);
diff --git a/gnu/llvm/lib/CodeGen/CMakeLists.txt b/gnu/llvm/lib/CodeGen/CMakeLists.txt
index 865de4f47af..42e91978782 100644
--- a/gnu/llvm/lib/CodeGen/CMakeLists.txt
+++ b/gnu/llvm/lib/CodeGen/CMakeLists.txt
@@ -120,6 +120,7 @@ add_llvm_library(LLVMCodeGen
RegUsageInfoCollector.cpp
RegUsageInfoPropagate.cpp
ResetMachineFunctionPass.cpp
+ ReturnProtectorPass.cpp
SafeStack.cpp
SafeStackColoring.cpp
SafeStackLayout.cpp
diff --git a/gnu/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/gnu/llvm/lib/CodeGen/PrologEpilogInserter.cpp
index a8d8ad8ac7d..529fa7406a5 100644
--- a/gnu/llvm/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/gnu/llvm/lib/CodeGen/PrologEpilogInserter.cpp
@@ -175,6 +175,10 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) {
const TargetRegisterInfo *TRI = Fn.getSubtarget().getRegisterInfo();
const TargetFrameLowering *TFI = Fn.getSubtarget().getFrameLowering();
+ // Set Return Protector in the frame
+ if (F.hasFnAttribute("ret-protector"))
+ Fn.getFrameInfo().setReturnProtector(true);
+
RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : nullptr;
FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn);
FrameIndexEliminationScavenging = (RS && !FrameIndexVirtualScavenging) ||
@@ -209,6 +213,19 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) {
if (!F.hasFnAttribute(Attribute::Naked))
insertPrologEpilogCode(Fn);
+ // Add Return Protectors if using them
+ if (Fn.getFrameInfo().hasReturnProtector()) {
+ std::vector<MachineBasicBlock *> ReturnBlocks;
+ bool insertedGuard = false;
+ for (auto &MBB: Fn)
+ if (MBB.isReturnBlock())
+ ReturnBlocks.push_back(&MBB);
+ for (MachineBasicBlock *MBB: ReturnBlocks)
+ insertedGuard |= TFI->insertReturnProtectorEpilogue(Fn, *MBB);
+ if (insertedGuard)
+ TFI->insertReturnProtectorPrologue(Fn, Fn.front());
+ }
+
// Replace all MO_FrameIndex operands with physical register references
// and actual offsets.
//
@@ -293,7 +310,8 @@ void PEI::calculateCallFrameInfo(MachineFunction &Fn) {
/// Compute the sets of entry and return blocks for saving and restoring
/// callee-saved registers, and placing prolog and epilog code.
void PEI::calculateSaveRestoreBlocks(MachineFunction &Fn) {
- const MachineFrameInfo &MFI = Fn.getFrameInfo();
+ MachineFrameInfo &MFI = Fn.getFrameInfo();
+ const TargetFrameLowering *TFI = Fn.getSubtarget().getFrameLowering();
// Even when we do not change any CSR, we still want to insert the
// prologue and epilogue of the function.
@@ -309,7 +327,18 @@ void PEI::calculateSaveRestoreBlocks(MachineFunction &Fn) {
// epilogue.
if (!RestoreBlock->succ_empty() || RestoreBlock->isReturnBlock())
RestoreBlocks.push_back(RestoreBlock);
- return;
+
+ // If we are adding return protectors ensure we can find a free register
+ if (MFI.hasReturnProtector() &&
+ !TFI->determineReturnProtectorTempRegister(Fn, SaveBlocks, RestoreBlocks)) {
+ // Shrinkwrapping will prevent finding a free register
+ SaveBlocks.clear();
+ RestoreBlocks.clear();
+ MFI.setSavePoint(nullptr);
+ MFI.setRestorePoint(nullptr);
+ } else {
+ return;
+ }
}
// Save refs to entry and return blocks.
@@ -320,6 +349,9 @@ void PEI::calculateSaveRestoreBlocks(MachineFunction &Fn) {
if (MBB.isReturnBlock())
RestoreBlocks.push_back(&MBB);
}
+
+ if (MFI.hasReturnProtector())
+ TFI->determineReturnProtectorTempRegister(Fn, SaveBlocks, RestoreBlocks);
}
static void assignCalleeSavedSpillSlots(MachineFunction &F,
@@ -341,6 +373,10 @@ static void assignCalleeSavedSpillSlots(MachineFunction &F,
const TargetFrameLowering *TFI = F.getSubtarget().getFrameLowering();
MachineFrameInfo &MFI = F.getFrameInfo();
+
+ if (MFI.hasReturnProtectorTempRegister())
+ CSI.push_back(CalleeSavedInfo(MFI.getReturnProtectorTempRegister()));
+
if (!TFI->assignCalleeSavedSpillSlots(F, RegInfo, CSI)) {
// If target doesn't implement this, use generic code.
diff --git a/gnu/llvm/lib/CodeGen/ReturnProtectorPass.cpp b/gnu/llvm/lib/CodeGen/ReturnProtectorPass.cpp
new file mode 100644
index 00000000000..c4f8cb4f1b1
--- /dev/null
+++ b/gnu/llvm/lib/CodeGen/ReturnProtectorPass.cpp
@@ -0,0 +1,61 @@
+//===- ReturnProtectorPass.cpp - Set up rteurn protectors -----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass sets up functions for return protectors.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+#define DEBUG_TYPE "return-protector"
+
+STATISTIC(NumSymbols, "Counts number of cookie symbols added");
+
+namespace {
+ struct ReturnProtector : public FunctionPass {
+ static char ID;
+ ReturnProtector() : FunctionPass(ID) {}
+
+ bool runOnFunction(Function &F) override {
+ if (F.hasFnAttribute("ret-protector")) {
+ // Create a symbol for the cookie
+ Module *M = F.getParent();
+ std::hash<std::string> hasher;
+ std::string cookiename = "__retguard_" + std::to_string(hasher((M->getName() + F.getName()).str()) % 4000);
+ Type *cookietype = Type::getInt8PtrTy(M->getContext());
+ GlobalVariable *cookie = dyn_cast_or_null<GlobalVariable>(
+ M->getOrInsertGlobal(cookiename, cookietype));
+ cookie->setInitializer(Constant::getNullValue(cookietype));
+ cookie->setLinkage(GlobalVariable::WeakAnyLinkage);
+ cookie->setVisibility(GlobalValue::HiddenVisibility);
+ cookie->setSection(".openbsd.randomdata");
+ cookie->setExternallyInitialized(true);
+ F.addFnAttr("ret-protector-cookie", cookiename);
+ NumSymbols++;
+ }
+ return false;
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesCFG();
+ }
+ };
+}
+
+char ReturnProtector::ID = 0;
+INITIALIZE_PASS(ReturnProtector, "return-protector", "Return Protector Pass",
+ false, false)
+FunctionPass *llvm::createReturnProtectorPass() { return new ReturnProtector(); }
+
diff --git a/gnu/llvm/lib/CodeGen/TargetPassConfig.cpp b/gnu/llvm/lib/CodeGen/TargetPassConfig.cpp
index 3e6ad3eeef0..04f60eca18b 100644
--- a/gnu/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/gnu/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -688,6 +688,8 @@ void TargetPassConfig::addISelPrepare() {
if (requiresCodeGenSCCOrder())
addPass(new DummyCGSCCPass);
+ addPass(createReturnProtectorPass());
+
// Add both the safe stack and the stack protection passes: each of them will
// only protect functions that have corresponding attributes.
addPass(createSafeStackPass());
diff --git a/gnu/llvm/lib/Target/X86/X86FrameLowering.cpp b/gnu/llvm/lib/Target/X86/X86FrameLowering.cpp
index 11808f8995f..16acc7ea459 100644
--- a/gnu/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/gnu/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -3059,3 +3059,201 @@ void X86FrameLowering::processFunctionBeforeFrameFinalized(
UnwindHelpFI)
.addImm(-2);
}
+
+static void markUsedRegsInSuccessors(MachineBasicBlock &MBB,
+ SmallSet<unsigned, 16> &Used,
+ SmallSet<int, 24> &Visited) {
+ int BBNum = MBB.getNumber();
+ if (Visited.count(BBNum))
+ return;
+
+ // Mark all the registers used
+ for (auto &MBBI : MBB.instrs())
+ for (auto &MBBIOp : MBBI.operands())
+ if (MBBIOp.isReg())
+ Used.insert(MBBIOp.getReg());
+ // Mark this MBB as visited
+ Visited.insert(BBNum);
+ // Recurse over all successors
+ for (auto &SuccMBB : MBB.successors())
+ markUsedRegsInSuccessors(*SuccMBB, Used, Visited);
+}
+
+static inline bool opcodeIsRealReturn(unsigned opcode) {
+ switch (opcode) {
+ case X86::RET:
+ case X86::RETL:
+ case X86::RETQ:
+ case X86::RETW:
+ case X86::RETIL:
+ case X86::RETIQ:
+ case X86::RETIW:
+ case X86::LRETL:
+ case X86::LRETQ:
+ case X86::LRETW:
+ case X86::LRETIL:
+ case X86::LRETIQ:
+ case X86::LRETIW:
+ return true;
+ default:
+ return false;
+ }
+}
+static inline bool needsReturnProtector(MachineFunction &MF) {
+ for (auto &MBB : MF)
+ for (auto &T : MBB.terminators())
+ if (opcodeIsRealReturn(T.getOpcode()))
+ return true;
+ return false;
+}
+
+bool X86FrameLowering::determineReturnProtectorTempRegister(MachineFunction &MF,
+ const SmallVector<MachineBasicBlock *, 4> &SaveBlocks,
+ const SmallVector<MachineBasicBlock *, 4> &RestoreBlocks) const {
+
+ MachineFrameInfo &MFI = MF.getFrameInfo();
+
+ if (!MFI.hasReturnProtector() || !needsReturnProtector(MF))
+ return true;
+
+ // CSR spills happen at the beginning of this block
+ std::vector<unsigned> TempRegs;
+ SmallSet<unsigned, 16> Used;
+ SmallSet<int, 24> Visited;
+ const Function &F = MF.getFunction();
+
+ TempRegs = {X86::R11, X86::R10};
+ if (!F.isVarArg()) {
+ // We can use any of the caller saved unused arg registers
+ switch (F.arg_size()) {
+ case 0: TempRegs.push_back(X86::RDI);
+ case 1: TempRegs.push_back(X86::RSI);
+ case 2: // RDX is the 2nd return register
+ case 3: TempRegs.push_back(X86::RCX);
+ case 4: TempRegs.push_back(X86::R8);
+ case 5: TempRegs.push_back(X86::R9);
+ default: break;
+ }
+ }
+
+ // so we can mark it as visited because anything past it is safe
+ for(auto &SB : SaveBlocks)
+ Visited.insert(SB->getNumber());
+
+ // CSR Restores happen at the end of restore blocks, before any terminators,
+ // so we need to search restores for MBB terminators, and any successor BBs.
+ for (auto &RB : RestoreBlocks) {
+ for (auto &RBI : RB->terminators())
+ for (auto &RBIOp : RBI.operands())
+ if (RBIOp.isReg())
+ Used.insert(RBIOp.getReg());
+ for (auto &SuccMBB : RB->successors())
+ markUsedRegsInSuccessors(*SuccMBB, Used, Visited);
+ }
+
+ // Now we iterate from the front to find code paths that
+ // bypass save blocks and land on return blocks
+ markUsedRegsInSuccessors(MF.front(), Used, Visited);
+
+ // Now we have gathered all the regs used outside the frame save / restore,
+ // so we can see if we have a free reg to use for the retguard cookie.
+ for (unsigned Reg : TempRegs) {
+ bool canUse = true;
+ for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) {
+ if (Used.count(*AI)) {
+ // Reg is used somewhere, so we cannot use it
+ canUse = false;
+ break;
+ }
+ }
+ if (canUse) {
+ MFI.setReturnProtectorTempRegister(Reg);
+ break;
+ }
+ }
+
+ // return whether or not we set a register
+ return MFI.hasReturnProtectorTempRegister();
+}
+
+void X86FrameLowering::insertReturnProtectorPrologue(MachineFunction &MF,
+ MachineBasicBlock &MBB) const
+{
+
+ const MachineFrameInfo &MFI = MF.getFrameInfo();
+
+ if (!MFI.hasReturnProtector() || !MFI.hasReturnProtectorTempRegister())
+ return;
+
+ unsigned CFIIndex;
+ MachineBasicBlock::instr_iterator MBBI = MBB.instr_begin();
+ DebugLoc MBBDL = MBB.findDebugLoc(MBBI);
+ const Function &Fn = MF.getFunction();
+ const Module *M = Fn.getParent();
+ GlobalVariable *cookie;
+ unsigned XORRM, MOVRM, SP, REG, IP;
+
+ XORRM = X86::XOR64rm;
+ MOVRM = X86::MOV64rm;
+ SP = X86::RSP;
+ REG = MFI.getReturnProtectorTempRegister();
+ IP = X86::RIP;
+
+ cookie = dyn_cast_or_null<GlobalVariable>(M->getGlobalVariable(
+ Fn.getFnAttribute("ret-protector-cookie").getValueAsString(),
+ Type::getInt8PtrTy(M->getContext())));
+ MBB.addLiveIn(REG);
+ BuildMI(MBB, MBBI, MBBDL, TII.get(MOVRM), REG)
+ .addReg(IP)
+ .addImm(0)
+ .addReg(0)
+ .addGlobalAddress(cookie)
+ .addReg(0);
+ addDirectMem(BuildMI(MBB, MBBI, MBBDL, TII.get(XORRM), REG).addReg(REG), SP);
+}
+
+bool X86FrameLowering::insertReturnProtectorEpilogue(MachineFunction &MF,
+ MachineBasicBlock &MBB) const
+{
+ const MachineFrameInfo &MFI = MF.getFrameInfo();
+
+ if (!MFI.hasReturnProtector() || !MFI.hasReturnProtectorTempRegister())
+ return false;
+
+ const Function &Fn = MF.getFunction();
+ const Module *M = Fn.getParent();
+ std::vector<MachineInstr *> returns;
+ GlobalVariable *cookie;
+ unsigned XORRM, CMPRM, SP, REG, IP;
+
+ XORRM = X86::XOR64rm;
+ CMPRM = X86::CMP64rm;
+ SP = X86::RSP;
+ REG = MFI.getReturnProtectorTempRegister();
+ IP = X86::RIP;
+
+ for (auto &MI : MBB.terminators())
+ if (opcodeIsRealReturn(MI.getOpcode()))
+ returns.push_back(&MI);
+
+ if (returns.empty())
+ return false;
+
+ for (auto &MI : returns) {
+ const DebugLoc &DL = MI->getDebugLoc();
+ cookie = dyn_cast_or_null<GlobalVariable>(M->getGlobalVariable(
+ Fn.getFnAttribute("ret-protector-cookie").getValueAsString(),
+ Type::getInt8PtrTy(M->getContext())));
+ MBB.addLiveIn(REG);
+ addDirectMem(BuildMI(MBB, MI, DL, TII.get(XORRM), REG).addReg(REG), SP);
+ BuildMI(MBB, MI, DL, TII.get(CMPRM))
+ .addReg(REG)
+ .addReg(IP)
+ .addImm(0)
+ .addReg(0)
+ .addGlobalAddress(cookie)
+ .addReg(0);
+ BuildMI(MBB, MI, DL, TII.get(X86::RETGUARD_JMP_TRAP));
+ }
+ return true;
+}
diff --git a/gnu/llvm/lib/Target/X86/X86FrameLowering.h b/gnu/llvm/lib/Target/X86/X86FrameLowering.h
index 909319fc18f..5938b36dbd7 100644
--- a/gnu/llvm/lib/Target/X86/X86FrameLowering.h
+++ b/gnu/llvm/lib/Target/X86/X86FrameLowering.h
@@ -68,6 +68,19 @@ public:
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
+ /// determineReturnProtectorTempRegister - find a free register for the
+ /// return protector cookie calculation.
+ virtual bool determineReturnProtectorTempRegister(MachineFunction &MF,
+ const SmallVector<MachineBasicBlock *, 4> &SaveBlocks,
+ const SmallVector<MachineBasicBlock *, 4> &RestoreBlocks) const override;
+
+
+ /// Insert Return Protector instrumentation prologue / epilogue
+ void insertReturnProtectorPrologue(MachineFunction &MF,
+ MachineBasicBlock &MBB) const override;
+ bool insertReturnProtectorEpilogue(MachineFunction &MF,
+ MachineBasicBlock &MBB) const override;
+
void adjustForSegmentedStacks(MachineFunction &MF,
MachineBasicBlock &PrologueMBB) const override;
diff --git a/gnu/llvm/lib/Target/X86/X86InstrCompiler.td b/gnu/llvm/lib/Target/X86/X86InstrCompiler.td
index d66d9258e96..34b20cba9aa 100644
--- a/gnu/llvm/lib/Target/X86/X86InstrCompiler.td
+++ b/gnu/llvm/lib/Target/X86/X86InstrCompiler.td
@@ -267,6 +267,21 @@ def MORESTACK_RET_RESTORE_R10 : I<0, Pseudo, (outs), (ins),
}
//===----------------------------------------------------------------------===//
+// Pseudo instruction used by retguard
+
+// This is lowered to a JE 2; INT3; INT3. Prior to this pseudo should be a
+// compare instruction to ensure the retguard cookie is correct.
+// We use a pseudo here in order to avoid splitting the BB just before the return.
+// Splitting the BB and inserting a JE_1 over a new INT3 BB occasionally
+// resulted in incorrect code when a value from a byte register (CL) was
+// used as a return value. When emitted as a split BB, the single byte
+// register would sometimes be widened to 4 bytes, which would corrupt
+// the return value (ie mov %ecx, %eax instead of mov %cl, %al).
+let isCodeGenOnly = 1, Uses = [EFLAGS] in {
+def RETGUARD_JMP_TRAP: I<0, Pseudo, (outs), (ins), "", []>;
+}
+
+//===----------------------------------------------------------------------===//
// Alias Instructions
//===----------------------------------------------------------------------===//
diff --git a/gnu/llvm/lib/Target/X86/X86MCInstLower.cpp b/gnu/llvm/lib/Target/X86/X86MCInstLower.cpp
index 5f0ada2d6d1..8f1259cb6a9 100644
--- a/gnu/llvm/lib/Target/X86/X86MCInstLower.cpp
+++ b/gnu/llvm/lib/Target/X86/X86MCInstLower.cpp
@@ -1623,6 +1623,16 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
.addReg(X86::RAX));
return;
+ case X86::RETGUARD_JMP_TRAP: {
+ MCSymbol *RGSuccSym = OutContext.createTempSymbol();
+ const MCExpr *RGSuccExpr = MCSymbolRefExpr::create(RGSuccSym, OutContext);
+ EmitAndCountInstruction(MCInstBuilder(X86::JE_1).addExpr(RGSuccExpr));
+ EmitAndCountInstruction(MCInstBuilder(X86::INT3));
+ EmitAndCountInstruction(MCInstBuilder(X86::INT3));
+ OutStreamer->EmitLabel(RGSuccSym);
+ return;
+ }
+
case X86::SEH_PushReg:
case X86::SEH_SaveReg:
case X86::SEH_SaveXMM:
diff --git a/gnu/llvm/tools/clang/include/clang/Driver/CC1Options.td b/gnu/llvm/tools/clang/include/clang/Driver/CC1Options.td
index 7dea88b62cc..f19b2c3f277 100644
--- a/gnu/llvm/tools/clang/include/clang/Driver/CC1Options.td
+++ b/gnu/llvm/tools/clang/include/clang/Driver/CC1Options.td
@@ -665,6 +665,8 @@ def stack_protector : Separate<["-"], "stack-protector">,
HelpText<"Enable stack protectors">;
def stack_protector_buffer_size : Separate<["-"], "stack-protector-buffer-size">,
HelpText<"Lower bound for a buffer to be considered for stack protection">;
+def ret_protector : Flag<["-"], "ret-protector">,
+ HelpText<"Enable Return Protectors">;
def fvisibility : Separate<["-"], "fvisibility">,
HelpText<"Default type and symbol visibility">;
def ftype_visibility : Separate<["-"], "ftype-visibility">,
diff --git a/gnu/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def b/gnu/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def
index bb91cf5f742..5c4b4c3aa84 100644
--- a/gnu/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def
+++ b/gnu/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def
@@ -252,6 +252,9 @@ VALUE_CODEGENOPT(NumRegisterParameters, 32, 0)
/// The lower bound for a buffer to be considered for stack protection.
VALUE_CODEGENOPT(SSPBufferSize, 32, 0)
+/// Whether to use return protectors
+CODEGENOPT(ReturnProtector, 1, 0)
+
/// The kind of generated debug info.
ENUM_CODEGENOPT(DebugInfo, codegenoptions::DebugInfoKind, 3, codegenoptions::NoDebugInfo)
diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CGCall.cpp b/gnu/llvm/tools/clang/lib/CodeGen/CGCall.cpp
index 38d7344572d..de67ee39c14 100644
--- a/gnu/llvm/tools/clang/lib/CodeGen/CGCall.cpp
+++ b/gnu/llvm/tools/clang/lib/CodeGen/CGCall.cpp
@@ -1878,6 +1878,9 @@ void CodeGenModule::ConstructAttributeList(
FuncAttrs.addAttribute("disable-tail-calls",
llvm::toStringRef(DisableTailCalls));
+ if (CodeGenOpts.ReturnProtector)
+ FuncAttrs.addAttribute("ret-protector");
+
// Add target-cpu and target-features attributes to functions. If
// we have a decl for the function and it has a target attribute then
// parse that and add it to the feature set.
diff --git a/gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp b/gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp
index f1137b2d928..91a656f4a48 100644
--- a/gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/gnu/llvm/tools/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3978,6 +3978,13 @@ 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) &&
+ !Args.hasArg(options::OPT_fno_stack_protector) &&
+ !Args.hasArg(options::OPT_pg)) {
+ CmdArgs.push_back(Args.MakeArgString("-D_RET_PROTECTOR"));
+ CmdArgs.push_back(Args.MakeArgString(Twine("-ret-protector")));
+ }
// Translate -mstackrealign
if (Args.hasFlag(options::OPT_mstackrealign, options::OPT_mno_stackrealign,
diff --git a/gnu/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp b/gnu/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp
index 6ce719aac67..a637af723ab 100644
--- a/gnu/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/gnu/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp
@@ -872,6 +872,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.StackAlignment = StackAlignment;
}
+ Opts.ReturnProtector = Args.hasArg(OPT_ret_protector);
+
if (Arg *A = Args.getLastArg(OPT_mstack_probe_size)) {
StringRef Val = A->getValue();
unsigned StackProbeSize = Opts.StackProbeSize;
diff --git a/gnu/usr.bin/clang/Makefile.inc b/gnu/usr.bin/clang/Makefile.inc
index 27678e1d38b..f772277db45 100644
--- a/gnu/usr.bin/clang/Makefile.inc
+++ b/gnu/usr.bin/clang/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.5 2017/04/17 15:53:21 kettenis Exp $
+# $OpenBSD: Makefile.inc,v 1.6 2018/06/06 00:14:29 mortimer Exp $
LLVM_SRCS?= ${.CURDIR}/../../../llvm
@@ -20,6 +20,9 @@ CLANG_INCLUDES= -I${LLVM_SRCS}/tools/clang/include
CPPFLAGS+= -I${LLVM_SRCS}/include -I${.CURDIR}/../include -I${.OBJDIR} \
-I${.OBJDIR}/../include
CPPFLAGS+= -DNDEBUG
+.if ${MACHINE} == "amd64"
+CPPFLAGS+= -fno-ret-protector
+.endif
CPPFLAGS+= -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS \
-D__STDC_FORMAT_MACROS
diff --git a/gnu/usr.bin/clang/libLLVMCodeGen/Makefile b/gnu/usr.bin/clang/libLLVMCodeGen/Makefile
index ab2ed35d582..f66dfe270e8 100644
--- a/gnu/usr.bin/clang/libLLVMCodeGen/Makefile
+++ b/gnu/usr.bin/clang/libLLVMCodeGen/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.6 2018/04/06 14:44:04 patrick Exp $
+# $OpenBSD: Makefile,v 1.7 2018/06/06 00:14:29 mortimer Exp $
LIB= LLVMCodeGen
NOPIC=
@@ -129,6 +129,7 @@ SRCS= AggressiveAntiDepBreaker.cpp \
RegisterUsageInfo.cpp \
RenameIndependentSubregs.cpp \
ResetMachineFunctionPass.cpp \
+ ReturnProtectorPass.cpp \
SafeStack.cpp \
SafeStackColoring.cpp \
SafeStackLayout.cpp \
diff --git a/share/mk/bsd.lib.mk b/share/mk/bsd.lib.mk
index 2a5e5906abf..aea8bfc468c 100644
--- a/share/mk/bsd.lib.mk
+++ b/share/mk/bsd.lib.mk
@@ -1,4 +1,4 @@
-# $OpenBSD: bsd.lib.mk,v 1.92 2017/11/14 10:02:56 kettenis Exp $
+# $OpenBSD: bsd.lib.mk,v 1.93 2018/06/06 00:14:29 mortimer Exp $
# $NetBSD: bsd.lib.mk,v 1.67 1996/01/17 20:39:26 mycroft Exp $
# @(#)bsd.lib.mk 5.26 (Berkeley) 5/2/91
@@ -34,7 +34,7 @@ CXXFLAGS+= ${NOPIE_FLAGS}
AFLAGS+= ${NOPIE_FLAGS}
.endif
-DIST_CFLAGS+= -Oz
+DIST_CFLAGS+= -Oz -fno-stack-protector
.c.o:
@echo "${COMPILE.c} ${.IMPSRC} -o ${.TARGET}"