[lld] r283300 - [ELF] Do not merge sections in case of relocatable object generation

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 5 00:49:18 PDT 2016


Author: atanasyan
Date: Wed Oct  5 02:49:18 2016
New Revision: 283300

URL: http://llvm.org/viewvc/llvm-project?rev=283300&view=rev
Log:
[ELF] Do not merge sections in case of relocatable object generation

Do not merge sections if generating a relocatable object. It makes
the code simpler because we do not need to update relocations addends
to reflect changes introduced by merging. Instead of that we write
such "merge" sections into separate OutputSections and keep SHF_MERGE
/ SHF_STRINGS flags and sh_entsize value to be able to perform merging
later during a final linking.

Differential Revision: http://reviews.llvm.org/D25066

Added:
    lld/trunk/test/ELF/merge-reloc.s
Modified:
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/OutputSections.cpp

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=283300&r1=283299&r2=283300&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Wed Oct  5 02:49:18 2016
@@ -177,6 +177,15 @@ bool elf::ObjectFile<ELFT>::shouldMerge(
   if (Config->Optimize == 0)
     return false;
 
+  // Do not merge sections if generating a relocatable object. It makes
+  // the code simpler because we do not need to update relocation addends
+  // to reflect changes introduced by merging. Instead of that we write
+  // such "merge" sections into separate OutputSections and keep SHF_MERGE
+  // / SHF_STRINGS flags and sh_entsize value to be able to perform merging
+  // later during a final linking.
+  if (Config->Relocatable)
+    return false;
+
   // A mergeable section with size 0 is useless because they don't have
   // any data to merge. A mergeable string section with size 0 can be
   // argued as invalid because it doesn't end with a null character.

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=283300&r1=283299&r2=283300&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Wed Oct  5 02:49:18 2016
@@ -894,6 +894,10 @@ void OutputSection<ELFT>::addSection(Inp
   Sections.push_back(S);
   S->OutSec = this;
   this->updateAlignment(S->Alignment);
+  // Keep sh_entsize value of the input section to be able to perform merging
+  // later during a final linking using the generated relocatable object.
+  if (Config->Relocatable && (S->getSectionHdr()->sh_flags & SHF_MERGE))
+    this->Header.sh_entsize = S->getSectionHdr()->sh_entsize;
 }
 
 // This function is called after we sort input sections
@@ -1836,8 +1840,12 @@ static SectionKey<ELFT::Is64Bits> create
   // For SHF_MERGE we create different output sections for each alignment.
   // This makes each output section simple and keeps a single level mapping from
   // input to output.
+  // In case of relocatable object generation we do not try to perform merging
+  // and treat SHF_MERGE sections as regular ones, but also create different
+  // output sections for them to allow merging at final linking stage.
   uintX_t Alignment = 0;
-  if (isa<MergeInputSection<ELFT>>(C))
+  if (isa<MergeInputSection<ELFT>>(C) ||
+      (Config->Relocatable && (H->sh_flags & SHF_MERGE)))
     Alignment = std::max(H->sh_addralign, H->sh_entsize);
 
   uint32_t Type = H->sh_type;

Added: lld/trunk/test/ELF/merge-reloc.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/merge-reloc.s?rev=283300&view=auto
==============================================================================
--- lld/trunk/test/ELF/merge-reloc.s (added)
+++ lld/trunk/test/ELF/merge-reloc.s Wed Oct  5 02:49:18 2016
@@ -0,0 +1,92 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o -r -o %t-rel
+# RUN: llvm-readobj -s -section-data %t-rel | FileCheck %s
+
+# When linker generates a relocatable object it should keep "merge"
+# sections as-is: do not merge content, do not join regular and
+# "merge" sections, do not joint "merge" sections with different
+# entry size.
+
+# CHECK:      Section {
+# CHECK:        Index:
+# CHECK:        Name: .data
+# CHECK-NEXT:   Type: SHT_PROGBITS
+# CHECK-NEXT:   Flags [
+# CHECK-NEXT:     SHF_ALLOC
+# CHECK-NEXT:     SHF_MERGE
+# CHECK-NEXT:   ]
+# CHECK-NEXT:   Address:
+# CHECK-NEXT:   Offset:
+# CHECK-NEXT:   Size: 12
+# CHECK-NEXT:   Link: 0
+# CHECK-NEXT:   Info: 0
+# CHECK-NEXT:   AddressAlignment: 4
+# CHECK-NEXT:   EntrySize: 4
+# CHECK-NEXT:   SectionData (
+# CHECK-NEXT:     0000: 42000000 42000000 42000000
+# CHECK-NEXT:   )
+# CHECK-NEXT: }
+# CHECK:      Section {
+# CHECK:        Index:
+# CHECK:        Name: .data
+# CHECK-NEXT:   Type: SHT_PROGBITS
+# CHECK-NEXT:   Flags [
+# CHECK-NEXT:     SHF_ALLOC
+# CHECK-NEXT:     SHF_MERGE
+# CHECK-NEXT:   ]
+# CHECK-NEXT:   Address:
+# CHECK-NEXT:   Offset:
+# CHECK-NEXT:   Size: 16
+# CHECK-NEXT:   Link: 0
+# CHECK-NEXT:   Info: 0
+# CHECK-NEXT:   AddressAlignment: 8
+# CHECK-NEXT:   EntrySize: 8
+# CHECK-NEXT:   SectionData (
+# CHECK-NEXT:     0000: 42000000 42000000 42000000 42000000
+# CHECK-NEXT:   )
+# CHECK-NEXT: }
+# CHECK:      Section {
+# CHECK:        Index:
+# CHECK:        Name: .data
+# CHECK-NEXT:   Type: SHT_PROGBITS
+# CHECK-NEXT:   Flags [
+# CHECK-NEXT:     SHF_ALLOC
+# CHECK-NEXT:     SHF_WRITE
+# CHECK-NEXT:   ]
+# CHECK-NEXT:   Address:
+# CHECK-NEXT:   Offset:
+# CHECK-NEXT:   Size: 16
+# CHECK-NEXT:   Link: 0
+# CHECK-NEXT:   Info: 0
+# CHECK-NEXT:   AddressAlignment: 1
+# CHECK-NEXT:   EntrySize: 0
+# CHECK-NEXT:   SectionData (
+# CHECK-NEXT:     0000: 42000000 42000000 42000000 42000000
+# CHECK-NEXT:   )
+# CHECK-NEXT: }
+
+        .section        .data.1,"aM", at progbits,4
+        .align  4
+        .global foo
+foo:
+        .long   0x42
+        .long   0x42
+        .long   0x42
+
+        .section        .data.2,"aM", at progbits,8
+        .align  8
+        .global bar
+bar:
+        .long   0x42
+        .long   0x42
+        .long   0x42
+        .long   0x42
+
+        .data
+        .global gar
+zed:
+        .long   0x42
+        .long   0x42
+        .long   0x42
+        .long   0x42




More information about the llvm-commits mailing list