diff options
| author | Simon Atanasyan <simon@atanasyan.com> | 2015-05-31 20:36:11 +0000 |
|---|---|---|
| committer | Simon Atanasyan <simon@atanasyan.com> | 2015-05-31 20:36:11 +0000 |
| commit | 70e21bc83d4ae19ab48b55a9cc142ce5edbd1a03 (patch) | |
| tree | be87d49bc0e7b61cd23fed5d2c6b903f5a6d4052 | |
| parent | f4784cce544408ad81d64d423eeea11f9a947d73 (diff) | |
| download | bcm5719-llvm-70e21bc83d4ae19ab48b55a9cc142ce5edbd1a03.tar.gz bcm5719-llvm-70e21bc83d4ae19ab48b55a9cc142ce5edbd1a03.zip | |
[Mips] Collect all ABI related info in the single MipsAbiInfoHandler class
New MipsAbiInfoHandler merges and hold both ELF header flags
and registries usage masks. In the future commits it will manage some
additional information.
llvm-svn: 238684
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp (renamed from lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp) | 41 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.h | 42 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp | 9 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h | 36 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp | 63 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h | 13 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp | 24 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h | 18 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp | 35 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp | 7 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h | 4 |
12 files changed, 151 insertions, 143 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Mips/CMakeLists.txt b/lld/lib/ReaderWriter/ELF/Mips/CMakeLists.txt index 5c5a9bc7f49..434e310640b 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/CMakeLists.txt +++ b/lld/lib/ReaderWriter/ELF/Mips/CMakeLists.txt @@ -1,7 +1,7 @@ add_llvm_library(lldMipsELFTarget + MipsAbiInfoHandler.cpp MipsCtorsOrderPass.cpp MipsELFFile.cpp - MipsELFFlagsMerger.cpp MipsELFWriters.cpp MipsLinkingContext.cpp MipsRelocationHandler.cpp diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp index bc3abb1d454..8629012fed2 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp @@ -1,4 +1,4 @@ -//===- lib/ReaderWriter/ELF/MipsELFFlagsMerger.cpp ------------------------===// +//===- lib/ReaderWriter/ELF/MipsAbiInfoHandler.cpp ------------------------===// // // The LLVM Linker // @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// -#include "MipsELFFlagsMerger.h" +#include "MipsAbiInfoHandler.h" #include "lld/Core/Error.h" +#include "lld/ReaderWriter/ELFLinkingContext.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/ELF.h" #include "llvm/Support/raw_ostream.h" -using namespace lld; -using namespace lld::elf; using namespace llvm::ELF; struct MipsISATreeEdge { @@ -59,16 +58,25 @@ static bool matchMipsISA(unsigned base, unsigned ext) { return false; } -MipsELFFlagsMerger::MipsELFFlagsMerger(bool is64Bits) - : _is64Bit(is64Bits), _flags(0) {} +namespace lld { +namespace elf { -uint32_t MipsELFFlagsMerger::getMergedELFFlags() const { return _flags; } +template <class ELFT> uint32_t MipsAbiInfoHandler<ELFT>::getFlags() const { + return _flags; +} + +template <class ELFT> +const llvm::Optional<MipsReginfo> & +MipsAbiInfoHandler<ELFT>::getRegistersMask() const { + return _regMask; +} -std::error_code MipsELFFlagsMerger::mergeFlags(uint32_t newFlags) { +template <class ELFT> +std::error_code MipsAbiInfoHandler<ELFT>::mergeFlags(uint32_t newFlags) { // We support two ABI: O32 and N64. The last one does not have // the corresponding ELF flag. uint32_t inAbi = newFlags & EF_MIPS_ABI; - uint32_t supportedAbi = _is64Bit ? 0 : uint32_t(EF_MIPS_ABI_O32); + uint32_t supportedAbi = ELFT::Is64Bits ? 0 : uint32_t(EF_MIPS_ABI_O32); if (inAbi != supportedAbi) return make_dynamic_error_code("Unsupported ABI"); @@ -141,3 +149,18 @@ std::error_code MipsELFFlagsMerger::mergeFlags(uint32_t newFlags) { return std::error_code(); } + +template <class ELFT> +void MipsAbiInfoHandler<ELFT>::mergeRegistersMask(const MipsReginfo &info) { + std::lock_guard<std::mutex> lock(_mutex); + if (_regMask.hasValue()) + _regMask->merge(info); + else + _regMask = info; +} + +template class MipsAbiInfoHandler<ELF32LE>; +template class MipsAbiInfoHandler<ELF64LE>; + +} +} diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.h b/lld/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.h new file mode 100644 index 00000000000..8d5fb9671a0 --- /dev/null +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.h @@ -0,0 +1,42 @@ +//===- lib/ReaderWriter/ELF/MipsAbiInfoHandler.h --------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_ABI_INFO_HANDLER_H +#define LLD_READER_WRITER_ELF_MIPS_MIPS_ABI_INFO_HANDLER_H + +#include "MipsReginfo.h" +#include "llvm/ADT/Optional.h" +#include <mutex> +#include <system_error> + +namespace lld { +namespace elf { + +template <class ELFT> class MipsAbiInfoHandler { +public: + MipsAbiInfoHandler() = default; + + uint32_t getFlags() const; + const llvm::Optional<MipsReginfo> &getRegistersMask() const; + + /// \brief Merge saved ELF header flags and the new set of flags. + std::error_code mergeFlags(uint32_t newFlags); + + /// \brief Merge saved and new sets of registers usage masks. + void mergeRegistersMask(const MipsReginfo &info); + +private: + std::mutex _mutex; + uint32_t _flags = 0; + llvm::Optional<MipsReginfo> _regMask; +}; + +} // namespace elf +} // namespace lld + +#endif diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp index 224e7b48b67..833c5ab6551 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "MipsELFFile.h" +#include "MipsTargetHandler.h" namespace lld { namespace elf { @@ -162,18 +163,20 @@ template <class ELFT> std::error_code MipsELFFile<ELFT>::readAuxData() { _dtpOff = sec->sh_addr + DTP_OFFSET; } - auto &ctx = static_cast<MipsLinkingContext &>(this->_ctx); + auto &handler = + static_cast<MipsTargetHandler<ELFT> &>(this->_ctx.getTargetHandler()); + auto &abi = handler.getAbiInfoHandler(); ErrorOr<const Elf_Mips_RegInfo *> regInfoSec = findRegInfoSec(); if (auto ec = regInfoSec.getError()) return ec; if (const Elf_Mips_RegInfo *regInfo = regInfoSec.get()) { - ctx.mergeReginfoMask(*regInfo); + abi.mergeRegistersMask(*regInfo); _gp0 = regInfo->ri_gp_value; } const Elf_Ehdr *hdr = this->_objFile->getHeader(); - if (std::error_code ec = ctx.mergeElfFlags(hdr->e_flags)) + if (std::error_code ec = abi.mergeFlags(hdr->e_flags)) return ec; return std::error_code(); diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h deleted file mode 100644 index 2e6e81a8078..00000000000 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h +++ /dev/null @@ -1,36 +0,0 @@ -//===- lib/ReaderWriter/ELF/MipsELFFlagsMerger.h --------------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_FLAGS_MERGER_H -#define LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_FLAGS_MERGER_H - -#include <mutex> -#include <system_error> - -namespace lld { -namespace elf { - -class MipsELFFlagsMerger { -public: - MipsELFFlagsMerger(bool is64Bits); - - uint32_t getMergedELFFlags() const; - - /// \brief Merge saved ELF header flags and the new set of flags. - std::error_code mergeFlags(uint32_t newFlags); - -private: - const bool _is64Bit; - std::mutex _mutex; - uint32_t _flags; -}; - -} // namespace elf -} // namespace lld - -#endif diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp index cf0f48e1cb6..7afcf3877a3 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp @@ -27,8 +27,9 @@ namespace elf { template <class ELFT> MipsELFWriter<ELFT>::MipsELFWriter(MipsLinkingContext &ctx, - MipsTargetLayout<ELFT> &targetLayout) - : _ctx(ctx), _targetLayout(targetLayout) {} + MipsTargetLayout<ELFT> &targetLayout, + const MipsAbiInfoHandler<ELFT> &abiInfo) + : _ctx(ctx), _targetLayout(targetLayout), _abiInfo(abiInfo) {} template <class ELFT> void MipsELFWriter<ELFT>::setELFHeader(ELFHeader<ELFT> &elfHeader) { @@ -40,7 +41,7 @@ void MipsELFWriter<ELFT>::setELFHeader(ELFHeader<ELFT> &elfHeader) { else elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, 0); - elfHeader.e_flags(_ctx.getMergedELFFlags()); + elfHeader.e_flags(_abiInfo.getFlags()); } template <class ELFT> @@ -70,6 +71,20 @@ std::unique_ptr<RuntimeFile<ELFT>> MipsELFWriter<ELFT>::createRuntimeFile() { } template <class ELFT> +unique_bump_ptr<Section<ELFT>> +MipsELFWriter<ELFT>::createOptionsSection(llvm::BumpPtrAllocator &alloc) { + typedef unique_bump_ptr<Section<ELFT>> Ptr; + const auto ®Mask = _abiInfo.getRegistersMask(); + if (!regMask.hasValue()) + return Ptr(); + return ELFT::Is64Bits + ? Ptr(new (alloc) + MipsOptionsSection<ELFT>(_ctx, _targetLayout, *regMask)) + : Ptr(new (alloc) + MipsReginfoSection<ELFT>(_ctx, _targetLayout, *regMask)); +} + +template <class ELFT> void MipsELFWriter<ELFT>::setAtomValue(StringRef name, uint64_t value) { AtomLayout *atom = _targetLayout.findAbsoluteAtom(name); assert(atom); @@ -78,9 +93,10 @@ void MipsELFWriter<ELFT>::setAtomValue(StringRef name, uint64_t value) { template <class ELFT> MipsDynamicLibraryWriter<ELFT>::MipsDynamicLibraryWriter( - MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout) - : DynamicLibraryWriter<ELFT>(ctx, layout), _writeHelper(ctx, layout), - _targetLayout(layout) {} + MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout, + const MipsAbiInfoHandler<ELFT> &abiInfo) + : DynamicLibraryWriter<ELFT>(ctx, layout), + _writeHelper(ctx, layout, abiInfo), _targetLayout(layout) {} template <class ELFT> void MipsDynamicLibraryWriter<ELFT>::createImplicitFiles( @@ -98,17 +114,9 @@ void MipsDynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() { template <class ELFT> void MipsDynamicLibraryWriter<ELFT>::createDefaultSections() { DynamicLibraryWriter<ELFT>::createDefaultSections(); - const auto &ctx = static_cast<const MipsLinkingContext &>(this->_ctx); - const auto &mask = ctx.getMergedReginfoMask(); - if (!mask.hasValue()) - return; - if (ELFT::Is64Bits) - _reginfo = unique_bump_ptr<Section<ELFT>>( - new (this->_alloc) MipsOptionsSection<ELFT>(ctx, _targetLayout, *mask)); - else - _reginfo = unique_bump_ptr<Section<ELFT>>( - new (this->_alloc) MipsReginfoSection<ELFT>(ctx, _targetLayout, *mask)); - this->_layout.addSection(_reginfo.get()); + _reginfo = _writeHelper.createOptionsSection(this->_alloc); + if (_reginfo) + this->_layout.addSection(_reginfo.get()); } template <class ELFT> @@ -143,9 +151,10 @@ template class MipsDynamicLibraryWriter<ELF32LE>; template class MipsDynamicLibraryWriter<ELF64LE>; template <class ELFT> -MipsExecutableWriter<ELFT>::MipsExecutableWriter(MipsLinkingContext &ctx, - MipsTargetLayout<ELFT> &layout) - : ExecutableWriter<ELFT>(ctx, layout), _writeHelper(ctx, layout), +MipsExecutableWriter<ELFT>::MipsExecutableWriter( + MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout, + const MipsAbiInfoHandler<ELFT> &abiInfo) + : ExecutableWriter<ELFT>(ctx, layout), _writeHelper(ctx, layout, abiInfo), _targetLayout(layout) {} template <class ELFT> @@ -223,17 +232,9 @@ void MipsExecutableWriter<ELFT>::finalizeDefaultAtomValues() { template <class ELFT> void MipsExecutableWriter<ELFT>::createDefaultSections() { ExecutableWriter<ELFT>::createDefaultSections(); - const auto &ctx = static_cast<const MipsLinkingContext &>(this->_ctx); - const auto &mask = ctx.getMergedReginfoMask(); - if (!mask.hasValue()) - return; - if (ELFT::Is64Bits) - _reginfo = unique_bump_ptr<Section<ELFT>>( - new (this->_alloc) MipsOptionsSection<ELFT>(ctx, _targetLayout, *mask)); - else - _reginfo = unique_bump_ptr<Section<ELFT>>( - new (this->_alloc) MipsReginfoSection<ELFT>(ctx, _targetLayout, *mask)); - this->_layout.addSection(_reginfo.get()); + _reginfo = _writeHelper.createOptionsSection(this->_alloc); + if (_reginfo) + this->_layout.addSection(_reginfo.get()); } template <class ELFT> diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h b/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h index 7accec55640..ddae9d41675 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h @@ -11,6 +11,7 @@ #include "DynamicLibraryWriter.h" #include "ExecutableWriter.h" +#include "MipsAbiInfoHandler.h" #include "MipsLinkingContext.h" namespace lld { @@ -20,17 +21,21 @@ template <class ELFT> class MipsTargetLayout; template <typename ELFT> class MipsELFWriter { public: - MipsELFWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout); + MipsELFWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout, + const MipsAbiInfoHandler<ELFT> &abiInfo); void setELFHeader(ELFHeader<ELFT> &elfHeader); void finalizeMipsRuntimeAtomValues(); std::unique_ptr<RuntimeFile<ELFT>> createRuntimeFile(); + unique_bump_ptr<Section<ELFT>> + createOptionsSection(llvm::BumpPtrAllocator &alloc); private: MipsLinkingContext &_ctx; MipsTargetLayout<ELFT> &_targetLayout; + const MipsAbiInfoHandler<ELFT> &_abiInfo; void setAtomValue(StringRef name, uint64_t value); }; @@ -39,7 +44,8 @@ template <class ELFT> class MipsDynamicLibraryWriter : public DynamicLibraryWriter<ELFT> { public: MipsDynamicLibraryWriter(MipsLinkingContext &ctx, - MipsTargetLayout<ELFT> &layout); + MipsTargetLayout<ELFT> &layout, + const MipsAbiInfoHandler<ELFT> &abiInfo); protected: // Add any runtime files and their atoms to the output @@ -63,7 +69,8 @@ private: template <class ELFT> class MipsExecutableWriter : public ExecutableWriter<ELFT> { public: - MipsExecutableWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout); + MipsExecutableWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout, + const MipsAbiInfoHandler<ELFT> &abiInfo); protected: void buildDynamicSymbolTable(const File &file) override; diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp index 369c225f4b9..bcf0a092a70 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp @@ -37,29 +37,7 @@ static std::unique_ptr<TargetHandler> createTarget(llvm::Triple triple, } MipsLinkingContext::MipsLinkingContext(llvm::Triple triple) - : ELFLinkingContext(triple, createTarget(triple, *this)), - _flagsMerger(triple.isArch64Bit()) {} - -std::error_code MipsLinkingContext::mergeElfFlags(uint64_t flags) { - return _flagsMerger.mergeFlags(flags); -} - -void MipsLinkingContext::mergeReginfoMask(const MipsReginfo &info) { - std::lock_guard<std::mutex> lock(_maskMutex); - if (_reginfoMask.hasValue()) - _reginfoMask->merge(info); - else - _reginfoMask = info; -} - -uint32_t MipsLinkingContext::getMergedELFFlags() const { - return _flagsMerger.getMergedELFFlags(); -} - -const llvm::Optional<MipsReginfo> & -MipsLinkingContext::getMergedReginfoMask() const { - return _reginfoMask; -} + : ELFLinkingContext(triple, createTarget(triple, *this)) {} uint64_t MipsLinkingContext::getBaseAddress() const { if (_baseAddress == 0 && getOutputELFType() == llvm::ELF::ET_EXEC) diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h index 36da1599db3..61b3ba1b4bd 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h @@ -9,10 +9,7 @@ #ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_LINKING_CONTEXT_H #define LLD_READER_WRITER_ELF_MIPS_MIPS_LINKING_CONTEXT_H -#include "MipsELFFlagsMerger.h" -#include "MipsReginfo.h" #include "lld/ReaderWriter/ELFLinkingContext.h" -#include <mutex> namespace lld { namespace elf { @@ -39,18 +36,10 @@ enum { class MipsLinkingContext final : public ELFLinkingContext { public: - int getMachineType() const override { return llvm::ELF::EM_MIPS; } MipsLinkingContext(llvm::Triple triple); - std::error_code mergeElfFlags(uint64_t flags); - void mergeReginfoMask(const MipsReginfo &info); - - uint32_t getMergedELFFlags() const; - const llvm::Optional<MipsReginfo> &getMergedReginfoMask() const; - void registerRelocationNames(Registry &r) override; - - // ELFLinkingContext + int getMachineType() const override { return llvm::ELF::EM_MIPS; } uint64_t getBaseAddress() const override; StringRef entrySymbolName() const override; StringRef getDefaultInterpreter() const override; @@ -60,11 +49,6 @@ public: bool isCopyRelocation(const Reference &r) const override; bool isPLTRelocation(const Reference &r) const override; bool isRelativeReloc(const Reference &r) const override; - -private: - MipsELFFlagsMerger _flagsMerger; - std::mutex _maskMutex; - llvm::Optional<MipsReginfo> _reginfoMask; }; } // elf diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp index 8947d9351eb..0b54a8922cf 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp @@ -10,6 +10,7 @@ #include "MipsELFFile.h" #include "MipsLinkingContext.h" #include "MipsRelocationPass.h" +#include "MipsTargetHandler.h" #include "llvm/ADT/DenseSet.h" using namespace lld; @@ -310,6 +311,12 @@ private: /// \brief Owner of all the Atoms created by this pass. RelocationPassFile _file; + /// \brief Linked files contain MIPS R6 code. + bool _isMipsR6 = false; + + /// \brief Linked files contain microMIPS code. + bool _isMicroMips = false; + /// \brief Map Atoms and addend to local GOT entries. typedef std::pair<const Atom *, int64_t> LocalGotMapKeyT; llvm::DenseMap<LocalGotMapKeyT, GOTAtom *> _gotLocalMap; @@ -411,8 +418,6 @@ private: bool mightBeDynamic(const MipsELFDefinedAtom<ELFT> &atom, Reference::KindValue refKind) const; bool hasPLTEntry(const Atom *atom) const; - - bool isR6Target() const; }; template <typename ELFT> @@ -425,6 +430,14 @@ RelocationPass<ELFT>::RelocationPass(MipsLinkingContext &ctx) template <typename ELFT> void RelocationPass<ELFT>::perform(std::unique_ptr<SimpleFile> &mf) { + auto &handler = + static_cast<MipsTargetHandler<ELFT> &>(this->_ctx.getTargetHandler()); + + uint32_t elfFlags = handler.getAbiInfoHandler().getFlags(); + _isMicroMips = elfFlags & EF_MIPS_MICROMIPS; + _isMipsR6 = (elfFlags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6 || + (elfFlags & EF_MIPS_ARCH) == EF_MIPS_ARCH_64R6; + for (const auto &atom : mf->defined()) for (const auto &ref : *atom) collectReferenceInfo(*cast<MipsELFDefinedAtom<ELFT>>(atom), @@ -696,16 +709,6 @@ bool RelocationPass<ELFT>::hasPLTEntry(const Atom *atom) const { return _pltRegMap.count(atom) || _pltMicroMap.count(atom); } -template <typename ELFT> bool RelocationPass<ELFT>::isR6Target() const { - switch (_ctx.getMergedELFFlags() & EF_MIPS_ARCH) { - case EF_MIPS_ARCH_32R6: - case EF_MIPS_ARCH_64R6: - return true; - default: - return false; - } -} - template <typename ELFT> bool RelocationPass<ELFT>::requirePLTEntry(const Atom *a) const { if (!_hasStaticRelocations.count(a)) @@ -757,10 +760,8 @@ const LA25Atom *RelocationPass<ELFT>::getLA25Entry(const Atom *target, template <typename ELFT> const PLTAtom *RelocationPass<ELFT>::getPLTEntry(const Atom *a) { - bool hasMicroCode = _ctx.getMergedELFFlags() & EF_MIPS_MICROMIPS; - // If file contains microMIPS code try to reuse compressed PLT entry... - if (hasMicroCode) { + if (_isMicroMips) { auto microPLT = _pltMicroMap.find(a); if (microPLT != _pltMicroMap.end()) return microPLT->second; @@ -772,7 +773,7 @@ const PLTAtom *RelocationPass<ELFT>::getPLTEntry(const Atom *a) { return regPLT->second; // ... and finally prefer to create new compressed PLT entry. - return hasMicroCode ? getPLTMicroEntry(a) : getPLTRegEntry(a); + return _isMicroMips ? getPLTMicroEntry(a) : getPLTRegEntry(a); } template <typename ELFT> @@ -1009,7 +1010,7 @@ const PLTAtom *RelocationPass<ELFT>::getPLTRegEntry(const Atom *a) { if (plt != _pltRegMap.end()) return plt->second; - PLTAAtom *pa = isR6Target() + PLTAAtom *pa = _isMipsR6 ? new (_file._alloc) PLTR6Atom(getGOTPLTEntry(a), _file) : new (_file._alloc) PLTAAtom(getGOTPLTEntry(a), _file); _pltRegMap[a] = pa; diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp index 3740cef069d..1e7e5945671 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp @@ -41,10 +41,11 @@ template <class ELFT> std::unique_ptr<Writer> MipsTargetHandler<ELFT>::getWriter() { switch (_ctx.getOutputELFType()) { case llvm::ELF::ET_EXEC: - return llvm::make_unique<MipsExecutableWriter<ELFT>>(_ctx, *_targetLayout); + return llvm::make_unique<MipsExecutableWriter<ELFT>>(_ctx, *_targetLayout, + _abiInfoHandler); case llvm::ELF::ET_DYN: - return llvm::make_unique<MipsDynamicLibraryWriter<ELFT>>(_ctx, - *_targetLayout); + return llvm::make_unique<MipsDynamicLibraryWriter<ELFT>>( + _ctx, *_targetLayout, _abiInfoHandler); case llvm::ELF::ET_REL: llvm_unreachable("TODO: support -r mode"); default: diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h index 2bf2f9e5097..8d5b6632345 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h @@ -9,6 +9,7 @@ #ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_TARGET_HANDLER_H #define LLD_READER_WRITER_ELF_MIPS_MIPS_TARGET_HANDLER_H +#include "MipsAbiInfoHandler.h" #include "MipsLinkingContext.h" #include "MipsTargetLayout.h" #include "TargetHandler.h" @@ -21,6 +22,8 @@ template <class ELFT> class MipsTargetHandler final : public TargetHandler { public: MipsTargetHandler(MipsLinkingContext &ctx); + MipsAbiInfoHandler<ELFT> &getAbiInfoHandler() { return _abiInfoHandler; } + std::unique_ptr<Reader> getObjReader() override; std::unique_ptr<Reader> getDSOReader() override; const TargetRelocationHandler &getRelocationHandler() const override; @@ -30,6 +33,7 @@ private: MipsLinkingContext &_ctx; std::unique_ptr<MipsTargetLayout<ELFT>> _targetLayout; std::unique_ptr<TargetRelocationHandler> _relocationHandler; + MipsAbiInfoHandler<ELFT> _abiInfoHandler; }; template <class ELFT> class MipsSymbolTable : public SymbolTable<ELFT> { |

