summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/MachO
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib/ReaderWriter/MachO')
-rw-r--r--lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp4
-rw-r--r--lld/lib/ReaderWriter/MachO/Atoms.h6
-rw-r--r--lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp2
-rw-r--r--lld/lib/ReaderWriter/MachO/ExecutableAtoms.h15
-rw-r--r--lld/lib/ReaderWriter/MachO/File.h26
-rw-r--r--lld/lib/ReaderWriter/MachO/FlatNamespaceFile.h27
-rw-r--r--lld/lib/ReaderWriter/MachO/GOTPass.cpp2
-rw-r--r--lld/lib/ReaderWriter/MachO/LayoutPass.cpp28
-rw-r--r--lld/lib/ReaderWriter/MachO/LayoutPass.h14
-rw-r--r--lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp14
-rw-r--r--lld/lib/ReaderWriter/MachO/ObjCPass.cpp2
-rw-r--r--lld/lib/ReaderWriter/MachO/SectCreateFile.h17
-rw-r--r--lld/lib/ReaderWriter/MachO/StubsPass.cpp10
-rw-r--r--lld/lib/ReaderWriter/MachO/TLVPass.cpp2
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;
}
OpenPOWER on IntegriCloud