[lld] r250297 - [ELF2][mips] Support both big and little endian MIPS 32-bit targets

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 14 07:24:46 PDT 2015


Author: atanasyan
Date: Wed Oct 14 09:24:46 2015
New Revision: 250297

URL: http://llvm.org/viewvc/llvm-project?rev=250297&view=rev
Log:
[ELF2][mips] Support both big and little endian MIPS 32-bit targets

- Make the `MipsTargetInfo` template class with `ELFType` argument. Use
  the argument to select an appropriate relocation type and read/write
  routines.
- Add template function `add32` to add-and-write relocation value in
  both big and little endian cases. Keep the `add32le` to reduce code
  changes.

Differential Revision: http://reviews.llvm.org/D13723

Modified:
    lld/trunk/ELF/Target.cpp
    lld/trunk/ELF/Target.h
    lld/trunk/test/elf2/mips-relocs.s

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=250297&r1=250296&r2=250297&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Wed Oct 14 09:24:46 2015
@@ -39,7 +39,14 @@ TargetInfo *createTarget() {
   case EM_AARCH64:
     return new AArch64TargetInfo();
   case EM_MIPS:
-    return new MipsTargetInfo();
+    switch (Config->EKind) {
+    case ELF32LEKind:
+      return new MipsTargetInfo<ELF32LE>();
+    case ELF32BEKind:
+      return new MipsTargetInfo<ELF32BE>();
+    default:
+      error("Unsupported MIPS target");
+    }
   case EM_PPC:
     return new PPCTargetInfo();
   case EM_PPC64:
@@ -84,8 +91,13 @@ bool X86TargetInfo::relocNeedsPlt(uint32
 }
 
 static void add32le(uint8_t *L, int32_t V) { write32le(L, read32le(L) + V); }
+static void add32be(uint8_t *L, int32_t V) { write32be(L, read32be(L) + V); }
 static void or32le(uint8_t *L, int32_t V) { write32le(L, read32le(L) | V); }
 
+template <bool IsLE> static void add32(uint8_t *L, int32_t V);
+template <> void add32<true>(uint8_t *L, int32_t V) { add32le(L, V); }
+template <> void add32<false>(uint8_t *L, int32_t V) { add32be(L, V); }
+
 void X86TargetInfo::relocateOne(uint8_t *Buf, uint8_t *BufEnd, const void *RelP,
                                 uint32_t Type, uint64_t BaseAddr,
                                 uint64_t SymVA) const {
@@ -542,32 +554,40 @@ void AArch64TargetInfo::relocateOne(uint
   }
 }
 
-MipsTargetInfo::MipsTargetInfo() {
+template <class ELFT> MipsTargetInfo<ELFT>::MipsTargetInfo() {
   // PCRelReloc = FIXME
   // GotReloc = FIXME
   PageSize = 65536;
 }
 
-void MipsTargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
-                                   uint64_t PltEntryAddr) const {}
-
-bool MipsTargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const {
+template <class ELFT>
+void MipsTargetInfo<ELFT>::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
+                                         uint64_t PltEntryAddr) const {}
+
+template <class ELFT>
+bool MipsTargetInfo<ELFT>::relocNeedsGot(uint32_t Type,
+                                         const SymbolBody &S) const {
   return false;
 }
 
-bool MipsTargetInfo::relocNeedsPlt(uint32_t Type, const SymbolBody &S) const {
+template <class ELFT>
+bool MipsTargetInfo<ELFT>::relocNeedsPlt(uint32_t Type,
+                                         const SymbolBody &S) const {
   return false;
 }
 
-void MipsTargetInfo::relocateOne(uint8_t *Buf, uint8_t *BufEnd,
-                                 const void *RelP, uint32_t Type,
-                                 uint64_t BaseAddr, uint64_t SymVA) const {
-  typedef ELFFile<ELF32LE>::Elf_Rel Elf_Rel;
+template <class ELFT>
+void MipsTargetInfo<ELFT>::relocateOne(uint8_t *Buf, uint8_t *BufEnd,
+                                       const void *RelP, uint32_t Type,
+                                       uint64_t BaseAddr,
+                                       uint64_t SymVA) const {
+  const bool IsLE = ELFT::TargetEndianness == support::little;
+  typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel;
   auto &Rel = *reinterpret_cast<const Elf_Rel *>(RelP);
 
   switch (Type) {
   case R_MIPS_32:
-    add32le(Buf + Rel.r_offset, SymVA);
+    add32<IsLE>(Buf + Rel.r_offset, SymVA);
     break;
   default:
     error("unrecognized reloc " + Twine(Type));

Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=250297&r1=250296&r2=250297&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Wed Oct 14 09:24:46 2015
@@ -110,7 +110,7 @@ public:
                    uint64_t SymVA) const override;
 };
 
-class MipsTargetInfo final : public TargetInfo {
+template <class ELFT> class MipsTargetInfo final : public TargetInfo {
 public:
   MipsTargetInfo();
   void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,

Modified: lld/trunk/test/elf2/mips-relocs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/mips-relocs.s?rev=250297&r1=250296&r2=250297&view=diff
==============================================================================
--- lld/trunk/test/elf2/mips-relocs.s (original)
+++ lld/trunk/test/elf2/mips-relocs.s Wed Oct 14 09:24:46 2015
@@ -1,7 +1,14 @@
 # Check R_MIPS_32 relocation calculation.
-# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t.o
-# RUN: ld.lld2 %t.o -o %t.exe
-# RUN: llvm-objdump -s -t %t.exe | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o
+# RUN: ld.lld2 %t-be.o -o %t-be.exe
+# RUN: llvm-objdump -t %t-be.exe | FileCheck %s
+# RUN: llvm-objdump -s %t-be.exe | FileCheck -check-prefix=BE %s
+
+# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o
+# RUN: ld.lld2 %t-el.o -o %t-el.exe
+# RUN: llvm-objdump -t %t-el.exe | FileCheck %s
+# RUN: llvm-objdump -s %t-el.exe | FileCheck -check-prefix=EL %s
 
 # REQUIRES: mips
 
@@ -22,10 +29,14 @@ v2:
   .word v2+4 # R_MIPS_32 target v2 addend 4
   .word v1   # R_MIPS_32 target v1 addend 0
 
-# CHECK: Contents of section .data:
-# CHECK-NEXT: 30000 00000000 08000300 00000300
-#                            ^-- v2+4 ^-- v1
-
 # CHECK: SYMBOL TABLE:
 # CHECK: 00030000 l       .data           00000004 v1
 # CHECK: 00030004 g       .data           00000008 v2
+
+# BE: Contents of section .data:
+# BE-NEXT: 30000 00000000 00030008 00030000
+#                         ^-- v2+4 ^-- v1
+
+# EL: Contents of section .data:
+# EL-NEXT: 30000 00000000 08000300 00000300
+#                         ^-- v2+4 ^-- v1




More information about the llvm-commits mailing list