Skip to content

Commit bb348ee

Browse files
committed
[MC][Mips] Add the required IMAGE_REL_MIPS_PAIR relocation after IMAGE_REL_MIPS_REFHI/IMAGE_REL_MIPS_SECRELHI
Microsoft PE/COFF specification says that the IMAGE_REL_MIPS_REFHI relocation contains "the high 16 bits of the target's 32-bit virtual address. [...] This relocation must be immediately followed by a PAIR relocation whose SymbolTableIndex contains a 16-bit displacement which is added to the upper 16 bits taken from the location being relocated." Microsoft PE/COFF specification says that the IMAGE_REL_MIPS_SECRELHI relocation contains "the high 16 bits of the 32-bit offset of the target from the beginning of its section. A PAIR relocation must immediately follow this on. The SymbolTableIndex of the PAIR relocation contains a 16-bit displacement, which is added to the upper 16 bits taken from the location being relocated." Behavior has been checked with Microsoft C compiler for MIPS.
1 parent 0575815 commit bb348ee

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

llvm/lib/MC/WinCOFFObjectWriter.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,10 @@ void WinCOFFWriter::assignFileOffsets(MCAssembler &Asm) {
772772

773773
for (auto &Relocation : Sec->Relocations) {
774774
assert(Relocation.Symb->getIndex() != -1);
775-
Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
775+
if (Header.Machine != COFF::IMAGE_FILE_MACHINE_R4000 ||
776+
Relocation.Data.Type != COFF::IMAGE_REL_MIPS_PAIR) {
777+
Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
778+
}
776779
}
777780
}
778781

@@ -966,8 +969,18 @@ void WinCOFFWriter::recordRelocation(MCAssembler &Asm,
966969
if (Fixup.getKind() == FK_SecRel_2)
967970
FixedValue = 0;
968971

969-
if (OWriter.TargetObjectWriter->recordRelocation(Fixup))
972+
if (OWriter.TargetObjectWriter->recordRelocation(Fixup)) {
970973
Sec->Relocations.push_back(Reloc);
974+
if (Header.Machine == COFF::IMAGE_FILE_MACHINE_R4000 &&
975+
(Reloc.Data.Type == COFF::IMAGE_REL_MIPS_REFHI ||
976+
Reloc.Data.Type == COFF::IMAGE_REL_MIPS_SECRELHI)) {
977+
// IMAGE_REL_MIPS_REFHI and IMAGE_REL_MIPS_SECRELHI *must*
978+
// be followed by IMAGE_REL_MIPS_PAIR
979+
auto RelocPair = Reloc;
980+
RelocPair.Data.Type = COFF::IMAGE_REL_MIPS_PAIR;
981+
Sec->Relocations.push_back(RelocPair);
982+
}
983+
}
971984
}
972985

973986
static std::time_t getTime() {

llvm/test/MC/Mips/coff-relocs.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ define i32 @foo_var() {
2222
; CHECK: - VirtualAddress: 32
2323
; CHECK: SymbolName: var
2424
; CHECK: Type: IMAGE_REL_MIPS_REFHI
25+
; CHECK: - VirtualAddress: 32
26+
; CHECK: SymbolName: .text
27+
; CHECK: Type: IMAGE_REL_MIPS_PAIR
2528
; CHECK: - VirtualAddress: 40
2629
; CHECK: SymbolName: var
2730
; CHECK: Type: IMAGE_REL_MIPS_REFLO

0 commit comments

Comments
 (0)