diff options
12 files changed, 58 insertions, 36 deletions
diff --git a/lld/include/lld/ReaderWriter/ELFLinkingContext.h b/lld/include/lld/ReaderWriter/ELFLinkingContext.h index 1ace8b93a07..582b345bc93 100644 --- a/lld/include/lld/ReaderWriter/ELFLinkingContext.h +++ b/lld/include/lld/ReaderWriter/ELFLinkingContext.h @@ -90,6 +90,15 @@ public: const Reference &) const { return false; } + + /// \brief Is this a copy relocation? + /// + /// If this is a copy relocation, its target must be an ObjectAtom. We must + /// include in DT_NEEDED the name of the library where this object came from. + virtual bool isCopyRelocation(const Reference &) const { + return false; + } + bool validateImpl(raw_ostream &diagnostics) override; /// \brief Does the linker allow dynamic libraries to be linked with? diff --git a/lld/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h b/lld/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h index 07ec6c1a2b3..2ae5b394556 100644 --- a/lld/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h +++ b/lld/lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h @@ -59,6 +59,15 @@ public: } } + bool isCopyRelocation(const Reference &r) const override { + if (r.kindNamespace() != Reference::KindNamespace::ELF) + return false; + assert(r.kindArch() == Reference::KindArch::AArch64); + if (r.kindValue() == llvm::ELF::R_AARCH64_COPY) + return true; + return false; + } + bool isPLTRelocation(const DefinedAtom &, const Reference &r) const override { if (r.kindNamespace() != Reference::KindNamespace::ELF) diff --git a/lld/lib/ReaderWriter/ELF/DefaultLayout.h b/lld/lib/ReaderWriter/ELF/DefaultLayout.h index d198c5abc6f..87c6cfc1a29 100644 --- a/lld/lib/ReaderWriter/ELF/DefaultLayout.h +++ b/lld/lib/ReaderWriter/ELF/DefaultLayout.h @@ -10,6 +10,7 @@ #ifndef LLD_READER_WRITER_ELF_DEFAULT_LAYOUT_H #define LLD_READER_WRITER_ELF_DEFAULT_LAYOUT_H +#include "Atoms.h" #include "Chunk.h" #include "HeaderChunks.h" #include "Layout.h" @@ -303,6 +304,10 @@ public: return _referencedDynAtoms.count(a); } + bool isCopied(const SharedLibraryAtom *sla) const { + return _copiedDynSymNames.count(sla->name()); + } + protected: /// \brief Allocate a new section. virtual AtomSection<ELFT> *createSection( @@ -325,6 +330,7 @@ protected: LLD_UNIQUE_BUMP_PTR(RelocationTable<ELFT>) _pltRelocationTable; std::vector<lld::AtomLayout *> _absoluteAtoms; AtomSetT _referencedDynAtoms; + llvm::StringSet<> _copiedDynSymNames; const ELFLinkingContext &_context; }; @@ -582,6 +588,11 @@ ErrorOr<const lld::AtomLayout &> DefaultLayout<ELFT>::addAtom(const Atom *atom) if (isa<UndefinedAtom>(reloc->target()) && isLocalReloc) continue; + if (_context.isCopyRelocation(*reloc)) { + _copiedDynSymNames.insert(definedAtom->name()); + continue; + } + _referencedDynAtoms.insert(reloc->target()); } diff --git a/lld/lib/ReaderWriter/ELF/ExecutableWriter.h b/lld/lib/ReaderWriter/ELF/ExecutableWriter.h index 5be96cc8f21..991fadb3665 100644 --- a/lld/lib/ReaderWriter/ELF/ExecutableWriter.h +++ b/lld/lib/ReaderWriter/ELF/ExecutableWriter.h @@ -35,6 +35,11 @@ protected: virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &); virtual void finalizeDefaultAtomValues(); virtual void createDefaultSections(); + + virtual bool isNeededTagRequired(const SharedLibraryAtom *sla) const { + return this->_layout.isCopied(sla); + } + LLD_UNIQUE_BUMP_PTR(InterpSection<ELFT>) _interpSection; std::unique_ptr<CRuntimeFile<ELFT> > _runtimeFile; }; diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h b/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h index 5d895d52bc5..819c0869e7a 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h @@ -37,10 +37,6 @@ protected: return std::error_code(); } - bool isNeededTagRequired(const SharedLibraryAtom *sla) const override { - return _writeHelper.isNeededTagRequired(sla); - } - LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) createDynamicTable(); LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>) createDynamicSymbolTable(); diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h b/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h index 3b26816885a..4f4f22662fb 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h @@ -69,11 +69,6 @@ public: return file; } - bool isNeededTagRequired(const SharedLibraryAtom *sla) const { - return _targetLayout.isReferencedByDefinedAtom(sla) || - _targetLayout.isCopied(sla); - } - private: MipsLinkingContext &_ctx; MipsTargetLayout<ELFT> &_targetLayout; diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h b/lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h index a220428582b..07b155e7f47 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h @@ -38,10 +38,6 @@ protected: return std::error_code(); } - bool isNeededTagRequired(const SharedLibraryAtom *sla) const override { - return _writeHelper.isNeededTagRequired(sla); - } - LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) createDynamicTable(); LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>) createDynamicSymbolTable(); diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp index 946c96c7fa2..af3f8ad31cf 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp @@ -65,6 +65,15 @@ bool MipsLinkingContext::isDynamicRelocation(const DefinedAtom &, } } +bool MipsLinkingContext::isCopyRelocation(const Reference &r) const { + if (r.kindNamespace() != Reference::KindNamespace::ELF) + return false; + assert(r.kindArch() == Reference::KindArch::Mips); + if (r.kindValue() == llvm::ELF::R_MIPS_COPY) + return true; + return false; +} + bool MipsLinkingContext::isPLTRelocation(const DefinedAtom &, const Reference &r) const { if (r.kindNamespace() != Reference::KindNamespace::ELF) diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h index d39e403ccfc..ef8ff42b6d7 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h @@ -47,6 +47,7 @@ public: bool isRelaOutputFormat() const override { return false; } bool isDynamicRelocation(const DefinedAtom &, const Reference &r) const override; + bool isCopyRelocation(const Reference &r) const override; bool isPLTRelocation(const DefinedAtom &, const Reference &r) const override; }; diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h index 1a3d6a3ebb3..04cc076fe62 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h @@ -62,26 +62,6 @@ public: } } - ErrorOr<const lld::AtomLayout &> addAtom(const Atom *atom) override { - // Maintain: - // 1. Set of shared library atoms referenced by regular defined atoms. - // 2. Set of shared library atoms have corresponding R_MIPS_COPY copies. - if (const auto *da = dyn_cast<DefinedAtom>(atom)) - for (const Reference *ref : *da) { - if (ref->kindNamespace() == lld::Reference::KindNamespace::ELF) { - assert(ref->kindArch() == Reference::KindArch::Mips); - if (ref->kindValue() == llvm::ELF::R_MIPS_COPY) - _copiedDynSymNames.insert(atom->name()); - } - } - - return TargetLayout<ELFType>::addAtom(atom); - } - - bool isCopied(const SharedLibraryAtom *sla) const { - return _copiedDynSymNames.count(sla->name()); - } - /// \brief GP offset relative to .got section. uint64_t getGPOffset() const { return 0x7FF0; } @@ -109,7 +89,6 @@ private: MipsPLTSection<ELFType> *_pltSection; llvm::Optional<AtomLayout *> _gpAtom; llvm::Optional<AtomLayout *> _gpDispAtom; - llvm::StringSet<> _copiedDynSymNames; }; /// \brief Mips Runtime file. diff --git a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h index 30b1e573a66..dfb9a1a4a6e 100644 --- a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h +++ b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h @@ -116,7 +116,7 @@ protected: /// \brief Create DT_NEEDED dynamic tage for the shared library. virtual bool isNeededTagRequired(const SharedLibraryAtom *sla) const { - return true; + return false; } llvm::BumpPtrAllocator _alloc; @@ -180,8 +180,11 @@ template <class ELFT> void OutputELFWriter<ELFT>::buildDynamicSymbolTable(const File &file) { ScopedTask task(getDefaultDomain(), "buildDynamicSymbolTable"); for (const auto &sla : file.sharedLibrary()) { - if (isDynSymEntryRequired(sla)) + if (isDynSymEntryRequired(sla)) { _dynamicSymbolTable->addSymbol(sla, ELF::SHN_UNDEF); + _soNeeded.insert(sla->loadName()); + continue; + } if (isNeededTagRequired(sla)) _soNeeded.insert(sla->loadName()); } diff --git a/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h b/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h index a25c1eb4a59..4a40b33c00a 100644 --- a/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h +++ b/lld/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h @@ -58,6 +58,15 @@ public: } } + bool isCopyRelocation(const Reference &r) const override { + if (r.kindNamespace() != Reference::KindNamespace::ELF) + return false; + assert(r.kindArch() == Reference::KindArch::x86_64); + if (r.kindValue() == llvm::ELF::R_X86_64_COPY) + return true; + return false; + } + virtual bool isPLTRelocation(const DefinedAtom &, const Reference &r) const override { if (r.kindNamespace() != Reference::KindNamespace::ELF) |

