[ELF] Bypass section type check

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

llvm-svn: 293276
This commit is contained in:
Eugene Leviant 2017-01-27 11:01:43 +00:00
parent 73190d3906
commit 8b7cadcf96
5 changed files with 28 additions and 14 deletions

View File

@ -288,7 +288,7 @@ void LinkerScript<ELFT>::addSection(OutputSectionFactory<ELFT> &Factory,
StringRef Name) {
OutputSectionBase *OutSec;
bool IsNew;
std::tie(OutSec, IsNew) = Factory.create(Sec, Name);
std::tie(OutSec, IsNew) = Factory.create(Sec, Name, true);
if (IsNew)
OutputSections->push_back(OutSec);
OutSec->addSection(Sec);

View File

@ -631,9 +631,9 @@ template <class ELFT> OutputSectionFactory<ELFT>::~OutputSectionFactory() {}
template <class ELFT>
std::pair<OutputSectionBase *, bool>
OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C,
StringRef OutsecName) {
StringRef OutsecName, bool IsScripted) {
SectionKey Key = createKey(C, OutsecName);
return create(Key, C);
return create(Key, C, IsScripted);
}
static uint64_t getIncompatibleFlags(uint64_t Flags) {
@ -643,18 +643,19 @@ static uint64_t getIncompatibleFlags(uint64_t Flags) {
template <class ELFT>
std::pair<OutputSectionBase *, bool>
OutputSectionFactory<ELFT>::create(const SectionKey &Key,
InputSectionBase<ELFT> *C) {
InputSectionBase<ELFT> *C, bool IsScripted) {
uintX_t Flags = getOutFlags(C);
OutputSectionBase *&Sec = Map[Key];
if (Sec) {
if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(C->Flags))
error("Section has flags incompatible with others with the same name " +
toString(C));
// Convert notbits to progbits if they are mixed. This happens is some
// linker scripts.
if (Sec->Type == SHT_NOBITS && C->Type == SHT_PROGBITS)
Sec->Type = SHT_PROGBITS;
if (Sec->Type != C->Type &&
// Convert notbits to progbits if they are mixed. This happens is some
// linker scripts.
if (Sec->Type == SHT_NOBITS && C->Type == SHT_PROGBITS)
Sec->Type = SHT_PROGBITS;
if (!IsScripted && Sec->Type != C->Type &&
!(Sec->Type == SHT_PROGBITS && C->Type == SHT_NOBITS))
error("Section has different type from others with the same name " +
toString(C));

View File

@ -238,10 +238,10 @@ template <class ELFT> class OutputSectionFactory {
public:
OutputSectionFactory();
~OutputSectionFactory();
std::pair<OutputSectionBase *, bool> create(InputSectionBase<ELFT> *C,
StringRef OutsecName);
std::pair<OutputSectionBase *, bool> create(const SectionKey &Key,
InputSectionBase<ELFT> *C);
std::pair<OutputSectionBase *, bool>
create(InputSectionBase<ELFT> *C, StringRef OutsecName, bool IsScripted);
std::pair<OutputSectionBase *, bool>
create(const SectionKey &Key, InputSectionBase<ELFT> *C, bool IsScripted);
private:
llvm::SmallDenseMap<SectionKey, OutputSectionBase *> Map;

View File

@ -840,7 +840,7 @@ void Writer<ELFT>::addInputSec(InputSectionBase<ELFT> *IS) {
OutputSectionBase *Sec;
bool IsNew;
StringRef OutsecName = getOutputSectionName(IS->Name);
std::tie(Sec, IsNew) = Factory.create(IS, OutsecName);
std::tie(Sec, IsNew) = Factory.create(IS, OutsecName, false);
if (IsNew)
OutputSections.push_back(Sec);
Sec->addSection(IS);

View File

@ -0,0 +1,13 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
# RUN: echo "SECTIONS { " > %t.script
# RUN: echo ".bar : { *(.foo) *(.init_array) }" >> %t.script
# RUN: echo "}" >> %t.script
# RUN: ld.lld -o %t1 --script %t.script %t
.section .foo,"aw"
.quad 1
.section .init_array,"aw",@init_array
.quad 0