Index: ELF/OutputSections.h =================================================================== --- ELF/OutputSections.h +++ ELF/OutputSections.h @@ -115,6 +115,7 @@ StringRef Name; uint64_t Flags; uint32_t Alignment; + uint32_t Info; }; } } Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -322,13 +322,18 @@ // incompatible types and flags. uint32_t Alignment = 0; + uint32_t Info = 0; uint64_t Flags = 0; - if (Config->Relocatable && (C->Flags & SHF_MERGE)) { - Alignment = std::max(C->Alignment, C->Entsize); - Flags = C->Flags & (SHF_MERGE | SHF_STRINGS); + if (Config->Relocatable) { + if (C->Flags & SHF_MERGE) { + Alignment = std::max(C->Alignment, C->Entsize); + Flags = C->Flags & (SHF_MERGE | SHF_STRINGS); + } + if (C->Type == SHT_GROUP) + Info = C->Info; } - return SectionKey{OutsecName, Flags, Alignment}; + return SectionKey{OutsecName, Flags, Alignment, Info}; } OutputSectionFactory::OutputSectionFactory( @@ -413,13 +418,14 @@ } unsigned DenseMapInfo::getHashValue(const SectionKey &Val) { - return hash_combine(Val.Name, Val.Flags, Val.Alignment); + return hash_combine(Val.Name, Val.Flags, Val.Alignment, Val.Info); } bool DenseMapInfo::isEqual(const SectionKey &LHS, const SectionKey &RHS) { return DenseMapInfo::isEqual(LHS.Name, RHS.Name) && - LHS.Flags == RHS.Flags && LHS.Alignment == RHS.Alignment; + LHS.Flags == RHS.Flags && LHS.Alignment == RHS.Alignment && + LHS.Info == RHS.Info; } uint64_t elf::getHeaderSize() { Index: test/ELF/relocatable-comdat-multiple.s =================================================================== --- test/ELF/relocatable-comdat-multiple.s +++ test/ELF/relocatable-comdat-multiple.s @@ -0,0 +1,33 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld -r %t.o %t.o -o %t +# RUN: llvm-readobj -elf-section-groups %t | FileCheck %s + +# CHECK: Groups { +# CHECK-NEXT: Group { +# CHECK-NEXT: Name: .group +# CHECK-NEXT: Index: 2 +# CHECK-NEXT: Type: COMDAT +# CHECK-NEXT: Signature: aaa +# CHECK-NEXT: Section(s) in group [ +# CHECK-NEXT: .text.a +# CHECK-NEXT: .text.b +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: Group { +# CHECK-NEXT: Name: .group +# CHECK-NEXT: Index: 5 +# CHECK-NEXT: Type: COMDAT +# CHECK-NEXT: Signature: bbb +# CHECK-NEXT: Section(s) in group [ +# CHECK-NEXT: .text.c +# CHECK-NEXT: .text.d +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: } + +.section .text.a,"axG",@progbits,aaa,comdat +.section .text.b,"axG",@progbits,aaa,comdat + +.section .text.c,"axG",@progbits,bbb,comdat +.section .text.d,"axG",@progbits,bbb,comdat