aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2017-06-06 06:38:32 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2017-06-06 06:38:32 +0000
commit8cde9a7e7715e509cd2cfab617def67dbd76abfa (patch)
tree8525bbb529333faf3fdc3a353b73d9fd80112107
parent1fa569db2386dfdeb61c0f719dd305c8342acee9 (diff)
downloadllvm-8cde9a7e7715e509cd2cfab617def67dbd76abfa.zip
llvm-8cde9a7e7715e509cd2cfab617def67dbd76abfa.tar.gz
llvm-8cde9a7e7715e509cd2cfab617def67dbd76abfa.tar.bz2
[ELF] - Allow multiple comdats when producing relocatable output.
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 may have similar name, alignment and flags and other properties. We need to produce separate output section for each such input one. Differential revision: https://reviews.llvm.org/D33643 llvm-svn: 304769
-rw-r--r--lld/ELF/OutputSections.cpp11
-rw-r--r--lld/test/ELF/Inputs/relocatable-comdat-multiple.s2
-rw-r--r--lld/test/ELF/relocatable-comdat-multiple.s31
3 files changed, 44 insertions, 0 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 05a58e3..804c186 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -345,6 +345,17 @@ void elf::reportDiscarded(InputSectionBase *IS) {
void OutputSectionFactory::addInputSec(InputSectionBase *IS,
StringRef OutsecName) {
+ // Sections with the SHT_GROUP attribute reach here only when the - r option
+ // is given. Such sections define "section groups", and InputFiles.cpp has
+ // dedup'ed section groups by their signatures. For the -r, we want to pass
+ // through all SHT_GROUP sections without merging them because merging them
+ // creates broken section contents.
+ if (IS->Type == SHT_GROUP) {
+ OutputSection *Out = nullptr;
+ addInputSec(IS, OutsecName, Out);
+ return;
+ }
+
SectionKey Key = createKey(IS, OutsecName);
OutputSection *&Sec = Map[Key];
return addInputSec(IS, OutsecName, Sec);
diff --git a/lld/test/ELF/Inputs/relocatable-comdat-multiple.s b/lld/test/ELF/Inputs/relocatable-comdat-multiple.s
new file mode 100644
index 0000000..837a6bb
--- /dev/null
+++ b/lld/test/ELF/Inputs/relocatable-comdat-multiple.s
@@ -0,0 +1,2 @@
+.section .text.c,"axG",@progbits,bbb,comdat
+.section .text.d,"axG",@progbits,bbb,comdat
diff --git a/lld/test/ELF/relocatable-comdat-multiple.s b/lld/test/ELF/relocatable-comdat-multiple.s
new file mode 100644
index 0000000..4c3e7ce
--- /dev/null
+++ b/lld/test/ELF/relocatable-comdat-multiple.s
@@ -0,0 +1,31 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/relocatable-comdat-multiple.s -o %t2.o
+# RUN: ld.lld -r %t.o %t2.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