[ELF] - Allow section to have multiple dependent sections.

That fixes a case when section has more than one metadata 
section. Previously GC would collect one of such sections 
because we had implementation that stored only last one as
dependent.

Differential revision: https://reviews.llvm.org/D29981

llvm-svn: 295298
This commit is contained in:
George Rimar 2017-02-16 08:41:19 +00:00
parent 14246c937d
commit 09015fee3c
4 changed files with 24 additions and 5 deletions

View File

@ -323,7 +323,7 @@ void elf::ObjectFile<ELFT>::initializeSections(
fatal(toString(this) + ": invalid sh_link index: " +
Twine(Sec.sh_link));
auto *IS = cast<InputSection<ELFT>>(Sections[Sec.sh_link]);
IS->DependentSection = Sections[I];
IS->DependentSections.push_back(Sections[I]);
}
}
}

View File

@ -281,8 +281,8 @@ public:
// to. The writer sets a value.
uint64_t OutSecOff = 0;
// InputSection that is dependent on us (reverse dependency for GC)
InputSectionBase<ELFT> *DependentSection = nullptr;
// InputSections that are dependent on us (reverse dependency for GC)
llvm::TinyPtrVector<InputSectionBase<ELFT> *> DependentSections;
static bool classof(const InputSectionData *S);

View File

@ -87,8 +87,8 @@ static void forEachSuccessor(InputSection<ELFT> &Sec,
for (const typename ELFT::Rel &Rel : Sec.rels())
Fn(resolveReloc(Sec, Rel));
}
if (Sec.DependentSection)
Fn({Sec.DependentSection, 0});
for (InputSectionBase<ELFT> *IS : Sec.DependentSections)
Fn({IS, 0});
}
// The .eh_frame section is an unfortunate special case.

View File

@ -0,0 +1,19 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
# RUN: ld.lld --gc-sections %t.o -o %t
# RUN: llvm-objdump -section-headers %t | FileCheck %s
# CHECK: .foo
# CHECK: .bar
# CHECK: .zed
.globl _start
_start:
.quad .foo
.section .foo,"a"
.quad 0
.section .bar,"am",@progbits,.foo
.quad 0
.section .zed,"am",@progbits,.foo
.quad 0