[lld] r212027 - MachO: support atomization of dylibs.
Tim Northover
tnorthover at apple.com
Mon Jun 30 02:11:39 PDT 2014
Author: tnorthover
Date: Mon Jun 30 04:11:38 2014
New Revision: 212027
URL: http://llvm.org/viewvc/llvm-project?rev=212027&view=rev
Log:
MachO: support atomization of dylibs.
For .dylib files, we refrain from actually creating any atoms until they're
requested via the "exports" method.
Added:
lld/trunk/test/mach-o/use-simple-dylib.yaml
Modified:
lld/trunk/lib/ReaderWriter/MachO/Atoms.h
lld/trunk/lib/ReaderWriter/MachO/File.h
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
Modified: lld/trunk/lib/ReaderWriter/MachO/Atoms.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/Atoms.h?rev=212027&r1=212026&r2=212027&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/Atoms.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/Atoms.h Mon Jun 30 04:11:38 2014
@@ -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
Modified: lld/trunk/lib/ReaderWriter/MachO/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/File.h?rev=212027&r1=212026&r2=212027&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/File.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/File.h Mon Jun 30 04:11:38 2014
@@ -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
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp?rev=212027&r1=212026&r2=212027&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp Mon Jun 30 04:11:38 2014
@@ -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;
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp?rev=212027&r1=212026&r2=212027&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp Mon Jun 30 04:11:38 2014
@@ -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 Normalized
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:
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp?rev=212027&r1=212026&r2=212027&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp Mon Jun 30 04:11:38 2014
@@ -651,6 +651,8 @@ bool MachOYamlIOTaggedDocumentHandler::h
// 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());
Added: lld/trunk/test/mach-o/use-simple-dylib.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/use-simple-dylib.yaml?rev=212027&view=auto
==============================================================================
--- lld/trunk/test/mach-o/use-simple-dylib.yaml (added)
+++ lld/trunk/test/mach-o/use-simple-dylib.yaml Mon Jun 30 04:11:38 2014
@@ -0,0 +1,129 @@
+# RUN: lld -flavor darwin -arch x86_64 -print_atoms -r %s | FileCheck %s
+# lld -flavor darwin -arch x86_64 -print_atoms -r %s %p/Inputs/simple-dylib.yaml -o - | FileCheck %s
+
+--- !mach-o
+arch: x86_64
+file-type: MH_OBJECT
+flags: [ ]
+has-UUID: false
+OS: unknown
+sections:
+ - segment: __TEXT
+ section: __text
+ type: S_REGULAR
+ attributes: [ S_ATTR_PURE_INSTRUCTIONS ]
+ address: 0x0000000000000000
+ content: [ 0x55, 0x48, 0x89, 0xE5, 0xE8, 0x00, 0x00, 0x00,
+ 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x00,
+ 0x00, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00,
+ 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xE9, 0x00,
+ 0x00, 0x00, 0x00 ]
+global-symbols:
+ - name: _foo
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ value: 0x0000000000000000
+undefined-symbols:
+ - name: _myGlobal
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+ - name: _myGlobalWeak
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+ - name: _myHidden
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+ - name: _myHiddenWeak
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+ - name: _myResolver
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+ - name: _myStatic
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+ - name: _myVariablePreviouslyKnownAsPrivateExtern
+ type: N_UNDF
+ scope: [ N_EXT ]
+ value: 0x0000000000000000
+
+--- !mach-o
+arch: x86_64
+file-type: MH_DYLIB
+flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+has-UUID: false
+OS: unknown
+sections:
+ - segment: __TEXT
+ section: __text
+ type: S_REGULAR
+ attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+ alignment: 4
+ address: 0x0000000000000000
+ content: [ 0xCC, 0xC3, 0x90, 0xC3, 0x90, 0x90, 0xC3, 0x90,
+ 0x90, 0x90, 0xC3, 0x90, 0x90, 0x90, 0x90, 0xC3,
+ 0x31, 0xC0, 0xC3 ]
+local-symbols:
+ - name: _myStatic
+ type: N_SECT
+ sect: 1
+ value: 0x000000000000000B
+ - name: _myVariablePreviouslyKnownAsPrivateExtern
+ type: N_SECT
+ scope: [ N_PEXT ]
+ sect: 1
+ desc: [ N_SYMBOL_RESOLVER ]
+ value: 0x0000000000000011
+global-symbols:
+ - name: _myGlobal
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ value: 0x0000000000000001
+ - name: _myGlobalWeak
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ desc: [ N_WEAK_DEF ]
+ value: 0x0000000000000002
+ - name: _myHidden
+ type: N_SECT
+ scope: [ N_EXT, N_PEXT ]
+ sect: 1
+ value: 0x0000000000000004
+ - name: _myHiddenWeak
+ type: N_SECT
+ scope: [ N_EXT, N_PEXT ]
+ sect: 1
+ desc: [ N_WEAK_DEF ]
+ value: 0x0000000000000007
+ - name: _myResolver
+ type: N_SECT
+ scope: [ N_EXT ]
+ sect: 1
+ desc: [ N_SYMBOL_RESOLVER ]
+ value: 0x0000000000000010
+...
+
+
+# CHECK: undefined-atoms:
+# CHECK: - name: _myStatic
+# CHECK: - name: _myVariablePreviouslyKnownAsPrivateExtern
+# CHECK: shared-library-atoms:
+# CHECK: - name: _myHidden
+# CHECK: load-name: {{.*}}use-simple-dylib.yaml
+# CHECK: - name: _myGlobal
+# CHECK: load-name: {{.*}}use-simple-dylib.yaml
+# CHECK: - name: _myHiddenWeak
+# CHECK: load-name: {{.*}}use-simple-dylib.yaml
+# CHECK: - name: _myGlobalWeak
+# CHECK: load-name: {{.*}}use-simple-dylib.yaml
+# CHECK: - name: _myResolver
+# CHECK: load-name: {{.*}}use-simple-dylib.yaml
More information about the llvm-commits
mailing list