91 lines
3.6 KiB
Text
91 lines
3.6 KiB
Text
Add RETGUARD implementation for powerpc and powerpc64.
|
|
|
|
Index: lib/Target/PowerPC/PPCAsmPrinter.cpp
|
|
--- lib/Target/PowerPC/PPCAsmPrinter.cpp.orig
|
|
+++ lib/Target/PowerPC/PPCAsmPrinter.cpp
|
|
@@ -815,6 +815,85 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr
|
|
return;
|
|
}
|
|
}
|
|
+ case PPC::RETGUARD_LOAD_PC: {
|
|
+ unsigned DEST = MI->getOperand(0).getReg();
|
|
+ unsigned LR = MI->getOperand(1).getReg();
|
|
+ MCSymbol *HereSym = MI->getOperand(2).getMCSymbol();
|
|
+
|
|
+ unsigned MTLR = PPC::MTLR;
|
|
+ unsigned MFLR = PPC::MFLR;
|
|
+ unsigned BL = PPC::BL;
|
|
+ if (Subtarget->isPPC64()) {
|
|
+ MTLR = PPC::MTLR8;
|
|
+ MFLR = PPC::MFLR8;
|
|
+ BL = PPC::BL8;
|
|
+ }
|
|
+
|
|
+ // Cache the current LR
|
|
+ EmitToStreamer(*OutStreamer, MCInstBuilder(MFLR)
|
|
+ .addReg(LR));
|
|
+
|
|
+ // Create the BL forward
|
|
+ const MCExpr *HereExpr = MCSymbolRefExpr::create(HereSym, OutContext);
|
|
+ EmitToStreamer(*OutStreamer, MCInstBuilder(BL)
|
|
+ .addExpr(HereExpr));
|
|
+ OutStreamer->emitLabel(HereSym);
|
|
+
|
|
+ // Grab the result
|
|
+ EmitToStreamer(*OutStreamer, MCInstBuilder(MFLR)
|
|
+ .addReg(DEST));
|
|
+ // Restore LR
|
|
+ EmitToStreamer(*OutStreamer, MCInstBuilder(MTLR)
|
|
+ .addReg(LR));
|
|
+ return;
|
|
+ }
|
|
+ case PPC::RETGUARD_LOAD_GOT: {
|
|
+ if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
|
|
+ StringRef GOTName = (PL == PICLevel::SmallPIC ?
|
|
+ "_GLOBAL_OFFSET_TABLE_" : ".LTOC");
|
|
+ unsigned DEST = MI->getOperand(0).getReg();
|
|
+ unsigned HERE = MI->getOperand(1).getReg();
|
|
+ MCSymbol *HereSym = MI->getOperand(2).getMCSymbol();
|
|
+ MCSymbol *GOTSym = OutContext.getOrCreateSymbol(GOTName);
|
|
+ const MCExpr *HereExpr = MCSymbolRefExpr::create(HereSym, OutContext);
|
|
+ const MCExpr *GOTExpr = MCSymbolRefExpr::create(GOTSym, OutContext);
|
|
+
|
|
+ // Get offset from Here to GOT
|
|
+ const MCExpr *GOTDeltaExpr =
|
|
+ MCBinaryExpr::createSub(GOTExpr, HereExpr, OutContext);
|
|
+ const MCExpr *GOTDeltaHi =
|
|
+ PPCMCExpr::createHa(GOTDeltaExpr, OutContext);
|
|
+ const MCExpr *GOTDeltaLo =
|
|
+ PPCMCExpr::createLo(GOTDeltaExpr, OutContext);
|
|
+
|
|
+ EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
|
|
+ .addReg(DEST)
|
|
+ .addReg(HERE)
|
|
+ .addExpr(GOTDeltaHi));
|
|
+ EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
|
|
+ .addReg(DEST)
|
|
+ .addReg(DEST)
|
|
+ .addExpr(GOTDeltaLo));
|
|
+ }
|
|
+ return;
|
|
+ }
|
|
+ case PPC::RETGUARD_LOAD_COOKIE: {
|
|
+ unsigned DEST = MI->getOperand(0).getReg();
|
|
+ MCSymbol *CookieSym = getSymbol(MI->getOperand(1).getGlobal());
|
|
+ const MCExpr *CookieExprHa = MCSymbolRefExpr::create(
|
|
+ CookieSym, MCSymbolRefExpr::VK_PPC_HA, OutContext);
|
|
+ const MCExpr *CookieExprLo = MCSymbolRefExpr::create(
|
|
+ CookieSym, MCSymbolRefExpr::VK_PPC_LO, OutContext);
|
|
+
|
|
+ EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LIS)
|
|
+ .addReg(DEST)
|
|
+ .addExpr(CookieExprHa));
|
|
+ EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ)
|
|
+ .addReg(DEST)
|
|
+ .addExpr(CookieExprLo)
|
|
+ .addReg(DEST));
|
|
+ return;
|
|
+ }
|
|
case PPC::LWZtoc: {
|
|
// Transform %rN = LWZtoc @op1, %r2
|
|
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
|