Skip to content

Conversation

@hpoussin
Copy link
Contributor

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.

…E_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.
@llvmbot llvmbot added the llvm:mc Machine (object) code label Dec 22, 2024
@llvmbot
Copy link
Member

llvmbot commented Dec 22, 2024

@llvm/pr-subscribers-mc

Author: Hervé Poussineau (hpoussin)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/120876.diff

2 Files Affected:

  • (modified) llvm/lib/MC/WinCOFFObjectWriter.cpp (+15-2)
  • (modified) llvm/test/MC/Mips/coff-relocs.ll (+3)
diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp
index 2d883e974a584a..a68ffd423b70c0 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 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

@hpoussin
Copy link
Contributor Author

This is an extract of PR #107744

@hpoussin
Copy link
Contributor Author

Ping

2 similar comments
@hpoussin
Copy link
Contributor Author

hpoussin commented Jan 5, 2025

Ping

@hpoussin
Copy link
Contributor Author

Ping

@wzssyqa wzssyqa merged commit 3b67383 into llvm:main Jan 20, 2025
10 checks passed
@hpoussin hpoussin deleted the clang-mips-coff-8 branch January 21, 2025 17:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

llvm:mc Machine (object) code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants