diff options
| author | James Henderson <jh7370@my.bristol.ac.uk> | 2017-12-12 11:51:13 +0000 |
|---|---|---|
| committer | James Henderson <jh7370@my.bristol.ac.uk> | 2017-12-12 11:51:13 +0000 |
| commit | 8d0efdd5db26e2d7c1354b275313629c66a7049f (patch) | |
| tree | ff05e669a572c95b296f080f1653a63eea7d4e39 /lld/ELF/OutputSections.cpp | |
| parent | 06d340281635eff14d294e11b21bc0c19ad35c93 (diff) | |
| download | bcm5719-llvm-8d0efdd5db26e2d7c1354b275313629c66a7049f.tar.gz bcm5719-llvm-8d0efdd5db26e2d7c1354b275313629c66a7049f.zip | |
[ELF] Reset OutputSection size prior to processing linker script commands
The size of an OutputSection is calculated early, to aid handling of compressed
debug sections. However, subsequent to this point, unused synthetic sections are
removed. In the event that an OutputSection, from which such an InputSection is
removed, is still required (e.g. because it has a symbol assignment), and no longer
has any InputSections, dot assignments, or BYTE()-family directives, the size
member is never updated when processing the commands. If the removed InputSection
had a non-zero size (such as a .got.plt section), the section ends up with the
wrong size in the output.
The fix is to reset the OutputSection size prior to processing the linker script
commands relating to that OutputSection. This ensures that the size is correct even
in the above situation.
Additionally, to reduce the risk of developers misusing OutputSection Size and
InputSection OutSecOff, they are set to simply the number of InputSections in an
OutputSection, and the corresponding index respectively. We cannot completely
stop using them, due to SHF_LINK_ORDER sections requiring them.
Compressed debug sections also require the full size. This is now calculated in
maybeCompress for these kinds of sections.
Reviewers: ruiu, rafael
Differential Revision: https://reviews.llvm.org/D38361
llvm-svn: 320472
Diffstat (limited to 'lld/ELF/OutputSections.cpp')
| -rw-r--r-- | lld/ELF/OutputSections.cpp | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index b6dee4303a6..27a45c75402 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -116,13 +116,7 @@ void OutputSection::addSection(InputSection *IS) { IS->Parent = this; Flags |= IS->Flags; Alignment = std::max(Alignment, IS->Alignment); - - // The actual offsets will be computed by assignAddresses. For now, use - // crude approximation so that it is at least easy for other code to know the - // section order. It is also used to calculate the output section size early - // for compressed debug sections. - IS->OutSecOff = alignTo(Size, IS->Alignment); - this->Size = IS->OutSecOff + IS->getSize(); + IS->OutSecOff = Size++; // If this section contains a table of fixed-size entries, sh_entsize // holds the element size. If it contains elements of different size we @@ -189,6 +183,15 @@ template <class ELFT> void OutputSection::maybeCompress() { !Name.startswith(".debug_")) return; + // Calculate the section offsets and size pre-compression. + Size = 0; + for (BaseCommand *Cmd : SectionCommands) + if (auto *ISD = dyn_cast<InputSectionDescription>(Cmd)) + for (InputSection *IS : ISD->Sections) { + IS->OutSecOff = alignTo(Size, IS->Alignment); + this->Size = IS->OutSecOff + IS->getSize(); + } + // Create a section header. ZDebugHeader.resize(sizeof(Elf_Chdr)); auto *Hdr = reinterpret_cast<Elf_Chdr *>(ZDebugHeader.data()); |

