[lld] r209928 - [mach-o] Add support for custom sections

Nick Kledzik kledzik at apple.com
Fri May 30 15:51:05 PDT 2014


Author: kledzik
Date: Fri May 30 17:51:04 2014
New Revision: 209928

URL: http://llvm.org/viewvc/llvm-project?rev=209928&view=rev
Log:
[mach-o] Add support for custom sections

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-data.yaml

Modified: lld/trunk/lib/ReaderWriter/MachO/Atoms.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/Atoms.h?rev=209928&r1=209927&r2=209928&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/Atoms.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/Atoms.h Fri May 30 17:51:04 2014
@@ -62,6 +62,26 @@ private:
   const Merge _merge;
 };
 
+class MachODefinedCustomSectionAtom : public MachODefinedAtom {
+public:
+  MachODefinedCustomSectionAtom(const File &f, const StringRef name, 
+                                Scope scope, ContentType type, Merge merge,
+                                const ArrayRef<uint8_t> content,
+                                StringRef sectionName)
+      : MachODefinedAtom(f, name, scope, type, merge, content), 
+        _sectionName(sectionName) {}
+
+  SectionChoice sectionChoice() const override {
+    return DefinedAtom::sectionCustomRequired;
+  }
+  
+  StringRef customSectionName() const override {
+    return _sectionName;
+  }
+private:  
+  StringRef _sectionName;
+};
+
 
 class MachOTentativeDefAtom : public SimpleDefinedAtom {
 public:

Modified: lld/trunk/lib/ReaderWriter/MachO/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/File.h?rev=209928&r1=209927&r2=209928&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/File.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/File.h Fri May 30 17:51:04 2014
@@ -35,6 +35,22 @@ public:
     addAtom(*atom);
   }
 
+  void addDefinedAtomInCustomSection(StringRef name, Atom::Scope scope,
+                      DefinedAtom::ContentType type, DefinedAtom::Merge merge,
+                      ArrayRef<uint8_t> content, StringRef sectionName,
+                      bool copyRefs) {
+    if (copyRefs) {
+      // Make a copy of the atom's name and content that is owned by this file.
+      name = name.copy(_allocator);
+      content = content.copy(_allocator);
+      sectionName = sectionName.copy(_allocator);
+    }
+    MachODefinedCustomSectionAtom *atom =
+        new (_allocator) MachODefinedCustomSectionAtom(*this, name, scope, type, 
+                                                  merge, content, sectionName);
+    addAtom(*atom);
+  }
+
   void addZeroFillDefinedAtom(StringRef name, Atom::Scope scope, uint64_t size,
                               bool copyRefs) {
     if (copyRefs) {

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=209928&r1=209927&r2=209928&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Fri May 30 17:51:04 2014
@@ -149,6 +149,7 @@ private:
   std::vector<SectionInfo*>     _sectionInfos;
   std::vector<SegmentInfo*>     _segmentInfos;
   TypeToSection                 _sectionMap;
+  std::vector<SectionInfo*>     _customSections;
   AtomToAddress                 _atomToAddress;
   DylibPathToInfo               _dylibInfo;
   const DefinedAtom            *_entryAtom;
@@ -206,6 +207,18 @@ SectionInfo *Util::makeSection(DefinedAt
   case DefinedAtom::typeCompactUnwindInfo:
      return new (_allocator) SectionInfo("__LD", "__compact_unwind",
                             S_REGULAR);
+  case DefinedAtom::typeConstant:
+     return new (_allocator) SectionInfo("__TEXT", "__const",
+                            S_REGULAR);
+  case DefinedAtom::typeData:
+     return new (_allocator) SectionInfo("__DATA", "__data",
+                            S_REGULAR);
+  case DefinedAtom::typeConstData:
+     return new (_allocator) SectionInfo("__DATA", "__const",
+                            S_REGULAR);
+  case DefinedAtom::typeLSDA:
+     return new (_allocator) SectionInfo("__TEXT", "__gcc_except_tab",
+                            S_REGULAR);
   default:
     llvm_unreachable("TO DO: add support for more sections");
     break;
@@ -215,14 +228,36 @@ SectionInfo *Util::makeSection(DefinedAt
 
 
 SectionInfo *Util::sectionForAtom(const DefinedAtom *atom) {
-  DefinedAtom::ContentType type = atom->contentType();
-  auto pos = _sectionMap.find(type);
-  if ( pos != _sectionMap.end() )
-    return pos->second;
-  SectionInfo *si = makeSection(type);
-  _sectionInfos.push_back(si);
-  _sectionMap[type] = si;
-  return si;
+  if (atom->sectionChoice() == DefinedAtom::sectionBasedOnContent) {
+    // Section for this atom is derived from content type.
+    DefinedAtom::ContentType type = atom->contentType();
+    auto pos = _sectionMap.find(type);
+    if ( pos != _sectionMap.end() )
+      return pos->second;
+    SectionInfo *si = makeSection(type);
+    _sectionInfos.push_back(si);
+    _sectionMap[type] = si;
+    return si;
+  } else {
+    // This atom needs to be in a custom section.
+    StringRef customName = atom->customSectionName();
+    // Look to see if we have already allocated the needed custom section.
+    for(SectionInfo *sect : _customSections) {
+      const DefinedAtom *firstAtom = sect->atomsAndOffsets.front().atom;
+      if (firstAtom->customSectionName().equals(customName)) {
+        return sect;
+      }
+    }
+    // Not found, so need to create a new custom section.
+    size_t seperatorIndex = customName.find('/');
+    assert(seperatorIndex != StringRef::npos);
+    StringRef segName = customName.slice(0, seperatorIndex-1);
+    StringRef sectName = customName.drop_front(seperatorIndex);
+    SectionInfo *sect = new (_allocator) SectionInfo(segName, sectName,
+                                                     S_REGULAR);
+    _customSections.push_back(sect);
+    return sect;
+  }
 }
 
 

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp?rev=209928&r1=209927&r2=209928&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp Fri May 30 17:51:04 2014
@@ -83,8 +83,25 @@ static Atom::Scope atomScope(uint8_t sco
 }
 
 static DefinedAtom::ContentType atomTypeFromSection(const Section &section) {
-  // FIX ME
-  return DefinedAtom::typeCode;
+  if (section.attributes & S_ATTR_PURE_INSTRUCTIONS)
+    return DefinedAtom::typeCode;
+  if (section.segmentName.equals("__TEXT")) {
+    if (section.sectionName.equals("__StaticInit"))
+      return DefinedAtom::typeCode;
+    if (section.sectionName.equals("__gcc_except_tab"))
+      return DefinedAtom::typeLSDA;
+    if (section.sectionName.startswith("__text"))
+      return DefinedAtom::typeCode;
+    if (section.sectionName.startswith("__const"))
+      return DefinedAtom::typeConstant;
+  } else if (section.segmentName.equals("__DATA")) {
+    if (section.sectionName.startswith("__data"))
+      return DefinedAtom::typeData;
+    if (section.sectionName.startswith("__const"))
+      return DefinedAtom::typeConstData;
+  }
+
+  return DefinedAtom::typeUnknown;
 }
 
 static error_code
@@ -124,8 +141,19 @@ processSymbol(const NormalizedFile &norm
     DefinedAtom::Merge m = DefinedAtom::mergeNo;
     if (sym.desc & N_WEAK_DEF)
       m = DefinedAtom::mergeAsWeak;
-    file.addDefinedAtom(sym.name, atomScope(sym.scope),
-                        atomTypeFromSection(section), m, atomContent, copyRefs);
+    DefinedAtom::ContentType type = atomTypeFromSection(section);
+    if (type == DefinedAtom::typeUnknown) {
+      // Mach-O needs a segment and section name.  Concatentate those two
+      // with a / seperator (e.g. "seg/sect") to fit into the lld model
+      // of just a section name.
+      std::string segSectName = section.segmentName.str() 
+                                + "/" + section.sectionName.str();
+      file.addDefinedAtomInCustomSection(sym.name, atomScope(sym.scope), type, 
+                                         m, atomContent, segSectName, true);
+    } else {
+      file.addDefinedAtom(sym.name, atomScope(sym.scope), type, m, atomContent, 
+                        copyRefs);
+    }
   }
   return error_code::success();
 }

Modified: lld/trunk/test/mach-o/parse-data.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/parse-data.yaml?rev=209928&r1=209927&r2=209928&view=diff
==============================================================================
--- lld/trunk/test/mach-o/parse-data.yaml (original)
+++ lld/trunk/test/mach-o/parse-data.yaml Fri May 30 17:51:04 2014
@@ -27,18 +27,25 @@ sections:
     content:         [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                        0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24,
                        0x31, 0x32, 0x33, 0x34, 0x41, 0x42, 0x43, 0x44 ]
+  - segment:         __CUST
+    section:         __custom
+    type:            S_REGULAR
+    attributes:      [  ]
+    alignment:       3
+    address:         0x0000000000000018
+    content:         [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]
   - segment:         __DATA
     section:         __bss
     type:            S_ZEROFILL
     attributes:      [  ]
     alignment:       2
-    address:         0x0000000000000018
+    address:         0x0000000000000020
     size:            4
 local-symbols:
   - name:            _s1
     type:            N_SECT
-    sect:            2
-    value:           0x0000000000000018
+    sect:            3
+    value:           0x0000000000000020
   - name:            _s2
     type:            N_SECT
     sect:            1
@@ -65,30 +72,48 @@ global-symbols:
     sect:            1
     desc:            [ N_WEAK_DEF ]
     value:           0x0000000000000014
+  - name:            _kustom
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            2
+    value:           0x0000000000000018
 ...
 
 # CHECK: defined-atoms:
 
-# CHECK:   - name:            _s1
-# CHECK:     type:            zero-fill
-# CHECK:     size:            4
-
 # CHECK:   - name:            _a
 # CHECK:     scope:           global
+# CHECK:     type:            data
 # CHECK:     content:         [ 01, 02, 03, 04, 05, 06, 07, 08 ]
 
 # CHECK:   - name:            _b
 # CHECK:     scope:           global
+# CHECK:     type:            data
 # CHECK:     content:         [ 11, 12, 13, 14 ]
 
 # CHECK:   - name:            _c
 # CHECK:     scope:           global
+# CHECK:     type:            data
 # CHECK:     content:         [ 21, 22, 23, 24 ]
 
 # CHECK:   - name:            _cWeak
 # CHECK:     scope:           global
+# CHECK:     type:            data
 # CHECK:     content:         [ 41, 42, 43, 44 ]
 # CHECK:     merge:           as-weak
 
 # CHECK:   - name:            _s2
+# CHECK:     type:            data
 # CHECK:     content:         [ 31, 32, 33, 34 ]
+
+# CHECK:   - name:            _s1
+# CHECK:     type:            zero-fill
+# CHECK:     size:            4
+
+# CHECK:   - name:            _kustom
+# CHECK:     scope:           global
+# CHECK:     type:            unknown
+# CHECK:     content:         [ 01, 02, 03, 04, 05, 06, 07, 08 ]
+# CHECK:     section-choice:  custom-required
+# CHECK:     section-name:    __CUST/__custom
+





More information about the llvm-commits mailing list