diff options
Diffstat (limited to 'lld/lib/ReaderWriter/MachO')
-rw-r--r-- | lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp | 4 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/Atoms.h | 6 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp | 2 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/ExecutableAtoms.h | 15 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/File.h | 26 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/FlatNamespaceFile.h | 27 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/GOTPass.cpp | 2 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/LayoutPass.cpp | 28 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/LayoutPass.h | 14 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp | 14 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/ObjCPass.cpp | 2 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/SectCreateFile.h | 17 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/StubsPass.cpp | 10 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/TLVPass.cpp | 2 |
14 files changed, 118 insertions, 51 deletions
diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp b/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp index cefa745add9..7eda42ef7a0 100644 --- a/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp +++ b/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp @@ -1429,6 +1429,8 @@ public: _name = tmp.copy(file.allocator()); } + ~Thumb2ToArmShimAtom() override = default; + StringRef name() const override { return _name; } @@ -1472,6 +1474,8 @@ public: _name = tmp.copy(file.allocator()); } + ~ArmToThumbShimAtom() override = default; + StringRef name() const override { return _name; } diff --git a/lld/lib/ReaderWriter/MachO/Atoms.h b/lld/lib/ReaderWriter/MachO/Atoms.h index f50a6cffe18..c3117d4ac89 100644 --- a/lld/lib/ReaderWriter/MachO/Atoms.h +++ b/lld/lib/ReaderWriter/MachO/Atoms.h @@ -32,6 +32,8 @@ public: _contentType(type), _scope(scope), _merge(mergeNo), _thumb(false), _noDeadStrip(noDeadStrip) {} + ~MachODefinedAtom() override = default; + uint64_t size() const override { return _content.size(); } ContentType contentType() const override { return _contentType; } @@ -83,6 +85,8 @@ public: content, align), _sectionName(sectionName) {} + ~MachODefinedCustomSectionAtom() override = default; + SectionChoice sectionChoice() const override { return DefinedAtom::sectionCustomRequired; } @@ -101,6 +105,8 @@ public: : SimpleDefinedAtom(f), _name(name), _scope(scope), _size(size), _align(align) {} + ~MachOTentativeDefAtom() override = default; + uint64_t size() const override { return _size; } Merge merge() const override { return DefinedAtom::mergeAsTentative; } diff --git a/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp b/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp index d2793033b5f..088f93bf630 100644 --- a/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp +++ b/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp @@ -88,6 +88,8 @@ public: addSecondLevelPages(pages); } + ~UnwindInfoAtom() override = default; + ContentType contentType() const override { return DefinedAtom::typeProcessedUnwindInfo; } diff --git a/lld/lib/ReaderWriter/MachO/ExecutableAtoms.h b/lld/lib/ReaderWriter/MachO/ExecutableAtoms.h index e1a252bbf9b..acced33b7e7 100644 --- a/lld/lib/ReaderWriter/MachO/ExecutableAtoms.h +++ b/lld/lib/ReaderWriter/MachO/ExecutableAtoms.h @@ -122,21 +122,28 @@ public: ArrayRef<uint8_t>(), DefinedAtom::Alignment(1))); } - const AtomVector<DefinedAtom> &defined() const override { + const AtomRange<DefinedAtom> defined() const override { return _definedAtoms; } - const AtomVector<UndefinedAtom> &undefined() const override { + const AtomRange<UndefinedAtom> undefined() const override { return _noUndefinedAtoms; } - const AtomVector<SharedLibraryAtom> &sharedLibrary() const override { + const AtomRange<SharedLibraryAtom> sharedLibrary() const override { return _noSharedLibraryAtoms; } - const AtomVector<AbsoluteAtom> &absolute() const override { + const AtomRange<AbsoluteAtom> absolute() const override { return _noAbsoluteAtoms; } + void clearAtoms() override { + _definedAtoms.clear(); + _noUndefinedAtoms.clear(); + _noSharedLibraryAtoms.clear(); + _noAbsoluteAtoms.clear(); + } + private: mutable AtomVector<DefinedAtom> _definedAtoms; diff --git a/lld/lib/ReaderWriter/MachO/File.h b/lld/lib/ReaderWriter/MachO/File.h index a0d20ea540f..f7262bbfaef 100644 --- a/lld/lib/ReaderWriter/MachO/File.h +++ b/lld/lib/ReaderWriter/MachO/File.h @@ -275,7 +275,8 @@ public: MachODylibFile(StringRef path) : SharedLibraryFile(path) {} - const SharedLibraryAtom *exports(StringRef name, bool isData) const override { + OwningAtomPtr<SharedLibraryAtom> exports(StringRef name, + bool isData) const override { // Pass down _installName so that if this requested symbol // is re-exported through this dylib, the SharedLibraryAtom's loadName() // is this dylib installName and not the implementation dylib's. @@ -328,25 +329,30 @@ public: } private: - const SharedLibraryAtom *exports(StringRef name, + OwningAtomPtr<SharedLibraryAtom> exports(StringRef name, StringRef installName) const { // First, check if requested symbol is directly implemented by this dylib. auto entry = _nameToAtom.find(name); if (entry != _nameToAtom.end()) { - if (!entry->second.atom) { - // Lazily create SharedLibraryAtom. - entry->second.atom = - new (allocator()) MachOSharedLibraryAtom(*this, name, installName, - entry->second.weakDef); - } - return entry->second.atom; + // FIXME: Make this map a set and only used in assert builds. + // Note, its safe to assert here as the resolver is the only client of + // this API and it only requests exports for undefined symbols. + // If we return from here we are no longer undefined so we should never + // get here again. + assert(!entry->second.atom && "Duplicate shared library export"); + bool weakDef = entry->second.weakDef; + auto *atom = new (allocator()) MachOSharedLibraryAtom(*this, name, + installName, + weakDef); + entry->second.atom = atom; + return atom; } // Next, check if symbol is implemented in some re-exported dylib. for (const ReExportedDylib &dylib : _reExportedDylibs) { assert(dylib.file); auto atom = dylib.file->exports(name, installName); - if (atom) + if (atom.get()) return atom; } diff --git a/lld/lib/ReaderWriter/MachO/FlatNamespaceFile.h b/lld/lib/ReaderWriter/MachO/FlatNamespaceFile.h index 6c6a9262ba2..08b28f43a15 100644 --- a/lld/lib/ReaderWriter/MachO/FlatNamespaceFile.h +++ b/lld/lib/ReaderWriter/MachO/FlatNamespaceFile.h @@ -25,34 +25,35 @@ public: FlatNamespaceFile(const MachOLinkingContext &context) : SharedLibraryFile("flat namespace") { } - const SharedLibraryAtom *exports(StringRef name, + OwningAtomPtr<SharedLibraryAtom> exports(StringRef name, bool dataSymbolOnly) const override { - _sharedLibraryAtoms.push_back( - new (allocator()) MachOSharedLibraryAtom(*this, name, getDSOName(), - false)); - - return _sharedLibraryAtoms.back(); + return new (allocator()) MachOSharedLibraryAtom(*this, name, getDSOName(), + false); } StringRef getDSOName() const override { return "flat-namespace"; } - const AtomVector<DefinedAtom> &defined() const override { + const AtomRange<DefinedAtom> defined() const override { return _noDefinedAtoms; } - const AtomVector<UndefinedAtom> &undefined() const override { + const AtomRange<UndefinedAtom> undefined() const override { return _noUndefinedAtoms; } - const AtomVector<SharedLibraryAtom> &sharedLibrary() const override { - return _sharedLibraryAtoms; + const AtomRange<SharedLibraryAtom> sharedLibrary() const override { + return _noSharedLibraryAtoms; } - const AtomVector<AbsoluteAtom> &absolute() const override { + const AtomRange<AbsoluteAtom> absolute() const override { return _noAbsoluteAtoms; } -private: - mutable AtomVector<SharedLibraryAtom> _sharedLibraryAtoms; + void clearAtoms() override { + _noDefinedAtoms.clear(); + _noUndefinedAtoms.clear(); + _noSharedLibraryAtoms.clear(); + _noAbsoluteAtoms.clear(); + } }; } // namespace mach_o diff --git a/lld/lib/ReaderWriter/MachO/GOTPass.cpp b/lld/lib/ReaderWriter/MachO/GOTPass.cpp index eac48644f6b..400dbf7de9d 100644 --- a/lld/lib/ReaderWriter/MachO/GOTPass.cpp +++ b/lld/lib/ReaderWriter/MachO/GOTPass.cpp @@ -54,6 +54,8 @@ public: GOTEntryAtom(const File &file, bool is64, StringRef name) : SimpleDefinedAtom(file), _is64(is64), _name(name) { } + ~GOTEntryAtom() override = default; + ContentType contentType() const override { return DefinedAtom::typeGOT; } diff --git a/lld/lib/ReaderWriter/MachO/LayoutPass.cpp b/lld/lib/ReaderWriter/MachO/LayoutPass.cpp index e64002e4bf7..811f74a4325 100644 --- a/lld/lib/ReaderWriter/MachO/LayoutPass.cpp +++ b/lld/lib/ReaderWriter/MachO/LayoutPass.cpp @@ -146,7 +146,7 @@ static void printDefinedAtoms(const SimpleFile::DefinedAtomRange &atomRange) { /// Verify that the followon chain is sane. Should not be called in /// release binary. -void LayoutPass::checkFollowonChain(SimpleFile::DefinedAtomRange &range) { +void LayoutPass::checkFollowonChain(const SimpleFile::DefinedAtomRange &range) { ScopedTask task(getDefaultDomain(), "LayoutPass::checkFollowonChain"); // Verify that there's no cycle in follow-on chain. @@ -176,8 +176,8 @@ static bool compareAtomsSub(const LayoutPass::SortKey &lc, const LayoutPass::SortKey &rc, LayoutPass::SortOverride customSorter, std::string &reason) { - const DefinedAtom *left = lc._atom; - const DefinedAtom *right = rc._atom; + const DefinedAtom *left = lc._atom.get(); + const DefinedAtom *right = rc._atom.get(); if (left == right) { reason = "same"; return false; @@ -252,8 +252,9 @@ static bool compareAtoms(const LayoutPass::SortKey &lc, bool result = compareAtomsSub(lc, rc, customSorter, reason); DEBUG({ StringRef comp = result ? "<" : ">="; - llvm::dbgs() << "Layout: '" << lc._atom->name() << "' " << comp << " '" - << rc._atom->name() << "' (" << reason << ")\n"; + llvm::dbgs() << "Layout: '" << lc._atom.get()->name() + << "' " << comp << " '" + << rc._atom.get()->name() << "' (" << reason << ")\n"; }); return result; } @@ -329,7 +330,7 @@ void LayoutPass::setChainRoot(const DefinedAtom *targetAtom, /// d) If the targetAtom is part of a different chain and the root of the /// targetAtom until the targetAtom has all atoms of size 0, then chain the /// targetAtoms and its tree to the current chain -void LayoutPass::buildFollowOnTable(SimpleFile::DefinedAtomRange &range) { +void LayoutPass::buildFollowOnTable(const SimpleFile::DefinedAtomRange &range) { ScopedTask task(getDefaultDomain(), "LayoutPass::buildFollowOnTable"); // Set the initial size of the followon and the followonNext hash to the // number of atoms that we have. @@ -397,7 +398,8 @@ void LayoutPass::buildFollowOnTable(SimpleFile::DefinedAtomRange &range) { /// assigning ordinals to each atom, if the atoms have their ordinals /// already assigned skip the atom and move to the next. This is the /// main map thats used to sort the atoms while comparing two atoms together -void LayoutPass::buildOrdinalOverrideMap(SimpleFile::DefinedAtomRange &range) { +void +LayoutPass::buildOrdinalOverrideMap(const SimpleFile::DefinedAtomRange &range) { ScopedTask task(getDefaultDomain(), "LayoutPass::buildOrdinalOverrideMap"); uint64_t index = 0; for (const DefinedAtom *ai : range) { @@ -419,12 +421,12 @@ void LayoutPass::buildOrdinalOverrideMap(SimpleFile::DefinedAtomRange &range) { std::vector<LayoutPass::SortKey> LayoutPass::decorate(SimpleFile::DefinedAtomRange &atomRange) const { std::vector<SortKey> ret; - for (const DefinedAtom *atom : atomRange) { - auto ri = _followOnRoots.find(atom); - auto oi = _ordinalOverrideMap.find(atom); - const DefinedAtom *root = (ri == _followOnRoots.end()) ? atom : ri->second; + for (OwningAtomPtr<DefinedAtom> &atom : atomRange.owning_ptrs()) { + auto ri = _followOnRoots.find(atom.get()); + auto oi = _ordinalOverrideMap.find(atom.get()); + const auto *root = (ri == _followOnRoots.end()) ? atom.get() : ri->second; uint64_t override = (oi == _ordinalOverrideMap.end()) ? 0 : oi->second; - ret.push_back(SortKey(atom, root, override)); + ret.push_back(SortKey(std::move(atom), root, override)); } return ret; } @@ -433,7 +435,7 @@ void LayoutPass::undecorate(SimpleFile::DefinedAtomRange &atomRange, std::vector<SortKey> &keys) const { size_t i = 0; for (SortKey &k : keys) - atomRange[i++] = k._atom; + atomRange[i++] = std::move(k._atom); } /// Perform the actual pass diff --git a/lld/lib/ReaderWriter/MachO/LayoutPass.h b/lld/lib/ReaderWriter/MachO/LayoutPass.h index d6072b0ca4f..d254891a789 100644 --- a/lld/lib/ReaderWriter/MachO/LayoutPass.h +++ b/lld/lib/ReaderWriter/MachO/LayoutPass.h @@ -33,9 +33,10 @@ namespace mach_o { class LayoutPass : public Pass { public: struct SortKey { - SortKey(const DefinedAtom *atom, const DefinedAtom *root, uint64_t override) - : _atom(atom), _root(root), _override(override) {} - const DefinedAtom *_atom; + SortKey(OwningAtomPtr<DefinedAtom> &&atom, + const DefinedAtom *root, uint64_t override) + : _atom(std::move(atom)), _root(root), _override(override) {} + OwningAtomPtr<DefinedAtom> _atom; const DefinedAtom *_root; uint64_t _override; }; @@ -53,10 +54,10 @@ public: private: // Build the followOn atoms chain as specified by the kindLayoutAfter // reference type - void buildFollowOnTable(SimpleFile::DefinedAtomRange &range); + void buildFollowOnTable(const SimpleFile::DefinedAtomRange &range); // Build a map of Atoms to ordinals for sorting the atoms - void buildOrdinalOverrideMap(SimpleFile::DefinedAtomRange &range); + void buildOrdinalOverrideMap(const SimpleFile::DefinedAtomRange &range); const Registry &_registry; SortOverride _customSorter; @@ -85,11 +86,12 @@ private: void setChainRoot(const DefinedAtom *targetAtom, const DefinedAtom *root); std::vector<SortKey> decorate(SimpleFile::DefinedAtomRange &atomRange) const; + void undecorate(SimpleFile::DefinedAtomRange &atomRange, std::vector<SortKey> &keys) const; // Check if the follow-on graph is a correct structure. For debugging only. - void checkFollowonChain(SimpleFile::DefinedAtomRange &range); + void checkFollowonChain(const SimpleFile::DefinedAtomRange &range); }; } // namespace mach_o diff --git a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp index 1cc87f0fac4..4431f347b27 100644 --- a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp +++ b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp @@ -171,7 +171,19 @@ bool MachOLinkingContext::sliceFromFatFile(MemoryBufferRef mb, uint32_t &offset, MachOLinkingContext::MachOLinkingContext() {} -MachOLinkingContext::~MachOLinkingContext() {} +MachOLinkingContext::~MachOLinkingContext() { + // Atoms are allocated on BumpPtrAllocator's on File's. + // As we transfer atoms from one file to another, we need to clear all of the + // atoms before we remove any of the BumpPtrAllocator's. + auto &nodes = getNodes(); + for (unsigned i = 0, e = nodes.size(); i != e; ++i) { + FileNode *node = dyn_cast<FileNode>(nodes[i].get()); + if (!node) + continue; + File *file = node->getFile(); + file->clearAtoms(); + } +} void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os, uint32_t minOSVersion, diff --git a/lld/lib/ReaderWriter/MachO/ObjCPass.cpp b/lld/lib/ReaderWriter/MachO/ObjCPass.cpp index 13fa9888cec..f8c7310d4ae 100644 --- a/lld/lib/ReaderWriter/MachO/ObjCPass.cpp +++ b/lld/lib/ReaderWriter/MachO/ObjCPass.cpp @@ -56,6 +56,8 @@ public: Data.info.flags |= (swiftVersion << 8); } + ~ObjCImageInfoAtom() override = default; + ContentType contentType() const override { return DefinedAtom::typeObjCImageInfo; } diff --git a/lld/lib/ReaderWriter/MachO/SectCreateFile.h b/lld/lib/ReaderWriter/MachO/SectCreateFile.h index 5236071e0e0..49e65f63151 100644 --- a/lld/lib/ReaderWriter/MachO/SectCreateFile.h +++ b/lld/lib/ReaderWriter/MachO/SectCreateFile.h @@ -31,6 +31,8 @@ public: _combinedName((segName + "/" + sectName).str()), _content(std::move(content)) {} + ~SectCreateAtom() override = default; + uint64_t size() const override { return _content->getBufferSize(); } Scope scope() const override { return scopeGlobal; } @@ -67,22 +69,29 @@ public: new (allocator()) SectCreateAtom(*this, seg, sect, std::move(content))); } - const AtomVector<DefinedAtom> &defined() const override { + const AtomRange<DefinedAtom> defined() const override { return _definedAtoms; } - const AtomVector<UndefinedAtom> &undefined() const override { + const AtomRange<UndefinedAtom> undefined() const override { return _noUndefinedAtoms; } - const AtomVector<SharedLibraryAtom> &sharedLibrary() const override { + const AtomRange<SharedLibraryAtom> sharedLibrary() const override { return _noSharedLibraryAtoms; } - const AtomVector<AbsoluteAtom> &absolute() const override { + const AtomRange<AbsoluteAtom> absolute() const override { return _noAbsoluteAtoms; } + void clearAtoms() override { + _definedAtoms.clear(); + _noUndefinedAtoms.clear(); + _noSharedLibraryAtoms.clear(); + _noAbsoluteAtoms.clear(); + } + private: AtomVector<DefinedAtom> _definedAtoms; }; diff --git a/lld/lib/ReaderWriter/MachO/StubsPass.cpp b/lld/lib/ReaderWriter/MachO/StubsPass.cpp index e69d6698cb6..2539c26c4ea 100644 --- a/lld/lib/ReaderWriter/MachO/StubsPass.cpp +++ b/lld/lib/ReaderWriter/MachO/StubsPass.cpp @@ -37,6 +37,8 @@ public: LazyPointerAtom(const File &file, bool is64) : SimpleDefinedAtom(file), _is64(is64) { } + ~LazyPointerAtom() override = default; + ContentType contentType() const override { return DefinedAtom::typeLazyPointer; } @@ -71,6 +73,8 @@ public: NonLazyPointerAtom(const File &file, bool is64, ContentType contentType) : SimpleDefinedAtom(file), _is64(is64), _contentType(contentType) { } + ~NonLazyPointerAtom() override = default; + ContentType contentType() const override { return _contentType; } @@ -106,6 +110,8 @@ public: StubAtom(const File &file, const ArchHandler::StubInfo &stubInfo) : SimpleDefinedAtom(file), _stubInfo(stubInfo){ } + ~StubAtom() override = default; + ContentType contentType() const override { return DefinedAtom::typeStub; } @@ -138,6 +144,8 @@ public: StubHelperAtom(const File &file, const ArchHandler::StubInfo &stubInfo) : SimpleDefinedAtom(file), _stubInfo(stubInfo) { } + ~StubHelperAtom() override = default; + ContentType contentType() const override { return DefinedAtom::typeStubHelper; } @@ -171,6 +179,8 @@ public: StubHelperCommonAtom(const File &file, const ArchHandler::StubInfo &stubInfo) : SimpleDefinedAtom(file), _stubInfo(stubInfo) { } + ~StubHelperCommonAtom() override = default; + ContentType contentType() const override { return DefinedAtom::typeStubHelper; } diff --git a/lld/lib/ReaderWriter/MachO/TLVPass.cpp b/lld/lib/ReaderWriter/MachO/TLVPass.cpp index b12f006d7a1..41aa223d3c5 100644 --- a/lld/lib/ReaderWriter/MachO/TLVPass.cpp +++ b/lld/lib/ReaderWriter/MachO/TLVPass.cpp @@ -30,6 +30,8 @@ public: TLVPEntryAtom(const File &file, bool is64, StringRef name) : SimpleDefinedAtom(file), _is64(is64), _name(name) {} + ~TLVPEntryAtom() override = default; + ContentType contentType() const override { return DefinedAtom::typeTLVInitializerPtr; } |