[llvm] [MC][Mips] Generate required IMAGE_REL_MIPS_PAIR relocation (PR #120876)

via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 22 00:07:53 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mc

Author: Hervé Poussineau (hpoussin)

<details>
<summary>Changes</summary>

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

``````````

</details>


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


More information about the llvm-commits mailing list