[PATCH] D66658: [ELF] Align the first section of a PT_LOAD even if its type is SHT_NOBITS
Peter Collingbourne via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 23 10:01:53 PDT 2019
pcc added a comment.
Thanks @MaskRay and @peter.smith for investigating this problem, I can confirm that this change fixes it for me.
================
Comment at: ELF/Writer.cpp:2277
+ // p_vaddr=p_offset (mod p_align).
+ if (os->type == SHT_NOBITS && !(os->ptLoad && os->ptLoad->firstSec == os))
return off;
----------------
Maybe it would be better to reorder the if statements here to make the logic slightly easier to understand? This seems to work:
```
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index fde253796a1..f14951f403b 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -2269,8 +2269,16 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
// 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.
+ // The first section in a PT_LOAD has to have congruent offset and address
+ // module the page size.
+ if (os->ptLoad && os->ptLoad->firstSec == os) {
+ uint64_t alignment = std::max<uint64_t>(os->alignment, 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;
@@ -2278,16 +2286,9 @@ static uint64_t computeFileOffset(OutputSection *os, uint64_t off) {
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);
- return alignTo(off, alignment, os->addr);
- }
-
// 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;
}
```
Repository:
rLLD LLVM Linker
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D66658/new/
https://reviews.llvm.org/D66658
More information about the llvm-commits
mailing list