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/AArch64/AArch64RelocationPass.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp @@ -452,7 +452,7 @@ if (obj != _objectMap.end()) return obj->second; - auto oa = new (_file._alloc) ObjectAtom(_file); + auto oa = new (_file._alloc) ObjectAtom(_file, a); // This needs to point to the atom that we just created. oa->addReferenceELF_AArch64(R_AARCH64_COPY, 0, oa, 0); Index: lib/ReaderWriter/ELF/Atoms.h =================================================================== --- lib/ReaderWriter/ELF/Atoms.h +++ lib/ReaderWriter/ELF/Atoms.h @@ -689,8 +689,11 @@ /// \brief Atom which represents an object for which a COPY relocation will be /// generated. class ObjectAtom : public SimpleELFDefinedAtom { + const SharedLibraryAtom *_sla; + public: - ObjectAtom(const File &f) : SimpleELFDefinedAtom(f) {} + ObjectAtom(const File &f, const SharedLibraryAtom *sla) + : SimpleELFDefinedAtom(f), _sla(sla) {} Scope scope() const override { return scopeGlobal; } @@ -713,6 +716,8 @@ StringRef name() const override { return _name; } + const SharedLibraryAtom *getOriginalOwner() const { return _sla; } + std::string _name; uint64_t _size; }; 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" @@ -171,6 +172,7 @@ typedef typename std::vector::iterator AbsoluteAtomIterT; typedef llvm::DenseSet AtomSetT; + typedef llvm::DenseSet SharedLibraryAtomSetT; DefaultLayout(const ELFLinkingContext &context) : _context(context) {} @@ -303,6 +305,10 @@ return _referencedDynAtoms.count(a); } + const SharedLibraryAtomSetT &getCopiedDynAtoms() const { + return _copiedDynAtoms; + } + protected: /// \brief Allocate a new section. virtual AtomSection *createSection( @@ -325,6 +331,7 @@ LLD_UNIQUE_BUMP_PTR(RelocationTable) _pltRelocationTable; std::vector _absoluteAtoms; AtomSetT _referencedDynAtoms; + SharedLibraryAtomSetT _copiedDynAtoms; const ELFLinkingContext &_context; }; @@ -582,7 +589,14 @@ if (isa(reloc->target()) && isLocalReloc) continue; - _referencedDynAtoms.insert(reloc->target()); + if (!_context.isCopyRelocation(*reloc)) { + _referencedDynAtoms.insert(reloc->target()); + continue; + } + + const ObjectAtom *oa = dyn_cast(reloc->target()); + assert (oa != nullptr && "Targets of copy relocs must be ObjectAtoms"); + _copiedDynAtoms.insert(oa->getOriginalOwner()); } return section->appendAtom(atom); 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/MipsRelocationPass.cpp =================================================================== --- lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp +++ lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp @@ -781,7 +781,7 @@ if (obj != _objectMap.end()) return obj->second; - auto oa = new (_file._alloc) ObjectAtom(_file); + auto oa = new (_file._alloc) ObjectAtom(_file, a); oa->addReferenceELF_Mips(R_MIPS_COPY, 0, oa, 0); oa->_name = a->name(); oa->_size = a->size(); 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 @@ -189,11 +189,14 @@ atom->_virtualAddr, atom); } for (const auto &sla : file.sharedLibrary()) { - if (isDynSymEntryRequired(sla)) - _dynamicSymbolTable->addSymbol(sla, ELF::SHN_UNDEF); + if (!isDynSymEntryRequired(sla)) + continue; + _dynamicSymbolTable->addSymbol(sla, ELF::SHN_UNDEF); if (isNeededTagRequired(sla)) _soNeeded.insert(sla->loadName()); } + for (const auto &sla : _layout.getCopiedDynAtoms()) + _soNeeded.insert(sla->loadName()); // Never mark the dynamic linker as DT_NEEDED _soNeeded.erase(sys::path::filename(_context.getInterpreter())); for (const auto &loadName : _soNeeded) { 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) Index: lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp =================================================================== --- lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp +++ lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp @@ -430,7 +430,7 @@ if (obj != _objectMap.end()) return obj->second; - auto oa = new (_file._alloc) ObjectAtom(_file); + auto oa = new (_file._alloc) ObjectAtom(_file, a); // This needs to point to the atom that we just created. oa->addReferenceELF_x86_64(R_X86_64_COPY, 0, oa, 0);