summaryrefslogtreecommitdiff
path: root/user/llvm6/secure-plt.patch
diff options
context:
space:
mode:
Diffstat (limited to 'user/llvm6/secure-plt.patch')
-rw-r--r--user/llvm6/secure-plt.patch208
1 files changed, 208 insertions, 0 deletions
diff --git a/user/llvm6/secure-plt.patch b/user/llvm6/secure-plt.patch
new file mode 100644
index 000000000..e8af33d87
--- /dev/null
+++ b/user/llvm6/secure-plt.patch
@@ -0,0 +1,208 @@
+Index: llvm/lib/Target/PowerPC/PPC.td
+===================================================================
+--- llvm/lib/Target/PowerPC/PPC.td
++++ llvm/lib/Target/PowerPC/PPC.td
+@@ -119,6 +119,8 @@
+ [FeatureBookE]>;
+ def FeatureE500 : SubtargetFeature<"e500", "IsE500", "true",
+ "Enable E500/E500mc instructions">;
++def FeatureSecurePlt : SubtargetFeature<"secure-plt","SecurePlt", "true",
++ "Enable secure plt mode">;
+ def FeaturePPC4xx : SubtargetFeature<"ppc4xx", "IsPPC4xx", "true",
+ "Enable PPC 4xx instructions">;
+ def FeaturePPC6xx : SubtargetFeature<"ppc6xx", "IsPPC6xx", "true",
+Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+===================================================================
+--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
++++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+@@ -563,33 +563,63 @@
+ // Transform %rd = UpdateGBR(%rt, %ri)
+ // Into: lwz %rt, .L0$poff - .L0$pb(%ri)
+ // add %rd, %rt, %ri
++ // or into (if secure plt mode is on):
++ // addis r30, r30, .LTOC - .L0$pb@ha
++ // addi r30, r30, .LTOC - .L0$pb@l
+ // Get the offset from the GOT Base Register to the GOT
+ LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
+- MCSymbol *PICOffset =
+- MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol();
+- TmpInst.setOpcode(PPC::LWZ);
+- const MCExpr *Exp =
+- MCSymbolRefExpr::create(PICOffset, MCSymbolRefExpr::VK_None, OutContext);
+- const MCExpr *PB =
+- MCSymbolRefExpr::create(MF->getPICBaseSymbol(),
+- MCSymbolRefExpr::VK_None,
+- OutContext);
+- const MCOperand TR = TmpInst.getOperand(1);
+- const MCOperand PICR = TmpInst.getOperand(0);
++ if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
++ unsigned PICR = TmpInst.getOperand(0).getReg();
++ MCSymbol *LTOCSymbol = OutContext.getOrCreateSymbol(StringRef(".LTOC"));
++ const MCExpr *PB =
++ MCSymbolRefExpr::create(MF->getPICBaseSymbol(),
++ OutContext);
+
+- // Step 1: lwz %rt, .L$poff - .L$pb(%ri)
+- TmpInst.getOperand(1) =
+- MCOperand::createExpr(MCBinaryExpr::createSub(Exp, PB, OutContext));
+- TmpInst.getOperand(0) = TR;
+- TmpInst.getOperand(2) = PICR;
+- EmitToStreamer(*OutStreamer, TmpInst);
++ const MCExpr *LTOCDeltaExpr =
++ MCBinaryExpr::createSub(MCSymbolRefExpr::create(LTOCSymbol, OutContext),
++ PB, OutContext);
+
+- TmpInst.setOpcode(PPC::ADD4);
+- TmpInst.getOperand(0) = PICR;
+- TmpInst.getOperand(1) = TR;
+- TmpInst.getOperand(2) = PICR;
+- EmitToStreamer(*OutStreamer, TmpInst);
+- return;
++ const MCExpr *LTOCDeltaHi =
++ PPCMCExpr::createHa(LTOCDeltaExpr, false, OutContext);
++ EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
++ .addReg(PICR)
++ .addReg(PICR)
++ .addExpr(LTOCDeltaHi));
++
++ const MCExpr *LTOCDeltaLo =
++ PPCMCExpr::createLo(LTOCDeltaExpr, false, OutContext);
++ EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
++ .addReg(PICR)
++ .addReg(PICR)
++ .addExpr(LTOCDeltaLo));
++ return;
++ } else {
++ MCSymbol *PICOffset =
++ MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol();
++ TmpInst.setOpcode(PPC::LWZ);
++ const MCExpr *Exp =
++ MCSymbolRefExpr::create(PICOffset, MCSymbolRefExpr::VK_None, OutContext);
++ const MCExpr *PB =
++ MCSymbolRefExpr::create(MF->getPICBaseSymbol(),
++ MCSymbolRefExpr::VK_None,
++ OutContext);
++ const MCOperand TR = TmpInst.getOperand(1);
++ const MCOperand PICR = TmpInst.getOperand(0);
++
++ // Step 1: lwz %rt, .L$poff - .L$pb(%ri)
++ TmpInst.getOperand(1) =
++ MCOperand::createExpr(MCBinaryExpr::createSub(Exp, PB, OutContext));
++ TmpInst.getOperand(0) = TR;
++ TmpInst.getOperand(2) = PICR;
++ EmitToStreamer(*OutStreamer, TmpInst);
++
++ TmpInst.setOpcode(PPC::ADD4);
++ TmpInst.getOperand(0) = PICR;
++ TmpInst.getOperand(1) = TR;
++ TmpInst.getOperand(2) = PICR;
++ EmitToStreamer(*OutStreamer, TmpInst);
++ return;
++ }
+ }
+ case PPC::LWZtoc: {
+ // Transform %r3 = LWZtoc @min1, %r2
+@@ -1233,7 +1263,7 @@
+
+ if (!Subtarget->isPPC64()) {
+ const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
+- if (PPCFI->usesPICBase()) {
++ if (PPCFI->usesPICBase() && !Subtarget->isSecurePlt()) {
+ MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol();
+ MCSymbol *PICBase = MF->getPICBaseSymbol();
+ OutStreamer->EmitLabel(RelocSymbol);
+Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+===================================================================
+--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
++++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+@@ -4001,6 +4001,27 @@
+ return;
+ break;
+
++ case PPCISD::CALL: {
++ const Module *M = MF->getFunction().getParent();
++
++ if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) != MVT::i32 ||
++ !PPCSubTarget->isSecurePlt() || !PPCSubTarget->isTargetELF() ||
++ M->getPICLevel() == PICLevel::SmallPIC)
++ break;
++
++ SDValue Op = N->getOperand(1);
++
++ if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op)) {
++ if (GA->getTargetFlags() == PPCII::MO_PLT)
++ getGlobalBaseReg();
++ }
++ else if (ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op)) {
++ if (ES->getTargetFlags() == PPCII::MO_PLT)
++ getGlobalBaseReg();
++ }
++ }
++ break;
++
+ case PPCISD::GlobalBaseReg:
+ ReplaceNode(N, getGlobalBaseReg());
+ return;
+Index: llvm/lib/Target/PowerPC/PPCMCInstLower.cpp
+===================================================================
+--- llvm/lib/Target/PowerPC/PPCMCInstLower.cpp
++++ llvm/lib/Target/PowerPC/PPCMCInstLower.cpp
+@@ -107,10 +107,20 @@
+ break;
+ }
+
+- if (MO.getTargetFlags() == PPCII::MO_PLT)
++ if (MO.getTargetFlags() == PPCII::MO_PLT)
+ RefKind = MCSymbolRefExpr::VK_PLT;
+
++ const MachineFunction *MF = MO.getParent()->getParent()->getParent();
++ const PPCSubtarget *Subtarget = &(MF->getSubtarget<PPCSubtarget>());
++ const TargetMachine &TM = Printer.TM;
+ const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, RefKind, Ctx);
++ // -msecure-plt option works only in PIC mode. If secure plt mode
++ // is on add 32768 to symbol.
++ if (Subtarget->isSecurePlt() && TM.isPositionIndependent() &&
++ MO.getTargetFlags() == PPCII::MO_PLT)
++ Expr = MCBinaryExpr::createAdd(Expr,
++ MCConstantExpr::create(32768, Ctx),
++ Ctx);
+
+ if (!MO.isJTI() && MO.getOffset())
+ Expr = MCBinaryExpr::createAdd(Expr,
+Index: llvm/lib/Target/PowerPC/PPCSubtarget.h
+===================================================================
+--- llvm/lib/Target/PowerPC/PPCSubtarget.h
++++ llvm/lib/Target/PowerPC/PPCSubtarget.h
+@@ -133,6 +133,7 @@
+ bool HasFloat128;
+ bool IsISA3_0;
+ bool UseLongCalls;
++ bool SecurePlt;
+
+ POPCNTDKind HasPOPCNTD;
+
+@@ -255,6 +256,7 @@
+ bool hasOnlyMSYNC() const { return HasOnlyMSYNC; }
+ bool isPPC4xx() const { return IsPPC4xx; }
+ bool isPPC6xx() const { return IsPPC6xx; }
++ bool isSecurePlt() const {return SecurePlt; }
+ bool isE500() const { return IsE500; }
+ bool isFeatureMFTB() const { return FeatureMFTB; }
+ bool isDeprecatedDST() const { return DeprecatedDST; }
+Index: llvm/test/CodeGen/PowerPC/ppc32-pic-large.ll
+===================================================================
+--- llvm/test/CodeGen/PowerPC/ppc32-pic-large.ll
++++ llvm/test/CodeGen/PowerPC/ppc32-pic-large.ll
+@@ -1,4 +1,5 @@
+ ; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic | FileCheck -check-prefix=LARGE-BSS %s
++; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -mattr=+secure-plt -relocation-model=pic | FileCheck -check-prefix=LARGE-SECUREPLT %s
+ @bar = common global i32 0, align 4
+
+ declare i32 @call_foo(i32, ...)
+@@ -29,3 +30,6 @@
+ ; LARGE-BSS: [[VREF]]:
+ ; LARGE-BSS-NEXT: .p2align 2
+ ; LARGE-BSS-NEXT: .long bar
++; LARGE-SECUREPLT: addis 30, 30, .LTOC-.L0$pb@ha
++; LARGE-SECUREPLT: addi 30, 30, .LTOC-.L0$pb@l
++; LARGE-SECUREPLT: bl call_foo@PLT+32768