diff options
| author | Simon Atanasyan <simon@atanasyan.com> | 2015-07-13 09:11:35 +0000 |
|---|---|---|
| committer | Simon Atanasyan <simon@atanasyan.com> | 2015-07-13 09:11:35 +0000 |
| commit | b34a080701942dc6e9ab3dac7e9eb220022bad46 (patch) | |
| tree | c212d81aff47096b24d8fb535e13a565fecf2241 /lld/lib/ReaderWriter/ELF | |
| parent | f8f780ccc5ad5f26e6473ffbbca71b4d7f98d255 (diff) | |
| download | bcm5719-llvm-b34a080701942dc6e9ab3dac7e9eb220022bad46.tar.gz bcm5719-llvm-b34a080701942dc6e9ab3dac7e9eb220022bad46.zip | |
[Mips] Support MIPS big-endian 32/64-bits targets
llvm-svn: 242014
Diffstat (limited to 'lld/lib/ReaderWriter/ELF')
11 files changed, 278 insertions, 60 deletions
diff --git a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp index 361bd509fa8..70ed30a12ed 100644 --- a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp +++ b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp @@ -52,7 +52,9 @@ uint16_t ELFLinkingContext::getOutputMachine() const { return llvm::ELF::EM_X86_64; case llvm::Triple::hexagon: return llvm::ELF::EM_HEXAGON; + case llvm::Triple::mips: case llvm::Triple::mipsel: + case llvm::Triple::mips64: case llvm::Triple::mips64el: return llvm::ELF::EM_MIPS; case llvm::Triple::aarch64: diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp index fac238ac952..2c2f528f8a0 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp @@ -643,7 +643,9 @@ MipsAbiInfoHandler<ELFT>::createAbiFromSection(const Elf_Mips_ABIFlags &sec) { return abi; } +template class MipsAbiInfoHandler<ELF32BE>; template class MipsAbiInfoHandler<ELF32LE>; +template class MipsAbiInfoHandler<ELF64BE>; template class MipsAbiInfoHandler<ELF64LE>; } diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp index 51d366479d8..398d302d29b 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp @@ -50,7 +50,9 @@ template <class ELFT> bool MipsELFDefinedAtom<ELFT>::isPIC() const { codeModel() == DefinedAtom::codeMipsPIC; } +template class MipsELFDefinedAtom<ELF32BE>; template class MipsELFDefinedAtom<ELF32LE>; +template class MipsELFDefinedAtom<ELF64BE>; template class MipsELFDefinedAtom<ELF64LE>; template <class ELFT> static bool isMips64EL() { @@ -78,7 +80,9 @@ MipsELFReference<ELFT>::MipsELFReference(uint64_t symValue, const Elf_Rel &rel) rel.getSymbol(isMips64EL<ELFT>())), _tag(extractTag(rel)) {} +template class MipsELFReference<ELF32BE>; template class MipsELFReference<ELF32LE>; +template class MipsELFReference<ELF64BE>; template class MipsELFReference<ELF64LE>; template <class ELFT> @@ -270,7 +274,8 @@ template <class ELFT> Reference::Addend MipsELFFile<ELFT>::readAddend(const Elf_Rel &ri, const ArrayRef<uint8_t> content) const { - return readMipsRelocAddend(getPrimaryType(ri), content.data() + ri.r_offset); + return readMipsRelocAddend<ELFT>(getPrimaryType(ri), + content.data() + ri.r_offset); } template <class ELFT> @@ -315,7 +320,9 @@ bool MipsELFFile<ELFT>::isLocalBinding(const Elf_Rel &rel) const { ->getBinding() == llvm::ELF::STB_LOCAL; } +template class MipsELFFile<ELF32BE>; template class MipsELFFile<ELF32LE>; +template class MipsELFFile<ELF64BE>; template class MipsELFFile<ELF64LE>; } // elf diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp index 9d17e4f2d06..1abb763e3a0 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp @@ -159,7 +159,9 @@ MipsDynamicLibraryWriter<ELFT>::createDynamicSymbolTable() { this->_alloc) MipsDynamicSymbolTable<ELFT>(this->_ctx, _targetLayout)); } +template class MipsDynamicLibraryWriter<ELF32BE>; template class MipsDynamicLibraryWriter<ELF32LE>; +template class MipsDynamicLibraryWriter<ELF64BE>; template class MipsDynamicLibraryWriter<ELF64LE>; template <class ELFT> @@ -275,7 +277,9 @@ MipsExecutableWriter<ELFT>::createDynamicSymbolTable() { this->_alloc) MipsDynamicSymbolTable<ELFT>(this->_ctx, _targetLayout)); } +template class MipsExecutableWriter<ELF32BE>; template class MipsExecutableWriter<ELF32LE>; +template class MipsExecutableWriter<ELF64BE>; template class MipsExecutableWriter<ELF64LE>; } // elf diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp index 0124b7b737c..b905fa5f3ab 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp @@ -18,7 +18,9 @@ using namespace lld::elf; std::unique_ptr<ELFLinkingContext> elf::createMipsLinkingContext(llvm::Triple triple) { - if (triple.getArch() == llvm::Triple::mipsel || + if (triple.getArch() == llvm::Triple::mips || + triple.getArch() == llvm::Triple::mipsel || + triple.getArch() == llvm::Triple::mips64 || triple.getArch() == llvm::Triple::mips64el) return llvm::make_unique<MipsLinkingContext>(triple); return nullptr; @@ -27,8 +29,12 @@ elf::createMipsLinkingContext(llvm::Triple triple) { static std::unique_ptr<TargetHandler> createTarget(llvm::Triple triple, MipsLinkingContext &ctx) { switch (triple.getArch()) { + case llvm::Triple::mips: + return llvm::make_unique<MipsTargetHandler<ELF32BE>>(ctx); case llvm::Triple::mipsel: return llvm::make_unique<MipsTargetHandler<ELF32LE>>(ctx); + case llvm::Triple::mips64: + return llvm::make_unique<MipsTargetHandler<ELF64BE>>(ctx); case llvm::Triple::mips64el: return llvm::make_unique<MipsTargetHandler<ELF64LE>>(ctx); default: diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp index 49e6ea00cd1..3e9619f9f19 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp @@ -356,11 +356,6 @@ static CrossJumpMode getCrossJumpMode(const Reference &ref) { } } -static uint64_t microShuffle(uint64_t ins) { - return (ins & 0xffffffff00000000ull) | ((ins & 0xffff) << 16) | - ((ins & 0xffff0000) >> 16); -} - static ErrorOr<int64_t> calculateRelocation(Reference::KindValue kind, Reference::Addend addend, uint64_t tgtAddr, uint64_t relAddr, @@ -502,29 +497,32 @@ static ErrorOr<int64_t> calculateRelocation(Reference::KindValue kind, } } +template <class ELFT> static uint64_t relocRead(const MipsRelocationParams ¶ms, const uint8_t *loc) { + assert((params._size == 4 || params._size == 8) && "Unexpected size"); uint64_t data; + memcpy(&data, loc, params._size); + if (params._shuffle) { + using namespace endian; + auto p = reinterpret_cast<const uint8_t *>(&data); + uint32_t a = readNext<uint16_t, ELFT::TargetEndianness, unaligned>(p); + uint32_t b = read<uint16_t, ELFT::TargetEndianness, unaligned>(p); + write<uint32_t, ELFT::TargetEndianness, unaligned>(&data, a << 16 | b); + } switch (params._size) { case 4: - data = endian::read32le(loc); - break; + return endian::read<uint32_t, ELFT::TargetEndianness, unaligned>(&data); case 8: - data = endian::read64le(loc); - break; + return endian::read<uint64_t, ELFT::TargetEndianness, unaligned>(&data); default: llvm_unreachable("Unexpected size"); } - if (params._shuffle) - data = microShuffle(data); - return data; } template <class ELFT> static void relocWrite(uint64_t data, const MipsRelocationParams ¶ms, uint8_t *loc) { - if (params._shuffle) - data = microShuffle(data); switch (params._size) { case 4: endian::write<uint32_t, ELFT::TargetEndianness, unaligned>(loc, data); @@ -535,6 +533,13 @@ static void relocWrite(uint64_t data, const MipsRelocationParams ¶ms, default: llvm_unreachable("Unexpected size"); } + if (params._shuffle) { + uint32_t v = endian::read<uint32_t, ELFT::TargetEndianness, unaligned>(loc); + uint16_t a = v >> 16; + uint16_t b = v & 0xffff; + endian::write<uint16_t, ELFT::TargetEndianness, unaligned>(loc, a); + endian::write<uint16_t, ELFT::TargetEndianness, unaligned>(loc + 2, b); + } } static uint32_t getRelKind(const Reference &ref, size_t num) { @@ -604,7 +609,7 @@ std::error_code RelocationHandler<ELFT>::applyRelocation( } auto params = getRelocationParams(lastRel); - uint64_t ins = relocRead(params, location); + uint64_t ins = relocRead<ELFT>(params, location); if (auto ec = adjustJumpOpCode(ins, tgtAddr, jumpMode)) return ec; @@ -619,6 +624,13 @@ namespace elf { template <> std::unique_ptr<TargetRelocationHandler> +createMipsRelocationHandler<ELF32BE>(MipsLinkingContext &ctx, + MipsTargetLayout<ELF32BE> &layout) { + return llvm::make_unique<RelocationHandler<ELF32BE>>(ctx, layout); +} + +template <> +std::unique_ptr<TargetRelocationHandler> createMipsRelocationHandler<ELF32LE>(MipsLinkingContext &ctx, MipsTargetLayout<ELF32LE> &layout) { return llvm::make_unique<RelocationHandler<ELF32LE>>(ctx, layout); @@ -626,15 +638,23 @@ createMipsRelocationHandler<ELF32LE>(MipsLinkingContext &ctx, template <> std::unique_ptr<TargetRelocationHandler> +createMipsRelocationHandler<ELF64BE>(MipsLinkingContext &ctx, + MipsTargetLayout<ELF64BE> &layout) { + return llvm::make_unique<RelocationHandler<ELF64BE>>(ctx, layout); +} + +template <> +std::unique_ptr<TargetRelocationHandler> createMipsRelocationHandler<ELF64LE>(MipsLinkingContext &ctx, MipsTargetLayout<ELF64LE> &layout) { return llvm::make_unique<RelocationHandler<ELF64LE>>(ctx, layout); } +template <class ELFT> Reference::Addend readMipsRelocAddend(Reference::KindValue kind, const uint8_t *content) { auto params = getRelocationParams(kind); - uint64_t ins = relocRead(params, content); + uint64_t ins = relocRead<ELFT>(params, content); int64_t res = (ins & params._mask) << params._shift; switch (kind) { case R_MIPS_GPREL16: @@ -660,5 +680,18 @@ Reference::Addend readMipsRelocAddend(Reference::KindValue kind, return res; } +template +Reference::Addend readMipsRelocAddend<ELF32BE>(Reference::KindValue kind, + const uint8_t *content); +template +Reference::Addend readMipsRelocAddend<ELF32LE>(Reference::KindValue kind, + const uint8_t *content); +template +Reference::Addend readMipsRelocAddend<ELF64BE>(Reference::KindValue kind, + const uint8_t *content); +template +Reference::Addend readMipsRelocAddend<ELF64LE>(Reference::KindValue kind, + const uint8_t *content); + } // elf } // lld diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h index d136be837f9..62a7aee3449 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h @@ -22,6 +22,7 @@ std::unique_ptr<TargetRelocationHandler> createMipsRelocationHandler(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout); +template <class ELFT> Reference::Addend readMipsRelocAddend(Reference::KindValue kind, const uint8_t *content); } // elf diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp index 38e31af2183..d9be544b681 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp @@ -37,8 +37,20 @@ static const uint8_t mipsGotTlsGdAtomContent[] = { 0x00, 0x00, 0x00, 0x00 }; -// Regular PLT0 entry -static const uint8_t mipsPlt0AtomContent[] = { +// Regular big-endian PLT0 entry +static const uint8_t mipsBePlt0AtomContent[] = { + 0x3c, 0x1c, 0x00, 0x00, // lui $28, %hi(&GOTPLT[0]) + 0x8f, 0x99, 0x00, 0x00, // lw $25, %lo(&GOTPLT[0])($28) + 0x27, 0x9c, 0x00, 0x00, // addiu $28, $28, %lo(&GOTPLT[0]) + 0x03, 0x1c, 0xc0, 0x23, // subu $24, $24, $28 + 0x03, 0xe0, 0x78, 0x21, // move $15, $31 + 0x00, 0x18, 0xc0, 0x82, // srl $24, $24, 2 + 0x03, 0x20, 0xf8, 0x09, // jalr $25 + 0x27, 0x18, 0xff, 0xfe // subu $24, $24, 2 +}; + +// Regular little-endian PLT0 entry +static const uint8_t mipsLePlt0AtomContent[] = { 0x00, 0x00, 0x1c, 0x3c, // lui $28, %hi(&GOTPLT[0]) 0x00, 0x00, 0x99, 0x8f, // lw $25, %lo(&GOTPLT[0])($28) 0x00, 0x00, 0x9c, 0x27, // addiu $28, $28, %lo(&GOTPLT[0]) @@ -49,8 +61,21 @@ static const uint8_t mipsPlt0AtomContent[] = { 0xfe, 0xff, 0x18, 0x27 // subu $24, $24, 2 }; -// microMIPS PLT0 entry -static const uint8_t micromipsPlt0AtomContent[] = { +// microMIPS big-endian PLT0 entry +static const uint8_t microMipsBePlt0AtomContent[] = { + 0x79, 0x80, 0x00, 0x00, // addiupc $3, (&GOTPLT[0]) - . + 0xff, 0x23, 0x00, 0x00, // lw $25, 0($3) + 0x05, 0x35, // subu $2, $2, $3 + 0x25, 0x25, // srl $2, $2, 2 + 0x33, 0x02, 0xff, 0xfe, // subu $24, $2, 2 + 0x0d, 0xff, // move $15, $31 + 0x45, 0xf9, // jalrs $25 + 0x0f, 0x83, // move $28, $3 + 0x0c, 0x00 // nop +}; + +// microMIPS little-endian PLT0 entry +static const uint8_t microMipsLePlt0AtomContent[] = { 0x80, 0x79, 0x00, 0x00, // addiupc $3, (&GOTPLT[0]) - . 0x23, 0xff, 0x00, 0x00, // lw $25, 0($3) 0x35, 0x05, // subu $2, $2, $3 @@ -62,40 +87,80 @@ static const uint8_t micromipsPlt0AtomContent[] = { 0x00, 0x0c // nop }; -// Regular PLT entry -static const uint8_t mipsPltAAtomContent[] = { +// Regular big-endian PLT entry +static const uint8_t mipsBePltAAtomContent[] = { + 0x3c, 0x0f, 0x00, 0x00, // lui $15, %hi(.got.plt entry) + 0x8d, 0xf9, 0x00, 0x00, // l[wd] $25, %lo(.got.plt entry)($15) + 0x03, 0x20, 0x00, 0x08, // jr $25 + 0x25, 0xf8, 0x00, 0x00 // addiu $24, $15, %lo(.got.plt entry) +}; + +// Regular little-endian PLT entry +static const uint8_t mipsLePltAAtomContent[] = { 0x00, 0x00, 0x0f, 0x3c, // lui $15, %hi(.got.plt entry) 0x00, 0x00, 0xf9, 0x8d, // l[wd] $25, %lo(.got.plt entry)($15) 0x08, 0x00, 0x20, 0x03, // jr $25 0x00, 0x00, 0xf8, 0x25 // addiu $24, $15, %lo(.got.plt entry) }; -// microMIPS PLT entry -static const uint8_t micromipsPltAtomContent[] = { +// microMIPS big-endian PLT entry +static const uint8_t microMipsBePltAAtomContent[] = { + 0x79, 0x00, 0x00, 0x00, // addiupc $2, (.got.plt entry) - . + 0xff, 0x22, 0x00, 0x00, // lw $25, 0($2) + 0x45, 0x99, // jr $25 + 0x0f, 0x02 // move $24, $2 +}; + +// microMIPS little-endian PLT entry +static const uint8_t microMipsLePltAAtomContent[] = { 0x00, 0x79, 0x00, 0x00, // addiupc $2, (.got.plt entry) - . 0x22, 0xff, 0x00, 0x00, // lw $25, 0($2) 0x99, 0x45, // jr $25 0x02, 0x0f // move $24, $2 }; -// R6 PLT entry -static const uint8_t mipsR6PltAAtomContent[] = { +// R6 big-endian PLT entry +static const uint8_t mipsR6BePltAAtomContent[] = { + 0x3c, 0x0f, 0x00, 0x00, // lui $15, %hi(.got.plt entry) + 0x8d, 0xf9, 0x00, 0x00, // l[wd] $25, %lo(.got.plt entry)($15) + 0x03, 0x20, 0x00, 0x09, // jr $25 + 0x25, 0xf8, 0x00, 0x00 // addiu $24, $15, %lo(.got.plt entry) +}; + +// R6 little-endian PLT entry +static const uint8_t mipsR6LePltAAtomContent[] = { 0x00, 0x00, 0x0f, 0x3c, // lui $15, %hi(.got.plt entry) 0x00, 0x00, 0xf9, 0x8d, // l[wd] $25, %lo(.got.plt entry)($15) 0x09, 0x00, 0x20, 0x03, // jr $25 0x00, 0x00, 0xf8, 0x25 // addiu $24, $15, %lo(.got.plt entry) }; -// LA25 stub entry -static const uint8_t mipsLA25AtomContent[] = { +// LA25 big-endian stub entry +static const uint8_t mipsBeLA25AtomContent[] = { + 0x3c, 0x19, 0x00, 0x00, // lui $25, %hi(func) + 0x08, 0x00, 0x00, 0x00, // j func + 0x27, 0x39, 0x00, 0x00, // addiu $25, $25, %lo(func) + 0x00, 0x00, 0x00, 0x00 // nop +}; + +// LA25 little-endian stub entry +static const uint8_t mipsLeLA25AtomContent[] = { 0x00, 0x00, 0x19, 0x3c, // lui $25, %hi(func) 0x00, 0x00, 0x00, 0x08, // j func 0x00, 0x00, 0x39, 0x27, // addiu $25, $25, %lo(func) 0x00, 0x00, 0x00, 0x00 // nop }; -// microMIPS LA25 stub entry -static const uint8_t micromipsLA25AtomContent[] = { +// microMIPS LA25 big-endian stub entry +static const uint8_t microMipsBeLA25AtomContent[] = { + 0x41, 0xbe, 0x00, 0x00, // lui $25, %hi(func) + 0xd4, 0x00, 0x00, 0x00, // j func + 0x33, 0x39, 0x00, 0x00, // addiu $25, $25, %lo(func) + 0x00, 0x00, 0x00, 0x00 // nop +}; + +// microMIPS LA25 little-endian stub entry +static const uint8_t microMipsLeLA25AtomContent[] = { 0xb9, 0x41, 0x00, 0x00, // lui $25, %hi(func) 0x00, 0xd4, 0x00, 0x00, // j func 0x39, 0x33, 0x00, 0x00, // addiu $25, $25, %lo(func) @@ -120,9 +185,15 @@ public: ArrayRef<uint8_t> rawContent() const override; }; +template <> ArrayRef<uint8_t> GOT0Atom<ELF32BE>::rawContent() const { + return llvm::makeArrayRef(mipsGot0AtomContent).slice(4); +} template <> ArrayRef<uint8_t> GOT0Atom<ELF32LE>::rawContent() const { return llvm::makeArrayRef(mipsGot0AtomContent).slice(4); } +template <> ArrayRef<uint8_t> GOT0Atom<ELF64BE>::rawContent() const { + return llvm::makeArrayRef(mipsGot0AtomContent); +} template <> ArrayRef<uint8_t> GOT0Atom<ELF64LE>::rawContent() const { return llvm::makeArrayRef(mipsGot0AtomContent); } @@ -136,10 +207,18 @@ public: }; template <> +ArrayRef<uint8_t> GOTModulePointerAtom<ELF32BE>::rawContent() const { + return llvm::makeArrayRef(mipsGotModulePointerAtomContent).slice(4); +} +template <> ArrayRef<uint8_t> GOTModulePointerAtom<ELF32LE>::rawContent() const { return llvm::makeArrayRef(mipsGotModulePointerAtomContent).slice(4); } template <> +ArrayRef<uint8_t> GOTModulePointerAtom<ELF64BE>::rawContent() const { + return llvm::makeArrayRef(mipsGotModulePointerAtomContent); +} +template <> ArrayRef<uint8_t> GOTModulePointerAtom<ELF64LE>::rawContent() const { return llvm::makeArrayRef(mipsGotModulePointerAtomContent); } @@ -152,12 +231,17 @@ public: ArrayRef<uint8_t> rawContent() const override; }; +template <> ArrayRef<uint8_t> GOTTLSGdAtom<ELF32BE>::rawContent() const { + return llvm::makeArrayRef(mipsGotTlsGdAtomContent).slice(8); +} template <> ArrayRef<uint8_t> GOTTLSGdAtom<ELF32LE>::rawContent() const { - return llvm::makeArrayRef(mipsGotTlsGdAtomContent).slice(8); + return llvm::makeArrayRef(mipsGotTlsGdAtomContent).slice(8); +} +template <> ArrayRef<uint8_t> GOTTLSGdAtom<ELF64BE>::rawContent() const { + return llvm::makeArrayRef(mipsGotTlsGdAtomContent); } - template <> ArrayRef<uint8_t> GOTTLSGdAtom<ELF64LE>::rawContent() const { - return llvm::makeArrayRef(mipsGotTlsGdAtomContent); + return llvm::makeArrayRef(mipsGotTlsGdAtomContent); } class GOTPLTAtom : public GOTAtom { @@ -180,7 +264,7 @@ public: } }; -class PLT0Atom : public PLTAtom { +template <class ELFT> class PLT0Atom : public PLTAtom { public: PLT0Atom(const Atom *got, const File &f) : PLTAtom(f, ".plt") { // Setup reference to fixup the PLT0 entry. @@ -190,11 +274,18 @@ public: } ArrayRef<uint8_t> rawContent() const override { - return llvm::makeArrayRef(mipsPlt0AtomContent); + llvm_unreachable("PLT0 is not applicable for this target"); } }; -class PLT0MicroAtom : public PLTAtom { +template <> ArrayRef<uint8_t> PLT0Atom<ELF32BE>::rawContent() const { + return llvm::makeArrayRef(mipsBePlt0AtomContent); +} +template <> ArrayRef<uint8_t> PLT0Atom<ELF32LE>::rawContent() const { + return llvm::makeArrayRef(mipsLePlt0AtomContent); +} + +template <class ELFT> class PLT0MicroAtom : public PLTAtom { public: PLT0MicroAtom(const Atom *got, const File &f) : PLTAtom(f, ".plt") { // Setup reference to fixup the PLT0 entry. @@ -204,10 +295,17 @@ public: CodeModel codeModel() const override { return codeMipsMicro; } ArrayRef<uint8_t> rawContent() const override { - return llvm::makeArrayRef(micromipsPlt0AtomContent); + llvm_unreachable("PLT0 is not applicable for this target"); } }; +template <> ArrayRef<uint8_t> PLT0MicroAtom<ELF32BE>::rawContent() const { + return llvm::makeArrayRef(microMipsBePlt0AtomContent); +} +template <> ArrayRef<uint8_t> PLT0MicroAtom<ELF32LE>::rawContent() const { + return llvm::makeArrayRef(microMipsLePlt0AtomContent); +} + class PLTAAtom : public PLTAtom { public: PLTAAtom(const GOTPLTAtom *got, const File &f) : PLTAtom(f, ".plt") { @@ -216,22 +314,41 @@ public: addReferenceELF_Mips(R_MIPS_LO16, 4, got, 0); addReferenceELF_Mips(R_MIPS_LO16, 12, got, 0); } +}; + +template <class ELFT> class PLTARegAtom : public PLTAAtom { +public: + PLTARegAtom(const GOTPLTAtom *got, const File &f) : PLTAAtom(got, f) {} ArrayRef<uint8_t> rawContent() const override { - return llvm::makeArrayRef(mipsPltAAtomContent); + llvm_unreachable("PLT is not applicable for this target"); } }; -class PLTR6Atom : public PLTAAtom { +template <> ArrayRef<uint8_t> PLTARegAtom<ELF32BE>::rawContent() const { + return llvm::makeArrayRef(mipsBePltAAtomContent); +} +template <> ArrayRef<uint8_t> PLTARegAtom<ELF32LE>::rawContent() const { + return llvm::makeArrayRef(mipsLePltAAtomContent); +} + +template <class ELFT> class PLTR6Atom : public PLTAAtom { public: PLTR6Atom(const GOTPLTAtom *got, const File &f) : PLTAAtom(got, f) {} ArrayRef<uint8_t> rawContent() const override { - return llvm::makeArrayRef(mipsR6PltAAtomContent); + llvm_unreachable("PLT is not applicable for this target"); } }; -class PLTMicroAtom : public PLTAtom { +template <> ArrayRef<uint8_t> PLTR6Atom<ELF32BE>::rawContent() const { + return llvm::makeArrayRef(mipsR6BePltAAtomContent); +} +template <> ArrayRef<uint8_t> PLTR6Atom<ELF32LE>::rawContent() const { + return llvm::makeArrayRef(mipsR6LePltAAtomContent); +} + +template <class ELFT> class PLTMicroAtom : public PLTAtom { public: PLTMicroAtom(const GOTPLTAtom *got, const File &f) : PLTAtom(f, ".plt") { // Setup reference to fixup the microMIPS PLT entry. @@ -242,16 +359,23 @@ public: CodeModel codeModel() const override { return codeMipsMicro; } ArrayRef<uint8_t> rawContent() const override { - return llvm::makeArrayRef(micromipsPltAtomContent); + llvm_unreachable("PLT is not applicable for this target"); } }; +template <> ArrayRef<uint8_t> PLTMicroAtom<ELF32BE>::rawContent() const { + return llvm::makeArrayRef(microMipsBePltAAtomContent); +} +template <> ArrayRef<uint8_t> PLTMicroAtom<ELF32LE>::rawContent() const { + return llvm::makeArrayRef(microMipsLePltAAtomContent); +} + class LA25Atom : public PLTAtom { public: LA25Atom(const File &f) : PLTAtom(f, ".text") {} }; -class LA25RegAtom : public LA25Atom { +template <typename ELFT> class LA25RegAtom : public LA25Atom { public: LA25RegAtom(const Atom *a, const File &f) : LA25Atom(f) { // Setup reference to fixup the LA25 stub entry. @@ -261,11 +385,18 @@ public: } ArrayRef<uint8_t> rawContent() const override { - return llvm::makeArrayRef(mipsLA25AtomContent); + llvm_unreachable("LA25 stubs are not applicable for this target"); } }; -class LA25MicroAtom : public LA25Atom { +template <> ArrayRef<uint8_t> LA25RegAtom<ELF32BE>::rawContent() const { + return llvm::makeArrayRef(mipsBeLA25AtomContent); +} +template <> ArrayRef<uint8_t> LA25RegAtom<ELF32LE>::rawContent() const { + return llvm::makeArrayRef(mipsLeLA25AtomContent); +} + +template <typename ELFT> class LA25MicroAtom : public LA25Atom { public: LA25MicroAtom(const Atom *a, const File &f) : LA25Atom(f) { // Setup reference to fixup the microMIPS LA25 stub entry. @@ -277,10 +408,17 @@ public: CodeModel codeModel() const override { return codeMipsMicro; } ArrayRef<uint8_t> rawContent() const override { - return llvm::makeArrayRef(micromipsLA25AtomContent); + llvm_unreachable("LA25 stubs are not applicable for this target"); } }; +template <> ArrayRef<uint8_t> LA25MicroAtom<ELF32BE>::rawContent() const { + return llvm::makeArrayRef(microMipsBeLA25AtomContent); +} +template <> ArrayRef<uint8_t> LA25MicroAtom<ELF32LE>::rawContent() const { + return llvm::makeArrayRef(microMipsLeLA25AtomContent); +} + class MipsGlobalOffsetTableAtom : public GlobalOffsetTableAtom { public: MipsGlobalOffsetTableAtom(const File &f) : GlobalOffsetTableAtom(f) {} @@ -342,14 +480,14 @@ private: /// \brief Map Atoms to their PLT entries. llvm::DenseMap<const Atom *, PLTAAtom *> _pltRegMap; - llvm::DenseMap<const Atom *, PLTMicroAtom *> _pltMicroMap; + llvm::DenseMap<const Atom *, PLTMicroAtom<ELFT> *> _pltMicroMap; /// \brief Map Atoms to their Object entries. llvm::DenseMap<const Atom *, ObjectAtom *> _objectMap; /// \brief Map Atoms to their LA25 entries. - llvm::DenseMap<const Atom *, LA25RegAtom *> _la25RegMap; - llvm::DenseMap<const Atom *, LA25MicroAtom *> _la25MicroMap; + llvm::DenseMap<const Atom *, LA25Atom *> _la25RegMap; + llvm::DenseMap<const Atom *, LA25Atom *> _la25MicroMap; /// \brief Atoms referenced by static relocations. llvm::DenseSet<const Atom *> _hasStaticRelocations; @@ -1085,9 +1223,8 @@ PLTAtom *RelocationPass<ELFT>::createPLTHeader(bool isMicroMips) { _gotpltVector.insert(_gotpltVector.begin(), ga0); if (isMicroMips) - return new (_file._alloc) PLT0MicroAtom(ga0, _file); - else - return new (_file._alloc) PLT0Atom(ga0, _file); + return new (_file._alloc) PLT0MicroAtom<ELFT>(ga0, _file); + return new (_file._alloc) PLT0Atom<ELFT>(ga0, _file); } template <typename ELFT> @@ -1108,9 +1245,11 @@ const PLTAtom *RelocationPass<ELFT>::getPLTRegEntry(const Atom *a) { if (plt != _pltRegMap.end()) return plt->second; - PLTAAtom *pa = isMipsR6() - ? new (_file._alloc) PLTR6Atom(getGOTPLTEntry(a), _file) - : new (_file._alloc) PLTAAtom(getGOTPLTEntry(a), _file); + PLTAAtom *pa = nullptr; + if (isMipsR6()) + pa = new (_file._alloc) PLTR6Atom<ELFT>(getGOTPLTEntry(a), _file); + else + pa = new (_file._alloc) PLTARegAtom<ELFT>(getGOTPLTEntry(a), _file); _pltRegMap[a] = pa; _pltRegVector.push_back(pa); @@ -1127,7 +1266,7 @@ const PLTAtom *RelocationPass<ELFT>::getPLTMicroEntry(const Atom *a) { if (plt != _pltMicroMap.end()) return plt->second; - auto pa = new (_file._alloc) PLTMicroAtom(getGOTPLTEntry(a), _file); + auto pa = new (_file._alloc) PLTMicroAtom<ELFT>(getGOTPLTEntry(a), _file); _pltMicroMap[a] = pa; _pltMicroVector.push_back(pa); @@ -1144,7 +1283,7 @@ const LA25Atom *RelocationPass<ELFT>::getLA25RegEntry(const Atom *a) { if (la25 != _la25RegMap.end()) return la25->second; - auto sa = new (_file._alloc) LA25RegAtom(a, _file); + auto sa = new (_file._alloc) LA25RegAtom<ELFT>(a, _file); _la25RegMap[a] = sa; _la25Vector.push_back(sa); @@ -1157,7 +1296,7 @@ const LA25Atom *RelocationPass<ELFT>::getLA25MicroEntry(const Atom *a) { if (la25 != _la25MicroMap.end()) return la25->second; - auto sa = new (_file._alloc) LA25MicroAtom(a, _file); + auto sa = new (_file._alloc) LA25MicroAtom<ELFT>(a, _file); _la25MicroMap[a] = sa; _la25Vector.push_back(sa); @@ -1186,8 +1325,12 @@ RelocationPass<ELFT>::getObjectEntry(const SharedLibraryAtom *a) { static std::unique_ptr<Pass> createPass(MipsLinkingContext &ctx) { switch (ctx.getTriple().getArch()) { + case llvm::Triple::mips: + return llvm::make_unique<RelocationPass<ELF32BE>>(ctx); case llvm::Triple::mipsel: return llvm::make_unique<RelocationPass<ELF32LE>>(ctx); + case llvm::Triple::mips64: + return llvm::make_unique<RelocationPass<ELF64BE>>(ctx); case llvm::Triple::mips64el: return llvm::make_unique<RelocationPass<ELF64LE>>(ctx); default: diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp index d6318cbee04..98cc059787e 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp @@ -44,7 +44,9 @@ template <class ELFT> void MipsReginfoSection<ELFT>::finalize() { this->_outputSection->setType(this->_type); } +template class MipsReginfoSection<ELF32BE>; template class MipsReginfoSection<ELF32LE>; +template class MipsReginfoSection<ELF64BE>; template class MipsReginfoSection<ELF64LE>; template <class ELFT> @@ -85,7 +87,9 @@ template <class ELFT> void MipsOptionsSection<ELFT>::finalize() { this->_outputSection->setType(this->_type); } +template class MipsOptionsSection<ELF32BE>; template class MipsOptionsSection<ELF32LE>; +template class MipsOptionsSection<ELF64BE>; template class MipsOptionsSection<ELF64LE>; template <class ELFT> @@ -116,7 +120,9 @@ template <class ELFT> void MipsAbiFlagsSection<ELFT>::finalize() { this->_outputSection->setType(this->_type); } +template class MipsAbiFlagsSection<ELF32BE>; template class MipsAbiFlagsSection<ELF32LE>; +template class MipsAbiFlagsSection<ELF64BE>; template class MipsAbiFlagsSection<ELF64LE>; template <class ELFT> @@ -175,7 +181,9 @@ const AtomLayout *MipsGOTSection<ELFT>::appendAtom(const Atom *atom) { return AtomSection<ELFT>::appendAtom(atom); } +template class MipsGOTSection<ELF32BE>; template class MipsGOTSection<ELF32LE>; +template class MipsGOTSection<ELF64BE>; template class MipsGOTSection<ELF64LE>; template <class ELFT> @@ -208,7 +216,9 @@ const AtomLayout *MipsPLTSection<ELFT>::appendAtom(const Atom *atom) { return layout; } +template class MipsPLTSection<ELF32BE>; template class MipsPLTSection<ELF32LE>; +template class MipsPLTSection<ELF64BE>; template class MipsPLTSection<ELF64LE>; template <class ELFT> static bool isMips64EL() { @@ -245,7 +255,9 @@ void MipsRelocationTable<ELFT>::writeRel(ELFWriter *writer, Elf_Rel &r, r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom(); } +template class MipsRelocationTable<ELF32BE>; template class MipsRelocationTable<ELF32LE>; +template class MipsRelocationTable<ELF64BE>; template class MipsRelocationTable<ELF64LE>; } // elf diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp index 2afc2c1fdcf..d78fc466b4d 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp @@ -53,7 +53,9 @@ std::unique_ptr<Writer> MipsTargetHandler<ELFT>::getWriter() { } } +template class MipsTargetHandler<ELF32BE>; template class MipsTargetHandler<ELF32LE>; +template class MipsTargetHandler<ELF64BE>; template class MipsTargetHandler<ELF64LE>; template <class ELFT> @@ -95,7 +97,9 @@ template <class ELFT> void MipsSymbolTable<ELFT>::finalize(bool sort) { } } +template class MipsSymbolTable<ELF32BE>; template class MipsSymbolTable<ELF32LE>; +template class MipsSymbolTable<ELF64BE>; template class MipsSymbolTable<ELF64LE>; template <class ELFT> @@ -149,7 +153,9 @@ template <class ELFT> void MipsDynamicSymbolTable<ELFT>::finalize() { } } +template class MipsDynamicSymbolTable<ELF32BE>; template class MipsDynamicSymbolTable<ELF32LE>; +template class MipsDynamicSymbolTable<ELF64BE>; template class MipsDynamicSymbolTable<ELF64LE>; } diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp index 78ea33d7d41..cb06d5d21ce 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp @@ -102,7 +102,9 @@ template <class ELFT> void MipsTargetLayout<ELFT>::sortSegments() { this->_segments.insert(outIt, abiSeg); } +template class MipsTargetLayout<ELF32BE>; template class MipsTargetLayout<ELF32LE>; +template class MipsTargetLayout<ELF64BE>; template class MipsTargetLayout<ELF64LE>; } // end namespace elf |

