[lld] r234946 - Revert "ELF: Attempt to simplify Segment::assignVirtualAddress()."

Rui Ueyama ruiu at google.com
Tue Apr 14 14:38:40 PDT 2015


Author: ruiu
Date: Tue Apr 14 16:38:39 2015
New Revision: 234946

URL: http://llvm.org/viewvc/llvm-project?rev=234946&view=rev
Log:
Revert "ELF: Attempt to simplify Segment::assignVirtualAddress()."

This reverts commit r234944 because it seems to have broken the buildbots.

Modified:
    lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp

Modified: lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp?rev=234946&r1=234945&r2=234946&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.cpp Tue Apr 14 16:38:39 2015
@@ -175,140 +175,158 @@ template <class ELFT> void Segment<ELFT>
   // slice align is set to the max alignment of the chunks that are
   // contained in the slice
   uint64_t sliceAlign = 0;
+  // Current slice size
   uint64_t curSliceSize = 0;
+  // Current Slice File Offset
   uint64_t curSliceAddress = 0;
 
   startSectionIter = _sections.begin();
   startSection = 0;
+  bool isFirstSection = true;
+  bool isDataPageAlignedForNMagic = false;
   uint64_t startAddr = addr;
   SegmentSlice<ELFT> *slice = nullptr;
   uint64_t tlsStartAddr = 0;
+  bool alignSegments = this->_ctx.alignSegments();
   StringRef prevOutputSectionName = StringRef();
 
-  auto si = _sections.begin();
-  if (si != _sections.end()) {
+  for (auto si = _sections.begin(); si != _sections.end(); ++si) {
     // If this is first section in the segment, page align the section start
     // address. The linker needs to align the data section to a page boundary
     // only if NMAGIC is set.
-    if (needAlign(*si) ||
-        (this->_ctx.alignSegments() &&
-         _outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
-         _outputMagic != ELFLinkingContext::OutputMagic::OMAGIC)) {
-      startAddr = llvm::RoundUpToAlignment(startAddr, this->_ctx.getPageSize());
-    }
-    // align the startOffset to the section alignment
-    uint64_t newAddr = llvm::RoundUpToAlignment(startAddr, (*si)->alignment());
-    // Handle linker script expressions, which *may update newAddr* if the
-    // expression assigns to "."
-    if (auto expr = dyn_cast<ExpressionChunk<ELFT>>(*si))
-      expr->evalExpr(newAddr);
-    curSliceAddress = newAddr;
-    sliceAlign = (*si)->alignment();
-    (*si)->setVirtualAddr(curSliceAddress);
-
-    // Handle TLS.
-    if (auto section = dyn_cast<Section<ELFT>>(*si)) {
-      if (section->getSegmentType() == llvm::ELF::PT_TLS) {
-        tlsStartAddr =
-          llvm::RoundUpToAlignment(tlsStartAddr, (*si)->alignment());
-        section->assignVirtualAddress(tlsStartAddr);
-        tlsStartAddr += (*si)->memSize();
-      } else {
-        section->assignVirtualAddress(newAddr);
-      }
-    }
-    // TBSS section is special in that it doesn't contribute to memory of any
-    // segment. If we see a tbss section, don't add memory size to addr The
-    // fileOffset is automatically taken care of since TBSS section does not
-    // end up using file size
-    if ((*si)->order() != TargetLayout<ELFT>::ORDER_TBSS)
-      curSliceSize = (*si)->memSize();
-  }
-  ++currSection;
-  ++si;
-
-  for (auto e = _sections.end(); si != e; ++si) {
-    uint64_t curAddr = curSliceAddress + curSliceSize;
-    uint64_t newAddr = llvm::RoundUpToAlignment(curAddr, (*si)->alignment());
-    // Handle linker script expressions, which *may update newAddr* if the
-    // expression assigns to "."
-    if (auto expr = dyn_cast<ExpressionChunk<ELFT>>(*si))
-      expr->evalExpr(newAddr);
-    Section<ELFT> *sec = dyn_cast<Section<ELFT>>(*si);
-    StringRef curOutputSectionName;
-    if (sec) {
-      curOutputSectionName = sec->outputSectionName();
-    } else {
-      // If this is a linker script expression, propagate the name of the
-      // previous section instead
-      if (isa<ExpressionChunk<ELFT>>(*si))
-        curOutputSectionName = prevOutputSectionName;
-      else
-        curOutputSectionName = (*si)->name();
-    }
-    bool autoCreateSlice = true;
-    if (curOutputSectionName == prevOutputSectionName)
-      autoCreateSlice = false;
-    // If the newAddress computed is more than a page away, let's create
-    // a separate segment, so that memory is not used up while running.
-    // Dont create a slice, if the new section falls in the same output
-    // section as the previous section.
-    if (autoCreateSlice && ((newAddr - curAddr) > this->_ctx.getPageSize()) &&
-        (_outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
-         _outputMagic != ELFLinkingContext::OutputMagic::OMAGIC)) {
-      auto sliceIter =
-        std::find_if(_segmentSlices.begin(), _segmentSlices.end(),
-                     [startSection](SegmentSlice<ELFT> *s) -> bool {
-                       return s->startSection() == startSection;
-                     });
-      if (sliceIter == _segmentSlices.end()) {
-        slice = new (_segmentAllocate.Allocate<SegmentSlice<ELFT>>())
-          SegmentSlice<ELFT>();
-        _segmentSlices.push_back(slice);
-      } else {
-        slice = *sliceIter;
+    if (isFirstSection) {
+      isFirstSection = false;
+      if (alignSegments &&
+          _outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
+          _outputMagic != ELFLinkingContext::OutputMagic::OMAGIC)
+        // Align to a page only if the output is not
+        // OutputMagic::NMAGIC/OutputMagic::OMAGIC
+        startAddr =
+            llvm::RoundUpToAlignment(startAddr, this->_ctx.getPageSize());
+      else if (!isDataPageAlignedForNMagic && needAlign(*si)) {
+        // If the linker outputmagic is set to OutputMagic::NMAGIC, align the
+        // Data to a page boundary.
+        startAddr =
+            llvm::RoundUpToAlignment(startAddr, this->_ctx.getPageSize());
+        isDataPageAlignedForNMagic = true;
       }
-      slice->setStart(startSection);
-      slice->setSections(make_range(startSectionIter, si));
-      slice->setMemSize(curSliceSize);
-      slice->setAlign(sliceAlign);
-      slice->setVirtualAddr(curSliceAddress);
-      // Start new slice
+      // align the startOffset to the section alignment
+      uint64_t newAddr =
+          llvm::RoundUpToAlignment(startAddr, (*si)->alignment());
+      // Handle linker script expressions, which *may update newAddr* if the
+      // expression assigns to "."
+      if (auto expr = dyn_cast<ExpressionChunk<ELFT>>(*si))
+        expr->evalExpr(newAddr);
       curSliceAddress = newAddr;
-      (*si)->setVirtualAddr(curSliceAddress);
-      startSectionIter = si;
-      startSection = currSection;
-      if (auto section = dyn_cast<Section<ELFT>>(*si))
-        section->assignVirtualAddress(newAddr);
-      curSliceSize = newAddr - curSliceAddress + (*si)->memSize();
       sliceAlign = (*si)->alignment();
-    } else {
-      if (sliceAlign < (*si)->alignment())
-        sliceAlign = (*si)->alignment();
-      (*si)->setVirtualAddr(newAddr);
+      (*si)->setVirtualAddr(curSliceAddress);
+
       // Handle TLS.
       if (auto section = dyn_cast<Section<ELFT>>(*si)) {
         if (section->getSegmentType() == llvm::ELF::PT_TLS) {
           tlsStartAddr =
-            llvm::RoundUpToAlignment(tlsStartAddr, (*si)->alignment());
+              llvm::RoundUpToAlignment(tlsStartAddr, (*si)->alignment());
           section->assignVirtualAddress(tlsStartAddr);
           tlsStartAddr += (*si)->memSize();
         } else {
           section->assignVirtualAddress(newAddr);
         }
       }
-      // TBSS section is special in that it doesn't contribute to memory of
-      // any segment. If we see a tbss section, don't add memory size to addr
-      // The fileOffset is automatically taken care of since TBSS section does
-      // not end up using file size.
-      if ((*si)->order() != TargetLayout<ELFT>::ORDER_TBSS) {
+      // TBSS section is special in that it doesn't contribute to memory of any
+      // segment. If we see a tbss section, don't add memory size to addr The
+      // fileOffset is automatically taken care of since TBSS section does not
+      // end up using file size
+      if ((*si)->order() != TargetLayout<ELFT>::ORDER_TBSS)
+        curSliceSize = (*si)->memSize();
+    } else {
+      uint64_t curAddr = curSliceAddress + curSliceSize;
+      if (!isDataPageAlignedForNMagic && needAlign(*si)) {
+        // If the linker outputmagic is set to OutputMagic::NMAGIC, align the
+        // Data
+        // to a page boundary
+        curAddr = llvm::RoundUpToAlignment(curAddr, this->_ctx.getPageSize());
+        isDataPageAlignedForNMagic = true;
+      }
+      uint64_t newAddr = llvm::RoundUpToAlignment(curAddr, (*si)->alignment());
+      // Handle linker script expressions, which *may update newAddr* if the
+      // expression assigns to "."
+      if (auto expr = dyn_cast<ExpressionChunk<ELFT>>(*si))
+        expr->evalExpr(newAddr);
+      Section<ELFT> *sec = dyn_cast<Section<ELFT>>(*si);
+      StringRef curOutputSectionName;
+      if (sec)
+        curOutputSectionName = sec->outputSectionName();
+      else {
+        // If this is a linker script expression, propagate the name of the
+        // previous section instead
+        if (isa<ExpressionChunk<ELFT>>(*si))
+          curOutputSectionName = prevOutputSectionName;
+        else
+          curOutputSectionName = (*si)->name();
+      }
+      bool autoCreateSlice = true;
+      if (curOutputSectionName == prevOutputSectionName)
+        autoCreateSlice = false;
+      // If the newAddress computed is more than a page away, let's create
+      // a separate segment, so that memory is not used up while running.
+      // Dont create a slice, if the new section falls in the same output
+      // section as the previous section.
+      if (autoCreateSlice && ((newAddr - curAddr) > this->_ctx.getPageSize()) &&
+          (_outputMagic != ELFLinkingContext::OutputMagic::NMAGIC &&
+           _outputMagic != ELFLinkingContext::OutputMagic::OMAGIC)) {
+        auto sliceIter =
+            std::find_if(_segmentSlices.begin(), _segmentSlices.end(),
+                         [startSection](SegmentSlice<ELFT> *s) -> bool {
+                           return s->startSection() == startSection;
+                         });
+        if (sliceIter == _segmentSlices.end()) {
+          slice = new (_segmentAllocate.Allocate<SegmentSlice<ELFT>>())
+              SegmentSlice<ELFT>();
+          _segmentSlices.push_back(slice);
+        } else {
+          slice = (*sliceIter);
+        }
+        slice->setStart(startSection);
+        slice->setSections(make_range(startSectionIter, si));
+        slice->setMemSize(curSliceSize);
+        slice->setAlign(sliceAlign);
+        slice->setVirtualAddr(curSliceAddress);
+        // Start new slice
+        curSliceAddress = newAddr;
+        (*si)->setVirtualAddr(curSliceAddress);
+        startSectionIter = si;
+        startSection = currSection;
+        if (auto section = dyn_cast<Section<ELFT>>(*si))
+          section->assignVirtualAddress(newAddr);
         curSliceSize = newAddr - curSliceAddress + (*si)->memSize();
+        sliceAlign = (*si)->alignment();
       } else {
-        curSliceSize = newAddr - curSliceAddress;
+        if (sliceAlign < (*si)->alignment())
+          sliceAlign = (*si)->alignment();
+        (*si)->setVirtualAddr(newAddr);
+        // Handle TLS.
+        if (auto section = dyn_cast<Section<ELFT>>(*si)) {
+          if (section->getSegmentType() == llvm::ELF::PT_TLS) {
+            tlsStartAddr =
+                llvm::RoundUpToAlignment(tlsStartAddr, (*si)->alignment());
+            section->assignVirtualAddress(tlsStartAddr);
+            tlsStartAddr += (*si)->memSize();
+          } else {
+            section->assignVirtualAddress(newAddr);
+          }
+        }
+        // TBSS section is special in that it doesn't contribute to memory of
+        // any segment. If we see a tbss section, don't add memory size to addr
+        // The fileOffset is automatically taken care of since TBSS section does
+        // not end up using file size.
+        if ((*si)->order() != TargetLayout<ELFT>::ORDER_TBSS)
+          curSliceSize = newAddr - curSliceAddress + (*si)->memSize();
+        else
+          curSliceSize = newAddr - curSliceAddress;
       }
+      prevOutputSectionName = curOutputSectionName;
     }
-    prevOutputSectionName = curOutputSectionName;
-    ++currSection;
+    currSection++;
   }
   auto sliceIter = std::find_if(_segmentSlices.begin(), _segmentSlices.end(),
                                 [startSection](SegmentSlice<ELFT> *s) -> bool {
@@ -319,7 +337,7 @@ template <class ELFT> void Segment<ELFT>
         SegmentSlice<ELFT>();
     _segmentSlices.push_back(slice);
   } else {
-    slice = *sliceIter;
+    slice = (*sliceIter);
   }
   slice->setStart(startSection);
   slice->setVirtualAddr(curSliceAddress);





More information about the llvm-commits mailing list