[lld] r280801 - [ELF] - Linkerscript: create multiple output sections for inputs with different attributes.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 7 03:46:08 PDT 2016


Author: grimar
Date: Wed Sep  7 05:46:07 2016
New Revision: 280801

URL: http://llvm.org/viewvc/llvm-project?rev=280801&view=rev
Log:
[ELF] - Linkerscript: create multiple output sections for inputs with different attributes.

Previously we combined sections by name if linkerscript was used.
For that we had to disable SHF_MERGE handling temporarily, but then
found that implementing it properly will require additional complexity layers like
subsections or something.
At the same time looks we can live with multiple output sections approach for now.
That patch do this change.

Differential revision: https://reviews.llvm.org/D24127

Removed:
    lld/trunk/test/ELF/linkerscript/merge-sections.s
Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/test/ELF/linkerscript/phdrs.s
    lld/trunk/test/ELF/linkerscript/repsection-va.s

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=280801&r1=280800&r2=280801&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Wed Sep  7 05:46:07 2016
@@ -242,14 +242,15 @@ void LinkerScript<ELFT>::createSections(
       if (V.empty())
         continue;
 
-      OutputSectionBase<ELFT> *OutSec;
-      bool IsNew;
-      std::tie(OutSec, IsNew) = Factory.create(V.front(), Cmd->Name);
-      if (IsNew)
-        OutputSections->push_back(OutSec);
-
-      uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0;
       for (InputSectionBase<ELFT> *Sec : V) {
+        OutputSectionBase<ELFT> *OutSec;
+        bool IsNew;
+        std::tie(OutSec, IsNew) = Factory.create(Sec, Cmd->Name);
+        if (IsNew)
+          OutputSections->push_back(OutSec);
+
+        uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0;
+
         if (Subalign)
           Sec->Alignment = Subalign;
         OutSec->addSection(Sec);
@@ -368,16 +369,15 @@ void assignOffsets(OutputSectionCommand
 }
 
 template <class ELFT>
-static OutputSectionBase<ELFT> *
-findSection(OutputSectionCommand &Cmd,
-            ArrayRef<OutputSectionBase<ELFT> *> Sections) {
-  for (OutputSectionBase<ELFT> *Sec : Sections) {
-    if (Sec->getName() != Cmd.Name)
-      continue;
-    if (checkConstraint(Sec->getFlags(), Cmd.Constraint))
-      return Sec;
-  }
-  return nullptr;
+static std::vector<OutputSectionBase<ELFT> *>
+findSections(OutputSectionCommand &Cmd,
+             ArrayRef<OutputSectionBase<ELFT> *> Sections) {
+  std::vector<OutputSectionBase<ELFT> *> Ret;
+  for (OutputSectionBase<ELFT> *Sec : Sections)
+    if (Sec->getName() == Cmd.Name &&
+        checkConstraint(Sec->getFlags(), Cmd.Constraint))
+      Ret.push_back(Sec);
+  return Ret;
 }
 
 template <class ELFT> void LinkerScript<ELFT>::assignAddresses() {
@@ -413,35 +413,35 @@ template <class ELFT> void LinkerScript<
     }
 
     auto *Cmd = cast<OutputSectionCommand>(Base.get());
-    OutputSectionBase<ELFT> *Sec = findSection<ELFT>(*Cmd, *OutputSections);
-    if (!Sec)
-      continue;
+    for (OutputSectionBase<ELFT> *Sec :
+         findSections<ELFT>(*Cmd, *OutputSections)) {
 
-    if (Cmd->AddrExpr)
-      Dot = Cmd->AddrExpr(Dot);
+      if (Cmd->AddrExpr)
+        Dot = Cmd->AddrExpr(Dot);
 
-    if (Cmd->AlignExpr)
-      Sec->updateAlignment(Cmd->AlignExpr(Dot));
+      if (Cmd->AlignExpr)
+        Sec->updateAlignment(Cmd->AlignExpr(Dot));
 
-    if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) {
-      uintX_t TVA = Dot + ThreadBssOffset;
-      TVA = alignTo(TVA, Sec->getAlignment());
-      Sec->setVA(TVA);
-      assignOffsets(Cmd, Sec);
-      ThreadBssOffset = TVA - Dot + Sec->getSize();
-      continue;
-    }
+      if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) {
+        uintX_t TVA = Dot + ThreadBssOffset;
+        TVA = alignTo(TVA, Sec->getAlignment());
+        Sec->setVA(TVA);
+        assignOffsets(Cmd, Sec);
+        ThreadBssOffset = TVA - Dot + Sec->getSize();
+        continue;
+      }
 
-    if (!(Sec->getFlags() & SHF_ALLOC)) {
+      if (!(Sec->getFlags() & SHF_ALLOC)) {
+        assignOffsets(Cmd, Sec);
+        continue;
+      }
+
+      Dot = alignTo(Dot, Sec->getAlignment());
+      Sec->setVA(Dot);
       assignOffsets(Cmd, Sec);
-      continue;
+      MinVA = std::min(MinVA, Dot);
+      Dot += Sec->getSize();
     }
-
-    Dot = alignTo(Dot, Sec->getAlignment());
-    Sec->setVA(Dot);
-    assignOffsets(Cmd, Sec);
-    MinVA = std::min(MinVA, Dot);
-    Dot += Sec->getSize();
   }
 
   // ELF and Program headers need to be right before the first section in

Removed: lld/trunk/test/ELF/linkerscript/merge-sections.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/merge-sections.s?rev=280800&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/merge-sections.s (original)
+++ lld/trunk/test/ELF/linkerscript/merge-sections.s (removed)
@@ -1,28 +0,0 @@
-# REQUIRES: x86
-# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
-
-# RUN: echo "SECTIONS { .foo : { *(.foo.*) } }" > %t.script
-# RUN: ld.lld -o %t1 --script %t.script %t
-# RUN: llvm-objdump -s %t1 | FileCheck %s
-# CHECK:      Contents of section .foo:
-# CHECK-NEXT:  0158 01000000 02000000 00000000 73686f72  ............shor
-# CHECK-NEXT:  0168 7420756e 7369676e 65642069 6e7400    t unsigned int.
-
-.global _start
-_start:
-  nop
-
-.section .foo.1, "aw"
-writable:
- .long 1
-
-.section .foo.2, "aM", at progbits,1
-readable:
- .long 2
-
-.section .foo.3, "awx"
- .long 0
-
-.section .foo.4, "MS", at progbits,1
-.LASF2:
- .string "short unsigned int"

Modified: lld/trunk/test/ELF/linkerscript/phdrs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/phdrs.s?rev=280801&r1=280800&r2=280801&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/phdrs.s (original)
+++ lld/trunk/test/ELF/linkerscript/phdrs.s Wed Sep  7 05:46:07 2016
@@ -17,8 +17,9 @@
 # CHECK-NEXT:    PhysicalAddress: 0x10000000
 # CHECK-NEXT:    FileSize: 521
 # CHECK-NEXT:    MemSize: 521
-# CHECK-NEXT:    Flags [ (0x5)
+# CHECK-NEXT:    Flags [ (0x7)
 # CHECK-NEXT:      PF_R (0x4)
+# CHECK-NEXT:      PF_W (0x2)
 # CHECK-NEXT:      PF_X (0x1)
 # CHECK-NEXT:    ]
 

Modified: lld/trunk/test/ELF/linkerscript/repsection-va.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/repsection-va.s?rev=280801&r1=280800&r2=280801&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/repsection-va.s (original)
+++ lld/trunk/test/ELF/linkerscript/repsection-va.s Wed Sep  7 05:46:07 2016
@@ -7,8 +7,9 @@
 # CHECK:      Sections:
 # CHECK-NEXT: Idx Name          Size      Address          Type
 # CHECK-NEXT:   0               00000000 0000000000000000
-# CHECK-NEXT:   1 .foo          00000008 0000000000000120 DATA
-# CHECK-NEXT:   2 .text         00000001 0000000000000128 TEXT DATA
+# CHECK-NEXT:   1 .foo          00000004 0000000000000158 DATA
+# CHECK-NEXT:   2 .foo          00000004 000000000000015c DATA
+# CHECK-NEXT:   3 .text         00000001 0000000000000160 TEXT DATA
 
 .global _start
 _start:




More information about the llvm-commits mailing list