[PATCH] D33643: [ELF] - Allow multiple comdats when producing relocatable output.

George Rimar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon May 29 02:57:00 PDT 2017


grimar created this revision.
Herald added a subscriber: emaste.

Previously LLD would fail for case when there are multiple comdats and -r.

That happened because it merged all ".group" (SHT_GROUP) sections into single
output, producing broken result. Such sections has similar name, alignment and flags,
the only way to find them are different seems to be to check Info field which provides a 
signature for the section group.


https://reviews.llvm.org/D33643

Files:
  ELF/OutputSections.cpp
  ELF/OutputSections.h
  test/ELF/relocatable-comdat-multiple.s


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", at progbits,aaa,comdat
+.section .text.b,"axG", at progbits,aaa,comdat
+
+.section .text.c,"axG", at progbits,bbb,comdat
+.section .text.d,"axG", at progbits,bbb,comdat
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<uint64_t>(C->Alignment, C->Entsize);
-    Flags = C->Flags & (SHF_MERGE | SHF_STRINGS);
+  if (Config->Relocatable) {
+    if (C->Flags & SHF_MERGE) {
+      Alignment = std::max<uint64_t>(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<SectionKey>::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<SectionKey>::isEqual(const SectionKey &LHS,
                                        const SectionKey &RHS) {
   return DenseMapInfo<StringRef>::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() {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D33643.100601.patch
Type: text/x-patch
Size: 2955 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170529/42795233/attachment-0001.bin>


More information about the llvm-commits mailing list