openbsd-ports/devel/llvm/patches/patch-lib_Target_Mips_MipsAsmPrinter_cpp
2022-03-10 00:04:05 +00:00

90 lines
3.3 KiB
Plaintext

- Add retguard for octeon/mips64.
Index: lib/Target/Mips/MipsAsmPrinter.cpp
--- lib/Target/Mips/MipsAsmPrinter.cpp.orig
+++ lib/Target/Mips/MipsAsmPrinter.cpp
@@ -242,6 +242,83 @@ void MipsAsmPrinter::emitInstruction(const MachineInst
case Mips::PATCHABLE_TAIL_CALL:
LowerPATCHABLE_TAIL_CALL(*MI);
return;
+ case Mips::RETGUARD_GET_FUNCTION_ADDR:
+ {
+ MCSymbol *PCSym = OutContext.createTempSymbol();
+ MCSymbol *FuncSym = OutContext.lookupSymbol(MI->getMF()->getName());
+ if (FuncSym == nullptr)
+ llvm_unreachable("Function name has no symbol");
+
+ // Branch and link forward, calculate the distance
+ // from here to the start of the function, and fill the
+ // address in the given dest register
+ unsigned OUT = MI->getOperand(0).getReg();
+ unsigned IN1 = MI->getOperand(1).getReg();
+ unsigned IN2 = MI->getOperand(2).getReg();
+ MCSymbol *ReturnSym = MI->getOperand(3).getMCSymbol();
+
+ // Save the value of RA in IN1
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::OR64)
+ .addReg(IN1)
+ .addReg(Mips::RA_64)
+ .addReg(Mips::ZERO_64));
+ // BAL to get the PC into RA
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::BAL)
+ .addExpr(MCSymbolRefExpr::create(ReturnSym, OutContext)));
+ // NOP
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::SLL)
+ .addReg(Mips::ZERO_64)
+ .addReg(Mips::ZERO_64)
+ .addImm(0));
+
+ // Emit a symbol for "here/PC" because BAL will put
+ // the address of the instruction following the NOP into RA
+ // and we need this symbol to do the math
+ OutStreamer->emitLabel(PCSym);
+
+ // Store PC in IN2
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::OR64)
+ .addReg(IN2)
+ .addReg(Mips::RA_64)
+ .addReg(Mips::ZERO_64));
+ // Restore original RA
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::OR64)
+ .addReg(Mips::RA_64)
+ .addReg(IN1)
+ .addReg(Mips::ZERO_64));
+ // Load the offset from PCSym to the start of the function
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::LUi64)
+ .addReg(IN1)
+ .addExpr(MipsMCExpr::create(MipsMCExpr::MipsExprKind::MEK_HI,
+ MCBinaryExpr::createSub(
+ MCSymbolRefExpr::create(PCSym, OutContext),
+ MCSymbolRefExpr::create(FuncSym, OutContext),
+ OutContext),
+ OutContext)));
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::DADDiu)
+ .addReg(IN1)
+ .addReg(IN1)
+ .addExpr(MipsMCExpr::create(MipsMCExpr::MipsExprKind::MEK_LO,
+ MCBinaryExpr::createSub(
+ MCSymbolRefExpr::create(PCSym, OutContext),
+ MCSymbolRefExpr::create(FuncSym, OutContext),
+ OutContext),
+ OutContext)));
+
+ // Sub distance from here to start of function
+ // to get address of the start of function
+ EmitToStreamer(*OutStreamer, MCInstBuilder(Mips::DSUBu)
+ .addReg(OUT)
+ .addReg(IN2)
+ .addReg(IN1));
+ return;
+ }
+ case Mips::RETGUARD_EMIT_SYMBOL:
+ {
+ MCSymbol *ReturnSym = MI->getOperand(0).getMCSymbol();
+ OutStreamer->emitLabel(ReturnSym);
+ return;
+ }
}
if (EmitJalrReloc &&