[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