diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 03573577dcfb..ed9c88fd1a73 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -288,7 +288,7 @@ void LinkerScript::addSection(OutputSectionFactory &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); diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 0e99de5d45ea..32fe19b2f8cd 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -631,9 +631,9 @@ template OutputSectionFactory::~OutputSectionFactory() {} template std::pair OutputSectionFactory::create(InputSectionBase *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 std::pair OutputSectionFactory::create(const SectionKey &Key, - InputSectionBase *C) { + InputSectionBase *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)); diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index 36713225840c..d21d6a4d818d 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -238,10 +238,10 @@ template class OutputSectionFactory { public: OutputSectionFactory(); ~OutputSectionFactory(); - std::pair create(InputSectionBase *C, - StringRef OutsecName); - std::pair create(const SectionKey &Key, - InputSectionBase *C); + std::pair + create(InputSectionBase *C, StringRef OutsecName, bool IsScripted); + std::pair + create(const SectionKey &Key, InputSectionBase *C, bool IsScripted); private: llvm::SmallDenseMap Map; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 0715bf04d6de..3ed91fd51a0f 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -840,7 +840,7 @@ void Writer::addInputSec(InputSectionBase *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); diff --git a/lld/test/ELF/linkerscript/section-types.s b/lld/test/ELF/linkerscript/section-types.s new file mode 100644 index 000000000000..0e47fa31a2d6 --- /dev/null +++ b/lld/test/ELF/linkerscript/section-types.s @@ -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