diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 085b7504c222..e82f8c3016fa 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -73,6 +73,16 @@ InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags, this->Alignment = V; } +// Drop SHF_GROUP bit unless we are producing a re-linkable object file. +// SHF_GROUP is a marker that a section belongs to some comdat group. +// That flag doesn't make sense in an executable. +static uint64_t getFlags(uint64_t Flags) { + Flags &= ~(uint64_t)SHF_INFO_LINK; + if (!Config->Relocatable) + Flags &= ~(uint64_t)SHF_GROUP; + return Flags; +} + // GNU assembler 2.24 and LLVM 4.0.0's MC (the newest release as of // March 2017) fail to infer section types for sections starting with // ".init_array." or ".fini_array.". They set SHT_PROGBITS instead of @@ -95,7 +105,7 @@ template InputSectionBase::InputSectionBase(elf::ObjectFile *File, const typename ELFT::Shdr *Hdr, StringRef Name, Kind SectionKind) - : InputSectionBase(File, Hdr->sh_flags & ~SHF_INFO_LINK, + : InputSectionBase(File, getFlags(Hdr->sh_flags), getType(Hdr->sh_type, Name), Hdr->sh_entsize, Hdr->sh_link, Hdr->sh_info, Hdr->sh_addralign, getSectionContents(File, Hdr), Name, SectionKind) { diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 47042b6eb66d..008871fd3889 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -313,10 +313,6 @@ void OutputSectionFactory::addInputSec(InputSectionBase *IS, return; } - uint64_t Flags = IS->Flags; - if (!Config->Relocatable) - Flags &= ~(uint64_t)SHF_GROUP; - if (Sec) { if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags)) error("incompatible section flags for " + Sec->Name + @@ -333,9 +329,9 @@ void OutputSectionFactory::addInputSec(InputSectionBase *IS, "\n>>> output section " + Sec->Name + ": " + getELFSectionTypeName(Config->EMachine, Sec->Type)); } - Sec->Flags |= Flags; + Sec->Flags |= IS->Flags; } else { - Sec = make(OutsecName, IS->Type, Flags); + Sec = make(OutsecName, IS->Type, IS->Flags); OutputSections.push_back(Sec); } diff --git a/lld/test/ELF/arm-icf-exidx.s b/lld/test/ELF/arm-icf-exidx.s index cb801b7f2420..6af30285db67 100644 --- a/lld/test/ELF/arm-icf-exidx.s +++ b/lld/test/ELF/arm-icf-exidx.s @@ -19,13 +19,15 @@ g: .section .text.h .global __aeabi_unwind_cpp_pr0 __aeabi_unwind_cpp_pr0: + nop bx lr // CHECK: Disassembly of section .text: // CHECK-NEXT: f: // CHECK-NEXT: 11000: 1e ff 2f e1 bx lr // CHECK: __aeabi_unwind_cpp_pr0: -// CHECK-NEXT: 11004: 1e ff 2f e1 bx lr +// CHECK-NEXT: 11004: 00 f0 20 e3 nop +// CHECK-NEXT: 11008: 1e ff 2f e1 bx lr // CHECK: Contents of section .ARM.exidx: // CHECK-NEXT: 100d4 2c0f0000 b0b0b080 280f0000 01000000 diff --git a/lld/test/ELF/icf-comdat.s b/lld/test/ELF/icf-comdat.s new file mode 100644 index 000000000000..28c0a586bf03 --- /dev/null +++ b/lld/test/ELF/icf-comdat.s @@ -0,0 +1,23 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s + +# CHECK: selected .text.f1 +# CHECK: removed .text.f2 + +.globl _start, f1, f2 +_start: + ret + +.section .text.f1,"ax" +f1: + mov $60, %rax + mov $42, %rdi + syscall + +.section .text.f2,"axG",@progbits,foo,comdat +f2: + mov $60, %rax + mov $42, %rdi + syscall