summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/MachO/File.h
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib/ReaderWriter/MachO/File.h')
-rw-r--r--lld/lib/ReaderWriter/MachO/File.h90
1 files changed, 70 insertions, 20 deletions
diff --git a/lld/lib/ReaderWriter/MachO/File.h b/lld/lib/ReaderWriter/MachO/File.h
index df9be71c18c..bc6a75a39f5 100644
--- a/lld/lib/ReaderWriter/MachO/File.h
+++ b/lld/lib/ReaderWriter/MachO/File.h
@@ -175,22 +175,16 @@ private:
class MachODylibFile : public SharedLibraryFile {
public:
- MachODylibFile(StringRef path) : SharedLibraryFile(path), _dylib_name(path) {}
-
- virtual const SharedLibraryAtom *exports(StringRef name,
- bool dataSymbolOnly) const {
- // FIXME: we obviously need to record code/data if we're going to make
- // proper use of dataSymbolOnly.
- auto sym = _nameToAtom.find(name);
-
- if (sym == _nameToAtom.end())
- return nullptr;
-
- if (!sym->second)
- sym->second =
- new (_allocator) MachOSharedLibraryAtom(*this, name, _dylib_name);
+ MachODylibFile(StringRef path, StringRef installName)
+ : SharedLibraryFile(path), _installName(installName) {
+ }
- return sym->second;
+ virtual const SharedLibraryAtom *exports(StringRef name, bool isData) const {
+ // Pass down _installName and _allocator 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.
+ // NOTE: isData is not needed for dylibs (it matters for static libs).
+ return exports(name, _installName, _allocator);
}
const atom_collection<DefinedAtom> &defined() const override {
@@ -209,22 +203,78 @@ public:
return _absoluteAtoms;
}
- void addSharedLibraryAtom(StringRef name, bool copyRefs) {
+ /// Adds symbol name that this dylib exports. The corresponding
+ /// SharedLibraryAtom is created lazily (since most symbols are not used).
+ void addExportedSymbol(StringRef name, bool weakDef, bool copyRefs) {
if (copyRefs) {
name = name.copy(_allocator);
}
+ AtomAndFlags info(weakDef);
+ _nameToAtom[name] = info;
+ }
- _nameToAtom[name] = nullptr;
+ void addReExportedDylib(StringRef dylibPath) {
+ _reExportedDylibs.emplace_back(dylibPath);
+ }
+
+ StringRef installName() { return _installName; }
+
+ typedef std::function<MachODylibFile *(StringRef)> FindDylib;
+
+ void loadReExportedDylibs(FindDylib find) {
+ for (ReExportedDylib &entry : _reExportedDylibs) {
+ entry.file = find(entry.path);
+ }
}
private:
- StringRef _dylib_name;
+ const SharedLibraryAtom *exports(StringRef name, StringRef installName,
+ llvm::BumpPtrAllocator &allocator) 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;
+ }
+
+ // 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, allocator);
+ if (atom)
+ return atom;
+ }
+
+ // Symbol not exported or re-exported by this dylib.
+ return nullptr;
+ }
+
+
+ struct ReExportedDylib {
+ ReExportedDylib(StringRef p) : path(p), file(nullptr) { }
+ StringRef path;
+ MachODylibFile *file;
+ };
+
+ struct AtomAndFlags {
+ AtomAndFlags() : atom(nullptr), weakDef(false) { }
+ AtomAndFlags(bool weak) : atom(nullptr), weakDef(weak) { }
+ const SharedLibraryAtom *atom;
+ bool weakDef;
+ };
+
+ StringRef _installName;
atom_collection_vector<DefinedAtom> _definedAtoms;
atom_collection_vector<UndefinedAtom> _undefinedAtoms;
atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
-
- mutable std::unordered_map<StringRef, SharedLibraryAtom *> _nameToAtom;
+ std::vector<ReExportedDylib> _reExportedDylibs;
+ mutable std::unordered_map<StringRef, AtomAndFlags> _nameToAtom;
mutable llvm::BumpPtrAllocator _allocator;
};
OpenPOWER on IntegriCloud