From c75ef85e84a9437695f7b8a5778a8e3fc6ca746e Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Wed, 21 Sep 2016 03:22:18 +0000 Subject: [PATCH] Accept sh_entsize = 0. This surfaced again with Rust. As per bug 30435, rustc creates a mergeable section with a sh_entsize zero. It bit us before, too. I think we should relax the input check rather than being too picky. Differential Revision: https://reviews.llvm.org/D24789 llvm-svn: 282049 --- lld/ELF/InputFiles.cpp | 16 ++++++++++++---- lld/test/ELF/invalid-elf.test | 4 ---- lld/test/ELF/merge-invalid-size.s | 7 +++++-- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 4857d5768e76..7d6a36815cdd 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -184,15 +184,23 @@ bool elf::ObjectFile::shouldMerge(const Elf_Shdr &Sec) { if (Sec.sh_size == 0) return false; + // Check for sh_entsize. The ELF spec is not clear about the zero + // sh_entsize. It says that "the member [sh_entsize] contains 0 if + // the section does not hold a table of fixed-size entries". We know + // that Rust 1.13 produces a string mergeable section with a zero + // sh_entsize. Here we just accept it rather than being picky about it. + uintX_t EntSize = Sec.sh_entsize; + if (EntSize == 0) + return false; + if (Sec.sh_size % EntSize) + fatal(getFilename(this) + + ": SHF_MERGE section size must be a multiple of sh_entsize"); + uintX_t Flags = Sec.sh_flags; if (!(Flags & SHF_MERGE)) return false; if (Flags & SHF_WRITE) fatal(getFilename(this) + ": writable SHF_MERGE section is not supported"); - uintX_t EntSize = Sec.sh_entsize; - if (!EntSize || Sec.sh_size % EntSize) - fatal(getFilename(this) + - ": SHF_MERGE section size must be a multiple of sh_entsize"); // Don't try to merge if the alignment is larger than the sh_entsize and this // is not SHF_STRINGS. diff --git a/lld/test/ELF/invalid-elf.test b/lld/test/ELF/invalid-elf.test index c3a97d37ffa9..73516a41a8c1 100644 --- a/lld/test/ELF/invalid-elf.test +++ b/lld/test/ELF/invalid-elf.test @@ -24,10 +24,6 @@ # RUN: FileCheck --check-prefix=INVALID-SECTION-INDEX %s # INVALID-SECTION-INDEX: Invalid section index -# RUN: not ld.lld %p/Inputs/invalid-shentsize-zero.elf -o %t2 2>&1 | \ -# RUN: FileCheck --check-prefix=INVALID-SHENTSIZE-ZERO %s -# INVALID-SHENTSIZE-ZERO: SHF_MERGE section size must be a multiple of sh_entsize - # RUN: not ld.lld %p/Inputs/invalid-multiple-eh-relocs.elf -o %t2 2>&1 | \ # RUN: FileCheck --check-prefix=INVALID-EH-RELOCS %s # INVALID-EH-RELOCS: multiple relocation sections to .eh_frame are not supported diff --git a/lld/test/ELF/merge-invalid-size.s b/lld/test/ELF/merge-invalid-size.s index 2a99e14ad836..c27b21b7caaa 100644 --- a/lld/test/ELF/merge-invalid-size.s +++ b/lld/test/ELF/merge-invalid-size.s @@ -3,5 +3,8 @@ // RUN: not ld.lld %t.o -o %t.so 2>&1 | FileCheck %s // CHECK: SHF_MERGE section size must be a multiple of sh_entsize - .section .foo,"aM",@progbits,4 - .short 42 +// Test that we accept a zero sh_entsize. +// RUN: ld.lld %p/Inputs/invalid-shentsize-zero.elf -o %t2 + +.section .foo,"aM",@progbits,4 +.short 42