diff options
author | Tim Northover <tnorthover@apple.com> | 2014-06-30 09:11:38 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2014-06-30 09:11:38 +0000 |
commit | f9b13d67662e842aa087ffb79a8d917e048e5388 (patch) | |
tree | 96e7b9b563cc5d56ab611a227af916a3383b4e85 /lld/lib/ReaderWriter | |
parent | e686c1d7effe0de87401591ae655e5d9f078c062 (diff) | |
download | bcm5719-llvm-f9b13d67662e842aa087ffb79a8d917e048e5388.tar.gz bcm5719-llvm-f9b13d67662e842aa087ffb79a8d917e048e5388.zip |
MachO: support atomization of dylibs.
For .dylib files, we refrain from actually creating any atoms until they're
requested via the "exports" method.
llvm-svn: 212027
Diffstat (limited to 'lld/lib/ReaderWriter')
-rw-r--r-- | lld/lib/ReaderWriter/MachO/Atoms.h | 42 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/File.h | 56 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp | 3 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp | 16 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp | 2 |
5 files changed, 118 insertions, 1 deletions
diff --git a/lld/lib/ReaderWriter/MachO/Atoms.h b/lld/lib/ReaderWriter/MachO/Atoms.h index 9db091ea315..80cad2964e6 100644 --- a/lld/lib/ReaderWriter/MachO/Atoms.h +++ b/lld/lib/ReaderWriter/MachO/Atoms.h @@ -117,6 +117,48 @@ private: const DefinedAtom::Alignment _align; }; +class MachOSharedLibraryAtom : public SharedLibraryAtom { +public: + MachOSharedLibraryAtom(const File &file, StringRef name, + StringRef dylibInstallName) + : SharedLibraryAtom(), _file(file), _name(name), + _dylibInstallName(dylibInstallName) {} + virtual ~MachOSharedLibraryAtom() {} + + virtual StringRef loadName() const override { + return _dylibInstallName; + } + + virtual bool canBeNullAtRuntime() const override { + // FIXME: this may actually be changeable. For now, all symbols are strongly + // defined though. + return false; + } + + virtual const File& file() const override { + return _file; + } + + virtual StringRef name() const override { + return _name; + } + + virtual Type type() const override { + // Unused in MachO (I think). + return Type::Unknown; + } + + virtual uint64_t size() const override { + // Unused in MachO (I think) + return 0; + } + +private: + const File &_file; + StringRef _name; + StringRef _dylibInstallName; +}; + } // mach_o } // lld diff --git a/lld/lib/ReaderWriter/MachO/File.h b/lld/lib/ReaderWriter/MachO/File.h index 0101350cdaf..d50e3ff0a61 100644 --- a/lld/lib/ReaderWriter/MachO/File.h +++ b/lld/lib/ReaderWriter/MachO/File.h @@ -15,6 +15,9 @@ #include "Atoms.h" #include "lld/Core/Simple.h" +#include "lld/Core/SharedLibraryFile.h" + +#include <unordered_map> namespace lld { namespace mach_o { @@ -156,7 +159,60 @@ private: NameToAtom _undefAtoms; }; +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); + + return sym->second; + } + + const atom_collection<DefinedAtom> &defined() const override { + return _definedAtoms; + } + + const atom_collection<UndefinedAtom> &undefined() const override { + return _undefinedAtoms; + } + + const atom_collection<SharedLibraryAtom> &sharedLibrary() const override { + return _sharedLibraryAtoms; + } + + const atom_collection<AbsoluteAtom> &absolute() const override { + return _absoluteAtoms; + } + + void addSharedLibraryAtom(StringRef name, bool copyRefs) { + if (copyRefs) { + name = name.copy(_allocator); + } + + _nameToAtom[name] = nullptr; + } +private: + StringRef _dylib_name; + 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; + mutable llvm::BumpPtrAllocator _allocator; +}; } // end namespace mach_o } // end namespace lld diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp index a328ec46a2d..09ff83b27c4 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp @@ -392,7 +392,8 @@ public: bool canParse(file_magic magic, StringRef ext, const MemoryBuffer &mb) const override { - if (magic != llvm::sys::fs::file_magic::macho_object) + if (magic != llvm::sys::fs::file_magic::macho_object && + magic != llvm::sys::fs::file_magic::macho_dynamically_linked_shared_lib) return false; if (mb.getBufferSize() < 32) return false; diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp index 61d68fa9575..56c5f44829e 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp @@ -195,6 +195,7 @@ Atom::Scope atomScope(uint8_t scope) { switch (scope) { case N_EXT: return Atom::scopeGlobal; + case N_PEXT: case N_PEXT | N_EXT: return Atom::scopeLinkageUnit; case 0: @@ -602,6 +603,19 @@ normalizedObjectToAtoms(const NormalizedFile &normalizedFile, StringRef path, return std::unique_ptr<File>(std::move(file)); } +ErrorOr<std::unique_ptr<lld::File>> +normalizedDylibToAtoms(const NormalizedFile &normalizedFile, StringRef path, + bool copyRefs) { + std::unique_ptr<MachODylibFile> file(new MachODylibFile(path)); + + for (auto &sym : normalizedFile.globalSymbols) { + assert((sym.scope & N_EXT) && "only expect external symbols here"); + file->addSharedLibraryAtom(sym.name, copyRefs); + } + + return std::unique_ptr<File>(std::move(file)); +} + } // anonymous namespace namespace normalized { @@ -634,6 +648,8 @@ ErrorOr<std::unique_ptr<lld::File>> normalizedToAtoms(const NormalizedFile &normalizedFile, StringRef path, bool copyRefs) { switch (normalizedFile.fileType) { + case MH_DYLIB: + return normalizedDylibToAtoms(normalizedFile, path, copyRefs); case MH_OBJECT: return normalizedObjectToAtoms(normalizedFile, path, copyRefs); default: diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp index 69a144112dd..65f18d23b65 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp @@ -651,6 +651,8 @@ bool MachOYamlIOTaggedDocumentHandler::handledDocTag(llvm::yaml::IO &io, // Step 2: parse normalized mach-o struct into atoms. ErrorOr<std::unique_ptr<lld::File>> foe = normalizedToAtoms(nf, info->_path, true); + + info->_normalizeMachOFile = nullptr; if (foe) { // Transfer ownership to "out" File parameter. std::unique_ptr<lld::File> f = std::move(foe.get()); |