Index: lld/ELF/InputFiles.h =================================================================== --- lld/ELF/InputFiles.h +++ lld/ELF/InputFiles.h @@ -175,7 +175,7 @@ StringRef getShtGroupSignature(ArrayRef Sections, const Elf_Shdr &Sec); - ArrayRef getShtGroupEntries(const Elf_Shdr &Sec); + std::pair> getShtGroupEntries(const Elf_Shdr &Sec); public: static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; } Index: lld/ELF/InputFiles.cpp =================================================================== --- lld/ELF/InputFiles.cpp +++ lld/ELF/InputFiles.cpp @@ -321,14 +321,15 @@ } template -ArrayRef::Elf_Word> +std::pair::Elf_Word, 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) + if (Entries.empty() || (Entries[0] != GRP_COMDAT && Entries[0] != 0)) { fatal(toString(this) + ": unsupported SHT_GROUP format"); - return Entries.slice(1); + } + return {Entries[0], Entries.slice(1)}; } template bool ObjFile::shouldMerge(const Elf_Shdr &Sec) { @@ -438,14 +439,24 @@ switch (Sec.sh_type) { case SHT_GROUP: { - // De-duplicate section groups by their signatures. - StringRef Signature = getShtGroupSignature(ObjSections, Sec); - bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second; - this->Sections[I] = &InputSection::Discarded; - - // We only support GRP_COMDAT type of group. Get the all entries of the + // We only support default and 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); + ArrayRef Entries; + Elf_Word Flag; + + std::tie(Flag, Entries) = getShtGroupEntries(Sec); + + bool IsNew; + if(Flag == 0) { + IsNew = true; + } + else { + // De-duplicate section groups by their signatures. + StringRef Signature = getShtGroupSignature(ObjSections, Sec); + IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second; + this->Sections[I] = &InputSection::Discarded; + } + // If it is a new section group, we want to keep group members. // Group leader sections, which contain indices of group members, are Index: lld/test/ELF/non-comdat-group.test =================================================================== --- /dev/null +++ lld/test/ELF/non-comdat-group.test @@ -0,0 +1,36 @@ +# 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: 0 + - SectionOrType: .text.foo + - Name: .text.foo + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ] + - Name: .rela.text.foo + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + Link: .symtab + Info: .text.foo + Relocations: + - Offset: 0x0000000000000000 + Symbol: foo + Type: R_X86_64_64 +Symbols: + Global: + - Name: foo