From bcba39ab9c8c4d2faeff70774fca91b1efec79e3 Mon Sep 17 00:00:00 2001 From: George Rimar Date: Wed, 2 Nov 2016 10:16:25 +0000 Subject: [PATCH] [ELF] - Check that .dynsym is present in DSO if SHT_GNU_versym section is. When we have SHT_GNU_versym section, it is should be associated with symbol table section. Usually (and in out implementation) it is .dynsym. In case when .dynsym is absent (due to broken object for example), lld crashes in parseVerdefs() when accesses null pointer: Versym = reinterpret_cast(this->ELFObj.base() + VersymSec->sh_offset) + this->Symtab->sh_info; DIfferential revision: https://reviews.llvm.org/D25553 llvm-svn: 285796 --- lld/ELF/InputFiles.cpp | 3 +++ lld/ELF/SymbolTable.cpp | 2 +- lld/test/ELF/invalid/verdef-no-symtab.test | 26 ++++++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 lld/test/ELF/invalid/verdef-no-symtab.test diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 6900f8f325d8..25fff944c2e4 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -610,6 +610,9 @@ template void SharedFile::parseSoName() { } } + if (this->VersymSec && !this->Symtab) + error("SHT_GNU_versym should be associated with symbol table"); + this->initStringTable(); // DSOs are identified by soname, and they usually contain diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index c45ab94d0b57..0d8c62dd4751 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -77,7 +77,7 @@ template void SymbolTable::addFile(InputFile *File) { if (auto *F = dyn_cast>(File)) { // DSOs are uniquified not by filename but by soname. F->parseSoName(); - if (!SoNames.insert(F->getSoName()).second) + if (HasError || !SoNames.insert(F->getSoName()).second) return; SharedFiles.push_back(F); F->parseRest(); diff --git a/lld/test/ELF/invalid/verdef-no-symtab.test b/lld/test/ELF/invalid/verdef-no-symtab.test new file mode 100644 index 000000000000..5b5c32e4ff5c --- /dev/null +++ b/lld/test/ELF/invalid/verdef-no-symtab.test @@ -0,0 +1,26 @@ +# RUN: yaml2obj %s -o %t +# RUN: not ld.lld %t -o %tout 2>&1 | FileCheck %s + +## When we have SHT_GNU_versym section, it is should be associated +## with symbol table section. +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .versym + Type: SHT_GNU_versym + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x1 + Content: "00000000" + + - Name: .verdef + Type: SHT_GNU_verdef + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x1 + Content: "00000000" + + +# CHECK: SHT_GNU_versym should be associated with symbol table