[lld] r209700 - [mach-o] Add support for initializers and terminators in object files

Nick Kledzik kledzik at apple.com
Tue May 27 16:20:53 PDT 2014


Author: kledzik
Date: Tue May 27 18:20:52 2014
New Revision: 209700

URL: http://llvm.org/viewvc/llvm-project?rev=209700&view=rev
Log:
[mach-o] Add support for initializers and terminators in object files

Added:
    lld/trunk/test/mach-o/parse-initializers32.yaml
    lld/trunk/test/mach-o/parse-initializers64.yaml
Modified:
    lld/trunk/lib/ReaderWriter/MachO/Atoms.h
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp

Modified: lld/trunk/lib/ReaderWriter/MachO/Atoms.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/Atoms.h?rev=209700&r1=209699&r2=209700&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/Atoms.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/Atoms.h Tue May 27 18:20:52 2014
@@ -36,6 +36,14 @@ public:
 
   Scope scope() const override { return _scope; }
 
+  DeadStripKind deadStrip() const override {
+    if (_contentType == DefinedAtom::typeInitializerPtr)
+      return deadStripNever;
+    if (_contentType == DefinedAtom::typeTerminatorPtr)
+      return deadStripNever;
+    return deadStripNormal;
+  }
+
   ArrayRef<uint8_t> rawContent() const override {
     // Zerofill atoms have a content pointer which is null.
     assert(_content.data() != nullptr);

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=209700&r1=209699&r2=209700&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Tue May 27 18:20:52 2014
@@ -179,6 +179,12 @@ SectionInfo *Util::makeSection(DefinedAt
   case DefinedAtom::typeZeroFill:
      return new (_allocator) SectionInfo("__DATA", "__bss",
                             S_ZEROFILL);
+  case DefinedAtom::typeInitializerPtr:
+     return new (_allocator) SectionInfo("__DATA", "__mod_init_func",
+                            S_MOD_INIT_FUNC_POINTERS);
+  case DefinedAtom::typeTerminatorPtr:
+     return new (_allocator) SectionInfo("__DATA", "__mod_term_func",
+                            S_MOD_TERM_FUNC_POINTERS);
   case DefinedAtom::typeLiteral4:
      return new (_allocator) SectionInfo("__TEXT", "__literal4",
                             S_4BYTE_LITERALS);

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp?rev=209700&r1=209699&r2=209700&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp Tue May 27 18:20:52 2014
@@ -109,8 +109,9 @@ static void processUndefindeSymbol(MachO
 }
 
 static error_code processSection(MachOFile &file, const Section &section,
-                                 bool copyRefs) {
+                                 bool is64, bool copyRefs) {
   unsigned offset = 0;
+  const unsigned pointerSize = (is64 ? 8 : 4);
   switch (section.type) {
   case llvm::MachO::S_REGULAR:
     if (section.segmentName.equals("__TEXT") && 
@@ -142,6 +143,40 @@ static error_code processSection(MachOFi
   case llvm::MachO::S_ZEROFILL:
     // These sections are broken in to atoms based on symbols.
     break;
+  case S_MOD_INIT_FUNC_POINTERS:
+    if ((section.content.size() % pointerSize) != 0) {
+      return make_dynamic_error_code(Twine("Section ") + section.segmentName
+                                     + "/" + section.sectionName
+                                     + " has type S_MOD_INIT_FUNC_POINTERS but "
+                                     "its size ("
+                                     + Twine(section.content.size())
+                                     + ") is not a multiple of "
+                                     + Twine(pointerSize));
+    }
+    for (size_t i = 0, e = section.content.size(); i != e; i += pointerSize) {
+      ArrayRef<uint8_t> bytes = section.content.slice(offset, pointerSize);
+      file.addDefinedAtom(StringRef(), DefinedAtom::scopeTranslationUnit,
+                          DefinedAtom::typeInitializerPtr, bytes, copyRefs);
+      offset += pointerSize;
+    }
+    break;
+  case S_MOD_TERM_FUNC_POINTERS:
+    if ((section.content.size() % pointerSize) != 0) {
+      return make_dynamic_error_code(Twine("Section ") + section.segmentName
+                                     + "/" + section.sectionName
+                                     + " has type S_MOD_TERM_FUNC_POINTERS but "
+                                     "its size ("
+                                     + Twine(section.content.size())
+                                     + ") is not a multiple of "
+                                     + Twine(pointerSize));
+    }
+    for (size_t i = 0, e = section.content.size(); i != e; i += pointerSize) {
+      ArrayRef<uint8_t> bytes = section.content.slice(offset, pointerSize);
+      file.addDefinedAtom(StringRef(), DefinedAtom::scopeTranslationUnit,
+                          DefinedAtom::typeTerminatorPtr, bytes, copyRefs);
+      offset += pointerSize;
+    }
+    break;
   case llvm::MachO::S_CSTRING_LITERALS:
     for (size_t i = 0, e = section.content.size(); i != e; ++i) {
       if (section.content[i] == 0) {
@@ -227,8 +262,9 @@ normalizedObjectToAtoms(const Normalized
     processUndefindeSymbol(*file, sym, copyRefs);
   }
   // Create atoms from sections that don't have symbols.
+  bool is64 = MachOLinkingContext::is64Bit(normalizedFile.arch);
   for (auto &sect : normalizedFile.sections) {
-    if (error_code ec = processSection(*file, sect, copyRefs))
+    if (error_code ec = processSection(*file, sect, is64, copyRefs))
       return ec;
   }
 

Added: lld/trunk/test/mach-o/parse-initializers32.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/parse-initializers32.yaml?rev=209700&view=auto
==============================================================================
--- lld/trunk/test/mach-o/parse-initializers32.yaml (added)
+++ lld/trunk/test/mach-o/parse-initializers32.yaml Tue May 27 18:20:52 2014
@@ -0,0 +1,84 @@
+# RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t  | FileCheck %s
+#
+# Test parsing of literal sections.
+#
+
+--- !mach-o
+arch:            x86
+file-type:       MH_OBJECT
+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 ]
+    address:         0x0000000000000000
+    content:         [ 0x55, 0x89, 0xE5, 0x5D, 0xC3, 0x55, 0x89, 0xE5,
+                       0x5D, 0xC3, 0x55, 0x89, 0xE5, 0x5D, 0xC3 ]
+  - segment:         __DATA
+    section:         __mod_init_func
+    type:            S_MOD_INIT_FUNC_POINTERS
+    attributes:      [  ]
+    alignment:       2
+    address:         0x0000000000000044
+    content:         [ 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00 ]
+    relocations:
+      - offset:          0x00000000
+        type:            GENERIC_RELOC_VANILLA
+        length:          2
+        pc-rel:          false
+        extern:          false
+        symbol:          1
+      - offset:          0x00000004
+        type:            GENERIC_RELOC_VANILLA
+        length:          2
+        pc-rel:          false
+        extern:          false
+        symbol:          1
+  - segment:         __DATA
+    section:         __mod_term_func
+    type:            S_MOD_TERM_FUNC_POINTERS
+    attributes:      [  ]
+    alignment:       2
+    address:         0x0000000000000104
+    content:         [ 0x0A, 0x00, 0x00, 0x00 ]
+global-symbols:
+  - name:            _init
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000000
+  - name:            _init2
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000005
+  - name:            _term
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x000000000000000A
+...
+
+
+# CHECK:defined-atoms:
+# CHECK:  - type:            initializer-pointer
+# CHECK:    content:         [ 00, 00, 00, 00 ]
+# CHECK:    dead-strip:      never
+# CHECK:  - type:            initializer-pointer
+# CHECK:    content:         [ 05, 00, 00, 00 ]
+# CHECK:    dead-strip:      never
+# CHECK:  - type:            terminator-pointer
+# CHECK:    content:         [ 0A, 00, 00, 00 ]
+# CHECK:    dead-strip:      never
+# CHECK:  - name:            _init
+# CHECK:    scope:           global
+# CHECK:    content:         [ 55, 89, E5, 5D, C3 ]
+# CHECK:  - name:            _init2
+# CHECK:    scope:           global
+# CHECK:    content:         [ 55, 89, E5, 5D, C3 ]
+# CHECK:  - name:            _term
+# CHECK:    scope:           global
+# CHECK:    content:         [ 55, 89, E5, 5D, C3 ]

Added: lld/trunk/test/mach-o/parse-initializers64.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/parse-initializers64.yaml?rev=209700&view=auto
==============================================================================
--- lld/trunk/test/mach-o/parse-initializers64.yaml (added)
+++ lld/trunk/test/mach-o/parse-initializers64.yaml Tue May 27 18:20:52 2014
@@ -0,0 +1,93 @@
+# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t  | FileCheck %s
+#
+# Test parsing of literal sections.
+#
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_OBJECT
+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 ]
+    address:         0x0000000000000000
+    content:         [ 0x55, 0x48, 0x89, 0xE5, 0x5D, 0xC3, 0x55, 0x48,
+                       0x89, 0xE5, 0x5D, 0xC3, 0x55, 0x48, 0x89, 0xE5,
+                       0x5D, 0xC3 ]
+  - segment:         __DATA
+    section:         __mod_init_func
+    type:            S_MOD_INIT_FUNC_POINTERS
+    attributes:      [  ]
+    alignment:       0
+    address:         0x0000000000000100
+    content:         [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
+    relocations:
+      - offset:          0x00000000
+        type:            X86_64_RELOC_UNSIGNED
+        length:          3
+        pc-rel:          false
+        extern:          true
+        symbol:          1
+      - offset:          0x00000008
+        type:            X86_64_RELOC_UNSIGNED
+        length:          3
+        pc-rel:          false
+        extern:          true
+        symbol:          2
+  - segment:         __DATA
+    section:         __mod_term_func
+    type:            S_MOD_TERM_FUNC_POINTERS
+    attributes:      [  ]
+    alignment:       3
+    address:         0x0000000000000108
+    content:         [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
+    relocations:
+      - offset:          0x00000000
+        type:            X86_64_RELOC_UNSIGNED
+        length:          3
+        pc-rel:          false
+        extern:          true
+        symbol:          3
+global-symbols:
+  - name:            _init
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000000
+  - name:            _init2
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000006
+  - name:            _term
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x000000000000000C
+...
+
+
+# CHECK:defined-atoms:
+# CHECK:  - type:            initializer-pointer
+# CHECK:    content:         [ 00, 00, 00, 00, 00, 00, 00, 00 ]
+# CHECK:    dead-strip:      never
+# CHECK:  - type:            initializer-pointer
+# CHECK:    content:         [ 00, 00, 00, 00, 00, 00, 00, 00 ]
+# CHECK:    dead-strip:      never
+# CHECK:  - type:            terminator-pointer
+# CHECK:    content:         [ 00, 00, 00, 00, 00, 00, 00, 00 ]
+# CHECK:    dead-strip:      never
+# CHECK:  - name:            _init
+# CHECK:    scope:           global
+# CHECK:    content:         [ 55, 48, 89, E5, 5D, C3 ]
+# CHECK:  - name:            _init2
+# CHECK:    scope:           global
+# CHECK:    content:         [ 55, 48, 89, E5, 5D, C3 ]
+# CHECK:  - name:            _term
+# CHECK:    scope:           global
+# CHECK:    content:         [ 55, 48, 89, E5, 5D, C3 ]





More information about the llvm-commits mailing list