From: Peter Collingbourne Date: Thu, 18 Jul 2019 16:47:29 +0000 (+0000) Subject: ELF: Allow forward references to linked sections. X-Git-Tag: llvmorg-11-init~14087 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cb2d8e912512305fb5c45cf0f35f654f713dfa7c;p=platform%2Fupstream%2Fllvm.git ELF: Allow forward references to linked sections. It's possible to create IR that uses !associated to refer to a global that appears later in the module, which can result in these types of forward references being generated. Unfortunately our assembler does not currently accept the resulting .s so I needed to use yaml2obj to test this. Differential Revision: https://reviews.llvm.org/D64880 llvm-svn: 366460 --- diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 98b8828..eeb5845 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -573,7 +573,7 @@ void ObjFile::initializeSections(bool ignoreComdats) { this->sectionStringTable = CHECK(obj.getSectionStringTable(objSections), this); - for (size_t i = 0, e = objSections.size(); i < e; i++) { + for (size_t i = 0, e = objSections.size(); i < e; ++i) { if (this->sections[i] == &InputSection::discarded) continue; const Elf_Shdr &sec = objSections[i]; @@ -652,25 +652,29 @@ void ObjFile::initializeSections(bool ignoreComdats) { default: this->sections[i] = createInputSection(sec); } + } + + for (size_t i = 0, e = objSections.size(); i < e; ++i) { + if (this->sections[i] == &InputSection::discarded) + continue; + const Elf_Shdr &sec = objSections[i]; + if (!(sec.sh_flags & SHF_LINK_ORDER)) + continue; // .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_flags & SHF_LINK_ORDER) { - InputSectionBase *linkSec = nullptr; - if (sec.sh_link < this->sections.size()) - linkSec = this->sections[sec.sh_link]; - if (!linkSec) - fatal(toString(this) + - ": invalid sh_link index: " + Twine(sec.sh_link)); - - InputSection *isec = cast(this->sections[i]); - linkSec->dependentSections.push_back(isec); - if (!isa(linkSec)) - error("a section " + isec->name + - " with SHF_LINK_ORDER should not refer a non-regular " - "section: " + - toString(linkSec)); - } + InputSectionBase *linkSec = nullptr; + if (sec.sh_link < this->sections.size()) + linkSec = this->sections[sec.sh_link]; + if (!linkSec) + fatal(toString(this) + ": invalid sh_link index: " + Twine(sec.sh_link)); + + InputSection *isec = cast(this->sections[i]); + linkSec->dependentSections.push_back(isec); + if (!isa(linkSec)) + error("a section " + isec->name + + " with SHF_LINK_ORDER should not refer a non-regular section: " + + toString(linkSec)); } } diff --git a/lld/test/ELF/linkorder-forward-ref.test b/lld/test/ELF/linkorder-forward-ref.test new file mode 100644 index 0000000..2e00516 --- /dev/null +++ b/lld/test/ELF/linkorder-forward-ref.test @@ -0,0 +1,23 @@ +# REQUIRES: x86 +# RUN: yaml2obj %s -o %t.o +# RUN: ld.lld %t.o -o %t +# RUN: llvm-readelf -S %t | FileCheck %s + +## Test that we accept forward sh_link references. + +# CHECK: .linkorder +# CHECK: .text + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .linkorder + Type: SHT_PROGBITS + Flags: [ SHF_LINK_ORDER ] + Link: 2 + - Name: .text + Type: SHT_PROGBITS