svn commit: r351879 - projects/clang900-import/contrib/llvm/tools/lld/ELF
Dimitry Andric
dim at FreeBSD.org
Thu Sep 5 17:53:42 UTC 2019
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;
}
More information about the svn-src-projects
mailing list