diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2018-05-23 01:58:43 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2018-05-23 01:58:43 +0000 |
commit | cc2395be7c7696f417cc9f3351211e06afc06909 (patch) | |
tree | 223749eae3ee6b085597817f33a18bca9805f869 | |
parent | a3c36404c94f96f8ba579cfd2f3eabb4a21ea281 (diff) |
ELF: Do not ICF two sections with different output sections.
Note that this doesn't do the right thing in the case where there is
a linker script. We probably need to move output section assignment
before ICF to get the correct behaviour here.
Differential Revision: https://reviews.llvm.org/D47241
git-svn-id: https://llvm.org/svn/llvm-project/lld/trunk@333052 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | ELF/ICF.cpp | 8 | ||||
-rw-r--r-- | ELF/InputSection.cpp | 2 | ||||
-rw-r--r-- | ELF/InputSection.h | 2 | ||||
-rw-r--r-- | ELF/Writer.cpp | 2 | ||||
-rw-r--r-- | ELF/Writer.h | 2 | ||||
-rw-r--r-- | test/ELF/icf-different-output-sections.s | 9 |
6 files changed, 21 insertions, 4 deletions
diff --git a/ELF/ICF.cpp b/ELF/ICF.cpp index 5d5cc8634..3e253a074 100644 --- a/ELF/ICF.cpp +++ b/ELF/ICF.cpp @@ -78,6 +78,7 @@ #include "SymbolTable.h" #include "Symbols.h" #include "SyntheticSections.h" +#include "Writer.h" #include "lld/Common/Threads.h" #include "llvm/ADT/Hashing.h" #include "llvm/BinaryFormat/ELF.h" @@ -302,6 +303,13 @@ bool ICF<ELFT>::equalsConstant(const InputSection *A, const InputSection *B) { A->getSize() != B->getSize() || A->Data != B->Data) return false; + // If two sections have different output sections, we cannot merge them. + // FIXME: This doesn't do the right thing in the case where there is a linker + // script. We probably need to move output section assignment before ICF to + // get the correct behaviour here. + if (getOutputSectionName(A) != getOutputSectionName(B)) + return false; + if (A->AreRelocsRela) return constantEq(A, A->template relas<ELFT>(), B, B->template relas<ELFT>()); diff --git a/ELF/InputSection.cpp b/ELF/InputSection.cpp index b958f575d..11d46cf9c 100644 --- a/ELF/InputSection.cpp +++ b/ELF/InputSection.cpp @@ -325,7 +325,7 @@ template <class ELFT> void InputSection::copyShtGroup(uint8_t *Buf) { *To++ = Sections[Idx]->getOutputSection()->SectionIndex; } -InputSectionBase *InputSection::getRelocatedSection() { +InputSectionBase *InputSection::getRelocatedSection() const { if (!File || (Type != SHT_RELA && Type != SHT_REL)) return nullptr; ArrayRef<InputSectionBase *> Sections = File->getSections(); diff --git a/ELF/InputSection.h b/ELF/InputSection.h index bc70baf8b..7a83bf9a1 100644 --- a/ELF/InputSection.h +++ b/ELF/InputSection.h @@ -317,7 +317,7 @@ public: static bool classof(const SectionBase *S); - InputSectionBase *getRelocatedSection(); + InputSectionBase *getRelocatedSection() const; template <class ELFT, class RelTy> void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels); diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp index 8bf4d764a..13bba61bf 100644 --- a/ELF/Writer.cpp +++ b/ELF/Writer.cpp @@ -92,7 +92,7 @@ static bool isSectionPrefix(StringRef Prefix, StringRef Name) { return Name.startswith(Prefix) || Name == Prefix.drop_back(); } -StringRef elf::getOutputSectionName(InputSectionBase *S) { +StringRef elf::getOutputSectionName(const InputSectionBase *S) { if (Config->Relocatable) return S->Name; diff --git a/ELF/Writer.h b/ELF/Writer.h index 41f1e550e..7806f824c 100644 --- a/ELF/Writer.h +++ b/ELF/Writer.h @@ -48,7 +48,7 @@ struct PhdrEntry { }; void addReservedSymbols(); -llvm::StringRef getOutputSectionName(InputSectionBase *S); +llvm::StringRef getOutputSectionName(const InputSectionBase *S); template <class ELFT> uint32_t calcMipsEFlags(); diff --git a/test/ELF/icf-different-output-sections.s b/test/ELF/icf-different-output-sections.s new file mode 100644 index 000000000..e66b102a1 --- /dev/null +++ b/test/ELF/icf-different-output-sections.s @@ -0,0 +1,9 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld %t -o %t2 --icf=all --print-icf-sections | count 0 + +.section foo,"ax" +.byte 42 + +.section bar,"ax" +.byte 42 |