diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -639,6 +639,8 @@ // .ARM.exidx sections have a reverse dependency on the InputSection they // have a SHF_LINK_ORDER dependency, this is identified by the sh_link. + if (!sec.sh_link) + continue; InputSectionBase *linkSec = nullptr; if (sec.sh_link < this->sections.size()) linkSec = this->sections[sec.sh_link]; diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -274,8 +274,9 @@ } InputSection *InputSectionBase::getLinkOrderDep() const { - assert(link); assert(flags & SHF_LINK_ORDER); + if (!link) + return nullptr; return cast(file->getSections()[link]); } diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1500,6 +1500,8 @@ static bool compareByFilePosition(InputSection *a, InputSection *b) { InputSection *la = a->getLinkOrderDep(); InputSection *lb = b->getLinkOrderDep(); + if (!la || !lb) + return !la && lb; OutputSection *aOut = la->getParent(); OutputSection *bOut = lb->getParent(); @@ -1530,7 +1532,7 @@ sections.push_back(isec); InputSection *link = isec->getLinkOrderDep(); - if (!link->getParent()) + if (link && !link->getParent()) error(toString(isec) + ": sh_link points to discarded section " + toString(link)); } diff --git a/lld/test/ELF/invalid/linkorder-invalid-sec2.test b/lld/test/ELF/invalid/linkorder-invalid-sec2.test deleted file mode 100644 --- a/lld/test/ELF/invalid/linkorder-invalid-sec2.test +++ /dev/null @@ -1,16 +0,0 @@ -# REQUIRES: x86 -# RUN: yaml2obj %s -o %t.o -# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s -# CHECK: invalid sh_link index: 0 - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 -Sections: - - Name: .linkorder - Type: SHT_PROGBITS - Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_LINK_ORDER ] - Link: 0 diff --git a/lld/test/ELF/linkorder-mixed-link.test b/lld/test/ELF/linkorder-mixed-link.test new file mode 100644 --- /dev/null +++ b/lld/test/ELF/linkorder-mixed-link.test @@ -0,0 +1,33 @@ +## Test that we allow SHF_LINK_ORDER sections with sh_link=0. +# RUN: yaml2obj %s -o %t.o +# RUN: ld.lld %t.o -o %t +# RUN: llvm-readelf -S %t | FileCheck %s + +# CHECK: Name {{.*}} Flg Lk Inf +# CHECK: .linkorder {{.*}} AL 0 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text [0] + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + - Name: .text [1] + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + - Name: .linkorder [0] + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_LINK_ORDER ] + Link: 0 + - Name: .linkorder [1] + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_LINK_ORDER ] + Link: 1 + - Name: .linkorder [2] + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_LINK_ORDER ] + Link: 2