From 0287efb891c1da33d8eb01889f18ef71cd689ebc Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Sat, 9 Nov 2019 09:29:42 +0300 Subject: [mips] Do not emit R_MIPS_JALR for sym+offset in case of O32 ABI O32 ABI uses relocations in REL format. Relocation's addend is written in place. R_MIPS_JALR relocation points to the `jalr` instruction which does not have a place to store the relocation addend. So it's impossible to save non-zero "offset". This patch blocks emission of `R_MIPS_JALR` relocations in such cases. Differential Revision: https://reviews.llvm.org/D70201 --- llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'llvm/lib/Target') diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 11c9cddb28c..65c373b10f5 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -562,6 +562,19 @@ public: return getSTI().getFeatureBits()[Mips::FeatureFP64Bit]; } + bool isJalrRelocAvailable(const MCExpr *JalExpr) { + if (!EmitJalrReloc) + return false; + MCValue Res; + if (!JalExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) + return false; + if (Res.getSymB() != nullptr) + return false; + if (Res.getConstant() != 0) + return ABI.IsN32() || ABI.IsN64(); + return true; + } + const MipsABIInfo &getABI() const { return ABI; } bool isABI_N32() const { return ABI.IsN32(); } bool isABI_N64() const { return ABI.IsN64(); } @@ -2048,7 +2061,7 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, JalrInst.addOperand(MCOperand::createReg(Mips::RA)); JalrInst.addOperand(MCOperand::createReg(Mips::T9)); - if (EmitJalrReloc) { + if (isJalrRelocAvailable(JalExpr)) { // As an optimization hint for the linker, before the JALR we add: // .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol // tmplabel: -- cgit v1.2.3