mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-08 10:30:09 +00:00
[PowerPC] Secure PLT support
This patch supports secure PLT mode for PowerPC 32 architecture. Differential Revision: https://reviews.llvm.org/D42112 llvm-svn: 328617
This commit is contained in:
parent
e8059b1de4
commit
06cf6a6490
@ -119,6 +119,8 @@ def FeatureMSYNC : SubtargetFeature<"msync", "HasOnlyMSYNC", "true",
|
||||
[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",
|
||||
|
@ -563,33 +563,63 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
// 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 @@ void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
|
||||
|
||||
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);
|
||||
|
@ -4001,6 +4001,27 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
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;
|
||||
|
@ -107,10 +107,20 @@ static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
|
||||
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,
|
||||
|
@ -133,6 +133,7 @@ protected:
|
||||
bool HasFloat128;
|
||||
bool IsISA3_0;
|
||||
bool UseLongCalls;
|
||||
bool SecurePlt;
|
||||
|
||||
POPCNTDKind HasPOPCNTD;
|
||||
|
||||
@ -255,6 +256,7 @@ public:
|
||||
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; }
|
||||
|
@ -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 @@ entry:
|
||||
; 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user