Index: include/lld/ReaderWriter/ELFLinkingContext.h =================================================================== --- include/lld/ReaderWriter/ELFLinkingContext.h +++ include/lld/ReaderWriter/ELFLinkingContext.h @@ -90,6 +90,15 @@ 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? Index: lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h +++ lib/ReaderWriter/ELF/AArch64/AArch64LinkingContext.h @@ -59,6 +59,15 @@ } } + 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) Index: lib/ReaderWriter/ELF/DefaultLayout.h =================================================================== --- lib/ReaderWriter/ELF/DefaultLayout.h +++ 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 @@ return _referencedDynAtoms.count(a); } + bool isCopied(const SharedLibraryAtom *sla) const { + return _copiedDynSymNames.count(sla->name()); + } + protected: /// \brief Allocate a new section. virtual AtomSection *createSection( @@ -325,6 +330,7 @@ LLD_UNIQUE_BUMP_PTR(RelocationTable) _pltRelocationTable; std::vector _absoluteAtoms; AtomSetT _referencedDynAtoms; + llvm::StringSet<> _copiedDynSymNames; const ELFLinkingContext &_context; }; @@ -582,6 +588,11 @@ if (isa(reloc->target()) && isLocalReloc) continue; + if (_context.isCopyRelocation(*reloc)) { + _copiedDynSymNames.insert(definedAtom->name()); + continue; + } + _referencedDynAtoms.insert(reloc->target()); } Index: lib/ReaderWriter/ELF/ExecutableWriter.h =================================================================== --- lib/ReaderWriter/ELF/ExecutableWriter.h +++ lib/ReaderWriter/ELF/ExecutableWriter.h @@ -35,6 +35,11 @@ virtual bool createImplicitFiles(std::vector > &); virtual void finalizeDefaultAtomValues(); virtual void createDefaultSections(); + + virtual bool isNeededTagRequired(const SharedLibraryAtom *sla) const { + return this->_layout.isCopied(sla); + } + LLD_UNIQUE_BUMP_PTR(InterpSection) _interpSection; std::unique_ptr > _runtimeFile; }; Index: lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h =================================================================== --- lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h +++ lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h @@ -37,10 +37,6 @@ return std::error_code(); } - bool isNeededTagRequired(const SharedLibraryAtom *sla) const override { - return _writeHelper.isNeededTagRequired(sla); - } - LLD_UNIQUE_BUMP_PTR(DynamicTable) createDynamicTable(); LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable) createDynamicSymbolTable(); Index: lib/ReaderWriter/ELF/Mips/MipsELFWriters.h =================================================================== --- lib/ReaderWriter/ELF/Mips/MipsELFWriters.h +++ lib/ReaderWriter/ELF/Mips/MipsELFWriters.h @@ -69,11 +69,6 @@ return file; } - bool isNeededTagRequired(const SharedLibraryAtom *sla) const { - return _targetLayout.isReferencedByDefinedAtom(sla) || - _targetLayout.isCopied(sla); - } - private: MipsLinkingContext &_ctx; MipsTargetLayout &_targetLayout; Index: lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h =================================================================== --- lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h +++ lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h @@ -38,10 +38,6 @@ return std::error_code(); } - bool isNeededTagRequired(const SharedLibraryAtom *sla) const override { - return _writeHelper.isNeededTagRequired(sla); - } - LLD_UNIQUE_BUMP_PTR(DynamicTable) createDynamicTable(); LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable) createDynamicSymbolTable(); Index: lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h =================================================================== --- lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h +++ lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h @@ -47,6 +47,7 @@ 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; }; Index: lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp =================================================================== --- lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp +++ lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp @@ -65,6 +65,15 @@ } } +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) Index: lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h =================================================================== --- lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h +++ lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h @@ -62,26 +62,6 @@ } } - ErrorOr 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(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::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 @@ MipsPLTSection *_pltSection; llvm::Optional _gpAtom; llvm::Optional _gpDispAtom; - llvm::StringSet<> _copiedDynSymNames; }; /// \brief Mips Runtime file. Index: lib/ReaderWriter/ELF/OutputELFWriter.h =================================================================== --- lib/ReaderWriter/ELF/OutputELFWriter.h +++ lib/ReaderWriter/ELF/OutputELFWriter.h @@ -116,7 +116,7 @@ /// \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 @@ void OutputELFWriter::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()); } Index: lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h =================================================================== --- lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h +++ lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h @@ -58,6 +58,15 @@ } } + 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)