[lld] r175207 - [ELF][Writer] Refactor Section to not have atoms. Move atoms into AtomSection.

Michael J. Spencer bigcheesegs at gmail.com
Thu Feb 14 12:24:39 PST 2013


Author: mspencer
Date: Thu Feb 14 14:24:38 2013
New Revision: 175207

URL: http://llvm.org/viewvc/llvm-project?rev=175207&view=rev
Log:
[ELF][Writer] Refactor Section to not have atoms. Move atoms into AtomSection.

The purpose of this change is to simplify creating non-atom sections.
Previously _contentType, _sectionKind and _order were used for multiple
purposes and collided in places. This moves all of the Atom specific logic down
into AtomSection and makes Section just have raw Elf_Shdr flags.

Modified:
    lld/trunk/lib/ReaderWriter/ELF/Chunk.h
    lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
    lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h
    lld/trunk/lib/ReaderWriter/ELF/Layout.h
    lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
    lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h
    lld/trunk/lib/ReaderWriter/ELF/Writer.cpp

Modified: lld/trunk/lib/ReaderWriter/ELF/Chunk.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Chunk.h?rev=175207&r1=175206&r2=175207&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Chunk.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Chunk.h Thu Feb 14 14:24:38 2013
@@ -38,6 +38,7 @@ public:
     K_ProgramHeader, // Program Header
     K_ELFSegment, // Segment
     K_ELFSection, // Section
+    K_AtomSection, //< A section containing atoms.
     K_SectionHeader // Section header
   };
   Chunk(StringRef name, Kind kind, const ELFTargetInfo &ti)
@@ -80,7 +81,7 @@ protected:
   uint64_t _fsize;
   uint64_t _msize;
   uint64_t _align2;
-  uint32_t  _order;
+  uint32_t _order;
   uint64_t _ordinal;
   uint64_t _start;
   uint64_t _fileoffset;

Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h?rev=175207&r1=175206&r2=175207&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h Thu Feb 14 14:24:38 2013
@@ -129,7 +129,7 @@ public:
     }
   };
 
-  typedef std::unordered_map<SectionKey, Section<ELFT> *, SectionKeyHash,
+  typedef std::unordered_map<SectionKey, AtomSection<ELFT> *, SectionKeyHash,
                              SectionKeyEq> SectionMapT;
   typedef std::unordered_map<SegmentKey, Segment<ELFT> *,
                              SegmentHashKey> SegmentMapT;
@@ -155,10 +155,10 @@ public:
   virtual StringRef getSectionName(StringRef name, const int32_t contentType,
                                    const int32_t contentPermissions);
 
-  /// \brief Returns the section to be created
-  virtual Section<ELFT> *getSection(StringRef name, const int32_t contentType,
-                                    const int32_t contentPermissions,
-                                    const int32_t sectionOrder);
+  /// \brief Gets or creates a section.
+  AtomSection<ELFT> *getSection(
+      StringRef name, int32_t contentType,
+      DefinedAtom::ContentPermissions contentPermissions);
 
   /// \brief Gets the segment for a output section
   virtual Layout::SegmentType getSegmentType(Section<ELFT> *section) const;
@@ -254,6 +254,13 @@ public:
     return 0;
   }
 
+protected:
+  /// \brief Allocate a new section.
+  virtual AtomSection<ELFT> *createSection(
+      StringRef name, int32_t contentType,
+      DefinedAtom::ContentPermissions contentPermissions,
+      SectionOrder sectionOrder);
+
 private:
   SectionMapT _sectionMap;
   MergedSectionMapT _mergedSectionMap;
@@ -381,9 +388,6 @@ Layout::SegmentType DefaultLayout<ELFT>:
 
 template <class ELFT>
 bool DefaultLayout<ELFT>::hasOutputSegment(Section<ELFT> *section) {
-  if (section->sectionKind() == Section<ELFT>::K_Target)
-    return section->hasOutputSegment();
-
   switch (section->order()) {
   case ORDER_INTERP:
   case ORDER_HASH:
@@ -410,18 +414,35 @@ bool DefaultLayout<ELFT>::hasOutputSegme
   case ORDER_FINI_ARRAY:
   case ORDER_BSS:
     return true;
-  
   default:
-    return false;
+    return section->hasOutputSegment();
   }
 }
 
 template <class ELFT>
-Section<ELFT> *DefaultLayout<ELFT>::getSection(
-    StringRef sectionName, int32_t contentType, int32_t permissions,
-    int32_t sectionOrder) {
-  return new (_allocator) Section<ELFT>(_targetInfo, sectionName, contentType,
-                                        permissions, sectionOrder);
+AtomSection<ELFT> *DefaultLayout<ELFT>::createSection(
+    StringRef sectionName, int32_t contentType,
+    DefinedAtom::ContentPermissions permissions, SectionOrder sectionOrder) {
+  return new (_allocator) AtomSection<ELFT>(
+      _targetInfo, sectionName, contentType, permissions, sectionOrder);
+}
+
+template <class ELFT>
+AtomSection<ELFT> *DefaultLayout<ELFT>::getSection(
+    StringRef sectionName, int32_t contentType,
+    DefinedAtom::ContentPermissions permissions) {
+  const SectionKey sectionKey(sectionName, permissions);
+  auto sec = _sectionMap.find(sectionKey);
+  if (sec != _sectionMap.end())
+    return sec->second;
+  SectionOrder sectionOrder =
+      getSectionOrder(sectionName, contentType, permissions);
+  AtomSection<ELFT> *newSec =
+      createSection(sectionName, contentType, permissions, sectionOrder);
+  newSec->setOrder(sectionOrder);
+  _sections.push_back(newSec);
+  _sectionMap.insert(std::make_pair(sectionKey, newSec));
+  return newSec;
 }
 
 template <class ELFT>
@@ -438,21 +459,8 @@ ErrorOr<const AtomLayout &> DefaultLayou
     const DefinedAtom::ContentType contentType = definedAtom->contentType();
 
     sectionName = getSectionName(sectionName, contentType, permissions);
-
-    const SectionKey sectionKey(sectionName, permissions);
-    Section<ELFT> *section;
-
-    if (_sectionMap.find(sectionKey) == _sectionMap.end()) {
-      SectionOrder section_order =
-          getSectionOrder(sectionName, contentType, permissions);
-      section =
-          getSection(sectionName, contentType, permissions, section_order);
-      section->setOrder(section_order);
-      _sections.push_back(section);
-      _sectionMap.insert(std::make_pair(sectionKey, section));
-    } else {
-      section = _sectionMap[sectionKey];
-    }
+    AtomSection<ELFT> *section =
+        getSection(sectionName, contentType, permissions);
     // Add runtime relocations to the .rela section.
     for (const auto &reloc : *definedAtom)
       if (_targetInfo.isRuntimeRelocation(*definedAtom, *reloc))

Modified: lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h?rev=175207&r1=175206&r2=175207&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h Thu Feb 14 14:24:38 2013
@@ -302,15 +302,15 @@ template<class ELFT>
 void 
 SectionHeader<ELFT>::updateSection(Section<ELFT> *section) {
   Elf_Shdr *shdr = _sectionInfo[section->ordinal()];
-  shdr->sh_type   = section->type();
-  shdr->sh_flags  = section->flags();
+  shdr->sh_type = section->getType();
+  shdr->sh_flags = section->getFlags();
   shdr->sh_offset = section->fileOffset();
   shdr->sh_addr   = section->virtualAddr();
   shdr->sh_size   = section->fileSize();
-  shdr->sh_link   = section->link();
-  shdr->sh_info   = section->shinfo();
+  shdr->sh_link = section->getLink();
+  shdr->sh_info = section->getInfo();
   shdr->sh_addralign = section->align2();
-  shdr->sh_entsize = section->entsize();
+  shdr->sh_entsize = section->getEntSize();
 }
 
 template <class ELFT>

Modified: lld/trunk/lib/ReaderWriter/ELF/Layout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Layout.h?rev=175207&r1=175206&r2=175207&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Layout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Layout.h Thu Feb 14 14:24:38 2013
@@ -46,17 +46,14 @@ public:
 
 public:
   /// Return the order the section would appear in the output file
-  virtual SectionOrder getSectionOrder
-                        (const StringRef name,
-                         int32_t contentType,
-                         int32_t contentPerm) = 0;
+  virtual SectionOrder getSectionOrder(StringRef name, int32_t contentType,
+                                       int32_t contentPerm) = 0;
   /// \brief Append the Atom to the layout and create appropriate sections.
   /// \returns A reference to the atom layout or an error. The atom layout will
   /// be updated as linking progresses.
   virtual ErrorOr<const AtomLayout &> addAtom(const Atom *atom) = 0;
   /// find the Atom Address in the current layout
-  virtual bool findAtomAddrByName(const StringRef name, 
-                                  uint64_t &addr) = 0;
+  virtual bool findAtomAddrByName(StringRef name, uint64_t &addr) = 0;
   /// associates a section to a segment
   virtual void assignSectionsToSegments() = 0;
   /// associates a virtual address to the segment, section, and the atom

Modified: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=175207&r1=175206&r2=175207&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h Thu Feb 14 14:24:38 2013
@@ -31,42 +31,122 @@
 
 namespace lld {
 namespace elf {
+using namespace llvm::ELF;
 
-/// \brief A section contains a set of atoms that have similiar properties
-///        The atoms that have similiar properties are merged to form a section
-template<class ELFT>
-class Section : public Chunk<ELFT> {
+/// \brief An ELF section.
+template <class ELFT> class Section : public Chunk<ELFT> {
 public:
-  // The Kind of section that the object represents
-  enum SectionKind {
-    K_Default,
-    K_Target, // The section is handed over to the target
-    K_SymbolTable,
-    K_StringTable,
-  };
-  // Create a section object, the section is set to the default type if the
-  // caller doesnot set it
-  Section(const ELFTargetInfo &, StringRef sectionName,
-          const int32_t contentType, const int32_t contentPermissions,
-          const int32_t order, const SectionKind kind = K_Default);
-
-  /// return the section kind
-  inline SectionKind sectionKind() const {
-    return _sectionKind;
-  }
-
-  /// set the section Kind, this function is needed by the targetHandler
-  /// to set the target section
-  inline void setKind(SectionKind k) { _sectionKind = k; }
+  /// \param type the ELF SHT_* type of the section.
+  Section(const ELFTargetInfo &ti, StringRef name,
+          typename Chunk<ELFT>::Kind k = Chunk<ELFT>::K_ELFSection)
+      : Chunk<ELFT>(name, k, ti),
+        _flags(0),
+        _entSize(0),
+        _type(0),
+        _link(0),
+        _info(0),
+        _segmentType(SHT_NULL) {}
+
+  /// \brief Finalize the section contents before writing
+  virtual void finalize() {}
 
-  /// Is the section part of any segment, Target sections must override 
-  /// this function
+  /// \brief Does this section have an output segment.
   virtual bool hasOutputSegment() {
-    assert((_sectionKind != K_Target) && 
-           "Cannot determine if the targetSection has any output segment");
     return false;
   }
 
+  /// \brief Assign file offsets starting at offset.
+  virtual void assignOffsets(uint64_t offset) {}
+
+  /// \brief Assign virtual addresses starting at addr. Addr is modified to be
+  /// the next available virtual address.
+  virtual void assignVirtualAddress(uint64_t &addr) {}
+
+  uint64_t getFlags() const { return _flags; }
+  uint64_t getEntSize() const { return _entSize; }
+  uint32_t getType() const { return _type; }
+  uint32_t getLink() const { return _link; }
+  uint32_t getInfo() const { return _info; }
+  Layout::SegmentType getSegmentType() const { return _segmentType; }
+
+  /// \brief convert the segment type to a String for diagnostics and printing
+  /// purposes
+  StringRef segmentKindToStr() const;
+
+  // TODO: Move this down to AtomSection.
+  virtual bool findAtomAddrByName(StringRef name, uint64_t &addr) {
+    return false;
+  }
+
+  /// \brief Records the segmentType, that this section belongs to
+  void setSegment(const Layout::SegmentType segmentType) {
+    this->_segmentType = segmentType;
+  }
+
+  static bool classof(const Chunk<ELFT> *c) {
+    return c->kind() == Chunk<ELFT>::K_ELFSection ||
+           c->kind() == Chunk<ELFT>::K_AtomSection;
+  }
+
+protected:
+  /// \brief ELF SHF_* flags.
+  uint64_t _flags;
+  /// \brief The size of each entity.
+  uint64_t _entSize;
+  /// \brief ELF SHT_* type.
+  uint32_t _type;
+  /// \brief sh_link field.
+  uint32_t _link;
+  /// \brief the sh_info field.
+  uint32_t _info;
+  /// \brief the output ELF segment type of this section.
+  Layout::SegmentType _segmentType;
+};
+
+/// \brief A section containing atoms.
+template <class ELFT> class AtomSection : public Section<ELFT> {
+public:
+  AtomSection(const ELFTargetInfo &ti, StringRef name, int32_t contentType,
+              int32_t permissions, int32_t order)
+      : Section<ELFT>(ti, name, Chunk<ELFT>::K_AtomSection),
+        _contentType(contentType), _contentPermissions(permissions) {
+    this->setOrder(order);
+    switch (contentType) {
+    case DefinedAtom::typeCode:
+    case DefinedAtom::typeData:
+    case DefinedAtom::typeConstant:
+    case DefinedAtom::typeGOT:
+    case DefinedAtom::typeStub:
+    case DefinedAtom::typeResolver:
+    case DefinedAtom::typeTLVInitialData:
+      this->_type = SHT_PROGBITS;
+      break;
+    case DefinedAtom::typeZeroFill:
+    case DefinedAtom::typeTLVInitialZeroFill:
+      this->_type = SHT_NOBITS;
+      break;
+    }
+
+    switch (permissions) {
+    case DefinedAtom::permR__:
+      this->_flags = SHF_ALLOC;
+      break;
+    case DefinedAtom::permR_X:
+      this->_flags = SHF_ALLOC | SHF_EXECINSTR;
+      break;
+    case DefinedAtom::permRW_:
+    case DefinedAtom::permRW_L:
+      this->_flags = SHF_ALLOC | SHF_WRITE;
+      if (_contentType == DefinedAtom::typeTLVInitialData ||
+          _contentType == DefinedAtom::typeTLVInitialZeroFill)
+        this->_flags |= SHF_TLS;
+      break;
+    case DefinedAtom::permRWX:
+      this->_flags = SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR;
+      break;
+    }
+  }
+
   /// Align the offset to the required modulus defined by the atom alignment
   uint64_t alignOffset(uint64_t offset, DefinedAtom::Alignment &atomAlign);
 
@@ -78,7 +158,7 @@ public:
   /// \brief Set the virtual address of each Atom in the Section. This
   /// routine gets called after the linker fixes up the virtual address
   /// of the section
-  inline void assignVirtualAddress(uint64_t &addr) {
+  virtual void assignVirtualAddress(uint64_t &addr) {
     for (auto &ai : _atoms) {
       ai->_virtualAddr = addr + ai->_fileOffset;
     }
@@ -86,7 +166,7 @@ public:
 
   /// \brief Set the file offset of each Atom in the section. This routine
   /// gets called after the linker fixes up the section offset
-  inline void assignOffsets(uint64_t offset) {
+  virtual void assignOffsets(uint64_t offset) {
     for (auto &ai : _atoms) {
       ai->_fileOffset = offset + ai->_fileOffset;
     }
@@ -95,7 +175,7 @@ public:
   /// \brief Find the Atom address given a name, this is needed to to properly
   ///  apply relocation. The section class calls this to find the atom address
   ///  to fix the relocation
-  inline bool findAtomAddrByName(StringRef name, uint64_t &addr) {
+  virtual bool findAtomAddrByName(StringRef name, uint64_t &addr) {
     for (auto ai : _atoms) {
       if (ai->_atom->name() == name) {
         addr = ai->_virtualAddr;
@@ -106,104 +186,43 @@ public:
   }
 
   /// \brief Does the Atom occupy any disk space
-  inline bool occupiesNoDiskSpace() const {
+  bool occupiesNoDiskSpace() const {
     return _contentType == DefinedAtom::typeZeroFill;
   }
 
   /// \brief The permission of the section is the most permissive permission
   /// of all atoms that the section contains
-  inline void setContentPermissions(int32_t perm) {
+  void setContentPermissions(int32_t perm) {
     _contentPermissions = std::max(perm, _contentPermissions);
   }
 
-  /// \brief Get the section flags, defined by the permissions of the section
-  int64_t flags();
-
-  /// \brief Return the section type, the returned value is recorded in the
-  /// sh_type field of the Section Header
-  int type();
-
-  /// \brief convert the segment type to a String for diagnostics
-  ///        and printing purposes
-  StringRef segmentKindToStr() const;
-
   /// \brief Return the raw flags, we need this to sort segments
   inline int64_t atomflags() const {
     return _contentPermissions;
   }
 
-  /// \brief Returns the section link field, the returned value is
-  ///        recorded in the sh_link field of the Section Header
-  inline int link() const {
-    return _link;
-  }
-
-  inline void setLink(int32_t link) {
-    _link = link;
-  }
-
-  /// \brief Returns the section entsize field, the returned value is
-  ///        recorded in the sh_entsize field of the Section Header
-  inline int entsize() const {
-    return _entSize;
-  }
-
-  /// \brief Returns the shinfo field, the returned value is
-  ///        recorded in the sh_info field of the Section Header
-  inline int shinfo() const {
-    return _shInfo;
-  }
-
-  /// \brief Records the segmentType, that this section belongs to
-  inline void setSegment(const Layout::SegmentType segmentType) {
-    _segmentType = segmentType;
-  }
-
-  /// \brief for LLVM style RTTI information
-  static inline bool classof(const Chunk<ELFT> *c) {
-    return c->kind() == Chunk<ELFT>::K_ELFSection;
-  }
-
-  /// \brief Finalize the section contents before writing
-  inline void finalize() { }
-
-  /// \brief Write the section and the atom contents to the buffer
-  void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
-
   /// Atom Iterators
   typedef typename std::vector<AtomLayout *>::iterator atom_iter;
 
   range<atom_iter> atoms() { return _atoms; }
 
+  virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+
+  static bool classof(const Chunk<ELFT> *c) {
+    return c->kind() == Chunk<ELFT>::K_AtomSection;
+  }
+
 protected:
+  llvm::BumpPtrAllocator _alloc;
   int32_t _contentType;
   int32_t _contentPermissions;
-  SectionKind _sectionKind;
   std::vector<AtomLayout *> _atoms;
-  Layout::SegmentType _segmentType;
-  int64_t _entSize;
-  int64_t _shInfo;
-  int64_t _link;
-  llvm::BumpPtrAllocator _alloc;
 };
 
-// Create a section object, the section is set to the default type if the
-// caller doesnot set it
-template <class ELFT>
-Section<ELFT>::Section(const ELFTargetInfo &ti, StringRef sectionName,
-                       const int32_t contentType,
-                       const int32_t contentPermissions, const int32_t order,
-                       const SectionKind kind)
-    : Chunk<ELFT>(sectionName, Chunk<ELFT>::K_ELFSection, ti),
-      _contentType(contentType), _contentPermissions(contentPermissions),
-      _sectionKind(kind), _entSize(0), _shInfo(0), _link(0) {
-  this->setOrder(order);
-}
-
 /// Align the offset to the required modulus defined by the atom alignment
-template<class ELFT>
-uint64_t 
-Section<ELFT>::alignOffset(uint64_t offset, DefinedAtom::Alignment &atomAlign) {
+template <class ELFT>
+uint64_t AtomSection<ELFT>::alignOffset(uint64_t offset,
+                                        DefinedAtom::Alignment &atomAlign) {
   uint64_t requiredModulus = atomAlign.modulus;
   uint64_t align2 = 1u << atomAlign.powerOf2;
   uint64_t currentModulus = (offset % align2);
@@ -221,7 +240,7 @@ Section<ELFT>::alignOffset(uint64_t offs
 // contains the atom, the atom file offset, the atom virtual address
 // the atom file offset is aligned appropriately as set by the Reader
 template <class ELFT>
-const AtomLayout &Section<ELFT>::appendAtom(const Atom *atom) {
+const AtomLayout &AtomSection<ELFT>::appendAtom(const Atom *atom) {
   Atom::Definition atomType = atom->definition();
   const DefinedAtom *definedAtom = cast<DefinedAtom>(atom);
 
@@ -235,9 +254,9 @@ const AtomLayout &Section<ELFT>::appendA
   switch (atomType) {
   case Atom::definitionRegular:
     switch(definedAtom->contentType()) {
-    case  DefinedAtom::typeCode:
-    case  DefinedAtom::typeData:
-    case  DefinedAtom::typeConstant:
+    case DefinedAtom::typeCode:
+    case DefinedAtom::typeData:
+    case DefinedAtom::typeConstant:
     case DefinedAtom::typeGOT:
     case DefinedAtom::typeStub:
     case DefinedAtom::typeResolver:
@@ -250,7 +269,7 @@ const AtomLayout &Section<ELFT>::appendA
                                    << "Adding atom: " << atom->name() << "@"
                                    << fOffset << "\n");
       break;
-    case  DefinedAtom::typeZeroFill:
+    case DefinedAtom::typeZeroFill:
     case DefinedAtom::typeTLVInitialZeroFill:
       _atoms.push_back(new (_alloc) AtomLayout(atom, mOffset, 0));
       this->_msize = mOffset + definedAtom->size();
@@ -272,73 +291,9 @@ const AtomLayout &Section<ELFT>::appendA
   return *_atoms.back();
 }
 
-/// \brief Get the section flags, defined by the permissions of the section
-template<class ELFT>
-int64_t 
-Section<ELFT>::flags() {
-  switch (_contentPermissions) {
-  case DefinedAtom::perm___:
-    return 0;
-
-  case DefinedAtom::permR__:
-      return llvm::ELF::SHF_ALLOC;
-
-  case DefinedAtom::permR_X:
-      return llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR;
-
-  case DefinedAtom::permRW_:
-  case DefinedAtom::permRW_L:
-    if (_contentType == DefinedAtom::typeTLVInitialData ||
-        _contentType == DefinedAtom::typeTLVInitialZeroFill)
-      return llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE | llvm::ELF::SHF_TLS;
-    return llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE;
-
-  case DefinedAtom::permRWX:
-      return llvm::ELF::SHF_ALLOC |
-              llvm::ELF::SHF_WRITE |
-              llvm::ELF::SHF_EXECINSTR;
-
-  default:
-      break;
-  }
-  return llvm::ELF::SHF_ALLOC;
-}
-
-/// \brief Return the section type, the returned value is recorded in the
-/// sh_type field of the Section Header
-
-template<class ELFT>
-int 
-Section<ELFT>::type() {
-  if (_sectionKind == K_SymbolTable)
-    return llvm::ELF::SHT_SYMTAB;
-
-  switch (_contentType) {
-  case DefinedAtom::typeCode:
-  case DefinedAtom::typeData:
-  case DefinedAtom::typeConstant:
-  case DefinedAtom::typeGOT:
-  case DefinedAtom::typeStub:
-  case DefinedAtom::typeResolver:
-  case DefinedAtom::typeTLVInitialData:
-    return llvm::ELF::SHT_PROGBITS;
-
-  case DefinedAtom::typeZeroFill:
-  case DefinedAtom::typeTLVInitialZeroFill:
-   return llvm::ELF::SHT_NOBITS;
-
-  // Case to handle section types
-  // Symtab, String Table ...
-  default:
-   return _contentType;
-  }
-}
-
 /// \brief convert the segment type to a String for diagnostics
 ///        and printing purposes
-template<class ELFT>
-StringRef 
-Section<ELFT>::segmentKindToStr() const {
+template <class ELFT> StringRef Section<ELFT>::segmentKindToStr() const {
   switch(_segmentType) {
   case llvm::ELF::PT_INTERP:
     return "INTERP";
@@ -361,7 +316,8 @@ Section<ELFT>::segmentKindToStr() const
 
 /// \brief Write the section and the atom contents to the buffer
 template <class ELFT>
-void Section<ELFT>::write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
+void AtomSection<ELFT>::write(ELFWriter *writer,
+                              llvm::FileOutputBuffer &buffer) {
   uint8_t *chunkBuffer = buffer.getBufferStart();
   for (auto &ai : _atoms) {
     DEBUG_WITH_TYPE("Section",
@@ -464,7 +420,7 @@ private:
   StringRef _name;
   bool _hasSegment;
   uint64_t _ordinal;
-  int64_t _flags;
+  uint64_t _flags;
   uint64_t _size;
   uint64_t _memSize;
   uint64_t _fileOffset;
@@ -503,12 +459,12 @@ MergedSections<ELFT>::appendSection(Chun
   if (c->align2() > _align2)
     _align2 = c->align2();
   if (const auto section = dyn_cast<Section<ELFT>>(c)) {
-    _link = section->link();
-    _shInfo = section->shinfo();
-    _entSize = section->entsize();
-    _type = section->type();
-    if (_flags < section->flags())
-      _flags = section->flags();
+    _link = section->getLink();
+    _shInfo = section->getInfo();
+    _entSize = section->getEntSize();
+    _type = section->getType();
+    if (_flags < section->getFlags())
+      _flags = section->getFlags();
   }
   _kind = c->kind();
   _sections.push_back(c);
@@ -520,15 +476,9 @@ class StringTable : public Section<ELFT>
 public:
   StringTable(const ELFTargetInfo &, const char *str, int32_t order);
 
-  static inline bool classof(const Chunk<ELFT> *c) {
-    return c->kind() == Section<ELFT>::K_StringTable;
-  }
-
   uint64_t addString(StringRef symname);
 
-  void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
-
-  inline void finalize() { }
+  virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
 
 private:
   std::vector<StringRef> _strings;
@@ -552,14 +502,14 @@ private:
 template <class ELFT>
 StringTable<ELFT>::StringTable(const ELFTargetInfo &ti, const char *str,
                                int32_t order)
-    : Section<ELFT>(ti, str, llvm::ELF::SHT_STRTAB, DefinedAtom::perm___, order,
-                    Section<ELFT>::K_StringTable) {
+    : Section<ELFT>(ti, str) {
   // the string table has a NULL entry for which
   // add an empty string
   _strings.push_back("");
   this->_fsize = 1;
   this->_align2 = 1;
   this->setOrder(order);
+  this->_type = SHT_STRTAB;
 }
 
 template <class ELFT> uint64_t StringTable<ELFT>::addString(StringRef symname) {
@@ -600,31 +550,23 @@ public:
 
   void addSymbol(const Atom *atom, int32_t sectionIndex, uint64_t addr = 0);
 
-  void finalize();
+  virtual void finalize();
 
-  void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+  virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
 
-  static inline bool classof(const Chunk<ELFT> *c) {
-    return c->kind() == Section<ELFT>::K_SymbolTable;
-  }
-
-  inline void setStringSection(StringTable<ELFT> *s) {
-    _stringSection = s;
-  }
+  void setStringSection(StringTable<ELFT> *s) { _stringSection = s; }
 
 private:
   StringTable<ELFT> *_stringSection;
   std::vector<Elf_Sym*> _symbolTable;
   llvm::BumpPtrAllocator _symbolAllocate;
-  int64_t _link;
 };
 
 /// ELF Symbol Table 
 template <class ELFT>
 SymbolTable<ELFT>::SymbolTable(const ELFTargetInfo &ti, const char *str,
-                                     int32_t order)
-    : Section<ELFT>(ti, str, llvm::ELF::SHT_SYMTAB, 0, order,
-                    Section<ELFT>::K_SymbolTable) {
+                               int32_t order)
+    : Section<ELFT>(ti, str) {
   this->setOrder(order);
   Elf_Sym *symbol = new (_symbolAllocate.Allocate<Elf_Sym>()) Elf_Sym;
   memset((void *)symbol, 0, sizeof(Elf_Sym));
@@ -632,13 +574,12 @@ SymbolTable<ELFT>::SymbolTable(const ELF
   this->_entSize = sizeof(Elf_Sym);
   this->_fsize = sizeof(Elf_Sym);
   this->_align2 = sizeof(void *);
+  this->_type = SHT_SYMTAB;
 }
 
-template<class ELFT>
-void 
-SymbolTable<ELFT>::addSymbol(const Atom *atom, 
-                                int32_t sectionIndex, 
-                                uint64_t addr) {
+template <class ELFT>
+void SymbolTable<ELFT>::addSymbol(const Atom *atom, int32_t sectionIndex,
+                                  uint64_t addr) {
   Elf_Sym *symbol = new(_symbolAllocate.Allocate<Elf_Sym>()) Elf_Sym;
   unsigned char binding = 0, type = 0;
   symbol->st_name = _stringSection->addString(atom->name());
@@ -707,9 +648,7 @@ SymbolTable<ELFT>::addSymbol(const Atom
   this->_fsize += sizeof(Elf_Sym);
 }
 
-template<class ELFT>
-void 
-SymbolTable<ELFT>::finalize() {
+template <class ELFT> void SymbolTable<ELFT>::finalize() {
   // sh_info should be one greater than last symbol with STB_LOCAL binding
   // we sort the symbol table to keep all local symbols at the beginning
   std::stable_sort(_symbolTable.begin(), _symbolTable.end(),
@@ -722,13 +661,13 @@ SymbolTable<ELFT>::finalize() {
       break;
     shInfo++;
   }
-  this->_shInfo = shInfo;
-  this->setLink(_stringSection->ordinal());
+  this->_info = shInfo;
+  this->_link = _stringSection->ordinal();
 }
 
 template <class ELFT>
 void SymbolTable<ELFT>::write(ELFWriter *writer,
-                                 llvm::FileOutputBuffer &buffer) {
+                              llvm::FileOutputBuffer &buffer) {
   uint8_t *chunkBuffer = buffer.getBufferStart();
   uint8_t *dest = chunkBuffer + this->fileOffset();
   for (auto sti : _symbolTable) {
@@ -742,11 +681,12 @@ public:
   typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
 
   RelocationTable(const ELFTargetInfo &ti, StringRef str, int32_t order)
-      : Section<ELFT>(ti, str, llvm::ELF::SHT_RELA, DefinedAtom::permR__, order,
-                      Section<ELFT>::K_Default) {
+      : Section<ELFT>(ti, str) {
     this->setOrder(order);
     this->_entSize = sizeof(Elf_Rela);
     this->_align2 = llvm::alignOf<Elf_Rela>();
+    this->_type = SHT_RELA;
+    this->_flags = SHF_ALLOC;
   }
 
   void addRelocation(const DefinedAtom &da, const Reference &r) {
@@ -755,7 +695,7 @@ public:
     this->_msize = this->_fsize;
   }
 
-  void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
+  virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
     uint8_t *chunkBuffer = buffer.getBufferStart();
     uint8_t *dest = chunkBuffer + this->fileOffset();
     for (const auto &rel : _relocs) {

Modified: lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h?rev=175207&r1=175206&r2=175207&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h Thu Feb 14 14:24:38 2013
@@ -224,7 +224,7 @@ protected:
   std::vector<Chunk<ELFT> *> _sections;
   std::vector<SegmentSlice<ELFT> *> _segmentSlices;
   Layout::SegmentType _segmentType;
-  int64_t _flags;
+  uint64_t _flags;
   int64_t _atomflags;
   llvm::BumpPtrAllocator _segmentAllocate;
 };
@@ -238,21 +238,36 @@ Segment<ELFT>::Segment(const ELFTargetIn
   this->_fsize = 0;
 }
 
-template<class ELFT>
-void 
-Segment<ELFT>::append(Section<ELFT> *section) {
+// This function actually is used, but not in all instantiations of Segment.
+LLVM_ATTRIBUTE_UNUSED
+static DefinedAtom::ContentPermissions toAtomPerms(uint64_t flags) {
+  switch (flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR)) {
+  case SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR:
+    return DefinedAtom::permRWX;
+  case SHF_ALLOC | SHF_EXECINSTR:
+    return DefinedAtom::permR_X;
+  case SHF_ALLOC:
+    return DefinedAtom::permR__;
+  case SHF_ALLOC | SHF_WRITE:
+    return DefinedAtom::permRW_;
+  default:
+    return DefinedAtom::permUnknown;
+  }
+}
+
+template <class ELFT> void Segment<ELFT>::append(Section<ELFT> *section) {
   _sections.push_back(section);
-  if (_flags < section->flags())
-    _flags = section->flags();
-  if (_atomflags < section->atomflags())
-    _atomflags = section->atomflags();
+  if (_flags < section->getFlags())
+    _flags = section->getFlags();
+  if (_atomflags < toAtomPerms(_flags))
+    _atomflags = toAtomPerms(_flags);
   if (this->_align2 < section->align2())
     this->_align2 = section->align2();
 }
 
 template <class ELFT>
 bool Segment<ELFT>::compareSegments(Segment<ELFT> *sega, Segment<ELFT> *segb) {
-  return (sega->atomflags() < segb->atomflags());
+  return sega->atomflags() < segb->atomflags();
 }
 
 template <class ELFT> void Segment<ELFT>::assignOffsets(uint64_t startOffset) {

Modified: lld/trunk/lib/ReaderWriter/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Writer.cpp?rev=175207&r1=175206&r2=175207&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Writer.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Writer.cpp Thu Feb 14 14:24:38 2013
@@ -92,7 +92,7 @@ void ExecutableWriter<ELFT>::buildChunks
 template<class ELFT>
 void ExecutableWriter<ELFT>::buildSymbolTable () {
   for (auto sec : _layout->sections())
-    if (auto section = dyn_cast<Section<ELFT>>(sec))
+    if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
       for (const auto &atom : section->atoms())
         _symtab->addSymbol(atom->_atom, section->ordinal(), atom->_virtualAddr);
 }
@@ -111,7 +111,7 @@ ExecutableWriter<ELFT>::addAbsoluteUndef
 template<class ELFT>
 void ExecutableWriter<ELFT>::buildAtomToAddressMap () {
   for (auto sec : _layout->sections())
-    if (auto section = dyn_cast<Section<ELFT>>(sec))
+    if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
       for (const auto &atom : section->atoms())
         _atomToAddressMap[atom->_atom] = atom->_virtualAddr;
   // build the atomToAddressMap that contains absolute symbols too
@@ -122,7 +122,8 @@ void ExecutableWriter<ELFT>::buildAtomTo
 template<class ELFT>
 void ExecutableWriter<ELFT>::buildSectionHeaderTable() {
   for (auto mergedSec : _layout->mergedSections()) {
-    if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection)
+    if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection &&
+        mergedSec->kind() != Chunk<ELFT>::K_AtomSection)
       continue;
     if (mergedSec->hasSegment())
       _shdrtab->appendSection(mergedSec);
@@ -132,7 +133,8 @@ void ExecutableWriter<ELFT>::buildSectio
 template<class ELFT>
 void ExecutableWriter<ELFT>::assignSectionsWithNoSegments() {
   for (auto mergedSec : _layout->mergedSections()) {
-    if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection)
+    if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection &&
+        mergedSec->kind() != Chunk<ELFT>::K_AtomSection)
       continue;
     if (!mergedSec->hasSegment())
       _shdrtab->appendSection(mergedSec);





More information about the llvm-commits mailing list