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

llvm-svn: 333052
This commit is contained in:
Peter Collingbourne 2018-05-23 01:58:43 +00:00
parent 6de0ca4296
commit 11dc7fcae2
6 changed files with 21 additions and 4 deletions

View File

@ -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>());

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -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();

View File

@ -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