-
Notifications
You must be signed in to change notification settings - Fork 15k
Global Stack Protector Option for s390x #164971
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Global Stack Protector Option for s390x #164971
Conversation
This commit allows `-mstack-protector-guard=global` for `s390x`. It also adds a new arch-specific option `-mstack-protector-guard-record`, analogous to `-mrecord-mcount`, which will cause `clang` to emit a `__stack_protector_loc` section containing all the locations in the output binary that load the stack guard, for the purposes of later rewriting of those loads by the kernel. This new option only works together with the `global` stack protector. In order to minimize exposure of the stack guard, both the storing of the stack guard onto the stack, and the later comparison of that value against the reference value, are handled via direct mem-to-mem instructions, those being `mvc` and `clc`. This is achieved by introducing two new pseudo instructions, `MOVE_STACK_GUARD` and `COMPARE_STACK_GUARD`, which are inserted by the DAGCombiner after SelectionDAG construction. This commit also adds tests for both kinds of stack protectors (tls and global), for the proper insertion of the pseudos, as well as the proper emission of the `__stack_protector_loc` section.
|
@llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-backend-systemz Author: Dominik Steenken (dominik-steenken) ChangesThis PR allows It also adds a new arch-specific option In order to minimize exposure of the stack guard, both the storing of the stack guard onto the stack, and the later comparison of that value against the reference value, are handled via direct mem-to-mem instructions, those being This commit also adds tests for both kinds of stack protectors (tls and global), for the proper insertion of the pseudos, as well as the proper emission of the Patch is 27.86 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/164971.diff 15 Files Affected:
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 90e1f8d1eb5e9..edb7d4e0b9480 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -157,6 +157,7 @@ CODEGENOPT(InstrumentForProfiling , 1, 0, Benign) ///< Set when -pg is enabled.
CODEGENOPT(CallFEntry , 1, 0, Benign) ///< Set when -mfentry is enabled.
CODEGENOPT(MNopMCount , 1, 0, Benign) ///< Set when -mnop-mcount is enabled.
CODEGENOPT(RecordMCount , 1, 0, Benign) ///< Set when -mrecord-mcount is enabled.
+CODEGENOPT(StackProtectorGuardRecord, 1, 0, Benign) ///< Set when -mstack-protector-guard-record is enabled.
CODEGENOPT(PackedStack , 1, 0, Benign) ///< Set when -mpacked-stack is enabled.
CODEGENOPT(LessPreciseFPMAD , 1, 0, Benign) ///< Enable less precise MAD instructions to
///< be generated.
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 0c9584f1b479f..1af0459e4e4ac 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5728,6 +5728,13 @@ def mstack_protector_guard_reg_EQ : Joined<["-"], "mstack-protector-guard-reg=">
Visibility<[ClangOption, CC1Option]>,
HelpText<"Use the given reg for addressing the stack-protector guard">,
MarshallingInfoString<CodeGenOpts<"StackProtectorGuardReg">>;
+def mstackprotector_guard_record
+ : Flag<["-"], "mstack-protector-guard-record">,
+ HelpText<"Generate a __stackprotector_loc section entry for each load of "
+ "the stackguard address.">,
+ Visibility<[ClangOption, CC1Option]>,
+ Group<m_Group>,
+ MarshallingInfoFlag<CodeGenOpts<"StackProtectorGuardRecord">>;
def mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at function entry (x86/SystemZ only)">,
Visibility<[ClangOption, CC1Option]>, Group<m_Group>,
MarshallingInfoFlag<CodeGenOpts<"CallFEntry">>;
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 88628530cf66b..6e35f91cac811 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1195,6 +1195,14 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
}
}
+ if (CGM.getCodeGenOpts().StackProtectorGuardRecord) {
+ if (CGM.getCodeGenOpts().StackProtectorGuard != "global")
+ CGM.getDiags().Report(diag::err_opt_not_valid_without_opt)
+ << "-mstack-protector-guard-record"
+ << "-mstack-protector-guard=global";
+ Fn->addFnAttr("mstackprotector-guard-record");
+ }
+
if (CGM.getCodeGenOpts().PackedStack) {
if (getContext().getTargetInfo().getTriple().getArch() !=
llvm::Triple::systemz)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 79edc561c551f..db80662f0dda5 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3433,11 +3433,12 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
StringRef Value = A->getValue();
if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
- !EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
+ !EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC() &&
+ !EffectiveTriple.isSystemZ())
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
- EffectiveTriple.isThumb()) &&
+ EffectiveTriple.isThumb() || EffectiveTriple.isSystemZ()) &&
Value != "tls" && Value != "global") {
D.Diag(diag::err_drv_invalid_value_with_suggestion)
<< A->getOption().getName() << Value << "tls global";
@@ -3553,6 +3554,10 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
}
A->render(Args, CmdArgs);
}
+
+ if (Arg *A = Args.getLastArg(options::OPT_mstackprotector_guard_record)) {
+ A->render(Args, CmdArgs);
+ }
}
static void RenderSCPOptions(const ToolChain &TC, const ArgList &Args,
diff --git a/clang/test/CodeGen/SystemZ/stack-guard-pseudos.c b/clang/test/CodeGen/SystemZ/stack-guard-pseudos.c
new file mode 100644
index 0000000000000..8e8e919e9a348
--- /dev/null
+++ b/clang/test/CodeGen/SystemZ/stack-guard-pseudos.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -S -mllvm -stop-after=systemz-isel -stack-protector 1 -triple=s390x-ibm-linux < %s -o - | FileCheck %s
+
+// CHECK: bb.0.entry:
+// CHECK: MOVE_STACK_GUARD %stack.0.StackGuardSlot, 0
+// CHECK: COMPARE_STACK_GUARD %stack.0.StackGuardSlot, implicit-def $cc
+
+extern char *strcpy (char * D, const char * S);
+int main(int argc, char *argv[])
+{
+ char Buffer[8] = {0};
+ strcpy(Buffer, argv[1]);
+ return 0;
+}
diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index e31d7c6a86476..7156b7d2113ac 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -23,6 +23,7 @@
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/BinaryFormat/GOFF.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
@@ -740,6 +741,31 @@ void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) {
case SystemZ::EH_SjLj_Setup:
return;
+ case SystemZ::LARL:
+ case SystemZ::LGRL: {
+ // If "-mstackprotector-guard-record" was supplied on the command line,
+ // we need special handling for LARL/LGRL.
+ if (MF->getFunction().hasFnAttribute("mstackprotector-guard-record")) {
+ // Obtain the name of the stack guard, and determine if that
+ // is what we are loading here.
+ const MachineOperand &Op = MI->getOperand(1);
+ if (Op.isGlobal() && (Op.getGlobal()->getName() == "__stack_chk_guard")) {
+ // If so, drop into the __stack_protector_loc section and record
+ // this locaytion.
+ MCSymbol *Sym = OutContext.createTempSymbol();
+ OutStreamer->pushSection();
+ OutStreamer->switchSection(OutContext.getELFSection(
+ "__stack_protector_loc", ELF::SHT_PROGBITS, ELF::SHF_ALLOC));
+ OutStreamer->emitSymbolValue(Sym, getDataLayout().getPointerSize());
+ OutStreamer->popSection();
+ OutStreamer->emitLabel(Sym);
+ }
+ }
+ // Otherwise, keep the MI as it is.
+ Lower.lower(MI, LoweredMI);
+ break;
+ }
+
default:
Lower.lower(MI, LoweredMI);
break;
diff --git a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
index a05fdc74e6366..3196a9d99ad88 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
@@ -10,10 +10,13 @@
//
//===----------------------------------------------------------------------===//
-#include "SystemZTargetMachine.h"
+#include "MCTargetDesc/SystemZMCTargetDesc.h"
#include "SystemZISelLowering.h"
+#include "SystemZTargetMachine.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/raw_ostream.h"
@@ -369,7 +372,11 @@ class SystemZDAGToDAGISel : public SelectionDAGISel {
if (F.hasFnAttribute("mrecord-mcount"))
report_fatal_error("mrecord-mcount only supported with fentry-call");
}
-
+ if (F.getParent()->getStackProtectorGuard() != "global") {
+ if (F.hasFnAttribute("mstack-protector-guard-record"))
+ report_fatal_error("mstack-protector-guard-record only supported with "
+ "mstack-protector-guard=global");
+ }
Subtarget = &MF.getSubtarget<SystemZSubtarget>();
return SelectionDAGISel::runOnMachineFunction(MF);
}
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index de28faf4908e9..a2ca28086bd76 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -11,21 +11,29 @@
//===----------------------------------------------------------------------===//
#include "SystemZISelLowering.h"
+#include "MCTargetDesc/SystemZMCTargetDesc.h"
#include "SystemZCallingConv.h"
#include "SystemZConstantPoolValue.h"
#include "SystemZMachineFunctionInfo.h"
+#include "SystemZRegisterInfo.h"
#include "SystemZTargetMachine.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsS390.h"
+#include "llvm/IR/Module.h"
#include "llvm/IR/PatternMatch.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
@@ -8177,6 +8185,23 @@ SDValue SystemZTargetLowering::combineSTORE(
SN->getMemOperand());
}
}
+
+ // combine STORE (LOAD_STACK_GUARD) into MOVE_STACK_GUARD
+ if (Op1->isMachineOpcode() &&
+ (Op1->getMachineOpcode() == SystemZ::LOAD_STACK_GUARD)) {
+ // If so, create a MOVE_STACK_GUARD node to subsume the LOAD_STACK_GUARD,
+ // Store sequence.
+ int FI = cast<FrameIndexSDNode>(SN->getOperand(2))->getIndex();
+ // Dummy Register, FrameIndex, Dummy Displacement
+ SDValue Ops[] = {DAG.getTargetFrameIndex(FI, MVT::i64),
+ DAG.getTargetConstant(0, SDLoc(SN), MVT::i64),
+ SN->getChain()};
+ MachineSDNode *Move = DAG.getMachineNode(SystemZ::MOVE_STACK_GUARD,
+ SDLoc(SN), MVT::Other, Ops);
+
+ return SDValue(Move, 0);
+ }
+
// Combine STORE (BSWAP) into STRVH/STRV/STRVG/VSTBR
if (!SN->isTruncatingStore() &&
Op1.getOpcode() == ISD::BSWAP &&
@@ -9106,6 +9131,41 @@ SDValue SystemZTargetLowering::combineSELECT_CCMASK(
return SDValue();
}
+SDValue SystemZTargetLowering::combineICMP(SDNode *N,
+ DAGCombinerInfo &DCI) const {
+ SelectionDAG &DAG = DCI.DAG;
+ SDLoc DL(N);
+
+ // Combine icmp (load fi, LOAD_STACK_GUARD) into COMPARE_STACK_GUARD.
+
+ const SDValue &LHS = N->getOperand(0);
+ const SDValue &RHS = N->getOperand(1);
+
+ if (!ISD::isNormalLoad(RHS.getNode()) ||
+ !(LHS.isMachineOpcode() &&
+ (LHS->getMachineOpcode() == SystemZ::LOAD_STACK_GUARD)))
+ return SDValue();
+
+ auto const *StackLoad = cast<LoadSDNode>(RHS.getNode());
+
+ // The StackLoad will have an outgoing chain that needs to be redirected.
+ SDValue InChain = StackLoad->getChain();
+ SDValue OutChain = SDValue(const_cast<LoadSDNode *>(StackLoad), 1);
+ DAG.ReplaceAllUsesOfValueWith(OutChain, InChain);
+
+ int FI = cast<FrameIndexSDNode>(StackLoad->getOperand(1))->getIndex();
+
+ // Now, create a COMPARE_STACK_GUARD node to subsume the
+ // LoadFI, LOAD_STACK_GUARD, Compare sequence.
+ // Operands are the FrameIndex where the stackguard is stored, and the input
+ // chain.
+ SDValue Ops[] = {DAG.getTargetFrameIndex(FI, MVT::i64), InChain};
+ MachineSDNode *Move =
+ DAG.getMachineNode(SystemZ::COMPARE_STACK_GUARD, DL, MVT::i32, Ops);
+
+ return SDValue(Move, 0);
+}
+
SDValue SystemZTargetLowering::combineGET_CCMASK(
SDNode *N, DAGCombinerInfo &DCI) const {
@@ -9420,6 +9480,8 @@ SDValue SystemZTargetLowering::PerformDAGCombine(SDNode *N,
case SystemZISD::BR_CCMASK: return combineBR_CCMASK(N, DCI);
case SystemZISD::SELECT_CCMASK: return combineSELECT_CCMASK(N, DCI);
case SystemZISD::GET_CCMASK: return combineGET_CCMASK(N, DCI);
+ case SystemZISD::ICMP:
+ return combineICMP(N, DCI);
case ISD::SRL:
case ISD::SRA: return combineShiftToMulAddHigh(N, DCI);
case ISD::MUL: return combineMUL(N, DCI);
@@ -11088,6 +11150,91 @@ getBackchainAddress(SDValue SP, SelectionDAG &DAG) const {
DAG.getIntPtrConstant(TFL->getBackchainOffset(MF), DL));
}
+namespace {
+// The custom inserters for MOVE_STACK_GUARD and COMPARE_STACK_GUARD both
+// need to load the address of the stack guard. This function enables that.
+Register emitLoadStackGuard(MachineInstr &MI, MachineBasicBlock *MBB) {
+ MachineFunction &MF = *MBB->getParent();
+ auto *II = MF.getTarget().getMCInstrInfo();
+ const Register AddrReg =
+ MF.getRegInfo().createVirtualRegister(&SystemZ::ADDR64BitRegClass);
+
+ Module *M = MF.getFunction().getParent();
+ StringRef GuardType = M->getStackProtectorGuard();
+
+ if (GuardType.empty() || (GuardType == "tls")) {
+ // TLS-based stack guard loading will be emitted post RA.
+ // This is so we can more easily guarantee the ear, sllg, ear, load
+ // sequence.
+ BuildMI(*MBB, MI, MI.getDebugLoc(), II->get(TargetOpcode::LOAD_STACK_GUARD),
+ AddrReg);
+
+ } else if (GuardType == "global") {
+ // Obtain the global value.
+ const GlobalValue *GV = M->getOrInsertGlobal(
+ "__stack_chk_guard", PointerType::getUnqual(M->getContext()));
+ // Emit the move.
+ if (M->getPICLevel() == PICLevel::NotPIC) {
+ BuildMI(*MBB, MI, MI.getDebugLoc(), II->get(SystemZ::LARL), AddrReg)
+ .addGlobalAddress(GV);
+ } else {
+ BuildMI(*MBB, MI, MI.getDebugLoc(), II->get(SystemZ::LGRL), AddrReg)
+ .addGlobalAddress(GV);
+ }
+ } else {
+ llvm_unreachable(
+ (Twine("Unknown stack protector type \"") + GuardType + "\"")
+ .str()
+ .c_str());
+ }
+ return AddrReg;
+}
+} // namespace
+
+// Custom Inserter for MOVE_STACK_GUARD. Loads the address of the stack guard,
+// then inserts an MVC.
+MachineBasicBlock *
+SystemZTargetLowering::emitMoveStackGuard(MachineInstr &MI,
+ MachineBasicBlock *MBB) const {
+ MachineOperand &FI = MI.getOperand(0);
+ auto *II = MBB->getParent()->getTarget().getMCInstrInfo();
+ Register AddrReg = emitLoadStackGuard(MI, MBB);
+
+ assert(FI.isFI() && "Operand 0 of MOVE_STACK_GUARD is not a frame index.");
+
+ BuildMI(*MBB, MI, MI.getDebugLoc(), II->get(SystemZ::MVC))
+ .addFrameIndex(FI.getIndex())
+ .addImm(0)
+ .addImm(8)
+ .addReg(AddrReg)
+ .addImm(0);
+ MI.removeFromParent();
+
+ return MBB;
+}
+
+// Custom Inserter for COMPARE_STACK_GUARD. Loads the address of the stack
+// guard, then inserts a CLC.
+MachineBasicBlock *
+SystemZTargetLowering::emitCompareStackGuard(MachineInstr &MI,
+ MachineBasicBlock *MBB) const {
+ MachineOperand &FI = MI.getOperand(0);
+ auto *II = MBB->getParent()->getTarget().getMCInstrInfo();
+ Register AddrReg = emitLoadStackGuard(MI, MBB);
+
+ assert(FI.isFI() && "Operand 0 of COMPARE_STACK_GUARD is not a frame index.");
+
+ BuildMI(*MBB, MI, MI.getDebugLoc(), II->get(SystemZ::CLC))
+ .addFrameIndex(FI.getIndex())
+ .addImm(0)
+ .addImm(8)
+ .addReg(AddrReg)
+ .addImm(0);
+ MI.removeFromParent();
+
+ return MBB;
+}
+
MachineBasicBlock *SystemZTargetLowering::EmitInstrWithCustomInserter(
MachineInstr &MI, MachineBasicBlock *MBB) const {
switch (MI.getOpcode()) {
@@ -11241,6 +11388,12 @@ MachineBasicBlock *SystemZTargetLowering::EmitInstrWithCustomInserter(
case SystemZ::EH_SjLj_LongJmp:
return emitEHSjLjLongJmp(MI, MBB);
+ case SystemZ::MOVE_STACK_GUARD:
+ return emitMoveStackGuard(MI, MBB);
+
+ case SystemZ::COMPARE_STACK_GUARD:
+ return emitCompareStackGuard(MI, MBB);
+
case TargetOpcode::STACKMAP:
case TargetOpcode::PATCHPOINT:
return emitPatchPoint(MI, MBB);
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
index d5b76031766dd..4aace28a5dd12 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
@@ -797,6 +797,7 @@ class SystemZTargetLowering : public TargetLowering {
SDValue combineBSWAP(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineSETCC(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineBR_CCMASK(SDNode *N, DAGCombinerInfo &DCI) const;
+ SDValue combineICMP(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineSELECT_CCMASK(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineGET_CCMASK(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineShiftToMulAddHigh(SDNode *N, DAGCombinerInfo &DCI) const;
@@ -851,6 +852,10 @@ class SystemZTargetLowering : public TargetLowering {
unsigned Opcode) const;
MachineBasicBlock *emitProbedAlloca(MachineInstr &MI,
MachineBasicBlock *MBB) const;
+ MachineBasicBlock *emitMoveStackGuard(MachineInstr &MI,
+ MachineBasicBlock *MBB) const;
+ MachineBasicBlock *emitCompareStackGuard(MachineInstr &MI,
+ MachineBasicBlock *MBB) const;
SDValue getBackchainAddress(SDValue SP, SelectionDAG &DAG) const;
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
index 2e21f27c9032f..fd34f0cb86b95 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
@@ -13,6 +13,7 @@
#include "SystemZInstrInfo.h"
#include "MCTargetDesc/SystemZMCTargetDesc.h"
#include "SystemZ.h"
+#include "SystemZISelLowering.h"
#include "SystemZInstrBuilder.h"
#include "SystemZSubtarget.h"
#include "llvm/ADT/Statistic.h"
@@ -33,6 +34,8 @@
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/CodeGen/VirtRegMap.h"
+#include "llvm/IR/Module.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/BranchProbability.h"
@@ -228,35 +231,6 @@ void SystemZInstrInfo::expandZExtPseudo(MachineInstr &MI, unsigned LowOpcode,
MI.eraseFromParent();
}
-void SystemZInstrInfo::expandLoadStackGuard(MachineInstr *MI) const {
- MachineBasicBlock *MBB = MI->getParent();
- MachineFunction &MF = *MBB->getParent();
- const Register Reg64 = MI->getOperand(0).getReg();
- const Register Reg32 = RI.getSubReg(Reg64, SystemZ::subreg_l32);
-
- // EAR can only load the low subregister so us a shift for %a0 to produce
- // the GR containing %a0 and %a1.
-
- // ear <reg>, %a0
- BuildMI(*MBB, MI, MI->getDebugLoc(), get(SystemZ::EAR), Reg32)
- .addReg(SystemZ::A0)
- .addReg(Reg64, RegState::ImplicitDefine);
-
- // sllg <reg>, <reg>, 32
- BuildMI(*MBB, MI, MI->getDebugLoc(), get(SystemZ::SLLG), Reg64)
- .addReg(Reg64)
- .addReg(0)
- .addImm(32);
-
- // ear <reg>, %a1
- BuildMI(*MBB, MI, MI->getDebugLoc(), get(SystemZ::EAR), Reg32)
- .addReg(SystemZ::A1);
-
- // lg <reg>, 40(<reg>)
- MI->setDesc(get(SystemZ::LG));
- MachineInstrBuilder(MF, MI).addReg(Reg64).addImm(40).addReg(0);
-}
-
// Emit a zero-extending move from 32-bit GPR SrcReg to 32-bit GPR
// DestReg before MBBI in MBB. Use LowLowOpcode when both DestReg and SrcReg
// are low registers, otherwise use RISB[LH]G. Size is the number of bits
@@ -1054,8 +1028,7 @@ void SystemZInstrInfo::loadRegFromStackSlot(
// and no index. Flag is SimpleBDXLoad for loads and SimpleBDXStore for stores.
static bool isSimpleBD12Move(const MachineInstr *MI, unsigned Flag) {
const MCInstrDesc &MCID = MI->getDesc();
- return ((MCID.TSFlags & Flag) &&
- isUInt<12>(MI->getOperand(2).getImm()) &&
+ return ((MCID.TSFlags & Flag) && isUInt<12>(MI->getOperand(2).getImm()) &&
MI->getOperand(3).getReg() == 0);
}
@@ -1812,6 +1785,49 @@ bool SystemZInstrInfo::expandPostRAPseudo(MachineInstr &MI...
[truncated]
|
|
Hold on, investigating an issue |
|
Closing pending updates |
This PR allows
-mstack-protector-guard=globalfors390x, which causes the stack guard value to be read from a global variable.It also adds a new arch-specific option
-mstack-protector-guard-record, analogous to-mrecord-mcount, which will causeclangto emit a__stack_protector_locsection containing all the locations in the output binary that load the stack guard, for the purposes of later rewriting of those loads by the kernel. This new option only works together with theglobalstack protector.In order to minimize exposure of the stack guard, both the storing of the stack guard onto the stack, and the later comparison of that value against the reference value, are handled via direct mem-to-mem instructions, those being
mvcandclc. This is achieved by introducing two new pseudo instructions,MOVE_STACK_GUARDandCOMPARE_STACK_GUARD, which are inserted by the DAGCombiner after SelectionDAG construction.This commit also adds tests for both kinds of stack protectors (tls and global), for the proper insertion of the pseudos, as well as the proper emission of the
__stack_protector_locsection.