[lld] r305700 - [LLD][LinkerScript] Add support for segment NONE.

Andrew Ng via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 19 08:28:58 PDT 2017


Author: anng
Date: Mon Jun 19 10:28:58 2017
New Revision: 305700

URL: http://llvm.org/viewvc/llvm-project?rev=305700&view=rev
Log:
[LLD][LinkerScript] Add support for segment NONE.

This patch adds support for segment NONE in linker scripts which enables the
specification that a section should not be assigned to any segment.

Note that GNU ld does not disallow the definition of a segment named NONE, which
if defined, effectively overrides the behaviour described above. This feature
has been copied.

Differential Revision: https://reviews.llvm.org/D34203

Added:
    lld/trunk/test/ELF/linkerscript/segment-none.s
Modified:
    lld/trunk/ELF/LinkerScript.cpp

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=305700&r1=305699&r2=305700&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Mon Jun 19 10:28:58 2017
@@ -1111,18 +1111,27 @@ ExprValue LinkerScript::getSymbolValue(c
 
 bool LinkerScript::isDefined(StringRef S) { return findSymbol(S) != nullptr; }
 
+static const size_t NoPhdr = -1;
+
 // Returns indices of ELF headers containing specific section. Each index is a
 // zero based number of ELF header listed within PHDRS {} script block.
 std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *Sec) {
   if (OutputSectionCommand *Cmd = getCmd(Sec)) {
     std::vector<size_t> Ret;
-    for (StringRef PhdrName : Cmd->Phdrs)
-      Ret.push_back(getPhdrIndex(Cmd->Location, PhdrName));
+    for (StringRef PhdrName : Cmd->Phdrs) {
+      size_t Index = getPhdrIndex(Cmd->Location, PhdrName);
+      if (Index != NoPhdr)
+        Ret.push_back(Index);
+    }
     return Ret;
   }
   return {};
 }
 
+// Returns the index of the segment named PhdrName if found otherwise
+// NoPhdr. When not found, if PhdrName is not the special case value 'NONE'
+// (which can be used to explicitly specify that a section isn't assigned to a
+// segment) then error.
 size_t LinkerScript::getPhdrIndex(const Twine &Loc, StringRef PhdrName) {
   size_t I = 0;
   for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {
@@ -1130,8 +1139,9 @@ size_t LinkerScript::getPhdrIndex(const
       return I;
     ++I;
   }
-  error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");
-  return 0;
+  if (PhdrName != "NONE")
+    error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");
+  return NoPhdr;
 }
 
 template void OutputSectionCommand::writeTo<ELF32LE>(uint8_t *Buf);

Added: lld/trunk/test/ELF/linkerscript/segment-none.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/segment-none.s?rev=305700&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/segment-none.s (added)
+++ lld/trunk/test/ELF/linkerscript/segment-none.s Mon Jun 19 10:28:58 2017
@@ -0,0 +1,39 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+
+## Test that section .foo is not placed in any segment when assigned to segment
+## NONE in the linker script and segment NONE is not defined.
+# RUN: echo "PHDRS {text PT_LOAD;} \
+# RUN:       SECTIONS { \
+# RUN:           .text : {*(.text .text*)} :text \
+# RUN:           .foo : {*(.foo)} :NONE \
+# RUN:       }" > %t.script
+# RUN: ld.lld -o %t --script %t.script %t.o
+# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck %s
+
+## Test that section .foo is placed in segment NONE when assigned to segment
+## NONE in the linker script and segment NONE is defined.
+# RUN: echo "PHDRS {text PT_LOAD; NONE PT_LOAD;} \
+# RUN:       SECTIONS { \
+# RUN:           .text : {*(.text .text*)} :text \
+# RUN:           .foo : {*(.foo)} :NONE \
+# RUN:       }" > %t.script
+# RUN: ld.lld -o %t --script %t.script %t.o
+# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck --check-prefix=DEFINED %s
+
+# CHECK: Section to Segment mapping:
+# CHECK-NEXT: Segment Sections...
+# CHECK-NOT: .foo
+
+# DEFINED: Section to Segment mapping:
+# DEFINED-NEXT: Segment Sections...
+# DEFINED-NEXT:  00     .text
+# DEFINED-NEXT:  01     .foo
+
+.global _start
+_start:
+ nop
+
+.section .foo,"a"
+foo:
+ .long 0




More information about the llvm-commits mailing list