Index: lld/trunk/ELF/Target.h =================================================================== --- lld/trunk/ELF/Target.h +++ lld/trunk/ELF/Target.h @@ -110,7 +110,7 @@ uint64_t SymVA) const override; }; -class MipsTargetInfo final : public TargetInfo { +template class MipsTargetInfo final : public TargetInfo { public: MipsTargetInfo(); void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, Index: lld/trunk/ELF/Target.cpp =================================================================== --- lld/trunk/ELF/Target.cpp +++ lld/trunk/ELF/Target.cpp @@ -39,7 +39,14 @@ case EM_AARCH64: return new AArch64TargetInfo(); case EM_MIPS: - return new MipsTargetInfo(); + switch (Config->EKind) { + case ELF32LEKind: + return new MipsTargetInfo(); + case ELF32BEKind: + return new MipsTargetInfo(); + default: + error("Unsupported MIPS target"); + } case EM_PPC: return new PPCTargetInfo(); case EM_PPC64: @@ -84,8 +91,13 @@ } 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 static void add32(uint8_t *L, int32_t V); +template <> void add32(uint8_t *L, int32_t V) { add32le(L, V); } +template <> void add32(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 @@ } } -MipsTargetInfo::MipsTargetInfo() { +template MipsTargetInfo::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 +void MipsTargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const {} + +template +bool MipsTargetInfo::relocNeedsGot(uint32_t Type, + const SymbolBody &S) const { return false; } -bool MipsTargetInfo::relocNeedsPlt(uint32_t Type, const SymbolBody &S) const { +template +bool MipsTargetInfo::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::Elf_Rel Elf_Rel; +template +void MipsTargetInfo::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::Elf_Rel Elf_Rel; auto &Rel = *reinterpret_cast(RelP); switch (Type) { case R_MIPS_32: - add32le(Buf + Rel.r_offset, SymVA); + add32(Buf + Rel.r_offset, SymVA); break; default: error("unrecognized reloc " + Twine(Type)); Index: lld/trunk/test/elf2/mips-relocs.s =================================================================== --- lld/trunk/test/elf2/mips-relocs.s +++ lld/trunk/test/elf2/mips-relocs.s @@ -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 @@ .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