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
This commit is contained in:
Peter Collingbourne 2019-07-18 16:47:29 +00:00
parent 6454a20b72
commit cb2d8e9125
2 changed files with 43 additions and 16 deletions

View File

@ -573,7 +573,7 @@ void ObjFile<ELFT>::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<ELFT>::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));
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<InputSection>(this->sections[i]);
linkSec->dependentSections.push_back(isec);
if (!isa<InputSection>(linkSec))
error("a section " + isec->name +
" with SHF_LINK_ORDER should not refer a non-regular "
"section: " +
toString(linkSec));
}
InputSection *isec = cast<InputSection>(this->sections[i]);
linkSec->dependentSections.push_back(isec);
if (!isa<InputSection>(linkSec))
error("a section " + isec->name +
" with SHF_LINK_ORDER should not refer a non-regular section: " +
toString(linkSec));
}
}

View File

@ -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