[llvm-commits] [lld] r173709 - add register section, remove contentType from sectionKey

Shankar Easwaran shankare at codeaurora.org
Mon Jan 28 11:21:04 PST 2013


Author: shankare
Date: Mon Jan 28 13:21:04 2013
New Revision: 173709

URL: http://llvm.org/viewvc/llvm-project?rev=173709&view=rev
Log:
add register section, remove contentType from sectionKey

Modified:
    lld/trunk/lib/ReaderWriter/ELF/DefaultELFLayout.h
    lld/trunk/lib/ReaderWriter/ELF/ELFTargetHandler.h

Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultELFLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultELFLayout.h?rev=173709&r1=173708&r2=173709&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultELFLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultELFLayout.h Mon Jan 28 13:21:04 2013
@@ -84,9 +84,29 @@ public:
 
   // The Key used for creating Sections
   // The sections are created using
-  // SectionName, [contentType, contentPermissions]
-  typedef std::pair<StringRef,
-                    std::pair<int32_t, int32_t>> Key;
+  // SectionName, contentPermissions
+  struct SectionKey {
+    SectionKey(StringRef name, DefinedAtom::ContentPermissions perm)
+        : _name(name), _perm(perm) {
+    }
+
+    // Data members
+    const StringRef _name;
+    DefinedAtom::ContentPermissions _perm;
+  };
+
+  struct SectionKeyHash {
+    int64_t operator()(const SectionKey &k) const {
+      return llvm::hash_combine(k._name, k._perm);
+    }
+  };
+
+  struct SectionKeyEq {
+    bool operator()(const SectionKey &lhs, const SectionKey &rhs) const {
+      return ((lhs._name == rhs._name) && (lhs._perm == rhs._perm));
+    }
+  };
+
   typedef typename std::vector<Chunk<ELFT> *>::iterator ChunkIter;
   // The key used for Segments
   // The segments are created using
@@ -95,18 +115,8 @@ public:
   // Merged Sections contain the map of Sectionnames to a vector of sections,
   // that have been merged to form a single section
   typedef std::map<StringRef, MergedSections<ELFT> *> MergedSectionMapT;
-  typedef typename std::vector<MergedSections<ELFT> *>::iterator
-    MergedSectionIter;
-
-  // HashKey for the Section
-  class HashKey {
-  public:
-    int64_t operator() (const Key &k) const {
-      // k.first = section Name
-      // k.second = [contentType, Permissions]
-      return llvm::hash_combine(k.first, k.second.first, k.second.second);
-    }
-  };
+  typedef typename std::vector<
+      MergedSections<ELFT> *>::iterator MergedSectionIter;
 
   // HashKey for the Segment
   class SegmentHashKey {
@@ -118,9 +128,9 @@ public:
     }
   };
 
-  typedef std::unordered_map<Key, Section<ELFT>*, HashKey> SectionMapT;
-  typedef std::unordered_map<SegmentKey,
-                             Segment<ELFT>*,
+  typedef std::unordered_map<SectionKey, Section<ELFT> *, SectionKeyHash,
+                             SectionKeyEq> SectionMapT;
+  typedef std::unordered_map<SegmentKey, Segment<ELFT> *,
                              SegmentHashKey> SegmentMapT;
 
   /// \brief All absolute atoms are created in the ELF Layout by using 
@@ -384,42 +394,35 @@ template<class ELFT>
 error_code
 DefaultELFLayout<ELFT>::addAtom(const Atom *atom) {
   if (const DefinedAtom *definedAtom = dyn_cast<DefinedAtom>(atom)) {
-    const StringRef sectionName =
-                getSectionName(definedAtom->customSectionName(),
-                               definedAtom->contentType());
+    const StringRef sectionName = getSectionName(
+        definedAtom->customSectionName(), definedAtom->contentType());
     const lld::DefinedAtom::ContentPermissions permissions =
-                                  definedAtom->permissions();
+        definedAtom->permissions();
     const lld::DefinedAtom::ContentType contentType =
-                                  definedAtom->contentType();
-    const Key key(sectionName, std::make_pair(contentType, permissions));
-    const std::pair<Key, Section<ELFT> *>currentSection(key, nullptr);
-    std::pair<typename SectionMapT::iterator, bool>
-      sectionInsert(_sectionMap.insert(currentSection));
+        definedAtom->contentType();
+    const SectionKey sectionKey(sectionName, permissions);
     Section<ELFT> *section;
-    // the section is already in the map
-    if (!sectionInsert.second) {
-      section = sectionInsert.first->second;
-      section->setContentPermissions(permissions);
-    } else {
-      SectionOrder section_order = getSectionOrder(sectionName,
-                                     contentType,
-                                     permissions);
-      section = new (_allocator.Allocate<Section<ELFT>>()) Section<ELFT>(
-        sectionName, contentType, permissions, section_order);
-      sectionInsert.first->second = section;
+
+    if (_sectionMap.find(sectionKey) == _sectionMap.end()) {
+      SectionOrder section_order =
+          getSectionOrder(sectionName, contentType, permissions);
+      section = new (_allocator.Allocate<Section<ELFT> >())
+          Section<ELFT>(sectionName, contentType, permissions, section_order);
       section->setOrder(section_order);
       _sections.push_back(section);
+      _sectionMap.insert(std::make_pair(sectionKey, section));
+    } else {
+      section = _sectionMap[sectionKey];
     }
     section->appendAtom(atom);
-  }
-  // Absolute atoms are not part of any section, they are global for the whole
-  // link
-  else if (const AbsoluteAtom *absoluteAtom = dyn_cast<AbsoluteAtom>(atom)) {
-    _absoluteAtoms.push_back(AbsoluteAtomPair(absoluteAtom, 
+  } else if (const AbsoluteAtom *absoluteAtom = dyn_cast<AbsoluteAtom>(atom)) {
+    // Absolute atoms are not part of any section, they are global for the whole
+    // link
+    _absoluteAtoms.push_back(AbsoluteAtomPair(absoluteAtom,
                                               absoluteAtom->value()));
-  }
-  else 
+  } else {
     llvm_unreachable("Only absolute / defined atoms can be added here");
+  }
   return error_code::success();
 }
 

Modified: lld/trunk/lib/ReaderWriter/ELF/ELFTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFTargetHandler.h?rev=173709&r1=173708&r2=173709&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFTargetHandler.h Mon Jan 28 13:21:04 2013
@@ -18,6 +18,7 @@
 
 #include <memory>
 #include <vector>
+#include <unordered_map>
 
 /// \brief All ELF targets would want to override the way the ELF file gets
 /// processed by the linker. This class serves as an interface which would be
@@ -89,6 +90,10 @@ public:
   //  segment or not
   bool hasOutputSegment(Section<ELFT> *section) = 0;
 
+  /// Returns the target Section for a section name and content Type
+  Section<ELFT> *getSection(const StringRef name,
+                            DefinedAtom::ContentPermissions permissions) = 0;
+
 private:
   const ELFTargetInfo &_targetInfo;
   const DefaultELFLayout<ELFT> &_layout;
@@ -99,9 +104,32 @@ private:
 template <class ELFT> class ELFTargetHandler : public ELFTargetHandlerBase {
 
 public:
-
   ELFTargetHandler(ELFTargetInfo &targetInfo) : _targetInfo(targetInfo) {}
 
+  /// Register a Target, so that the target backend may choose on how to merge
+  /// individual atoms within the section, this is a way to control output order
+  /// of atoms that is determined by the target
+  void registerTargetSection(StringRef name,
+                             DefinedAtom::ContentPermissions perm) {
+    const TargetSectionKey targetSection(name, perm);
+    if (_registeredTargetSections.find(targetSection) ==
+        _registeredTargetSections.end())
+      _registeredTargetSections.insert(std::make_pair(targetSection, true));
+  }
+
+  /// Check if the section is registered given the section name and its
+  /// contentType, if they are registered the target would need to 
+  /// create a section so that atoms insert, atom virtual address assignment
+  /// could be overridden and controlled by the Target
+  bool isSectionRegisteredByTarget(StringRef name,
+                                   DefinedAtom::ContentPermissions perm) {
+    const TargetSectionKey targetSection(name, perm);
+    if (_registeredTargetSections.find(targetSection) ==
+        _registeredTargetSections.end())
+      return false;
+    return true;
+  }
+
   /// If the target overrides ELF header information, this API would
   /// return true, so that the target can set all fields specific to
   /// that target
@@ -132,8 +160,37 @@ public:
   /// symbols over to small data, this would also be used 
   virtual void allocateCommons() = 0;
 
+private:
+  struct TargetSectionKey {
+    TargetSectionKey(StringRef name, DefinedAtom::ContentPermissions perm)
+        : _name(name), _perm(perm) {
+    }
+
+    // Data members
+    const StringRef _name;
+    DefinedAtom::ContentPermissions _perm;
+  };
+
+  struct TargetSectionKeyHash {
+    int64_t operator()(const TargetSectionKey &k) const {
+      return llvm::hash_combine(k._name, k._perm);
+    }
+  };
+
+  struct TargetSectionKeyEq {
+    bool operator()(const TargetSectionKey &lhs,
+                    const TargetSectionKey &rhs) const {
+      return ((lhs._name == rhs._name) && (lhs._perm == rhs._perm));
+    }
+  };
+
+  typedef std::unordered_map<TargetSectionKey, bool, TargetSectionKeyHash,
+                             TargetSectionKeyEq> RegisteredTargetSectionMapT;
+  typedef typename RegisteredTargetSectionMapT::iterator RegisteredTargetSectionMapIterT;
+
 protected:
   const ELFTargetInfo &_targetInfo;
+  RegisteredTargetSectionMapT _registeredTargetSections;
 };
 
 } // elf





More information about the llvm-commits mailing list