[lld] r327378 - [ELF] - Implement INSERT BEFORE.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 13 02:18:11 PDT 2018


Author: grimar
Date: Tue Mar 13 02:18:11 2018
New Revision: 327378

URL: http://llvm.org/viewvc/llvm-project?rev=327378&view=rev
Log:
[ELF] - Implement INSERT BEFORE.

This finishes PR35877.

INSERT BEFORE used similar to INSERT AFTER,
it inserts sections before the given target section.

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

Added:
    lld/trunk/test/ELF/linkerscript/insert-before.test
Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/LinkerScript.h
    lld/trunk/ELF/ScriptParser.cpp
    lld/trunk/test/ELF/linkerscript/insert-after.test
    lld/trunk/test/ELF/linkerscript/insert-broken.test

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=327378&r1=327377&r2=327378&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Tue Mar 13 02:18:11 2018
@@ -207,18 +207,26 @@ static void declareSymbol(SymbolAssignme
 // the list of script commands to mix sections inserted into.
 void LinkerScript::processInsertCommands() {
   std::vector<BaseCommand *> V;
+  auto Insert = [&](std::vector<BaseCommand *> &From) {
+    V.insert(V.end(), From.begin(), From.end());
+    From.clear();
+  };
+
   for (BaseCommand *Base : SectionCommands) {
-    V.push_back(Base);
-    if (auto *Cmd = dyn_cast<OutputSection>(Base)) {
-      std::vector<BaseCommand *> &W = InsertAfterCommands[Cmd->Name];
-      V.insert(V.end(), W.begin(), W.end());
-      W.clear();
+    if (auto *OS = dyn_cast<OutputSection>(Base)) {
+      Insert(InsertBeforeCommands[OS->Name]);
+      V.push_back(Base);
+      Insert(InsertAfterCommands[OS->Name]);
+      continue;
     }
+    V.push_back(Base);
   }
-  for (std::pair<StringRef, std::vector<BaseCommand *>> &P :
-       InsertAfterCommands)
-    if (!P.second.empty())
-      error("unable to INSERT AFTER " + P.first + ": section not defined");
+
+  for (auto &Cmds : {InsertBeforeCommands, InsertAfterCommands})
+    for (const std::pair<StringRef, std::vector<BaseCommand *>> &P : Cmds)
+      if (!P.second.empty())
+        error("unable to INSERT AFTER/BEFORE " + P.first +
+              ": section not defined");
 
   SectionCommands = std::move(V);
 }

Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=327378&r1=327377&r2=327378&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Tue Mar 13 02:18:11 2018
@@ -289,9 +289,10 @@ public:
   // A list of symbols referenced by the script.
   std::vector<llvm::StringRef> ReferencedSymbols;
 
-  // Used to implement INSERT AFTER. Contains commands that need
+  // Used to implement INSERT [AFTER|BEFORE]. Contains commands that need
   // to be inserted into SECTIONS commands list.
   llvm::DenseMap<StringRef, std::vector<BaseCommand *>> InsertAfterCommands;
+  llvm::DenseMap<StringRef, std::vector<BaseCommand *>> InsertBeforeCommands;
 };
 
 extern LinkerScript *Script;

Modified: lld/trunk/ELF/ScriptParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ScriptParser.cpp?rev=327378&r1=327377&r2=327378&view=diff
==============================================================================
--- lld/trunk/ELF/ScriptParser.cpp (original)
+++ lld/trunk/ELF/ScriptParser.cpp Tue Mar 13 02:18:11 2018
@@ -450,9 +450,15 @@ void ScriptParser::readSections() {
   }
 
   if (!atEOF() && consume("INSERT")) {
-    expect("AFTER");
-    std::vector<BaseCommand *> &Dest = Script->InsertAfterCommands[next()];
-    Dest.insert(Dest.end(), V.begin(), V.end());
+    std::vector<BaseCommand *> *Dest = nullptr;
+    if (consume("AFTER"))
+      Dest = &Script->InsertAfterCommands[next()];
+    else if (consume("BEFORE"))
+      Dest = &Script->InsertBeforeCommands[next()];
+    else
+      setError("expected AFTER/BEFORE, but got '" + next() + "'");
+    if (Dest)
+      Dest->insert(Dest->end(), V.begin(), V.end());
     return;
   }
 

Modified: lld/trunk/test/ELF/linkerscript/insert-after.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/insert-after.test?rev=327378&r1=327377&r2=327378&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/insert-after.test (original)
+++ lld/trunk/test/ELF/linkerscript/insert-after.test Tue Mar 13 02:18:11 2018
@@ -25,5 +25,5 @@ SECTIONS {
 
 # RUN: not ld.lld %t1.o -o %t1 --script %s 2>&1 \
 # RUN:   | FileCheck %s --check-prefix=ERR
-# ERR-DAG: error: unable to INSERT AFTER .text: section not defined
-# ERR-DAG: error: unable to INSERT AFTER .data: section not defined
+# ERR-DAG: error: unable to INSERT AFTER/BEFORE .text: section not defined
+# ERR-DAG: error: unable to INSERT AFTER/BEFORE .data: section not defined

Added: lld/trunk/test/ELF/linkerscript/insert-before.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/insert-before.test?rev=327378&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/insert-before.test (added)
+++ lld/trunk/test/ELF/linkerscript/insert-before.test Tue Mar 13 02:18:11 2018
@@ -0,0 +1,29 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/insert-after.s -o %t1.o
+
+## Main linker script contains .text and .data sections. Here
+## we check that can use INSERT BEFORE to insert sections .foo.data
+## and .foo.text at the right places.
+
+SECTIONS {
+  .foo.data : { *(.foo.data) }
+} INSERT BEFORE .data;
+
+SECTIONS {
+  .foo.text : { *(.foo.text) }
+} INSERT BEFORE .text;
+
+# RUN: ld.lld %t1.o -o %t1 --script %p/Inputs/insert-after.script --script %s
+# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
+# CHECK:      Sections:
+# CHECK-NEXT: Idx Name          Size      Address          Type
+# CHECK-NEXT:   0               00000000 0000000000000000
+# CHECK-NEXT:   1 .foo.text     00000008 0000000000000000 TEXT DATA
+# CHECK-NEXT:   2 .text         00000008 0000000000000008 TEXT DATA
+# CHECK-NEXT:   3 .foo.data     00000008 0000000000000010 DATA
+# CHECK-NEXT:   4 .data         00000008 0000000000000018 DATA
+
+# RUN: not ld.lld %t1.o -o %t1 --script %s 2>&1 \
+# RUN:   | FileCheck %s --check-prefix=ERR
+# ERR-DAG: error: unable to INSERT AFTER/BEFORE .text: section not defined
+# ERR-DAG: error: unable to INSERT AFTER/BEFORE .data: section not defined

Modified: lld/trunk/test/ELF/linkerscript/insert-broken.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/insert-broken.test?rev=327378&r1=327377&r2=327378&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/insert-broken.test (original)
+++ lld/trunk/test/ELF/linkerscript/insert-broken.test Tue Mar 13 02:18:11 2018
@@ -3,4 +3,4 @@ SECTIONS {
 } INSERT .data;
 
 # RUN: not ld.lld -o %t1 --script %s 2>&1 | FileCheck %s
-# CHECK: {{.*}}:3: AFTER expected, but got .data
+# CHECK: {{.*}}:3: expected AFTER/BEFORE, but got '.data'




More information about the llvm-commits mailing list