[lld] r175904 - sort quickdata for the hexagon target

Shankar Easwaran shankare at codeaurora.org
Fri Feb 22 10:01:08 PST 2013


Author: shankare
Date: Fri Feb 22 12:01:08 2013
New Revision: 175904

URL: http://llvm.org/viewvc/llvm-project?rev=175904&view=rev
Log:
sort quickdata for the hexagon target

Added:
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h
    lld/trunk/test/elf/Inputs/quickdata-sort-test.o.elf-hexagon   (with props)
    lld/trunk/test/elf/hexagon-quickdata-sort.test
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/Hexagon/HexagonTargetHandler.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=175904&r1=175903&r2=175904&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Chunk.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Chunk.h Fri Feb 22 12:01:08 2013
@@ -69,9 +69,11 @@ public:
   uint64_t            virtualAddr() const { return _start; }
   // Does the chunk occupy memory during execution ?
   uint64_t            memSize() const { return _msize; }
-  void               setMemSize(uint64_t msize) { _msize = msize; }
+  void setMemSize(uint64_t msize) { _msize = msize; }
   // Writer the chunk
   virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) = 0;
+  // Finalize the chunk before assigning offsets/virtual addresses
+  virtual void doPreFlight() = 0;
   // Finalize the chunk before writing
   virtual void finalize() = 0;
 

Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h?rev=175904&r1=175903&r2=175904&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h Fri Feb 22 12:01:08 2013
@@ -208,6 +208,11 @@ public:
       si->finalize();
   }
 
+  inline void doPreFlight() {
+    for (auto &si : _sections)
+      si->doPreFlight();
+  }
+
   inline bool findAtomAddrByName(StringRef name, uint64_t &addr) {
     for (auto sec : _sections)
       if (auto section = dyn_cast<Section<ELFT> >(sec))

Modified: lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h?rev=175904&r1=175903&r2=175904&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h Fri Feb 22 12:01:08 2013
@@ -52,7 +52,9 @@ public:
 
   void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
 
-  void finalize() { }
+  virtual void doPreFlight() {}
+
+  void finalize() {}
 
 private:
   Elf_Ehdr _eh;
@@ -145,11 +147,11 @@ public:
     return _ph.end();
   }
 
-  void finalize() { }
+  virtual void doPreFlight() {}
 
-  int64_t entsize() {
-    return sizeof(Elf_Phdr);
-  }
+  void finalize() {}
+
+  int64_t entsize() { return sizeof(Elf_Phdr); }
 
   int64_t numHeaders() {
     return _ph.size();
@@ -249,12 +251,12 @@ public:
   }
 
   void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
-  
-  void finalize() { }
-  
-  inline uint16_t fileSize() {
-    return sizeof(Elf_Shdr) * _sectionInfo.size();
-  }
+
+  virtual void doPreFlight() {}
+
+  void finalize() {}
+
+  inline uint16_t fileSize() { return sizeof(Elf_Shdr) * _sectionInfo.size(); }
 
   inline int64_t entsize() {
     return sizeof(Elf_Shdr);

Added: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h?rev=175904&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h Fri Feb 22 12:01:08 2013
@@ -0,0 +1,76 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h-----------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "HexagonTargetHandler.h"
+
+namespace lld {
+namespace elf {
+typedef llvm::object::ELFType<llvm::support::little, 4, false> HexagonELFType;
+template <typename ELFT> class HexagonTargetLayout;
+class HexagonTargetInfo;
+
+/// \brief Handle Hexagon SData section
+template <class HexagonELFType>
+class SDataSection : public AtomSection<HexagonELFType> {
+public:
+  SDataSection(const HexagonTargetInfo &hti)
+      : AtomSection<HexagonELFType>(
+            hti, ".sdata", DefinedAtom::typeDataFast, 0,
+            HexagonTargetLayout<HexagonELFType>::ORDER_SDATA) {
+    this->_type = SHT_PROGBITS;
+    this->_flags = SHF_ALLOC | SHF_WRITE;
+  }
+
+  /// \brief Finalize the section contents before writing
+  virtual void doPreFlight();
+
+  /// \brief Does this section have an output segment.
+  virtual bool hasOutputSegment() { return true; }
+
+  const AtomLayout &appendAtom(const Atom *atom) {
+    const DefinedAtom *definedAtom = cast<DefinedAtom>(atom);
+    DefinedAtom::Alignment atomAlign = definedAtom->alignment();
+    uint64_t align2 = 1u << atomAlign.powerOf2;
+    this->_atoms.push_back(new (this->_alloc) AtomLayout(atom, 0, 0));
+    // Set the section alignment to the largest alignment
+    // std::max doesnot support uint64_t
+    if (this->_align2 < align2)
+      this->_align2 = align2;
+    return *(this->_atoms.back());
+  }
+
+}; // SDataSection
+
+template <class HexagonELFType>
+void SDataSection<HexagonELFType>::doPreFlight() {
+  // sort the atoms on the alignments they have been set
+  std::stable_sort(this->_atoms.begin(), this->_atoms.end(),
+                   [](const AtomLayout * A, const AtomLayout * B) {
+    const DefinedAtom *definedAtomA = cast<DefinedAtom>(A->_atom);
+    const DefinedAtom *definedAtomB = cast<DefinedAtom>(B->_atom);
+    int64_t align2A = 1 << definedAtomA->alignment().powerOf2;
+    int64_t align2B = 1 << definedAtomB->alignment().powerOf2;
+    return align2A < align2B;
+  });
+
+  // Set the fileOffset, and the appropriate size of the section
+  for (auto &ai : this->_atoms) {
+    const DefinedAtom *definedAtom = cast<DefinedAtom>(ai->_atom);
+    DefinedAtom::Alignment atomAlign = definedAtom->alignment();
+    uint64_t fOffset = this->alignOffset(this->fileSize(), atomAlign);
+    uint64_t mOffset = this->alignOffset(this->memSize(), atomAlign);
+    ai->_fileOffset = fOffset;
+    this->_fsize = fOffset + definedAtom->size();
+    this->_msize = mOffset + definedAtom->size();
+  }
+} // finalize
+
+} // elf
+} // lld
+

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h?rev=175904&r1=175903&r2=175904&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h Fri Feb 22 12:01:08 2013
@@ -13,6 +13,7 @@
 #include "DefaultTargetHandler.h"
 #include "ExecutableAtoms.h"
 #include "HexagonRelocationHandler.h"
+#include "HexagonSectionChunks.h"
 #include "TargetLayout.h"
 
 namespace lld {
@@ -75,6 +76,64 @@ public:
   }
 };
 
+/// \brief TargetLayout for Hexagon
+template <class HexagonELFType>
+class HexagonTargetLayout LLVM_FINAL : public TargetLayout<HexagonELFType> {
+
+public:
+  enum HexagonSectionOrder {
+    ORDER_SDATA = 205
+  };
+
+  HexagonTargetLayout(const HexagonTargetInfo &hti)
+      : TargetLayout<HexagonELFType>(hti), _sdataSection(nullptr) {
+    _sdataSection = new (_alloc) SDataSection<HexagonELFType>(hti);
+  }
+
+  /// \brief Return the section order for a input section
+  virtual Layout::SectionOrder getSectionOrder(
+      StringRef name, int32_t contentType, int32_t contentPermissions) {
+    if (contentType == DefinedAtom::typeDataFast)
+      return ORDER_SDATA;
+
+    return DefaultLayout<HexagonELFType>::getSectionOrder(name, contentType,
+                                                          contentPermissions);
+  }
+
+  /// \brief This maps the input sections to the output section names
+  virtual StringRef getSectionName(StringRef name, const int32_t contentType,
+                                   const int32_t contentPermissions) {
+    if (contentType == DefinedAtom::typeDataFast)
+      return ".sdata";
+    return DefaultLayout<HexagonELFType>::getSectionName(name, contentType,
+                                                         contentPermissions);
+  }
+
+  /// \brief Gets or creates a section.
+  virtual AtomSection<HexagonELFType> *
+  createSection(StringRef name, int32_t contentType,
+                DefinedAtom::ContentPermissions contentPermissions,
+                Layout::SectionOrder sectionOrder) {
+    if (contentType == DefinedAtom::typeDataFast)
+      return _sdataSection;
+    return DefaultLayout<HexagonELFType>::createSection(
+        name, contentType, contentPermissions, sectionOrder);
+  }
+
+  /// \brief get the segment type for the section thats defined by the target
+  virtual Layout::SegmentType
+  getSegmentType(Section<HexagonELFType> *section) const {
+    if (section->order() == ORDER_SDATA)
+      return PT_LOAD;
+
+    return DefaultLayout<HexagonELFType>::getSegmentType(section);
+  }
+
+private:
+  llvm::BumpPtrAllocator _alloc;
+  SDataSection<HexagonELFType> *_sdataSection;
+};
+
 /// \brief TargetHandler for Hexagon 
 class HexagonTargetHandler LLVM_FINAL :
     public DefaultTargetHandler<HexagonELFType> {
@@ -95,7 +154,7 @@ public:
 
 private:
   HexagonTargetRelocationHandler _relocationHandler;
-  TargetLayout<HexagonELFType> _targetLayout;
+  HexagonTargetLayout<HexagonELFType> _targetLayout;
   HexagonTargetAtomHandler<HexagonELFType> _targetAtomHandler;
 };
 } // end namespace elf

Modified: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=175904&r1=175903&r2=175904&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h Fri Feb 22 12:01:08 2013
@@ -39,13 +39,12 @@ public:
   /// \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) {}
+      : Chunk<ELFT>(name, k, ti), _flags(0), _entSize(0), _type(0), _link(0),
+        _info(0), _segmentType(SHT_NULL) {}
+
+  /// \brief Modify the section contents before assigning virtual addresses
+  //  or assigning file offsets
+  virtual void doPreFlight() {}
 
   /// \brief Finalize the section contents before writing
   virtual void finalize() {}

Modified: lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h?rev=175904&r1=175903&r2=175904&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h Fri Feb 22 12:01:08 2013
@@ -159,8 +159,11 @@ public:
     _sections.insert(_sections.begin(), c);
   }
 
+  // Finalize the segment before assigning File Offsets / Virtual addresses
+  inline void doPreFlight() {}
+
   // Finalize the segment, before we want to write to the output file
-  inline void finalize() { }
+  inline void finalize() {}
 
   // For LLVM RTTI
   static inline bool classof(const Chunk<ELFT> *c) {

Modified: lld/trunk/lib/ReaderWriter/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Writer.cpp?rev=175904&r1=175903&r2=175904&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Writer.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Writer.cpp Fri Feb 22 12:01:08 2013
@@ -231,11 +231,14 @@ void ExecutableWriter<ELFT>::finalizeDef
   (*endAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_memsz;
 }
 
-template<class ELFT>
-error_code
-ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) {
+template <class ELFT>
+error_code ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) {
   buildChunks(file);
 
+  // Call the preFlight callbacks to modify the sections and the atoms 
+  // contained in them, in anyway the targets may want
+  _layout->doPreFlight();
+
   // Create the default sections like the symbol table, string table, and the
   // section string table
   createDefaultSections();

Added: lld/trunk/test/elf/Inputs/quickdata-sort-test.o.elf-hexagon
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/quickdata-sort-test.o.elf-hexagon?rev=175904&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lld/trunk/test/elf/Inputs/quickdata-sort-test.o.elf-hexagon
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lld/trunk/test/elf/hexagon-quickdata-sort.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/hexagon-quickdata-sort.test?rev=175904&view=auto
==============================================================================
--- lld/trunk/test/elf/hexagon-quickdata-sort.test (added)
+++ lld/trunk/test/elf/hexagon-quickdata-sort.test Fri Feb 22 12:01:08 2013
@@ -0,0 +1,12 @@
+RUN: lld-core -arch hexagon -reader ELF %p/Inputs/quickdata-sort-test.o.elf-hexagon -writer ELF -o %t1
+RUN: llvm-nm -n %t1 | FileCheck %s -check-prefix=quickdataSort 
+
+quickdataSort: 00002000 D A1
+quickdataSort: 00002001 D AA1
+quickdataSort: 00002002 D B1
+quickdataSort: 00002004 D BB1
+quickdataSort: 00002008 D C1
+quickdataSort: 0000200c D CC1
+quickdataSort: 00002010 D D1
+quickdataSort: 00002018 D DD1
+





More information about the llvm-commits mailing list