[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