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