Hi Shankar,<br><br>Can you please try to separate out distinct patches in the future? The "cleanup" aspects of this patch make it hard to determine what changed.<div><br></div><div>-eric</div><div><br><div class="gmail_quote">On Mon Nov 03 2014 at 8:10:35 PM Shankar Easwaran <<a href="mailto:shankarke@gmail.com">shankarke@gmail.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: shankare<br>
Date: Mon Nov  3 21:57:04 2014<br>
New Revision: 221233<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=221233&view=rev" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project?rev=221233&view=rev</a><br>
Log:<br>
[ELF] Fix program headers.<br>
<br>
The ELF writer creates a invalid binary for few cases with large filesize and<br>
memory size for segments. This patch addresses the functionality and updates the<br>
test. This patch also cleans up parts of the ELF writer for future enhancements<br>
to support Linker scripts.<br>
<br>
Modified:<br>
    lld/trunk/lib/ReaderWriter/<u></u>ELF/Chunk.h<br>
    lld/trunk/lib/ReaderWriter/<u></u>ELF/DefaultLayout.h<br>
    lld/trunk/lib/ReaderWriter/<u></u>ELF/HeaderChunks.h<br>
    lld/trunk/lib/ReaderWriter/<u></u>ELF/Layout.h<br>
    lld/trunk/lib/ReaderWriter/<u></u>ELF/OutputELFWriter.h<br>
    lld/trunk/lib/ReaderWriter/<u></u>ELF/SectionChunks.h<br>
    lld/trunk/lib/ReaderWriter/<u></u>ELF/SegmentChunks.h<br>
    lld/trunk/test/elf/phdr.test<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/<u></u>ELF/Chunk.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Chunk.h?rev=221233&r1=221232&r2=221233&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/lld/trunk/lib/<u></u>ReaderWriter/ELF/Chunk.h?rev=<u></u>221233&r1=221232&r2=221233&<u></u>view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- lld/trunk/lib/ReaderWriter/<u></u>ELF/Chunk.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/<u></u>ELF/Chunk.h Mon Nov  3 21:57:04 2014<br>
@@ -52,9 +52,10 @@ public:<br>
   StringRef name() const { return _name; }<br>
   // Kind of chunk<br>
   Kind kind() const { return _kind; }<br>
-  uint64_t        fileSize() const { return _fsize; }<br>
-  void            setAlign(uint64_t align) { _align2 = align; }<br>
-  uint64_t        align2() const { return _align2; }<br>
+  virtual uint64_t fileSize() const { return _fsize; }<br>
+  virtual void setFileSize(uint64_t sz) { _fsize = sz; }<br>
+  virtual void setAlign(uint64_t align) { _align2 = align; }<br>
+  virtual uint64_t align2() const { return _align2; }<br>
<br>
   // The ordinal value of the chunk<br>
   uint64_t            ordinal() const { return _ordinal;}<br>
@@ -66,8 +67,8 @@ public:<br>
   uint64_t            fileOffset() const { return _fileoffset; }<br>
   void               setFileOffset(uint64_t offset) { _fileoffset = offset; }<br>
   // Output start address of the chunk<br>
-  void               setVAddr(uint64_t start) { _start = start; }<br>
-  uint64_t            virtualAddr() const { return _start; }<br>
+  virtual void setVirtualAddr(uint64_t start) { _start = start; }<br>
+  virtual uint64_t virtualAddr() const { return _start; }<br>
   // Memory size of the chunk<br>
   uint64_t memSize() const { return _msize; }<br>
   void setMemSize(uint64_t msize) { _msize = msize; }<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/<u></u>ELF/DefaultLayout.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h?rev=221233&r1=221232&r2=221233&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/lld/trunk/lib/<u></u>ReaderWriter/ELF/<u></u>DefaultLayout.h?rev=221233&r1=<u></u>221232&r2=221233&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- lld/trunk/lib/ReaderWriter/<u></u>ELF/DefaultLayout.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/<u></u>ELF/DefaultLayout.h Mon Nov  3 21:57:04 2014<br>
@@ -215,9 +215,7 @@ public:<br>
<br>
   void assignVirtualAddress() override;<br>
<br>
-  void assignOffsetsForMiscSections()<u></u>;<br>
-<br>
-  void assignFileOffsets() override;<br>
+  void assignFileOffsetsForMiscSectio<u></u>ns();<br>
<br>
   /// Inline functions<br>
   inline range<AbsoluteAtomIterT> absoluteAtoms() { return _absoluteAtoms; }<br>
@@ -734,32 +732,15 @@ template <class ELFT> void DefaultLayout<br>
   }<br>
 }<br>
<br>
-template <class ELFT> void DefaultLayout<ELFT>::<u></u>assignFileOffsets() {<br>
-  // TODO: Do we want to give a chance for the targetHandlers<br>
-  // to sort segments in an arbitrary order?<br>
-  std::sort(_segments.begin(), _segments.end(), Segment<ELFT>::<u></u>compareSegments);<br>
-  int ordinal = 0;<br>
-  // Compute the number of segments that might be needed, so that the<br>
-  // size of the program header can be computed<br>
-  uint64_t offset = 0;<br>
-  for (auto si : _segments) {<br>
-    si->setOrdinal(++ordinal);<br>
-    // Don't assign offsets for segments that are not loadable<br>
-    if (si->segmentType() != llvm::ELF::PT_LOAD)<br>
-      continue;<br>
-    si->assignOffsets(offset);<br>
-    offset += si->fileSize();<br>
-  }<br>
-}<br>
-<br>
 template<class ELFT><br>
 void<br>
 DefaultLayout<ELFT>::<u></u>assignVirtualAddress() {<br>
   if (_segments.empty())<br>
     return;<br>
<br>
+  std::sort(_segments.begin(), _segments.end(), Segment<ELFT>::<u></u>compareSegments);<br>
+<br>
   uint64_t virtualAddress = _context.getBaseAddress();<br>
-  ELFLinkingContext::OutputMagic outputMagic = _context.getOutputMagic();<br>
<br>
   // HACK: This is a super dirty hack. The elf header and program header are<br>
   // not part of a section, but we need them to be loaded at the base address<br>
@@ -777,6 +758,7 @@ DefaultLayout<ELFT>::<u></u>assignVirtualAddres<br>
   firstLoadSegment->prepend(_<u></u>programHeader);<br>
   firstLoadSegment->prepend(_<u></u>elfHeader);<br>
   bool newSegmentHeaderAdded = true;<br>
+  bool virtualAddressAssigned = false;<br>
   while (true) {<br>
     for (auto si : _segments) {<br>
       si->finalize();<br>
@@ -784,24 +766,10 @@ DefaultLayout<ELFT>::<u></u>assignVirtualAddres<br>
       if (si->segmentType() != llvm::ELF::PT_NULL)<br>
         newSegmentHeaderAdded = _programHeader->addSegment(si)<u></u>;<br>
     }<br>
-    if (!newSegmentHeaderAdded)<br>
+    if (!newSegmentHeaderAdded && virtualAddressAssigned)<br>
       break;<br>
-    uint64_t fileoffset = 0;<br>
+    virtualAddressAssigned = true;<br>
     uint64_t address = virtualAddress;<br>
-    // Fix the offsets after adding the program header<br>
-    for (auto &si : _segments) {<br>
-      if ((si->segmentType() != llvm::ELF::PT_LOAD) &&<br>
-          (si->segmentType() != llvm::ELF::PT_NULL))<br>
-        continue;<br>
-      // Align the segment to a page boundary only if the output mode is<br>
-      // not OutputMagic::NMAGIC/<u></u>OutputMagic::OMAGIC<br>
-      if (outputMagic != ELFLinkingContext::<u></u>OutputMagic::NMAGIC &&<br>
-          outputMagic != ELFLinkingContext::<u></u>OutputMagic::OMAGIC)<br>
-        fileoffset =<br>
-            llvm::RoundUpToAlignment(<u></u>fileoffset, _context.getPageSize());<br>
-      si->assignOffsets(fileoffset);<br>
-      fileoffset = si->fileOffset() + si->fileSize();<br>
-    }<br>
     // start assigning virtual addresses<br>
     for (auto &si : _segments) {<br>
       if ((si->segmentType() != llvm::ELF::PT_LOAD) &&<br>
@@ -809,22 +777,19 @@ DefaultLayout<ELFT>::<u></u>assignVirtualAddres<br>
         continue;<br>
<br>
       if (si->segmentType() == llvm::ELF::PT_NULL) {<br>
-        // Handle Non allocatable sections.<br>
-        uint64_t nonLoadableAddr = 0;<br>
-        si->setVAddr(nonLoadableAddr);<br>
-        si->assignVirtualAddress(<u></u>nonLoadableAddr);<br>
+        si->assignVirtualAddress(0 /*non loadable*/);<br>
       } else {<br>
-        si->setVAddr(virtualAddress);<br>
-        // The first segment has the virtualAddress set to the base address as<br>
-        // we have added the file header and the program header don't align the<br>
-        // first segment to the pagesize<br>
         si->assignVirtualAddress(<u></u>address);<br>
-        si->setMemSize(address - virtualAddress);<br>
-        if (outputMagic != ELFLinkingContext::<u></u>OutputMagic::NMAGIC &&<br>
-            outputMagic != ELFLinkingContext::<u></u>OutputMagic::OMAGIC)<br>
-          virtualAddress =<br>
-              llvm::RoundUpToAlignment(<u></u>address, _context.getPageSize());<br>
       }<br>
+      address = si->virtualAddr() + si->memSize();<br>
+    }<br>
+    uint64_t fileoffset = 0;<br>
+    for (auto &si : _segments) {<br>
+      if ((si->segmentType() != llvm::ELF::PT_LOAD) &&<br>
+          (si->segmentType() != llvm::ELF::PT_NULL))<br>
+        continue;<br>
+      si->assignFileOffsets(<u></u>fileoffset);<br>
+      fileoffset = si->fileOffset() + si->fileSize();<br>
     }<br>
     _programHeader-><u></u>resetProgramHeaders();<br>
   }<br>
@@ -833,7 +798,7 @@ DefaultLayout<ELFT>::<u></u>assignVirtualAddres<br>
   for (auto &si : _sections) {<br>
     section = dyn_cast<Section<ELFT>>(si);<br>
     if (section && DefaultLayout<ELFT>::<u></u>hasOutputSegment(section))<br>
-      section->assignOffsets(<u></u>section->fileOffset());<br>
+      section->assignFileOffsets(<u></u>section->fileOffset());<br>
   }<br>
   // Set the size of the merged Sections<br>
   for (auto msi : _mergedSections) {<br>
@@ -873,9 +838,8 @@ DefaultLayout<ELFT>::<u></u>assignVirtualAddres<br>
   }<br>
 }<br>
<br>
-template<class ELFT><br>
-void<br>
-DefaultLayout<ELFT>::<u></u>assignOffsetsForMiscSections() {<br>
+template <class ELFT><br>
+void DefaultLayout<ELFT>::<u></u>assignFileOffsetsForMiscSectio<u></u>ns() {<br>
   uint64_t fileoffset = 0;<br>
   uint64_t size = 0;<br>
   for (auto si : _segments) {<br>
@@ -894,7 +858,7 @@ DefaultLayout<ELFT>::<u></u>assignOffsetsForMis<br>
       continue;<br>
     fileoffset = llvm::RoundUpToAlignment(<u></u>fileoffset, si->align2());<br>
     si->setFileOffset(fileoffset);<br>
-    si->setVAddr(0);<br>
+    si->setVirtualAddr(0);<br>
     fileoffset += si->fileSize();<br>
   }<br>
 }<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/<u></u>ELF/HeaderChunks.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h?rev=221233&r1=221232&r2=221233&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/lld/trunk/lib/<u></u>ReaderWriter/ELF/HeaderChunks.<u></u>h?rev=221233&r1=221232&r2=<u></u>221233&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- lld/trunk/lib/ReaderWriter/<u></u>ELF/HeaderChunks.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/<u></u>ELF/HeaderChunks.h Mon Nov  3 21:57:04 2014<br>
@@ -43,7 +43,7 @@ public:<br>
   void e_shentsize(uint16_t shentsize) { _eh.e_shentsize = shentsize; }<br>
   void e_shnum(uint16_t shnum)         { _eh.e_shnum = shnum; }<br>
   void e_shstrndx(uint16_t shstrndx)   { _eh.e_shstrndx = shstrndx; }<br>
-  uint64_t  fileSize()                 { return sizeof (Elf_Ehdr); }<br>
+  uint64_t fileSize() const { return sizeof(Elf_Ehdr); }<br>
<br>
   static inline bool classof(const Chunk<ELFT> *c) {<br>
     return c->Kind() == Chunk<ELFT>::Kind::ELFHeader;<br>
@@ -125,9 +125,7 @@ public:<br>
<br>
   void resetProgramHeaders() { _phi = _ph.begin(); }<br>
<br>
-  uint64_t  fileSize() {<br>
-    return sizeof(Elf_Phdr) * _ph.size();<br>
-  }<br>
+  uint64_t fileSize() const { return sizeof(Elf_Phdr) * _ph.size(); }<br>
<br>
   static inline bool classof(const Chunk<ELFT> *c) {<br>
     return c->Kind() == Chunk<ELFT>::Kind::<u></u>ProgramHeader;<br>
@@ -271,7 +269,7 @@ public:<br>
<br>
   void finalize() {}<br>
<br>
-  inline uint64_t fileSize() { return sizeof(Elf_Shdr) * _sectionInfo.size(); }<br>
+  uint64_t fileSize() const { return sizeof(Elf_Shdr) * _sectionInfo.size(); }<br>
<br>
   inline uint64_t entsize() {<br>
     return sizeof(Elf_Shdr);<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/<u></u>ELF/Layout.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Layout.h?rev=221233&r1=221232&r2=221233&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/lld/trunk/lib/<u></u>ReaderWriter/ELF/Layout.h?rev=<u></u>221233&r1=221232&r2=221233&<u></u>view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- lld/trunk/lib/ReaderWriter/<u></u>ELF/Layout.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/<u></u>ELF/Layout.h Mon Nov  3 21:57:04 2014<br>
@@ -47,8 +47,6 @@ public:<br>
   virtual void assignSectionsToSegments() = 0;<br>
   /// associates a virtual address to the segment, section, and the atom<br>
   virtual void assignVirtualAddress() = 0;<br>
-  /// associates a file offset to the segment, section and the atom<br>
-  virtual void assignFileOffsets() = 0;<br>
<br>
 public:<br>
   Layout() {}<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/<u></u>ELF/OutputELFWriter.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h?rev=221233&r1=221232&r2=221233&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/lld/trunk/lib/<u></u>ReaderWriter/ELF/<u></u>OutputELFWriter.h?rev=221233&<u></u>r1=221232&r2=221233&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- lld/trunk/lib/ReaderWriter/<u></u>ELF/OutputELFWriter.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/<u></u>ELF/OutputELFWriter.h Mon Nov  3 21:57:04 2014<br>
@@ -265,7 +265,7 @@ void OutputELFWriter<ELFT>::<u></u>assignSectio<br>
     if (!mergedSec->hasSegment())<br>
       _shdrtab->appendSection(<u></u>mergedSec);<br>
   }<br>
-  _layout.<u></u>assignOffsetsForMiscSections()<u></u>;<br>
+  _layout.<u></u>assignFileOffsetsForMiscSectio<u></u>ns();<br>
   for (auto sec : _layout.sections())<br>
     if (auto section = dyn_cast<Section<ELFT>>(sec))<br>
       if (!DefaultLayout<ELFT>::<u></u>hasOutputSegment(section))<br>
@@ -377,7 +377,6 @@ std::error_code OutputELFWriter<ELFT>::b<br>
   // contained in them, in anyway the targets may want<br>
   _layout.doPreFlight();<br>
<br>
-  _layout.assignFileOffsets();<br>
   _layout.assignVirtualAddress()<u></u>;<br>
<br>
   // Finalize the default value of symbols that the linker adds<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/<u></u>ELF/SectionChunks.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=221233&r1=221232&r2=221233&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/lld/trunk/lib/<u></u>ReaderWriter/ELF/<u></u>SectionChunks.h?rev=221233&r1=<u></u>221232&r2=221233&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- lld/trunk/lib/ReaderWriter/<u></u>ELF/SectionChunks.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/<u></u>ELF/SectionChunks.h Mon Nov  3 21:57:04 2014<br>
@@ -59,11 +59,10 @@ public:<br>
   virtual bool isLoadableSection() const { return false; }<br>
<br>
   /// \brief Assign file offsets starting at offset.<br>
-  virtual void assignOffsets(uint64_t offset) {}<br>
+  virtual void assignFileOffsets(uint64_t offset) {}<br>
<br>
-  /// \brief Assign virtual addresses starting at addr. Addr is modified to be<br>
-  /// the next available virtual address.<br>
-  virtual void assignVirtualAddress(uint64_t &addr) {}<br>
+  /// \brief Assign virtual addresses starting at addr.<br>
+  virtual void assignVirtualAddress(uint64_t addr) {}<br>
<br>
   uint64_t getFlags() const { return _flags; }<br>
   uint64_t getEntSize() const { return _entSize; }<br>
@@ -195,7 +194,7 @@ public:<br>
   /// \brief Set the virtual address of each Atom in the Section. This<br>
   /// routine gets called after the linker fixes up the virtual address<br>
   /// of the section<br>
-  virtual void assignVirtualAddress(uint64_t &addr) {<br>
+  virtual void assignVirtualAddress(uint64_t addr) {<br>
     for (auto &ai : _atoms) {<br>
       ai->_virtualAddr = addr + ai->_fileOffset;<br>
     }<br>
@@ -203,7 +202,7 @@ public:<br>
<br>
   /// \brief Set the file offset of each Atom in the section. This routine<br>
   /// gets called after the linker fixes up the section offset<br>
-  virtual void assignOffsets(uint64_t offset) {<br>
+  virtual void assignFileOffsets(uint64_t offset) {<br>
     for (auto &ai : _atoms) {<br>
       ai->_fileOffset = offset + ai->_fileOffset;<br>
     }<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/<u></u>ELF/SegmentChunks.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h?rev=221233&r1=221232&r2=221233&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/lld/trunk/lib/<u></u>ReaderWriter/ELF/<u></u>SegmentChunks.h?rev=221233&r1=<u></u>221232&r2=221233&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- lld/trunk/lib/ReaderWriter/<u></u>ELF/SegmentChunks.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/<u></u>ELF/SegmentChunks.h Mon Nov  3 21:57:04 2014<br>
@@ -41,14 +41,8 @@ public:<br>
<br>
   SegmentSlice() { }<br>
<br>
-  /// Set the segment slice so that it begins at the offset specified<br>
-  /// by file offset and set the start of the slice to be s and the end<br>
-  /// of the slice to be e<br>
-  void set(uint64_t fileoffset, int32_t s, int e) {<br>
-    _startSection = s;<br>
-    _endSection = e + 1;<br>
-    _offset = fileoffset;<br>
-  }<br>
+  /// Set the start of the slice.<br>
+  void setStart(int32_t s) { _startSection = s; }<br>
<br>
   // Set the segment slice start and end iterators. This is used to walk through<br>
   // the sections that are part of the Segment slice<br>
@@ -59,8 +53,12 @@ public:<br>
   // Return the fileOffset of the slice<br>
   inline uint64_t fileOffset() const { return _offset; }<br>
<br>
+  void setFileOffset(uint64_t offset) { _offset = offset; }<br>
+<br>
   // Return the size of the slice<br>
-  inline uint64_t fileSize() const { return _size; }<br>
+  inline uint64_t fileSize() const { return _fsize; }<br>
+<br>
+  void setFileSize(uint64_t filesz) { _fsize = filesz; }<br>
<br>
   // Return the start of the slice<br>
   inline int32_t startSection() const { return _startSection; }<br>
@@ -74,11 +72,9 @@ public:<br>
   // Return the alignment of the slice<br>
   inline uint64_t align2() const { return _align2; }<br>
<br>
-  inline void setSize(uint64_t sz) { _size = sz; }<br>
-<br>
   inline void setMemSize(uint64_t memsz) { _memSize = memsz; }<br>
<br>
-  inline void setVAddr(uint64_t addr) { _addr = addr; }<br>
+  inline void setVirtualAddr(uint64_t addr) { _addr = addr; }<br>
<br>
   inline void setAlign(uint64_t align) { _align2 = align; }<br>
<br>
@@ -91,13 +87,12 @@ public:<br>
   }<br>
<br>
 private:<br>
-  int32_t _startSection;<br>
-  int32_t _endSection;<br>
   range<SectionIter> _sections;<br>
+  int32_t _startSection;<br>
   uint64_t _addr;<br>
   uint64_t _offset;<br>
-  uint64_t _size;<br>
   uint64_t _align2;<br>
+  uint64_t _fsize;<br>
   uint64_t _memSize;<br>
 };<br>
<br>
@@ -151,10 +146,10 @@ public:<br>
   /// the newly computed offset is greater than a page, then we create a segment<br>
   /// slice, as it would be a waste of virtual memory just to be filled with<br>
   /// zeroes<br>
-  void assignOffsets(uint64_t startOffset);<br>
+  void assignFileOffsets(uint64_t startOffset);<br>
<br>
   /// \brief Assign virtual addresses to the slices<br>
-  void assignVirtualAddress(uint64_t &addr);<br>
+  void assignVirtualAddress(uint64_t addr);<br>
<br>
   // Write the Segment<br>
   void write(ELFWriter *writer, TargetLayout<ELFT> &layout,<br>
@@ -181,7 +176,7 @@ public:<br>
     // last section to the first section, especially for TLS because<br>
     // the TLS segment contains both .tdata/.tbss<br>
     this->setFileOffset(_sections.<u></u>front()->fileOffset());<br>
-    this->setVAddr(_sections.<u></u>front()->virtualAddr());<br>
+    this->setVirtualAddr(_<u></u>sections.front()->virtualAddr(<u></u>));<br>
     size_t startFileOffset = _sections.front()->fileOffset(<u></u>);<br>
     size_t startAddr = _sections.front()-><u></u>virtualAddr();<br>
     for (auto ai : _sections) {<br>
@@ -260,16 +255,6 @@ public:<br>
<br>
   inline range<SliceIter> slices() { return _segmentSlices; }<br>
<br>
-  // These two accessors are still needed for a call to std::stable_sort.<br>
-  // Consider adding wrappers for two iterator algorithms.<br>
-  inline SliceIter slices_begin() {<br>
-    return _segmentSlices.begin();<br>
-  }<br>
-<br>
-  inline SliceIter slices_end() {<br>
-    return _segmentSlices.end();<br>
-  }<br>
-<br>
   Chunk<ELFT> *firstSection() { return _sections[0]; }<br>
<br>
 private:<br>
@@ -316,7 +301,7 @@ public:<br>
     // section points to the ELF header and the second chunk points to the<br>
     // actual program headers<br>
     this->setFileOffset(_sections.<u></u>back()->fileOffset());<br>
-    this->setVAddr(_sections.back(<u></u>)->virtualAddr());<br>
+    this->setVirtualAddr(_<u></u>sections.back()->virtualAddr()<u></u>);<br>
     this->_fsize = _sections.back()->fileSize();<br>
     this->_msize = _sections.back()->memSize();<br>
   }<br>
@@ -409,58 +394,132 @@ bool Segment<ELFT>::<u></u>compareSegments(Segm<br>
   return false;<br>
 }<br>
<br>
-template <class ELFT> void Segment<ELFT>::assignOffsets(<u></u>uint64_t startOffset) {<br>
+template <class ELFT><br>
+void Segment<ELFT>::<u></u>assignFileOffsets(uint64_t startOffset) {<br>
+  uint64_t fileOffset = startOffset;<br>
+  uint64_t curSliceFileOffset = fileOffset;<br>
+  bool isDataPageAlignedForNMagic = false;<br>
+<br>
+  this->setFileOffset(<u></u>startOffset);<br>
+  for (auto &slice : slices()) {<br>
+    // Align to the slice alignment<br>
+    fileOffset = llvm::RoundUpToAlignment(<u></u>fileOffset, slice->align2());<br>
+<br>
+    bool isFirstSection = true;<br>
+<br>
+    for (auto section : slice->sections()) {<br>
+      // If the linker outputmagic is set to OutputMagic::NMAGIC, align the Data<br>
+      // to a page boundary<br>
+      if (isFirstSection &&<br>
+          _outputMagic != ELFLinkingContext::<u></u>OutputMagic::NMAGIC &&<br>
+          _outputMagic != ELFLinkingContext::<u></u>OutputMagic::OMAGIC) {<br>
+        // Align to a page only if the output is not<br>
+        // OutputMagic::NMAGIC/<u></u>OutputMagic::OMAGIC<br>
+        fileOffset =<br>
+            llvm::RoundUpToAlignment(<u></u>fileOffset, this->_context.getPageSize());<br>
+      }<br>
+      if (!isDataPageAlignedForNMagic && needAlign(section)) {<br>
+        fileOffset =<br>
+            llvm::RoundUpToAlignment(<u></u>fileOffset, this->_context.getPageSize());<br>
+        isDataPageAlignedForNMagic = true;<br>
+      }<br>
+      // Align the section address<br>
+      fileOffset = llvm::RoundUpToAlignment(<u></u>fileOffset, section->align2());<br>
+<br>
+      if (isFirstSection) {<br>
+        slice->setFileOffset(<u></u>fileOffset);<br>
+        isFirstSection = false;<br>
+        curSliceFileOffset = fileOffset;<br>
+      }<br>
+      section->setFileOffset(<u></u>fileOffset);<br>
+      fileOffset += section->fileSize();<br>
+    }<br>
+    slice->setFileSize(fileOffset - curSliceFileOffset);<br>
+  }<br>
+  this->setFileSize(fileOffset - startOffset);<br>
+}<br>
+<br>
+/// \brief Assign virtual addresses to the slices<br>
+template <class ELFT> void Segment<ELFT>::<u></u>assignVirtualAddress(uint64_t addr) {<br>
   int startSection = 0;<br>
   int currSection = 0;<br>
-  SectionIter startSectionIter, endSectionIter;<br>
+  SectionIter startSectionIter;<br>
+<br>
   // slice align is set to the max alignment of the chunks that are<br>
   // contained in the slice<br>
   uint64_t sliceAlign = 0;<br>
   // Current slice size<br>
   uint64_t curSliceSize = 0;<br>
   // Current Slice File Offset<br>
-  uint64_t curSliceFileOffset = 0;<br>
+  uint64_t curSliceAddress = 0;<br>
<br>
   startSectionIter = _sections.begin();<br>
-  endSectionIter = _sections.end();<br>
   startSection = 0;<br>
   bool isFirstSection = true;<br>
   bool isDataPageAlignedForNMagic = false;<br>
+  uint64_t startAddr = addr;<br>
+  SegmentSlice<ELFT> *slice = nullptr;<br>
+  uint64_t tlsStartAddr = 0;<br>
+<br>
   for (auto si = _sections.begin(); si != _sections.end(); ++si) {<br>
+    // If this is first section in the segment, page align the section start<br>
+    // address. The linker needs to align the data section to a page boundary<br>
+    // only if NMAGIC is set.<br>
     if (isFirstSection) {<br>
-      // If the linker outputmagic is set to OutputMagic::NMAGIC, align the Data<br>
-      // to a page boundary<br>
-      if (!isDataPageAlignedForNMagic && needAlign(*si)) {<br>
-        startOffset =<br>
-            llvm::RoundUpToAlignment(<u></u>startOffset, this->_context.getPageSize());<br>
+      isFirstSection = false;<br>
+      if (_outputMagic != ELFLinkingContext::<u></u>OutputMagic::NMAGIC &&<br>
+          _outputMagic != ELFLinkingContext::<u></u>OutputMagic::OMAGIC)<br>
+        // Align to a page only if the output is not<br>
+        // OutputMagic::NMAGIC/<u></u>OutputMagic::OMAGIC<br>
+        startAddr =<br>
+            llvm::RoundUpToAlignment(<u></u>startAddr, this->_context.getPageSize());<br>
+      else if (!isDataPageAlignedForNMagic && needAlign(*si)) {<br>
+        // If the linker outputmagic is set to OutputMagic::NMAGIC, align the<br>
+        // Data to a page boundary.<br>
+        startAddr =<br>
+            llvm::RoundUpToAlignment(<u></u>startAddr, this->_context.getPageSize());<br>
         isDataPageAlignedForNMagic = true;<br>
       }<br>
       // align the startOffset to the section alignment<br>
-      uint64_t newOffset =<br>
-        llvm::RoundUpToAlignment(<u></u>startOffset, (*si)->align2());<br>
-      curSliceFileOffset = newOffset;<br>
+      uint64_t newAddr = llvm::RoundUpToAlignment(<u></u>startAddr, (*si)->align2());<br>
+      curSliceAddress = newAddr;<br>
       sliceAlign = (*si)->align2();<br>
-      this->setFileOffset(<u></u>startOffset);<br>
-      (*si)->setFileOffset(<u></u>newOffset);<br>
-      curSliceSize = (*si)->fileSize();<br>
-      isFirstSection = false;<br>
+      (*si)->setVirtualAddr(<u></u>curSliceAddress);<br>
+<br>
+      // Handle TLS.<br>
+      if (auto section = dyn_cast<AtomSection<ELFT>>(*<u></u>si)) {<br>
+        if (section->getSegmentType() == llvm::ELF::PT_TLS) {<br>
+          tlsStartAddr =<br>
+              llvm::RoundUpToAlignment(<u></u>tlsStartAddr, (*si)->align2());<br>
+          section->assignVirtualAddress(<u></u>tlsStartAddr);<br>
+          tlsStartAddr += (*si)->memSize();<br>
+        } else {<br>
+          section->assignVirtualAddress(<u></u>newAddr);<br>
+        }<br>
+      }<br>
+      // TBSS section is special in that it doesn't contribute to memory of any<br>
+      // segment. If we see a tbss section, don't add memory size to addr The<br>
+      // fileOffset is automatically taken care of since TBSS section does not<br>
+      // end up using file size<br>
+      if ((*si)->order() != DefaultLayout<ELFT>::ORDER_<u></u>TBSS)<br>
+        curSliceSize = (*si)->memSize();<br>
     } else {<br>
-      uint64_t curOffset = curSliceFileOffset + curSliceSize;<br>
-      // If the linker outputmagic is set to OutputMagic::NMAGIC, align the Data<br>
-      // to a page boundary<br>
+      uint64_t curAddr = curSliceAddress + curSliceSize;<br>
       if (!isDataPageAlignedForNMagic && needAlign(*si)) {<br>
-        curOffset =<br>
-            llvm::RoundUpToAlignment(<u></u>curOffset, this->_context.getPageSize());<br>
+        // If the linker outputmagic is set to OutputMagic::NMAGIC, align the<br>
+        // Data<br>
+        // to a page boundary<br>
+        curAddr =<br>
+            llvm::RoundUpToAlignment(<u></u>curAddr, this->_context.getPageSize());<br>
         isDataPageAlignedForNMagic = true;<br>
       }<br>
-      uint64_t newOffset = llvm::RoundUpToAlignment(<u></u>curOffset, (*si)->align2());<br>
-      SegmentSlice<ELFT> *slice = nullptr;<br>
-      // If the newOffset computed is more than a page away, let's create<br>
+      uint64_t newAddr = llvm::RoundUpToAlignment(<u></u>curAddr, (*si)->align2());<br>
+      // If the newAddress computed is more than a page away, let's create<br>
       // a separate segment, so that memory is not used up while running<br>
-      if (((newOffset - curOffset) > this->_context.getPageSize()) &&<br>
+      if (((newAddr - curAddr) > this->_context.getPageSize()) &&<br>
           (_outputMagic != ELFLinkingContext::<u></u>OutputMagic::NMAGIC &&<br>
            _outputMagic != ELFLinkingContext::<u></u>OutputMagic::OMAGIC)) {<br>
-<br>
+        slice = nullptr;<br>
         // TODO: use std::find here<br>
         for (auto s : slices()) {<br>
           if (s->startSection() == startSection) {<br>
@@ -473,30 +532,48 @@ template <class ELFT> void Segment<ELFT><br>
             SegmentSlice<ELFT>();<br>
           _segmentSlices.push_back(<u></u>slice);<br>
         }<br>
-        slice->set(curSliceFileOffset, startSection, currSection);<br>
-        slice->setSections(make_range(<u></u>startSectionIter, endSectionIter));<br>
-        slice->setSize(curSliceSize);<br>
+        slice->setStart(startSection);<br>
+        slice->setSections(make_range(<u></u>startSectionIter, si));<br>
+        slice->setMemSize(<u></u>curSliceSize);<br>
         slice->setAlign(sliceAlign);<br>
-        uint64_t newPageOffset =<br>
-            llvm::RoundUpToAlignment(<u></u>curOffset, this->_context.getPageSize());<br>
-        newOffset = llvm::RoundUpToAlignment(<u></u>newPageOffset, (*si)->align2());<br>
-        curSliceFileOffset = newOffset;<br>
-        startSectionIter = endSectionIter;<br>
+        slice->setVirtualAddr(<u></u>curSliceAddress);<br>
+        // Start new slice<br>
+        curSliceAddress = newAddr;<br>
+        (*si)->setVirtualAddr(<u></u>curSliceAddress);<br>
+        startSectionIter = si;<br>
         startSection = currSection;<br>
-        (*si)->setFileOffset(<u></u>curSliceFileOffset);<br>
-        curSliceSize = newOffset - curSliceFileOffset + (*si)->fileSize();<br>
+        if (auto section = dyn_cast<AtomSection<ELFT>>(*<u></u>si))<br>
+          section->assignVirtualAddress(<u></u>newAddr);<br>
+        curSliceSize = newAddr - curSliceAddress + (*si)->memSize();<br>
         sliceAlign = (*si)->align2();<br>
       } else {<br>
         if (sliceAlign < (*si)->align2())<br>
           sliceAlign = (*si)->align2();<br>
-        (*si)->setFileOffset(<u></u>newOffset);<br>
-        curSliceSize = newOffset - curSliceFileOffset + (*si)->fileSize();<br>
+        (*si)->setVirtualAddr(newAddr)<u></u>;<br>
+        // Handle TLS.<br>
+        if (auto section = dyn_cast<AtomSection<ELFT>>(*<u></u>si)) {<br>
+          if (section->getSegmentType() == llvm::ELF::PT_TLS) {<br>
+            tlsStartAddr =<br>
+                llvm::RoundUpToAlignment(<u></u>tlsStartAddr, (*si)->align2());<br>
+            section->assignVirtualAddress(<u></u>tlsStartAddr);<br>
+            tlsStartAddr += (*si)->memSize();<br>
+          } else {<br>
+            section->assignVirtualAddress(<u></u>newAddr);<br>
+          }<br>
+        }<br>
+        // TBSS section is special in that it doesn't contribute to memory of<br>
+        // any segment. If we see a tbss section, don't add memory size to addr<br>
+        // The fileOffset is automatically taken care of since TBSS section does<br>
+        // not end up using file size.<br>
+        if ((*si)->order() != DefaultLayout<ELFT>::ORDER_<u></u>TBSS)<br>
+          curSliceSize = newAddr - curSliceAddress + (*si)->memSize();<br>
+        else<br>
+          curSliceSize = newAddr - curSliceAddress;<br>
       }<br>
     }<br>
     currSection++;<br>
-    endSectionIter = si;<br>
   }<br>
-  SegmentSlice<ELFT> *slice = nullptr;<br>
+  slice = nullptr;<br>
   for (auto s : slices()) {<br>
     // TODO: add std::find<br>
     if (s->startSection() == startSection) {<br>
@@ -509,74 +586,17 @@ template <class ELFT> void Segment<ELFT><br>
       SegmentSlice<ELFT>();<br>
     _segmentSlices.push_back(<u></u>slice);<br>
   }<br>
-  slice->set(curSliceFileOffset, startSection, currSection);<br>
+  slice->setStart(startSection);<br>
+  slice->setVirtualAddr(<u></u>curSliceAddress);<br>
+  slice->setMemSize(<u></u>curSliceSize);<br>
   slice->setSections(make_range(<u></u>startSectionIter, _sections.end()));<br>
-  slice->setSize(curSliceSize);<br>
   slice->setAlign(sliceAlign);<br>
-  this->_fsize = curSliceFileOffset - startOffset + curSliceSize;<br>
-  std::stable_sort(slices_begin(<u></u>), slices_end(),<br>
-                   SegmentSlice<ELFT>::compare_<u></u>slices);<br>
-}<br>
<br>
-/// \brief Assign virtual addresses to the slices<br>
-template <class ELFT> void Segment<ELFT>::<u></u>assignVirtualAddress(uint64_t &addr) {<br>
-  bool isTLSSegment = false;<br>
-  bool isDataPageAlignedForNMagic = false;<br>
-  uint64_t tlsStartAddr = 0;<br>
-<br>
-  for (auto slice : slices()) {<br>
-    // Align to a page only if the output is not<br>
-    // OutputMagic::NMAGIC/<u></u>OutputMagic::OMAGIC<br>
-    if (_outputMagic != ELFLinkingContext::<u></u>OutputMagic::NMAGIC &&<br>
-        _outputMagic != ELFLinkingContext::<u></u>OutputMagic::OMAGIC)<br>
-      addr = llvm::RoundUpToAlignment(addr, this->_context.getPageSize());<br>
-<br>
-    // Align to the slice alignment<br>
-    addr = llvm::RoundUpToAlignment(addr, slice->align2());<br>
-<br>
-    bool virtualAddressSet = false;<br>
-    for (auto section : slice->sections()) {<br>
-      // If the linker outputmagic is set to OutputMagic::NMAGIC, align the Data<br>
-      // to a page boundary<br>
-      if (!isDataPageAlignedForNMagic && needAlign(section)) {<br>
-        addr = llvm::RoundUpToAlignment(addr, this->_context.getPageSize());<br>
-        isDataPageAlignedForNMagic = true;<br>
-      }<br>
-      // Align the section address<br>
-      addr = llvm::RoundUpToAlignment(addr, section->align2());<br>
-      // Check if the segment is of type TLS<br>
-      // The sections that belong to the TLS segment have their<br>
-      // virtual addresses that are relative To TP<br>
-      Section<ELFT> *currentSection = dyn_cast<Section<ELFT> >(section);<br>
-      if (currentSection)<br>
-        isTLSSegment = (currentSection-><u></u>getSegmentType() == llvm::ELF::PT_TLS);<br>
-<br>
-      tlsStartAddr = (isTLSSegment)<br>
-                     ? llvm::RoundUpToAlignment(<u></u>tlsStartAddr, section->align2())<br>
-                     : 0;<br>
-      if (!virtualAddressSet) {<br>
-        slice->setVAddr(addr);<br>
-        virtualAddressSet = true;<br>
-      }<br>
-      section->setVAddr(addr);<br>
-      if (auto s = dyn_cast<Section<ELFT> >(section)) {<br>
-        if (isTLSSegment)<br>
-          s->assignVirtualAddress(<u></u>tlsStartAddr);<br>
-        else<br>
-          s->assignVirtualAddress(addr);<br>
-      }<br>
-      if (isTLSSegment)<br>
-        tlsStartAddr += section->memSize();<br>
-      section->setMemSize(addr + section->memSize() - section->virtualAddr());<br>
-      // TBSS section is special in that it doesn't contribute to memory of any<br>
-      // segment. If we see a tbss section, don't add memory size to addr<br>
-      // The fileOffset is automatically taken care of since TBSS section does<br>
-      // not end up using file size<br>
-      if (section->order() != DefaultLayout<ELFT>::ORDER_<u></u>TBSS)<br>
-        addr += section->memSize();<br>
-    }<br>
-    slice->setMemSize(addr - slice->virtualAddr());<br>
-  }<br>
+  // Set the segment memory size and the virtual address.<br>
+  this->setMemSize(<u></u>curSliceAddress - startAddr + curSliceSize);<br>
+  this->setVirtualAddr(<u></u>curSliceAddress);<br>
+  std::stable_sort(_<u></u>segmentSlices.begin(), _segmentSlices.end(),<br>
+                   SegmentSlice<ELFT>::compare_<u></u>slices);<br>
 }<br>
<br>
 // Write the Segment<br>
<br>
Modified: lld/trunk/test/elf/phdr.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/phdr.test?rev=221233&r1=221232&r2=221233&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/lld/trunk/test/elf/<u></u>phdr.test?rev=221233&r1=<u></u>221232&r2=221233&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- lld/trunk/test/elf/phdr.test (original)<br>
+++ lld/trunk/test/elf/phdr.test Mon Nov  3 21:57:04 2014<br>
@@ -50,7 +50,7 @@ I386-NEXT:     Offset: 0x1000<br>
 I386-NEXT:     VirtualAddress: 0x1000<br>
 I386-NEXT:     PhysicalAddress: 0x1000<br>
 I386-NEXT:     FileSize: 260<br>
-I386-NEXT:     MemSize: 4<br>
+I386-NEXT:     MemSize: 260<br>
 I386-NEXT:     Flags [ (0x6)<br>
 I386-NEXT:       PF_R (0x4)<br>
 I386-NEXT:       PF_W (0x2)<br>
@@ -63,7 +63,7 @@ I386-NEXT:     Offset: 0x4000<br>
 I386-NEXT:     VirtualAddress: 0x4000<br>
 I386-NEXT:     PhysicalAddress: 0x4000<br>
 I386-NEXT:     FileSize: 4<br>
-I386-NEXT:     MemSize: 16392<br>
+I386-NEXT:     MemSize: 8<br>
 I386-NEXT:     Flags [ (0x6)<br>
 I386-NEXT:       PF_R (0x4)<br>
 I386-NEXT:       PF_W (0x2)<br>
<br>
<br>
______________________________<u></u>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div>