Index: lld/ELF/InputFiles.cpp =================================================================== --- lld/ELF/InputFiles.cpp +++ lld/ELF/InputFiles.cpp @@ -320,17 +320,6 @@ return Signature; } -template -ArrayRef::Elf_Word> -ObjFile::getShtGroupEntries(const Elf_Shdr &Sec) { - const ELFFile &Obj = this->getObj(); - ArrayRef Entries = - CHECK(Obj.template getSectionContentsAsArray(&Sec), this); - if (Entries.empty() || Entries[0] != GRP_COMDAT) - fatal(toString(this) + ": unsupported SHT_GROUP format"); - return Entries.slice(1); -} - template bool ObjFile::shouldMerge(const Elf_Shdr &Sec) { // On a regular link we don't merge sections if -O0 (default is -O1). This // sometimes makes the linker significantly faster, although the output will @@ -440,30 +429,43 @@ case SHT_GROUP: { // De-duplicate section groups by their signatures. StringRef Signature = getShtGroupSignature(ObjSections, Sec); - bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second; + + const ELFFile &Obj = this->getObj(); + ArrayRef Entries = + CHECK(Obj.template getSectionContentsAsArray(&Sec), this); this->Sections[I] = &InputSection::Discarded; - // We only support GRP_COMDAT type of group. Get the all entries of the - // section here to let getShtGroupEntries to check the type early for us. - ArrayRef Entries = getShtGroupEntries(Sec); + // We only support default and GRP_COMDAT type of group. + // Default group members are unconditionnaly added to the target, + // and their grouping semantic is *not* honored by the garbage collector. + if (Entries.empty() || (Entries[0] != GRP_COMDAT && Entries[0] != 0)) + fatal(toString(this) + ": unsupported SHT_GROUP format"); + + bool AddGroupMembers = true; + if(Entries[0] == GRP_COMDAT) { + // De-duplicate section groups by their signatures. + StringRef Signature = getShtGroupSignature(ObjSections, Sec); + AddGroupMembers = ComdatGroups.insert(CachedHashStringRef(Signature)).second; + + } - // If it is a new section group, we want to keep group members. // Group leader sections, which contain indices of group members, are // discarded because they are useless beyond this point. The only // exception is the -r option because in order to produce re-linkable // object files, we want to pass through basically everything. - if (IsNew) { + // If it is a new section group, we want to keep group members. + if (AddGroupMembers) { if (Config->Relocatable) this->Sections[I] = createInputSection(Sec); - continue; } - - // Otherwise, discard group members. - for (uint32_t SecIndex : Entries) { - if (SecIndex >= Size) - fatal(toString(this) + - ": invalid section index in group: " + Twine(SecIndex)); - this->Sections[SecIndex] = &InputSection::Discarded; + else { + // Otherwise, discard group members. + for (uint32_t SecIndex : Entries.slice(1)) { + if (SecIndex >= Size) + fatal(toString(this) + + ": invalid section index in group: " + Twine(SecIndex)); + this->Sections[SecIndex] = &InputSection::Discarded; + } } break; } Index: lld/test/ELF/non-comdat-group.test =================================================================== --- /dev/null +++ lld/test/ELF/non-comdat-group.test @@ -0,0 +1,55 @@ +# RUN: yaml2obj %s -o %t.o +# RUN: ld.lld %t.o %t.o -o %t -r +# RUN: llvm-readobj -s %t | FileCheck %s + +# CHECK: Name: .text.foo +# CHECK: Name: .rela.text.foo + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .group + Type: SHT_GROUP + Link: .symtab + Info: foo + Members: + - SectionOrType: GRP_COMDAT + - SectionOrType: .text.foo + - SectionOrType: .text.bar + - SectionOrType: .note + - Name: .note + Type: SHT_NOTE + Flags: [ SHF_GROUP ] + - Name: .text.foo + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ] + - Name: .text.bar + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ] + - Name: .rela.text.foo + Type: SHT_RELA + Flags: [ SHF_INFO_LINK, SHF_GROUP ] + Link: .symtab + Info: .text.foo + Relocations: + - Offset: 0x0000000000000000 + Symbol: foo + Type: R_X86_64_64 + - Name: .rela.text.bar + Type: SHT_RELA + Flags: [ SHF_INFO_LINK, SHF_GROUP ] + Link: .symtab + Info: .text.bar + Relocations: + - Offset: 0x0000000000000000 + Symbol: bar + Type: R_X86_64_64 +Symbols: + Global: + - Name: foo + - Name: bar +