diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp index 2d883e974a584..a68ffd423b70c 100644 --- a/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -772,7 +772,10 @@ void WinCOFFWriter::assignFileOffsets(MCAssembler &Asm) { for (auto &Relocation : Sec->Relocations) { assert(Relocation.Symb->getIndex() != -1); - Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex(); + if (Header.Machine != COFF::IMAGE_FILE_MACHINE_R4000 || + Relocation.Data.Type != COFF::IMAGE_REL_MIPS_PAIR) { + Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex(); + } } } @@ -966,8 +969,18 @@ void WinCOFFWriter::recordRelocation(MCAssembler &Asm, if (Fixup.getKind() == FK_SecRel_2) FixedValue = 0; - if (OWriter.TargetObjectWriter->recordRelocation(Fixup)) + if (OWriter.TargetObjectWriter->recordRelocation(Fixup)) { Sec->Relocations.push_back(Reloc); + if (Header.Machine == COFF::IMAGE_FILE_MACHINE_R4000 && + (Reloc.Data.Type == COFF::IMAGE_REL_MIPS_REFHI || + Reloc.Data.Type == COFF::IMAGE_REL_MIPS_SECRELHI)) { + // IMAGE_REL_MIPS_REFHI and IMAGE_REL_MIPS_SECRELHI *must* + // be followed by IMAGE_REL_MIPS_PAIR + auto RelocPair = Reloc; + RelocPair.Data.Type = COFF::IMAGE_REL_MIPS_PAIR; + Sec->Relocations.push_back(RelocPair); + } + } } static std::time_t getTime() { diff --git a/llvm/test/MC/Mips/coff-relocs.ll b/llvm/test/MC/Mips/coff-relocs.ll index 1d8b3f192d7af..2d289e8d44659 100644 --- a/llvm/test/MC/Mips/coff-relocs.ll +++ b/llvm/test/MC/Mips/coff-relocs.ll @@ -22,6 +22,9 @@ define i32 @foo_var() { ; CHECK: - VirtualAddress: 32 ; CHECK: SymbolName: var ; CHECK: Type: IMAGE_REL_MIPS_REFHI +; CHECK: - VirtualAddress: 32 +; CHECK: SymbolName: .text +; CHECK: Type: IMAGE_REL_MIPS_PAIR ; CHECK: - VirtualAddress: 40 ; CHECK: SymbolName: var ; CHECK: Type: IMAGE_REL_MIPS_REFLO