From: Fangrui Song Date: Tue, 26 May 2020 18:06:07 +0000 (-0700) Subject: [ELF] Allow misaligned SHT_GNU_verneed X-Git-Tag: llvmorg-12-init~5111 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b8a3c618d6c5df081cad69b5ffb386a7a7b0361f;p=platform%2Fupstream%2Fllvm.git [ELF] Allow misaligned SHT_GNU_verneed Bazel created interface shared objects (.ifso) may be misaligned. We use llvm::support::detail::packed_endian_specific_integral under the hood which allows reading of misaligned values, so there is not a need to diagnose (in LLD we don't intend to support sophisticated parsing for SHT_GNU_*). --- diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 9fdd054..c451aee 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1224,14 +1224,12 @@ std::vector SharedFile::parseVerneed(const ELFFile &obj, ArrayRef data = CHECK(obj.getSectionContents(sec), this); const uint8_t *verneedBuf = data.begin(); for (unsigned i = 0; i != sec->sh_info; ++i) { - if (verneedBuf + sizeof(typename ELFT::Verneed) > data.end() || - uintptr_t(verneedBuf) % sizeof(uint32_t) != 0) + if (verneedBuf + sizeof(typename ELFT::Verneed) > data.end()) fatal(toString(this) + " has an invalid Verneed"); auto *vn = reinterpret_cast(verneedBuf); const uint8_t *vernauxBuf = verneedBuf + vn->vn_aux; for (unsigned j = 0; j != vn->vn_cnt; ++j) { - if (vernauxBuf + sizeof(typename ELFT::Vernaux) > data.end() || - uintptr_t(vernauxBuf) % sizeof(uint32_t) != 0) + if (vernauxBuf + sizeof(typename ELFT::Vernaux) > data.end()) fatal(toString(this) + " has an invalid Vernaux"); auto *aux = reinterpret_cast(vernauxBuf); if (aux->vna_name >= this->stringTable.size()) diff --git a/lld/test/ELF/invalid/verneed-shared.yaml b/lld/test/ELF/invalid/verneed-shared.test similarity index 89% rename from lld/test/ELF/invalid/verneed-shared.yaml rename to lld/test/ELF/invalid/verneed-shared.test index 18315fe..916b8c1 100644 --- a/lld/test/ELF/invalid/verneed-shared.yaml +++ b/lld/test/ELF/invalid/verneed-shared.test @@ -6,7 +6,7 @@ ## sh_offset(SHT_GNU_verneed) is out of bounds. # RUN: yaml2obj --docnum=1 %s -o %t1.so # RUN: not ld.lld %t.o %t1.so -o /dev/null 2>&1 | FileCheck --check-prefix=SHOFFSET %s -# SHOFFSET: error: {{.*}}.so: section [index 1] has a sh_offset (0xffffffff) + sh_size (0x0) that is greater than the file size (0x228) +# SHOFFSET: error: {{.*}}.so: section [index 1] has a sh_offset (0xffffffff) + sh_size (0x0) that is greater than the file size (0x168) --- !ELF FileHeader: Class: ELFCLASS64 @@ -17,12 +17,14 @@ Sections: - Name: .gnu.version_r Type: SHT_GNU_verneed Flags: [ SHF_ALLOC ] + Info: 1 ShOffset: 0xFFFFFFFF -## A Verneed entry is misaligned (not a multiple of 4). +## A Verneed entry is misaligned (not a multiple of 4). This may happen +## some interface shared objects. We use memcpy to read the fields, so +## misalignment isn't a problem and there is no need to diagnose. # RUN: yaml2obj --docnum=2 %s -o %t2.so -# RUN: not ld.lld %t.o %t2.so -o /dev/null 2>&1 | FileCheck --check-prefix=VN-MISALIGNED %s -# VN-MISALIGNED: {{.*}}.so has an invalid Verneed +# RUN: ld.lld %t.o %t2.so -o /dev/null --- !ELF FileHeader: Class: ELFCLASS64