[llvm-commits] [lld] r173300 - in /lld/trunk: include/lld/Core/ lib/Core/ lib/Passes/ lib/ReaderWriter/ lib/ReaderWriter/ELF/ lib/ReaderWriter/MachO/ lib/ReaderWriter/Native/ lib/ReaderWriter/PECOFF/ lib/ReaderWriter/YAML/ test/ tools/lld-core/

Nick Kledzik kledzik at apple.com
Wed Jan 23 14:32:57 PST 2013


Author: kledzik
Date: Wed Jan 23 16:32:56 2013
New Revision: 173300

URL: http://llvm.org/viewvc/llvm-project?rev=173300&view=rev
Log:
Add SectionPosition and OrderPass

Added:
    lld/trunk/lib/Passes/OrderPass.cpp
    lld/trunk/test/section-position.objtxt
Modified:
    lld/trunk/include/lld/Core/DefinedAtom.h
    lld/trunk/include/lld/Core/File.h
    lld/trunk/include/lld/Core/InputFiles.h
    lld/trunk/include/lld/Core/Pass.h
    lld/trunk/include/lld/Core/Resolver.h
    lld/trunk/lib/Core/DefinedAtom.cpp
    lld/trunk/lib/Core/File.cpp
    lld/trunk/lib/Core/InputFiles.cpp
    lld/trunk/lib/Core/Resolver.cpp
    lld/trunk/lib/Passes/CMakeLists.txt
    lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h
    lld/trunk/lib/ReaderWriter/MachO/MachOTargetInfo.cpp
    lld/trunk/lib/ReaderWriter/MachO/SimpleAtoms.hpp
    lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h
    lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp
    lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
    lld/trunk/lib/ReaderWriter/ReaderArchive.cpp
    lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
    lld/trunk/tools/lld-core/TestingHelpers.hpp
    lld/trunk/tools/lld-core/lld-core.cpp

Modified: lld/trunk/include/lld/Core/DefinedAtom.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/DefinedAtom.h?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/DefinedAtom.h (original)
+++ lld/trunk/include/lld/Core/DefinedAtom.h Wed Jan 23 16:32:56 2013
@@ -142,8 +142,6 @@
     typeTLVInitialData,     // initial data for a TLV [Darwin]
     typeTLVInitialZeroFill, // TLV initial zero fill data [Darwin]
     typeTLVInitializerPtr,  // pointer to thread local initializer [Darwin]
-    typeFirstInSection,     // label for boundary of section [Darwin]
-    typeLastInSection,      // label for boundary of section [Darwin]
   };
 
   enum ContentPermissions {
@@ -163,6 +161,13 @@
     sectionCustomRequired   // linker must place in specific section
   };
 
+  enum SectionPosition {
+    sectionPositionStart,   // atom must be at start of section (and zero size)
+    sectionPositionEarly,   // atom should be near start of section
+    sectionPositionAny,     // atom can be anywhere in section
+    sectionPositionEnd      // atom must be at end of section (and zero size)
+  };
+
   enum DeadStripKind {
     deadStripNormal,        // linker may dead strip this atom
     deadStripNever,         // linker must never dead strip this atom
@@ -226,6 +231,9 @@
   virtual StringRef customSectionName() const = 0;
 
   /// \brief constraints on whether the linker may dead strip away this atom.
+  virtual SectionPosition sectionPosition() const = 0; 
+   
+  /// \brief constraints on whether the linker may dead strip away this atom.
   virtual DeadStripKind deadStrip() const = 0;
 
   /// \brief Returns the OS memory protections required for this atom's content

Modified: lld/trunk/include/lld/Core/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/File.h?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/File.h (original)
+++ lld/trunk/include/lld/Core/File.h Wed Jan 23 16:32:56 2013
@@ -12,6 +12,7 @@
 
 #include "lld/Core/AbsoluteAtom.h"
 #include "lld/Core/DefinedAtom.h"
+#include "lld/Core/range.h"
 #include "lld/Core/SharedLibraryAtom.h"
 #include "lld/Core/UndefinedAtom.h"
 
@@ -61,6 +62,19 @@
   /// be ascertained, this method returns the empty string.
   virtual StringRef translationUnitSource() const;
 
+  /// Returns the command line order of the file.
+  uint64_t ordinal() const { 
+    assert(_ordinal != UINT64_MAX);
+    return _ordinal; 
+  }
+  
+  /// Sets the command line order of the file.  The parameter must
+  /// also be incremented to the next available ordinal number.
+  virtual void setOrdinalAndIncrement(uint64_t &ordinal) const {
+    _ordinal = ordinal;
+    ++ordinal;
+  }
+
 public:
   template <typename T> class atom_iterator; // forward reference
 
@@ -140,7 +154,7 @@
 
 protected:
   /// \brief only subclasses of File can be instantiated 
-  File(StringRef p) : _path(p) {}
+  File(StringRef p) : _path(p), _ordinal(UINT64_MAX) {}
 
 
   /// \brief This is a convenience class for File subclasses which manage their
@@ -193,7 +207,8 @@
   static atom_collection_empty<SharedLibraryAtom> _noSharedLibaryAtoms;
   static atom_collection_empty<AbsoluteAtom>      _noAbsoluteAtoms;
 
-  StringRef _path;
+  StringRef         _path;
+  mutable uint64_t  _ordinal;
 };
 
 /// \brief A mutable File.
@@ -202,6 +217,10 @@
   /// \brief Add an atom to the file. Invalidates iterators for all returned
   /// containters.
   virtual void addAtom(const Atom&) = 0;
+  
+  typedef range<std::vector<const DefinedAtom*>::iterator>  DefinedAtomRange;
+  virtual DefinedAtomRange definedAtoms() = 0;
+  
 
 protected:
   /// \brief only subclasses of MutableFile can be instantiated 

Modified: lld/trunk/include/lld/Core/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/InputFiles.h?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/InputFiles.h (original)
+++ lld/trunk/include/lld/Core/InputFiles.h Wed Jan 23 16:32:56 2013
@@ -46,6 +46,9 @@
  
  /// Transfers ownership of a vector of Files to this InputFile object.
   virtual void appendFiles(std::vector<std::unique_ptr<File>> &files);
+  
+  /// Assigns an ordinal to each File for use by sort().
+  virtual void assignFileOrdinals();
 
   /// @brief iterates all atoms in initial files
   virtual void forEachInitialAtom(Handler &) const;

Modified: lld/trunk/include/lld/Core/Pass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Pass.h?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Pass.h (original)
+++ lld/trunk/include/lld/Core/Pass.h Wed Jan 23 16:32:56 2013
@@ -110,6 +110,17 @@
   /// the specified atom.
   virtual const DefinedAtom *makeGOTEntry(const Atom &target) = 0;
 };
+
+/// Pass for sorting atoms.
+class OrderPass : public Pass {
+public:
+  OrderPass() : Pass() {}
+  
+  /// Sorts atoms in mergedFile by content type then by command line order.
+  virtual void perform(MutableFile &mergedFile);
+};
+
+
 } // namespace lld
 
 #endif // LLD_CORE_PASS_H_

Modified: lld/trunk/include/lld/Core/Resolver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Resolver.h?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Resolver.h (original)
+++ lld/trunk/include/lld/Core/Resolver.h Wed Jan 23 16:32:56 2013
@@ -86,6 +86,7 @@
   void addAtoms(std::vector<const Atom*>& atoms);
 
   virtual void addAtom(const Atom& atom);
+  virtual DefinedAtomRange definedAtoms();
 
   private:
     friend class Resolver;

Modified: lld/trunk/lib/Core/DefinedAtom.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/DefinedAtom.cpp?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/lib/Core/DefinedAtom.cpp (original)
+++ lld/trunk/lib/Core/DefinedAtom.cpp Wed Jan 23 16:32:56 2013
@@ -66,8 +66,6 @@
   
   case typeUnknown:
   case typeTempLTO:
-  case typeFirstInSection:
-  case typeLastInSection:
     return permUnknown;
   }
   llvm_unreachable("unknown content type");

Modified: lld/trunk/lib/Core/File.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/File.cpp?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/lib/Core/File.cpp (original)
+++ lld/trunk/lib/Core/File.cpp Wed Jan 23 16:32:56 2013
@@ -24,4 +24,7 @@
 File::atom_collection_empty<SharedLibraryAtom> File::_noSharedLibaryAtoms;
 File::atom_collection_empty<AbsoluteAtom>      File::_noAbsoluteAtoms;
 
-}
+
+
+
+} // namespace lld

Modified: lld/trunk/lib/Core/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/InputFiles.cpp?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/lib/Core/InputFiles.cpp (original)
+++ lld/trunk/lib/Core/InputFiles.cpp Wed Jan 23 16:32:56 2013
@@ -41,6 +41,13 @@
   }
 }
 
+void InputFiles::assignFileOrdinals() {
+  uint64_t i = 0;
+  for ( const File *file : _files ) {
+    file->setOrdinalAndIncrement(i);
+  }
+}
+
 
 bool InputFiles::searchLibraries(StringRef name, bool searchSharedLibs,
                                bool searchArchives, bool dataSymbolOnly,

Modified: lld/trunk/lib/Core/Resolver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/lib/Core/Resolver.cpp (original)
+++ lld/trunk/lib/Core/Resolver.cpp Wed Jan 23 16:32:56 2013
@@ -104,10 +104,25 @@
   DEBUG_WITH_TYPE("resolver", llvm::dbgs()
                     << "         DefinedAtom: "
                     << llvm::format("0x%09lX", &atom)
+                    << ", file=#"
+                    << atom.file().ordinal()
+                    << ", atom=#"
+                    << atom.ordinal()
                     << ", name="
                     << atom.name()
                     << "\n");
 
+  // Verify on zero-size atoms are pinned to start or end of section.
+  switch ( atom.sectionPosition() ) {
+  case DefinedAtom::sectionPositionStart: 
+  case DefinedAtom::sectionPositionEnd:
+    assert(atom.size() == 0);
+    break;
+  case DefinedAtom::sectionPositionEarly: 
+  case DefinedAtom::sectionPositionAny: 
+    break;
+  }
+
   // add to list of known atoms
   _atoms.push_back(&atom);
 
@@ -364,6 +379,14 @@
   }
 }
 
+
+MutableFile::DefinedAtomRange Resolver::MergedFile::definedAtoms() {
+  return range<std::vector<const DefinedAtom*>::iterator>(
+                    _definedAtoms._atoms.begin(), _definedAtoms._atoms.end());
+}
+
+
+
 void Resolver::MergedFile::addAtoms(std::vector<const Atom*>& all) {
   DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "Resolver final atom list:\n");
   for ( const Atom *atom : all ) {

Modified: lld/trunk/lib/Passes/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Passes/CMakeLists.txt?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/lib/Passes/CMakeLists.txt (original)
+++ lld/trunk/lib/Passes/CMakeLists.txt Wed Jan 23 16:32:56 2013
@@ -1,4 +1,5 @@
 add_lld_library(lldPasses
   GOTPass.cpp
+  OrderPass.cpp
   StubsPass.cpp
   )

Added: lld/trunk/lib/Passes/OrderPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Passes/OrderPass.cpp?rev=173300&view=auto
==============================================================================
--- lld/trunk/lib/Passes/OrderPass.cpp (added)
+++ lld/trunk/lib/Passes/OrderPass.cpp Wed Jan 23 16:32:56 2013
@@ -0,0 +1,84 @@
+//===- Passes/OrderPass.cpp - sort atoms ----------------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This linker pass sorts atoms.  By default atoms are sort first by the
+// order their .o files were found on the command line, then by order of the
+// atoms (address) in the .o file.  But some atoms have a prefered location
+// in their section (such as pinned to the start or end of the section), so
+// the sort must take that into account too.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "lld/Core/DefinedAtom.h"
+#include "lld/Core/File.h"
+#include "lld/Core/LLVM.h"
+#include "lld/Core/Pass.h"
+#include "lld/Core/Reference.h"
+#include "llvm/ADT/DenseMap.h"
+
+
+namespace lld {
+
+static bool compare(const DefinedAtom *left, const DefinedAtom *right) {
+  if ( left == right )
+    return false;
+
+  // Sort same permissions together.
+  DefinedAtom::ContentPermissions leftPerms  = left->permissions();
+  DefinedAtom::ContentPermissions rightPerms = right->permissions();
+  if (leftPerms != rightPerms) 
+		return leftPerms < rightPerms;
+
+  
+  // Sort same content types together.
+  DefinedAtom::ContentType leftType  = left->contentType();
+  DefinedAtom::ContentType rightType = right->contentType();
+  if (leftType != rightType) 
+		return leftType < rightType;
+
+
+  // TO DO: Sort atoms in customs sections together.
+
+
+  // Sort by section position preference.
+  DefinedAtom::SectionPosition leftPos  = left->sectionPosition();
+  DefinedAtom::SectionPosition rightPos = right->sectionPosition();
+  bool leftSpecialPos  = (leftPos  != DefinedAtom::sectionPositionAny); 
+  bool rightSpecialPos = (rightPos != DefinedAtom::sectionPositionAny); 
+  if (leftSpecialPos || rightSpecialPos) {
+    if (leftPos != rightPos)
+      return leftPos < rightPos;
+  }
+  
+  // Sort by .o order.
+  const File *leftFile  = &left->file();
+  const File *rightFile = &right->file();
+  if ( leftFile != rightFile ) 
+		return leftFile->ordinal() < rightFile->ordinal();
+  
+  // Sort by atom order with .o file.
+  uint64_t leftOrdinal  = left->ordinal();
+  uint64_t rightOrdinal = right->ordinal();
+  if ( leftOrdinal != rightOrdinal ) 
+		return leftOrdinal < rightOrdinal;
+ 
+  return false;
+}
+
+
+
+void OrderPass::perform(MutableFile &mergedFile) {
+
+  MutableFile::DefinedAtomRange atomRange = mergedFile.definedAtoms();
+  
+  std::sort(atomRange.begin(), atomRange.end(), compare);
+}
+
+} // namespace

Modified: lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h Wed Jan 23 16:32:56 2013
@@ -305,6 +305,10 @@
     return _sectionName;
   }
 
+  virtual SectionPosition sectionPosition() const {
+    return sectionPositionAny;
+  }
+
   // It isn't clear that __attribute__((used)) is transmitted to the ELF object
   // file.
   virtual DeadStripKind deadStrip() const {

Modified: lld/trunk/lib/ReaderWriter/MachO/MachOTargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOTargetInfo.cpp?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachOTargetInfo.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachOTargetInfo.cpp Wed Jan 23 16:32:56 2013
@@ -80,6 +80,7 @@
   virtual void addPasses(PassManager &pm) const {
     pm.add(std::unique_ptr<Pass>(new mach_o::GOTPass));
     pm.add(std::unique_ptr<Pass>(new mach_o::StubsPass(*this)));
+    pm.add(std::unique_ptr<Pass>(new OrderPass()));
   }
 };
 

Modified: lld/trunk/lib/ReaderWriter/MachO/SimpleAtoms.hpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/SimpleAtoms.hpp?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/SimpleAtoms.hpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/SimpleAtoms.hpp Wed Jan 23 16:32:56 2013
@@ -160,6 +160,11 @@
   virtual StringRef customSectionName() const {
     return StringRef();
   }
+
+  virtual SectionPosition sectionPosition() const {
+    return DefinedAtom::sectionPositionAny;
+  }
+
   virtual DeadStripKind deadStrip() const {
     return DefinedAtom::deadStripNormal;
   }

Modified: lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h (original)
+++ lld/trunk/lib/ReaderWriter/Native/NativeFileFormat.h Wed Jan 23 16:32:56 2013
@@ -150,7 +150,7 @@
   uint8_t   interposable;
   uint8_t   merge;
   uint8_t   contentType;
-  uint8_t   sectionChoice;
+  uint8_t   sectionChoiceAndPosition; // high nibble is choice, low is position
   uint8_t   deadStrip;
   uint8_t   permissions;
   uint8_t   alias;

Modified: lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp (original)
+++ lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp Wed Jan 23 16:32:56 2013
@@ -75,11 +75,17 @@
   }
 
   virtual DefinedAtom::SectionChoice sectionChoice() const {
-    return (DefinedAtom::SectionChoice)(attributes().sectionChoice);
+    return (DefinedAtom::SectionChoice)(
+        attributes().sectionChoiceAndPosition >> 4);
   }
 
   virtual StringRef customSectionName() const;
 
+  virtual SectionPosition sectionPosition() const {
+     return (DefinedAtom::SectionPosition)(
+        attributes().sectionChoiceAndPosition & 0xF);
+  }
+  
   virtual DefinedAtom::DeadStripKind deadStrip() const {
      return (DefinedAtom::DeadStripKind)(attributes().deadStrip);
   }

Modified: lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp (original)
+++ lld/trunk/lib/ReaderWriter/Native/WriterNative.cpp Wed Jan 23 16:32:56 2013
@@ -436,7 +436,8 @@
     attrs.interposable      = atom.interposable();
     attrs.merge             = atom.merge();
     attrs.contentType       = atom.contentType();
-    attrs.sectionChoice     = atom.sectionChoice();
+    attrs.sectionChoiceAndPosition 
+                          = atom.sectionChoice() << 4 | atom.sectionPosition();
     attrs.deadStrip         = atom.deadStrip();
     attrs.permissions       = atom.permissions();
     //attrs.thumb             = atom.isThumb();

Modified: lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp Wed Jan 23 16:32:56 2013
@@ -153,6 +153,10 @@
     return "";
   }
 
+  virtual SectionPosition sectionPosition() const {
+    return sectionPositionAny;
+  }
+
   virtual DeadStripKind deadStrip() const {
     return deadStripNormal;
   }

Modified: lld/trunk/lib/ReaderWriter/ReaderArchive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ReaderArchive.cpp?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ReaderArchive.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ReaderArchive.cpp Wed Jan 23 16:32:56 2013
@@ -56,10 +56,21 @@
 
     assert(result.size() == 1);
 
+    // TO DO: set ordinal of child just loaded
+    
     // give up the pointer so that this object no longer manages it
     return result[0].release();
   }
 
+  virtual void setOrdinalAndIncrement(uint64_t &ordinal) const {
+    _ordinal = ordinal++;
+    // Leave space in ordinal range for all children
+    for (auto mf = _archive->begin_children(), 
+              me = _archive->end_children(); mf != me; ++mf) {
+        ordinal++;
+    }
+  }
+
   virtual const atom_collection<DefinedAtom> &defined() const {
     return _definedAtoms;
   }

Modified: lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp (original)
+++ lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp Wed Jan 23 16:32:56 2013
@@ -335,6 +335,16 @@
 };
 
 template <>
+struct ScalarEnumerationTraits<lld::DefinedAtom::SectionPosition> {
+  static void enumeration(IO &io, lld::DefinedAtom::SectionPosition &value) {
+    io.enumCase(value, "start",   lld::DefinedAtom::sectionPositionStart);
+    io.enumCase(value, "early",   lld::DefinedAtom::sectionPositionEarly);
+    io.enumCase(value, "any",     lld::DefinedAtom::sectionPositionAny);
+    io.enumCase(value, "end",     lld::DefinedAtom::sectionPositionEnd);
+  }
+};
+
+template <>
 struct ScalarEnumerationTraits<lld::DefinedAtom::Interposable> {
   static void enumeration(IO &io, lld::DefinedAtom::Interposable &value) {
     io.enumCase(value, "no",  lld::DefinedAtom::interposeNo);
@@ -451,10 +461,6 @@
                           lld::DefinedAtom::typeTLVInitialZeroFill);
     io.enumCase(value, "tlv-initializer-ptr", 
                           lld::DefinedAtom::typeTLVInitializerPtr);
-    io.enumCase(value, "first-in-section",    
-                          lld::DefinedAtom::typeFirstInSection);
-    io.enumCase(value, "last-in-section",     
-                          lld::DefinedAtom::typeLastInSection);
   }
 };
 
@@ -617,6 +623,14 @@
       return this;
     }
 
+    virtual void setOrdinalAndIncrement(uint64_t &ordinal) const {
+      _ordinal = ordinal++;
+      // Assign sequential ordinals to member files
+      for (const ArchMember &member : _members) {
+        member._content->setOrdinalAndIncrement(ordinal);
+      }
+    }
+    
     virtual const atom_collection<lld::DefinedAtom> &defined() const {
       return _noDefinedAtoms;
     }
@@ -824,6 +838,8 @@
     NormalizedAtom(IO &io)
       : _file(fileFromContext(io)), _name(), _refName(), 
         _alignment(0), _content(), _references() {
+      static uint32_t ordinalCounter = 1;
+      _ordinal = ordinalCounter++;
     }
     NormalizedAtom(IO &io, const lld::DefinedAtom *atom)
       : _file(fileFromContext(io)),
@@ -835,6 +851,7 @@
         _contentType(atom->contentType()),
         _alignment(atom->alignment()),
         _sectionChoice(atom->sectionChoice()),
+        _sectionPosition(atom->sectionPosition()),
         _deadStrip(atom->deadStrip()),
         _permissions(atom->permissions()),
         _size(atom->size()),
@@ -882,6 +899,7 @@
     virtual Alignment          alignment() const     { return _alignment; }
     virtual SectionChoice      sectionChoice() const { return _sectionChoice; }
     virtual StringRef          customSectionName() const { return _sectionName;}
+    virtual SectionPosition    sectionPosition() const{return _sectionPosition;}
     virtual DeadStripKind      deadStrip() const     { return _deadStrip;  }
     virtual ContentPermissions permissions() const   { return _permissions; }
     virtual bool               isThumb() const       { return false; }
@@ -891,7 +909,7 @@
         reinterpret_cast<const uint8_t *>(_content.data()), _content.size());
     }
 
-    virtual uint64_t           ordinal() const       { return 0; }
+    virtual uint64_t           ordinal() const       { return _ordinal; }
     
     reference_iterator begin() const { 
       uintptr_t index = 0;
@@ -923,8 +941,10 @@
     ContentType               _contentType;
     Alignment                 _alignment;
     SectionChoice             _sectionChoice;
+    SectionPosition           _sectionPosition;
     DeadStripKind             _deadStrip;
     ContentPermissions        _permissions;
+    uint32_t                  _ordinal;
     std::vector<ImplicitHex8> _content;
     uint64_t                  _size;
     StringRef                 _sectionName;
@@ -968,6 +988,8 @@
                                         lld::DefinedAtom::sectionBasedOnContent);
     io.mapOptional("section-name",   keys->_sectionName,   
                                         StringRef());
+    io.mapOptional("section-position",keys->_sectionPosition,   
+                                        lld::DefinedAtom::sectionPositionAny);
     io.mapOptional("dead-strip",     keys->_deadStrip,     
                                         lld::DefinedAtom::deadStripNormal);
     // default permissions based on content type
@@ -1038,6 +1060,7 @@
 };
 
 
+
 // YAML conversion for const lld::SharedLibraryAtom*
 template <>
 struct MappingTraits<const lld::SharedLibraryAtom*> {

Added: lld/trunk/test/section-position.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/section-position.objtxt?rev=173300&view=auto
==============================================================================
--- lld/trunk/test/section-position.objtxt (added)
+++ lld/trunk/test/section-position.objtxt Wed Jan 23 16:32:56 2013
@@ -0,0 +1,85 @@
+# RUN: lld-core -order-pass=true %s | FileCheck %s -check-prefix=CHKORDER
+# RUN: lld-core -order-pass=false %s | FileCheck %s -check-prefix=CHKUNORD
+
+#
+# Test that atoms with section position requirements are sorted properly.
+#
+
+---
+defined-atoms:
+    - name:              data_end
+      type:              data
+      section-position:  end
+
+    - name:              some_data
+      type:              data
+      content:           [ 01, 02 ]
+
+    - name:              early_data
+      type:              data
+      section-position:  early
+      content:           [ 00, 00, 00, 00 ]
+
+    - name:              data_start
+      type:              data
+      section-position:  start
+      
+---
+defined-atoms:
+    - name:              data_end_too
+      type:              data
+      section-position:  end
+
+    - name:              some_more_data
+      type:              data
+      content:           [ 03, 04 ]
+      
+---
+defined-atoms:
+    - name:              early_data_too
+      type:              data
+      section-position:  early
+      content:           [ 00, 00, 00, 01 ]
+
+...
+
+
+# CHKUNORD: defined-atoms:   
+# CHKUNORD:   - name:             data_end
+# CHKUNORD:     section-position: end
+# CHKUNORD:   - name:             some_data
+# CHKUNORD:     content:          [ 01, 02 ]
+# CHKUNORD:   - name:             early_data
+# CHKUNORD:     content:          [ 00, 00, 00, 00 ]
+# CHKUNORD:     section-position: early
+# CHKUNORD:   - name:             data_start
+# CHKUNORD:     section-position: start
+# CHKUNORD:   - name:             data_end_too
+# CHKUNORD:     section-position: end
+# CHKUNORD:   - name:             some_more_data
+# CHKUNORD:     content:          [ 03, 04 ]
+# CHKUNORD:   - name:             early_data_too
+# CHKUNORD:     content:          [ 00, 00, 00, 01 ]
+# CHKUNORD:     section-position: early
+# CHKUNORD: ...
+
+# CHKORDER: defined-atoms:   
+# CHKORDER:   - name:             data_start
+# CHKORDER:     section-position: start
+# CHKORDER:   - name:             early_data
+# CHKORDER:     content:          [ 00, 00, 00, 00 ]
+# CHKORDER:     section-position: early
+# CHKORDER:   - name:             early_data_too
+# CHKORDER:     content:          [ 00, 00, 00, 01 ]
+# CHKORDER:     section-position: early
+# CHKORDER:   - name:             some_data
+# CHKORDER:     content:          [ 01, 02 ]
+# CHKORDER:   - name:             some_more_data
+# CHKORDER:     content:          [ 03, 04 ]
+# CHKORDER:   - name:             data_end
+# CHKORDER:     section-position: end
+# CHKORDER:   - name:             data_end_too
+# CHKORDER:    section-position:  end
+# CHKORDER: ...
+
+

Modified: lld/trunk/tools/lld-core/TestingHelpers.hpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/tools/lld-core/TestingHelpers.hpp?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/tools/lld-core/TestingHelpers.hpp (original)
+++ lld/trunk/tools/lld-core/TestingHelpers.hpp Wed Jan 23 16:32:56 2013
@@ -81,6 +81,11 @@
   virtual StringRef customSectionName() const {
     return StringRef();
   }
+  
+  virtual SectionPosition sectionPosition() const {
+    return sectionPositionAny;
+  }
+  
   virtual DeadStripKind deadStrip() const {
     return DefinedAtom::deadStripNormal;
   }
@@ -173,6 +178,10 @@
     return StringRef();
   }
 
+  virtual SectionPosition sectionPosition() const {
+    return sectionPositionAny;
+  }
+
   virtual DeadStripKind deadStrip() const {
     return DefinedAtom::deadStripNormal;
   }
@@ -224,6 +233,11 @@
       llvm_unreachable("atom has unknown definition kind");
   }
 
+  virtual DefinedAtomRange definedAtoms() {
+    return range<std::vector<const DefinedAtom*>::iterator>(
+                  _definedAtoms._atoms.begin(), _definedAtoms._atoms.end());
+  }
+    
   virtual const atom_collection<DefinedAtom> &defined() const {
     return _definedAtoms;
   }

Modified: lld/trunk/tools/lld-core/lld-core.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/tools/lld-core/lld-core.cpp?rev=173300&r1=173299&r2=173300&view=diff
==============================================================================
--- lld/trunk/tools/lld-core/lld-core.cpp (original)
+++ lld/trunk/tools/lld-core/lld-core.cpp Wed Jan 23 16:32:56 2013
@@ -69,6 +69,10 @@
           llvm::cl::desc("Run pass to create GOT atoms"));
 
 llvm::cl::opt<bool> 
+cmdLineDoOrderPass("order-pass", 
+          llvm::cl::desc("Run pass to sort atoms"));
+
+llvm::cl::opt<bool> 
 cmdLineUndefinesIsError("undefines-are-errors", 
           llvm::cl::desc("Any undefined symbols at end is an error"));
 
@@ -155,8 +159,8 @@
     
 class TestingTargetInfo : public TargetInfo {
 public:
-  TestingTargetInfo(const LinkerOptions &lo, bool stubs, bool got)
-      : TargetInfo(lo), _doStubs(stubs), _doGOT(got) {}
+  TestingTargetInfo(const LinkerOptions &lo, bool stubs, bool got, bool order)
+      : TargetInfo(lo), _doStubs(stubs), _doGOT(got), _doOrder(order) {}
 
   virtual uint64_t getPageSize() const { return 0x1000; }
 
@@ -165,6 +169,8 @@
       pm.add(std::unique_ptr<Pass>(new TestingStubsPass));
     if (_doGOT)
       pm.add(std::unique_ptr<Pass>(new TestingGOTPass));
+    if (_doOrder)
+      pm.add(std::unique_ptr<Pass>(new OrderPass));
   }
 
   virtual ErrorOr<int32_t> relocKindFromString(StringRef str) const {
@@ -187,6 +193,7 @@
 private:
   bool              _doStubs;
   bool              _doGOT;
+  bool              _doOrder;
 };
 
 int main(int argc, char *argv[]) {
@@ -230,7 +237,8 @@
     break;
   }
 
-  TestingTargetInfo tti(lo, cmdLineDoStubsPass, cmdLineDoGotPass);
+  TestingTargetInfo tti(lo, cmdLineDoStubsPass, cmdLineDoGotPass, 
+                                                          cmdLineDoOrderPass);
 
   std::unique_ptr<ELFTargetInfo> eti = ELFTargetInfo::create(lo);
   std::unique_ptr<MachOTargetInfo> mti = MachOTargetInfo::create(lo);
@@ -296,6 +304,9 @@
   // given writer a chance to add files
   writer->addFiles(inputFiles);
 
+  // assign an ordinal to each file so sort() can preserve command line order
+  inputFiles.assignFileOrdinals();
+
   // merge all atom graphs
   Resolver resolver(tti, inputFiles);
   resolver.resolve();





More information about the llvm-commits mailing list