[lld] r216234 - [mach-o] support N_NO_DEAD_STRIP nlist.desc bit

Nick Kledzik kledzik at apple.com
Thu Aug 21 15:18:30 PDT 2014


Author: kledzik
Date: Thu Aug 21 17:18:30 2014
New Revision: 216234

URL: http://llvm.org/viewvc/llvm-project?rev=216234&view=rev
Log:
[mach-o] support N_NO_DEAD_STRIP nlist.desc bit

Mach-O symbols can have an attribute on them means their content should never be
dead code stripped.  This translates to deadStrip() == deadStripNever.

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

Modified: lld/trunk/lib/ReaderWriter/MachO/Atoms.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/Atoms.h?rev=216234&r1=216233&r2=216234&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/Atoms.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/Atoms.h Thu Aug 21 17:18:30 2014
@@ -17,18 +17,20 @@ namespace mach_o {
 class MachODefinedAtom : public SimpleDefinedAtom {
 public:
   MachODefinedAtom(const File &f, const StringRef name, Scope scope,
-                   ContentType type, Merge merge, bool thumb,
+                   ContentType type, Merge merge, bool thumb, bool noDeadStrip,
                    const ArrayRef<uint8_t> content)
       : SimpleDefinedAtom(f), _name(name), _content(content),
-        _contentType(type), _scope(scope), _merge(merge), _thumb(thumb) {}
+        _contentType(type), _scope(scope), _merge(merge), _thumb(thumb),
+        _noDeadStrip(noDeadStrip) {}
 
   // Constructor for zero-fill content
   MachODefinedAtom(const File &f, const StringRef name, Scope scope,
-                   uint64_t size)
+                   uint64_t size, bool noDeadStrip)
       : SimpleDefinedAtom(f), _name(name),
         _content(ArrayRef<uint8_t>(nullptr, size)),
         _contentType(DefinedAtom::typeZeroFill),
-        _scope(scope), _merge(mergeNo), _thumb(false) {}
+        _scope(scope), _merge(mergeNo), _thumb(false),
+        _noDeadStrip(noDeadStrip) {}
 
   uint64_t size() const override { return _content.size(); }
 
@@ -45,6 +47,8 @@ public:
       return deadStripNever;
     if (_contentType == DefinedAtom::typeTerminatorPtr)
       return deadStripNever;
+    if (_noDeadStrip)
+      return deadStripNever;
     return deadStripNormal;
   }
 
@@ -55,13 +59,15 @@ public:
 
   bool isThumb() const { return _thumb; }
 
-  void addReference(uint32_t offsetInAtom, uint16_t relocType, 
-               const Atom *target, Reference::Addend addend, 
-               Reference::KindArch arch = Reference::KindArch::x86_64,
-               Reference::KindNamespace ns = Reference::KindNamespace::mach_o) {
-    SimpleDefinedAtom::addReference(ns, arch, relocType, offsetInAtom, target, addend);
+  void addReference(uint32_t offsetInAtom, uint16_t relocType,
+                    const Atom *target, Reference::Addend addend,
+                    Reference::KindArch arch = Reference::KindArch::x86_64,
+                    Reference::KindNamespace ns
+                     = Reference::KindNamespace::mach_o) {
+    SimpleDefinedAtom::addReference(ns, arch, relocType, offsetInAtom, target,
+                                    addend);
   }
-  
+
 private:
   const StringRef _name;
   const ArrayRef<uint8_t> _content;
@@ -69,25 +75,28 @@ private:
   const Scope _scope;
   const Merge _merge;
   const bool _thumb;
+  const bool _noDeadStrip;
 };
 
 class MachODefinedCustomSectionAtom : public MachODefinedAtom {
 public:
-  MachODefinedCustomSectionAtom(const File &f, const StringRef name, 
+  MachODefinedCustomSectionAtom(const File &f, const StringRef name,
                                 Scope scope, ContentType type, Merge merge,
-                                bool thumb, const ArrayRef<uint8_t> content,
+                                bool thumb, bool noDeadStrip,
+                                const ArrayRef<uint8_t> content,
                                 StringRef sectionName)
-      : MachODefinedAtom(f, name, scope, type, merge, thumb, content), 
+      : MachODefinedAtom(f, name, scope, type, merge, thumb, noDeadStrip,
+                         content),
         _sectionName(sectionName) {}
 
   SectionChoice sectionChoice() const override {
     return DefinedAtom::sectionCustomRequired;
   }
-  
+
   StringRef customSectionName() const override {
     return _sectionName;
   }
-private:  
+private:
   StringRef _sectionName;
 };
 

Modified: lld/trunk/lib/ReaderWriter/MachO/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/File.h?rev=216234&r1=216233&r2=216234&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/File.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/File.h Thu Aug 21 17:18:30 2014
@@ -32,9 +32,10 @@ public:
   void addDefinedAtom(StringRef name, Atom::Scope scope,
                       DefinedAtom::ContentType type, DefinedAtom::Merge merge,
                       uint64_t sectionOffset, uint64_t contentSize, bool thumb,
-                      bool copyRefs, const Section *inSection) {
+                      bool noDeadStrip, bool copyRefs,
+                      const Section *inSection) {
     assert(sectionOffset+contentSize <= inSection->content.size());
-    ArrayRef<uint8_t> content = inSection->content.slice(sectionOffset, 
+    ArrayRef<uint8_t> content = inSection->content.slice(sectionOffset,
                                                         contentSize);
     if (copyRefs) {
       // Make a copy of the atom's name and content that is owned by this file.
@@ -42,18 +43,18 @@ public:
       content = content.copy(_allocator);
     }
     MachODefinedAtom *atom =
-        new (_allocator) MachODefinedAtom(*this, name, scope, type, merge, 
-                                          thumb, content);
+        new (_allocator) MachODefinedAtom(*this, name, scope, type, merge,
+                                          thumb, noDeadStrip, content);
     addAtomForSection(inSection, atom, sectionOffset);
   }
 
   void addDefinedAtomInCustomSection(StringRef name, Atom::Scope scope,
                       DefinedAtom::ContentType type, DefinedAtom::Merge merge,
-                      bool thumb, uint64_t sectionOffset, uint64_t contentSize,
-                      StringRef sectionName, bool copyRefs, 
-                      const Section *inSection) {
+                      bool thumb, bool noDeadStrip, uint64_t sectionOffset,
+                      uint64_t contentSize, StringRef sectionName,
+                      bool copyRefs, const Section *inSection) {
     assert(sectionOffset+contentSize <= inSection->content.size());
-    ArrayRef<uint8_t> content = inSection->content.slice(sectionOffset, 
+    ArrayRef<uint8_t> content = inSection->content.slice(sectionOffset,
                                                         contentSize);
    if (copyRefs) {
       // Make a copy of the atom's name and content that is owned by this file.
@@ -63,20 +64,22 @@ public:
     }
     MachODefinedCustomSectionAtom *atom =
         new (_allocator) MachODefinedCustomSectionAtom(*this, name, scope, type,
-                                                        merge, thumb, content,
+                                                        merge, thumb,
+                                                        noDeadStrip, content,
                                                         sectionName);
     addAtomForSection(inSection, atom, sectionOffset);
   }
 
   void addZeroFillDefinedAtom(StringRef name, Atom::Scope scope,
                               uint64_t sectionOffset, uint64_t size,
-                              bool copyRefs, const Section *inSection) {
+                              bool noDeadStrip, bool copyRefs,
+                              const Section *inSection) {
     if (copyRefs) {
       // Make a copy of the atom's name and content that is owned by this file.
       name = name.copy(_allocator);
     }
     MachODefinedAtom *atom =
-        new (_allocator) MachODefinedAtom(*this, name, scope, size);
+       new (_allocator) MachODefinedAtom(*this, name, scope, size, noDeadStrip);
     addAtomForSection(inSection, atom, sectionOffset);
   }
 

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=216234&r1=216233&r2=216234&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Thu Aug 21 17:18:30 2014
@@ -656,6 +656,11 @@ uint16_t Util::descBits(const DefinedAto
     desc |= N_SYMBOL_RESOLVER;
   if (_archHandler.isThumbFunction(*atom))
     desc |= N_ARM_THUMB_DEF;
+  if (atom->deadStrip() == DefinedAtom::deadStripNever) {
+    if ((atom->contentType() != DefinedAtom::typeInitializerPtr)
+     && (atom->contentType() != DefinedAtom::typeTerminatorPtr))
+    desc |= N_NO_DEAD_STRIP;
+  }
   return desc;
 }
 

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp?rev=216234&r1=216233&r2=216234&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp Thu Aug 21 17:18:30 2014
@@ -225,9 +225,10 @@ void atomFromSymbol(DefinedAtom::Content
   // difference between this and the next symbol.
   uint64_t size = nextSymbolAddr - symbolAddr;
   uint64_t offset = symbolAddr - section.address;
+  bool noDeadStrip = (symbolDescFlags & N_NO_DEAD_STRIP);
   if (section.type == llvm::MachO::S_ZEROFILL) {
-    file.addZeroFillDefinedAtom(symbolName, symbolScope, offset, size, copyRefs, 
-                                &section);
+    file.addZeroFillDefinedAtom(symbolName, symbolScope, offset, size,
+                                noDeadStrip, copyRefs, &section);
   } else {
     DefinedAtom::Merge merge = (symbolDescFlags & N_WEAK_DEF)
                               ? DefinedAtom::mergeAsWeak : DefinedAtom::mergeNo;
@@ -239,15 +240,15 @@ void atomFromSymbol(DefinedAtom::Content
       std::string segSectName = section.segmentName.str()
                                 + "/" + section.sectionName.str();
       file.addDefinedAtomInCustomSection(symbolName, symbolScope, atomType,
-                                         merge, thumb,offset, size, segSectName, 
-                                         true, &section);
+                                         merge, thumb, noDeadStrip, offset,
+                                         size, segSectName, true, &section);
     } else {
       if ((atomType == lld::DefinedAtom::typeCode) &&
           (symbolDescFlags & N_SYMBOL_RESOLVER)) {
         atomType = lld::DefinedAtom::typeResolver;
       }
       file.addDefinedAtom(symbolName, symbolScope, atomType, merge,
-                          offset, size, thumb, copyRefs, &section);
+                          offset, size, thumb, noDeadStrip, copyRefs, &section);
     }
   }
 }
@@ -419,7 +420,7 @@ std::error_code processSection(DefinedAt
                                      "not zero terminated.");
       }
       file.addDefinedAtom(StringRef(), scope, atomType, merge, offset, size,
-                          false, copyRefs, &section);
+                          false, false, copyRefs, &section);
       offset += size;
     }
   }

Modified: lld/trunk/test/mach-o/parse-function.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/parse-function.yaml?rev=216234&r1=216233&r2=216234&view=diff
==============================================================================
--- lld/trunk/test/mach-o/parse-function.yaml (original)
+++ lld/trunk/test/mach-o/parse-function.yaml Thu Aug 21 17:18:30 2014
@@ -19,7 +19,7 @@ sections:
     address:         0x0000000000000000
     content:         [ 0xCC, 0xC3, 0x90, 0xC3, 0x90, 0x90, 0xC3, 0x90, 
                        0x90, 0x90, 0xC3, 0x90, 0x90, 0x90, 0x90, 0xC3,
-                       0x31, 0xC0, 0xC3 ]
+                       0xCC, 0x31, 0xC0, 0xC3 ]
 local-symbols:
   - name:            _myStatic
     type:            N_SECT
@@ -48,12 +48,18 @@ global-symbols:
     sect:            1
     desc:            [ N_WEAK_DEF ]
     value:           0x0000000000000007
+  - name:            _myStripNot
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    desc:            [ N_NO_DEAD_STRIP ]
+    value:           0x0000000000000010
   - name:            _myResolver
     type:            N_SECT
     scope:           [ N_EXT ]
     sect:            1
     desc:            [ N_SYMBOL_RESOLVER ]
-    value:           0x0000000000000010
+    value:           0x0000000000000011
 ...
 
 # CHECK-NOT:  name:  
@@ -82,6 +88,11 @@ global-symbols:
 # CHECK-NOT:	scope:  hidden
 # CHECK:      content:         [ 90, 90, 90, 90, C3 ]
 
+# CHECK:      name:    _myStripNot
+# CHECK:      scope:   global
+# CHECK:      content:         [ CC ]
+# CHECK:      dead-strip:  never
+
 # CHECK:      name:    _myResolver
 # CHECK:      scope:   global
 # CHECK:      type:    resolver





More information about the llvm-commits mailing list