Skip to content

Commit 3b67383

Browse files
authored
[MC][Mips] Generate required IMAGE_REL_MIPS_PAIR relocation (#120876)
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 against Microsoft C compiler for MIPS.
1 parent 84c89d0 commit 3b67383

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
@@ -773,7 +773,10 @@ void WinCOFFWriter::assignFileOffsets(MCAssembler &Asm) {
773773

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

@@ -976,8 +979,18 @@ void WinCOFFWriter::recordRelocation(MCAssembler &Asm,
976979
if (Fixup.getKind() == FK_SecRel_2)
977980
FixedValue = 0;
978981

979-
if (OWriter.TargetObjectWriter->recordRelocation(Fixup))
982+
if (OWriter.TargetObjectWriter->recordRelocation(Fixup)) {
980983
Sec->Relocations.push_back(Reloc);
984+
if (Header.Machine == COFF::IMAGE_FILE_MACHINE_R4000 &&
985+
(Reloc.Data.Type == COFF::IMAGE_REL_MIPS_REFHI ||
986+
Reloc.Data.Type == COFF::IMAGE_REL_MIPS_SECRELHI)) {
987+
// IMAGE_REL_MIPS_REFHI and IMAGE_REL_MIPS_SECRELHI *must*
988+
// be followed by IMAGE_REL_MIPS_PAIR
989+
auto RelocPair = Reloc;
990+
RelocPair.Data.Type = COFF::IMAGE_REL_MIPS_PAIR;
991+
Sec->Relocations.push_back(RelocPair);
992+
}
993+
}
981994
}
982995

983996
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)