mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-25 21:33:25 +00:00
[PPC32] Support PLT calls for -msecure-plt -fpic
Summary: In Secure PLT ABI, -fpic is similar to -fPIC. The differences are that: * -fpic stores the address of _GLOBAL_OFFSET_TABLE_ in r30, while -fPIC stores .got2+0x8000. * -fpic uses an addend of 0 for R_PPC_PLTREL24, while -fPIC uses 0x8000. Reviewers: hfinkel, jhibbits, joerg, nemanjai, spetrovic Reviewed By: jhibbits Subscribers: adalava, kbarton, jsji, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D63563 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364324 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b0917b06be
commit
4284cfd291
@ -461,6 +461,7 @@ void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,
|
||||
StringRef Name = "__tls_get_addr";
|
||||
MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(Name);
|
||||
MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
|
||||
const Module *M = MF->getFunction().getParent();
|
||||
|
||||
assert(MI->getOperand(0).isReg() &&
|
||||
((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) ||
|
||||
@ -478,10 +479,10 @@ void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,
|
||||
MCSymbolRefExpr::create(TlsGetAddr, Kind, OutContext);
|
||||
|
||||
// Add 32768 offset to the symbol so we follow up the latest GOT/PLT ABI.
|
||||
if (Kind == MCSymbolRefExpr::VK_PLT && Subtarget->isSecurePlt())
|
||||
TlsRef = MCBinaryExpr::createAdd(TlsRef,
|
||||
MCConstantExpr::create(32768, OutContext),
|
||||
OutContext);
|
||||
if (Kind == MCSymbolRefExpr::VK_PLT && Subtarget->isSecurePlt() &&
|
||||
M->getPICLevel() == PICLevel::BigPIC)
|
||||
TlsRef = MCBinaryExpr::createAdd(
|
||||
TlsRef, MCConstantExpr::create(32768, OutContext), OutContext);
|
||||
const MachineOperand &MO = MI->getOperand(2);
|
||||
const GlobalValue *GValue = MO.getGlobal();
|
||||
MCSymbol *MOSymbol = getSymbol(GValue);
|
||||
@ -583,34 +584,30 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
// 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
|
||||
// addis r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@ha
|
||||
// addi r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@l
|
||||
// Get the offset from the GOT Base Register to the GOT
|
||||
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
|
||||
if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
|
||||
unsigned PICR = TmpInst.getOperand(0).getReg();
|
||||
MCSymbol *LTOCSymbol = OutContext.getOrCreateSymbol(StringRef(".LTOC"));
|
||||
MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol(
|
||||
M->getPICLevel() == PICLevel::SmallPIC ? "_GLOBAL_OFFSET_TABLE_"
|
||||
: ".LTOC");
|
||||
const MCExpr *PB =
|
||||
MCSymbolRefExpr::create(MF->getPICBaseSymbol(),
|
||||
OutContext);
|
||||
MCSymbolRefExpr::create(MF->getPICBaseSymbol(), OutContext);
|
||||
|
||||
const MCExpr *LTOCDeltaExpr =
|
||||
MCBinaryExpr::createSub(MCSymbolRefExpr::create(LTOCSymbol, OutContext),
|
||||
PB, OutContext);
|
||||
const MCExpr *DeltaExpr = MCBinaryExpr::createSub(
|
||||
MCSymbolRefExpr::create(BaseSymbol, OutContext), PB, OutContext);
|
||||
|
||||
const MCExpr *LTOCDeltaHi =
|
||||
PPCMCExpr::createHa(LTOCDeltaExpr, false, OutContext);
|
||||
EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
|
||||
.addReg(PICR)
|
||||
.addReg(PICR)
|
||||
.addExpr(LTOCDeltaHi));
|
||||
const MCExpr *DeltaHi = PPCMCExpr::createHa(DeltaExpr, false, OutContext);
|
||||
EmitToStreamer(
|
||||
*OutStreamer,
|
||||
MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi));
|
||||
|
||||
const MCExpr *LTOCDeltaLo =
|
||||
PPCMCExpr::createLo(LTOCDeltaExpr, false, OutContext);
|
||||
EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
|
||||
.addReg(PICR)
|
||||
.addReg(PICR)
|
||||
.addExpr(LTOCDeltaLo));
|
||||
const MCExpr *DeltaLo = PPCMCExpr::createLo(DeltaExpr, false, OutContext);
|
||||
EmitToStreamer(
|
||||
*OutStreamer,
|
||||
MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo));
|
||||
return;
|
||||
} else {
|
||||
MCSymbol *PICOffset =
|
||||
|
@ -439,7 +439,8 @@ SDNode *PPCDAGToDAGISel::getGlobalBaseReg() {
|
||||
if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) == MVT::i32) {
|
||||
if (PPCSubTarget->isTargetELF()) {
|
||||
GlobalBaseReg = PPC::R30;
|
||||
if (M->getPICLevel() == PICLevel::SmallPIC) {
|
||||
if (!PPCSubTarget->isSecurePlt() &&
|
||||
M->getPICLevel() == PICLevel::SmallPIC) {
|
||||
BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MoveGOTtoLR));
|
||||
BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MFLR), GlobalBaseReg);
|
||||
MF->getInfo<PPCFunctionInfo>()->setUsesPICBase(true);
|
||||
@ -4395,11 +4396,9 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
getGlobalBaseReg();
|
||||
} break;
|
||||
case PPCISD::CALL: {
|
||||
const Module *M = MF->getFunction().getParent();
|
||||
|
||||
if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) != MVT::i32 ||
|
||||
(!TM.isPositionIndependent() || !PPCSubTarget->isSecurePlt()) ||
|
||||
!PPCSubTarget->isTargetELF() || M->getPICLevel() == PICLevel::SmallPIC)
|
||||
!TM.isPositionIndependent() || !PPCSubTarget->isSecurePlt() ||
|
||||
!PPCSubTarget->isTargetELF())
|
||||
break;
|
||||
|
||||
SDValue Op = N->getOperand(1);
|
||||
|
@ -110,16 +110,16 @@ static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
|
||||
RefKind = MCSymbolRefExpr::VK_PLT;
|
||||
|
||||
const MachineFunction *MF = MO.getParent()->getParent()->getParent();
|
||||
const Module *M = MF->getFunction().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 -msecure-plt -fPIC, add 32768 to symbol.
|
||||
if (Subtarget->isSecurePlt() && TM.isPositionIndependent() &&
|
||||
M->getPICLevel() == PICLevel::BigPIC &&
|
||||
MO.getTargetFlags() == PPCII::MO_PLT)
|
||||
Expr = MCBinaryExpr::createAdd(Expr,
|
||||
MCConstantExpr::create(32768, Ctx),
|
||||
Ctx);
|
||||
Expr =
|
||||
MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(32768, Ctx), Ctx);
|
||||
|
||||
if (!MO.isJTI() && MO.getOffset())
|
||||
Expr = MCBinaryExpr::createAdd(Expr,
|
||||
|
@ -1,4 +1,7 @@
|
||||
; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic | FileCheck -check-prefix=SMALL-BSS %s
|
||||
; RUN: llc < %s -mtriple=powerpc -relocation-model=pic | \
|
||||
; RUN: FileCheck -check-prefixes=SMALL,SMALL-BSS %s
|
||||
; RUN: llc < %s -mtriple=powerpc -relocation-model=pic -mattr=+secure-plt | \
|
||||
; RUN: FileCheck -check-prefixes=SMALL,SMALL-SECUREPLT %s
|
||||
@bar = common global i32 0, align 4
|
||||
|
||||
declare i32 @call_foo(i32, ...)
|
||||
@ -12,13 +15,16 @@ entry:
|
||||
|
||||
!llvm.module.flags = !{!0}
|
||||
!0 = !{i32 1, !"PIC Level", i32 1}
|
||||
; SMALL-BSS-LABEL:foo:
|
||||
; SMALL-BSS: stwu 1, -32(1)
|
||||
; SMALL-BSS: stw 30, 24(1)
|
||||
; SMALL-BSS: bl _GLOBAL_OFFSET_TABLE_@local-4
|
||||
; SMALL-BSS: mflr 30
|
||||
; SMALL-BSS-DAG: stw {{[0-9]+}}, 8(1)
|
||||
; SMALL-BSS-DAG: lwz [[VREG:[0-9]+]], bar@GOT(30)
|
||||
; SMALL-BSS-DAG: lwz {{[0-9]+}}, 0([[VREG]])
|
||||
; SMALL-BSS: bl call_foo@PLT
|
||||
; SMALL-BSS: lwz 30, 24(1)
|
||||
; SMALL-LABEL: foo:
|
||||
; SMALL: stwu 1, -32(1)
|
||||
; SMALL: stw 30, 24(1)
|
||||
; SMALL-BSS: bl _GLOBAL_OFFSET_TABLE_@local-4
|
||||
; SMALL-SECURE: bl .L0$pb
|
||||
; SMALL: mflr 30
|
||||
; SMALL-SECURE: addis 30, 30, _GLOBAL_OFFSET_TABLE_-.Lo$pb@ha
|
||||
; SMALL-SECURE: addi 30, 30, _GLOBAL_OFFSET_TABLE_-.Lo$pb@l
|
||||
; SMALL-DAG: stw {{[0-9]+}}, 8(1)
|
||||
; SMALL-DAG: lwz [[VREG:[0-9]+]], bar@GOT(30)
|
||||
; SMALL-DAG: lwz {{[0-9]+}}, 0([[VREG]])
|
||||
; SMALL: bl call_foo@PLT{{$}}
|
||||
; SMALL: lwz 30, 24(1)
|
||||
|
18
test/CodeGen/PowerPC/ppc32-secure-plt-tls2.ll
Normal file
18
test/CodeGen/PowerPC/ppc32-secure-plt-tls2.ll
Normal file
@ -0,0 +1,18 @@
|
||||
; RUN: llc < %s -mtriple=powerpc -mattr=+secure-plt -relocation-model=pic | FileCheck -check-prefix=SECURE-PLT-TLS %s
|
||||
|
||||
@a = thread_local local_unnamed_addr global i32 6, align 4
|
||||
define i32 @main() local_unnamed_addr #0 {
|
||||
entry:
|
||||
%0 = load i32, i32* @a, align 4
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
|
||||
!llvm.module.flags = !{!0}
|
||||
!0 = !{i32 7, !"PIC Level", i32 1}
|
||||
|
||||
; SECURE-PLT-TLS: mflr 30
|
||||
; SECURE-PLT-TLS-NEXT: addis 30, 30, _GLOBAL_OFFSET_TABLE_-.L0$pb@ha
|
||||
; SECURE-PLT-TLS-NEXT: addi 30, 30, _GLOBAL_OFFSET_TABLE_-.L0$pb@l
|
||||
; SECURE-PLT-TLS: addi 3, 30, a@got@tlsgd
|
||||
; SECURE-PLT-TLS: bl __tls_get_addr(a@tlsgd)@PLT{{$}}
|
Loading…
x
Reference in New Issue
Block a user