From 3ebc71eb9113885f4e3c29d024a504d5e470f37c Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Wed, 3 Aug 2016 05:28:02 +0000 Subject: [PATCH] Do not handle zero-sized mergeable section as mergeable. Mergeable sections with size zero are useless because they don't actually contain data, and therefore there's no merit ot merge them. However, in reality, there are object files in the wild containing such sections. Currently, LLD can't handle them proerply. This patch makes LLD to handle such sections as if they are non- mergeable to fix the issue. Fixes bug 28822. llvm-svn: 277568 --- lld/ELF/InputFiles.cpp | 7 +++++++ lld/test/ELF/merge-string-empty.s | 12 ++++++++++++ lld/test/ELF/relocation-past-merge-end.s | 7 ++++--- lld/test/ELF/writable-merge.s | 1 + 4 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 lld/test/ELF/merge-string-empty.s diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 6caf567e3f2e..009aa1f75fae 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -162,6 +162,13 @@ bool elf::ObjectFile::shouldMerge(const Elf_Shdr &Sec) { if (Config->Optimize == 0) return false; + // A mergeable section with size 0 is useless because they don't have + // any data to merge. A mergeable string section with size 0 can be + // argued as invalid because it doesn't end with a null character. + // We'll avoid a mess by handling them as if they were non-mergeable. + if (Sec.sh_size == 0) + return false; + uintX_t Flags = Sec.sh_flags; if (!(Flags & SHF_MERGE)) return false; diff --git a/lld/test/ELF/merge-string-empty.s b/lld/test/ELF/merge-string-empty.s new file mode 100644 index 000000000000..0b82ce700a2c --- /dev/null +++ b/lld/test/ELF/merge-string-empty.s @@ -0,0 +1,12 @@ +// Ensure that a mergeable string with size 0 does not cause any issue. + +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -o %t + +.globl _start, s +.section .rodata.str1.1,"aMS",@progbits,1 +s: +.text +_start: + .quad s diff --git a/lld/test/ELF/relocation-past-merge-end.s b/lld/test/ELF/relocation-past-merge-end.s index de67a458dcee..0900d0e7d4d3 100644 --- a/lld/test/ELF/relocation-past-merge-end.s +++ b/lld/test/ELF/relocation-past-merge-end.s @@ -3,6 +3,7 @@ // RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s // CHECK: relocation-past-merge-end.s.tmp.o(.foo): entry is past the end of the section - .data - .long .foo + 1 - .section .foo,"aM",@progbits,4 +.data +.long .foo + 10 +.section .foo,"aM",@progbits,4 +.quad 0 diff --git a/lld/test/ELF/writable-merge.s b/lld/test/ELF/writable-merge.s index 431cb6282d91..3006fa387fb5 100644 --- a/lld/test/ELF/writable-merge.s +++ b/lld/test/ELF/writable-merge.s @@ -4,3 +4,4 @@ // CHECK: writable SHF_MERGE section is not supported .section .foo,"awM",@progbits,4 +.quad 0