[llvm] 3b67383 - [MC][Mips] Generate required IMAGE_REL_MIPS_PAIR relocation (#120876)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 19 22:54:47 PST 2025
Author: Hervé Poussineau
Date: 2025-01-20T14:54:43+08:00
New Revision: 3b67383c6cb777e4f37dd1a5af0872843c9ab35a
URL: https://github.com/llvm/llvm-project/commit/3b67383c6cb777e4f37dd1a5af0872843c9ab35a
DIFF: https://github.com/llvm/llvm-project/commit/3b67383c6cb777e4f37dd1a5af0872843c9ab35a.diff
LOG: [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.
Added:
Modified:
llvm/lib/MC/WinCOFFObjectWriter.cpp
llvm/test/MC/Mips/coff-relocs.ll
Removed:
################################################################################
diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp
index da0c0661117b28..f79c374640c219 100644
--- a/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -773,7 +773,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();
+ }
}
}
@@ -976,8 +979,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 1d8b3f192d7af6..2d289e8d446599 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
More information about the llvm-commits
mailing list