Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Sep 2019 17:53:42 +0000 (UTC)
From:      Dimitry Andric <dim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r351879 - projects/clang900-import/contrib/llvm/tools/lld/ELF
Message-ID:  <201909051753.x85HrgAi036673@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dim
Date: Thu Sep  5 17:53:41 2019
New Revision: 351879
URL: https://svnweb.freebsd.org/changeset/base/351879

Log:
  Pull in r369828 from upstream lld trunk (by Fāng-ruì Sòng):
  
    [ELF] Align the first section of a PT_LOAD even if its type is
    SHT_NOBITS
  
    Reported at https://reviews.llvm.org/D64930#1642223
  
    If the only section of a PT_LOAD is a SHT_NOBITS section (e.g. .bss),
    we may not align its sh_offset. p_offset of the PT_LOAD will be set
    to sh_offset, and we will get p_offset!=p_vaddr (mod p_align).  If
    such executable is mapped by the Linux kernel, it will segfault.
  
    After D64906, this may happen the non-linker script case.
  
    The linker script case has had this issue for a long time.  This was
    fixed by rL321657 (but the test linkerscript/nobits-offset.s failed
    to test a SHT_NOBITS section), but broken by rL345154.
  
    Reviewed By: peter.smith
  
    Differential Revision: https://reviews.llvm.org/D66658
  
  Pull in r371013 from upstream lld trunk (by Rui Ueyama):
  
    Align output segments correctly
  
    Previously, segments were aligned according to their first section's
    alignment requirements. That was not correct, but segments are also
    aligned to a page boundary, and a page boundary is usually much
    larger than a section alignment requirement, so no one noticed this
    bug before.
  
    Now, lld has --nmagic option which sets maxPageSize to 1 to
    effectively disable page alignment, which reveals the issue.
  
    Fixes https://bugs.llvm.org/show_bug.cgi?id=43212
  
    Differential Revision: https://reviews.llvm.org/D67152
  
  Together, these should ensure gpboot.out gets a correctly aligned offset
  for its .rodata section, and fix "layout constraint violation" errors
  from objcopy.

Modified:
  projects/clang900-import/contrib/llvm/tools/lld/ELF/Writer.cpp

Modified: projects/clang900-import/contrib/llvm/tools/lld/ELF/Writer.cpp
==============================================================================
--- projects/clang900-import/contrib/llvm/tools/lld/ELF/Writer.cpp	Thu Sep  5 17:48:39 2019	(r351878)
+++ projects/clang900-import/contrib/llvm/tools/lld/ELF/Writer.cpp	Thu Sep  5 17:53:41 2019	(r351879)
@@ -2230,25 +2230,27 @@ template <class ELFT> void Writer<ELFT>::fixSectionAli
 // same with its virtual address modulo the page size, so that the loader can
 // load executables without any address adjustment.
 static uint64_t computeFileOffset(OutputSection *os, uint64_t off) {
-  // File offsets are not significant for .bss sections. By convention, we keep
-  // section offsets monotonically increasing rather than setting to zero.
-  if (os->type == SHT_NOBITS)
-    return off;
-
-  // If the section is not in a PT_LOAD, we just have to align it.
-  if (!os->ptLoad)
-    return alignTo(off, os->alignment);
-
   // The first section in a PT_LOAD has to have congruent offset and address
   // module the page size.
-  OutputSection *first = os->ptLoad->firstSec;
-  if (os == first) {
-    uint64_t alignment = std::max<uint64_t>(os->alignment, config->maxPageSize);
+  if (os->ptLoad && os->ptLoad->firstSec == os) {
+    uint64_t alignment =
+        std::max<uint64_t>(os->ptLoad->p_align, config->maxPageSize);
     return alignTo(off, alignment, os->addr);
   }
 
+  // File offsets are not significant for .bss sections other than the first one
+  // in a PT_LOAD. By convention, we keep section offsets monotonically
+  // increasing rather than setting to zero.
+   if (os->type == SHT_NOBITS)
+     return off;
+
+  // If the section is not in a PT_LOAD, we just have to align it.
+  if (!os->ptLoad)
+    return alignTo(off, os->alignment);
+
   // If two sections share the same PT_LOAD the file offset is calculated
   // using this formula: Off2 = Off1 + (VA2 - VA1).
+  OutputSection *first = os->ptLoad->firstSec;
   return first->offset + os->addr - first->addr;
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201909051753.x85HrgAi036673>