diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -259,7 +259,8 @@ void initializeSymbols(); void initializeJustSymbols(); - InputSectionBase *getRelocTarget(const Elf_Shdr &sec); + InputSectionBase *getRelocTarget(uint32_t idx, StringRef name, + const Elf_Shdr &sec); InputSectionBase *createInputSection(uint32_t idx, const Elf_Shdr &sec, StringRef shstrtab); diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -837,21 +837,25 @@ } template -InputSectionBase *ObjFile::getRelocTarget(const Elf_Shdr &sec) { - uint32_t idx = sec.sh_info; - if (idx >= this->sections.size()) - fatal(toString(this) + ": invalid relocated section index: " + Twine(idx)); - InputSectionBase *target = this->sections[idx]; - - // Strictly speaking, a relocation section must be included in the - // group of the section it relocates. However, LLVM 3.3 and earlier - // would fail to do so, so we gracefully handle that case. - if (target == &InputSection::discarded) - return nullptr; - - if (!target) - fatal(toString(this) + ": unsupported relocation reference"); - return target; +InputSectionBase *ObjFile::getRelocTarget(uint32_t idx, StringRef name, + const Elf_Shdr &sec) { + uint32_t info = sec.sh_info; + if (info < this->sections.size()) { + InputSectionBase *target = this->sections[info]; + + // Strictly speaking, a relocation section must be included in the + // group of the section it relocates. However, LLVM 3.3 and earlier + // would fail to do so, so we gracefully handle that case. + if (target == &InputSection::discarded) + return nullptr; + + if (target != nullptr) + return target; + } + + error(toString(this) + Twine(": relocation section ") + name + " (index " + + Twine(idx) + ") has invalid sh_info (" + Twine(info) + ")"); + return nullptr; } // Create a regular InputSection class that has the same contents @@ -939,7 +943,7 @@ // and the group is discarded, even though it's a violation of the // spec. We handle that situation gracefully by discarding dangling // relocation sections. - InputSectionBase *target = getRelocTarget(sec); + InputSectionBase *target = getRelocTarget(idx, name, sec); if (!target) return nullptr; diff --git a/lld/test/ELF/invalid-relocations.test b/lld/test/ELF/invalid-relocations.test deleted file mode 100644 --- a/lld/test/ELF/invalid-relocations.test +++ /dev/null @@ -1,23 +0,0 @@ -# RUN: yaml2obj %s -o %t -# RUN: not ld.lld %t -o /dev/null 2>&1 | FileCheck %s - -!ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 -Sections: - - Type: SHT_PROGBITS - - Name: .rela.text - Type: SHT_RELA - Info: 12 # Invalid index - Relocations: - - Offset: 0x0000000000000001 - Symbol: lulz - Type: R_X86_64_PC32 -Symbols: - - Name: lulz - Binding: STB_GLOBAL - -# CHECK: invalid relocated section index diff --git a/lld/test/ELF/invalid/bad-reloc-target.test b/lld/test/ELF/invalid/bad-reloc-target.test --- a/lld/test/ELF/invalid/bad-reloc-target.test +++ b/lld/test/ELF/invalid/bad-reloc-target.test @@ -1,6 +1,6 @@ # RUN: yaml2obj --docnum=1 %s -o %t1.o # RUN: not ld.lld %t1.o -o /dev/null 2>&1 | FileCheck %s -# CHECK: error: {{.*}}.o: unsupported relocation reference +# CHECK: error: {{.*}}.o: relocation section .rela.text (index 2) has invalid sh_info (0) --- !ELF FileHeader: @@ -25,7 +25,7 @@ # RUN: yaml2obj --docnum=2 %s -o %t2.o # RUN: not ld.lld %t2.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2 -# ERR2: error: {{.*}}.o: invalid relocated section index: 99 +# ERR2: error: {{.*}}.o: relocation section .rela.text (index 2) has invalid sh_info (99) --- !ELF FileHeader: