summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2014-06-30 09:11:38 +0000
committerTim Northover <tnorthover@apple.com>2014-06-30 09:11:38 +0000
commitf9b13d67662e842aa087ffb79a8d917e048e5388 (patch)
tree96e7b9b563cc5d56ab611a227af916a3383b4e85 /lld/lib/ReaderWriter
parente686c1d7effe0de87401591ae655e5d9f078c062 (diff)
downloadbcm5719-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.h42
-rw-r--r--lld/lib/ReaderWriter/MachO/File.h56
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp3
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp16
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp2
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());
OpenPOWER on IntegriCloud