[lld] r278561 - [ELF] - Linkerscript: fix VA value assigned to sections when using constraints.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 12 13:38:21 PDT 2016


Author: grimar
Date: Fri Aug 12 15:38:20 2016
New Revision: 278561

URL: http://llvm.org/viewvc/llvm-project?rev=278561&view=rev
Log:
[ELF] - Linkerscript: fix VA value assigned to sections when using constraints.

Previously we searched output section by name to assign VA. That did not
work in the case when multiple output sections with different constraints were defined in script.
Testcase shows the possible issue scenario, patch fixes the issue.

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

Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/test/ELF/linkerscript/linkerscript-multi-sections-constraint.s

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=278561&r1=278560&r2=278561&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Fri Aug 12 15:38:20 2016
@@ -215,14 +215,20 @@ void LinkerScript<ELFT>::discard(OutputS
   }
 }
 
+static bool checkConstraint(uint64_t Flags, ConstraintKind Kind) {
+  bool RO = (Kind == ConstraintKind::ReadOnly);
+  bool RW = (Kind == ConstraintKind::ReadWrite);
+  bool Writable = Flags & SHF_WRITE;
+  return !((RO && Writable) || (RW && !Writable));
+}
+
 template <class ELFT>
 static bool matchConstraints(ArrayRef<InputSectionBase<ELFT> *> Sections,
                              ConstraintKind Kind) {
-  bool RO = (Kind == ConstraintKind::ReadOnly);
-  bool RW = (Kind == ConstraintKind::ReadWrite);
-  return !llvm::any_of(Sections, [=](InputSectionBase<ELFT> *Sec) {
-    bool Writable = Sec->getSectionHdr()->sh_flags & SHF_WRITE;
-    return (RO && Writable) || (RW && !Writable);
+  if (Kind == ConstraintKind::NoConstraint)
+    return true;
+  return llvm::all_of(Sections, [=](InputSectionBase<ELFT> *Sec) {
+    return checkConstraint(Sec->getSectionHdr()->sh_flags, Kind);
   });
 }
 
@@ -330,6 +336,19 @@ template <class ELFT> void assignOffsets
   }
 }
 
+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;
+}
+
 template <class ELFT> void LinkerScript<ELFT>::assignAddresses() {
   // Orphan sections are sections present in the input files which
   // are not explicitly placed into the output file by the linker script.
@@ -363,12 +382,9 @@ template <class ELFT> void LinkerScript<
     }
 
     auto *Cmd = cast<OutputSectionCommand>(Base.get());
-    auto I = llvm::find_if(*OutputSections, [&](OutputSectionBase<ELFT> *S) {
-      return S->getName() == Cmd->Name;
-    });
-    if (I == OutputSections->end())
+    OutputSectionBase<ELFT> *Sec = findSection<ELFT>(*Cmd, *OutputSections);
+    if (!Sec)
       continue;
-    OutputSectionBase<ELFT> *Sec = *I;
 
     if (Cmd->AddrExpr)
       Dot = Cmd->AddrExpr(Dot);

Modified: lld/trunk/test/ELF/linkerscript/linkerscript-multi-sections-constraint.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/linkerscript-multi-sections-constraint.s?rev=278561&r1=278560&r2=278561&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/linkerscript-multi-sections-constraint.s (original)
+++ lld/trunk/test/ELF/linkerscript/linkerscript-multi-sections-constraint.s Fri Aug 12 15:38:20 2016
@@ -15,6 +15,21 @@
 # CHECK-NEXT:   4 .shstrtab     00000026 0000000000000000
 # CHECK-NEXT:   5 .strtab       00000008 0000000000000000
 
+# RUN: echo "SECTIONS { \
+# RUN:  . = 0x1000; .aaa : ONLY_IF_RW { *(.aaa.*) } \
+# RUN:  . = 0x2000; .aaa : ONLY_IF_RO { *(.aaa.*) } } " > %t2.script
+# RUN: ld.lld -o %t2 --script %t2.script %t
+# RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=REV
+
+# REV:      Sections:
+# REV-NEXT: Idx Name          Size      Address          Type
+# REV-NEXT:   0               00000000 0000000000000000
+# REV-NEXT:   1 .aaa          00000010 0000000000001000 DATA
+# REV-NEXT:   2 .text         00000001 0000000000002000 TEXT DATA
+# REV-NEXT:   3 .symtab       00000030 0000000000000000
+# REV-NEXT:   4 .shstrtab     00000026 0000000000000000
+# REV-NEXT:   5 .strtab       00000008 0000000000000000
+
 .global _start
 _start:
  nop




More information about the llvm-commits mailing list