[lld] r297802 - Support ABSOLUTE on the right hand side in linker scripts

Petr Hosek via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 14 20:33:23 PDT 2017


Author: phosek
Date: Tue Mar 14 22:33:23 2017
New Revision: 297802

URL: http://llvm.org/viewvc/llvm-project?rev=297802&view=rev
Log:
Support ABSOLUTE on the right hand side in linker scripts

This also requires postponing the assignment the assignment of
symbols defined in input linker scripts since those can refer to
output sections and in case we don't have a SECTIONS command, we
need to wait until all output sections have been created and
assigned addresses.

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

Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/LinkerScript.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/linkerscript/absolute.s

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=297802&r1=297801&r2=297802&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Tue Mar 14 22:33:23 2017
@@ -153,11 +153,6 @@ void LinkerScript<ELFT>::addSymbol(Symbo
     return;
 
   Cmd->Sym = addRegular<ELFT>(Cmd);
-
-  // If there are sections, then let the value be assigned later in
-  // `assignAddresses`.
-  if (!ScriptConfig->HasSections)
-    assignSymbol(Cmd);
 }
 
 bool SymbolAssignment::classof(const BaseCommand *C) {
@@ -344,15 +339,6 @@ void LinkerScript<ELFT>::processCommands
       continue;
     }
 
-    if (auto *Cmd = dyn_cast<AssertCommand>(Base1.get())) {
-      // If we don't have SECTIONS then output sections have already been
-      // created by Writer<ELFT>. The LinkerScript<ELFT>::assignAddresses
-      // will not be called, so ASSERT should be evaluated now.
-      if (!Opt.HasSections)
-        Cmd->Expression();
-      continue;
-    }
-
     if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) {
       std::vector<InputSectionBase *> V = createInputSectionList(*Cmd);
 
@@ -779,6 +765,15 @@ void LinkerScriptBase::placeOrphanSectio
   }
 }
 
+void LinkerScriptBase::processNonSectionCommands() {
+  for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
+    if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get()))
+      assignSymbol(Cmd);
+    else if (auto *Cmd = dyn_cast<AssertCommand>(Base.get()))
+      Cmd->Expression();
+  }
+}
+
 void LinkerScriptBase::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
   // Assign addresses as instructed by linker script SECTIONS sub-commands.
   Dot = 0;
@@ -1556,14 +1551,8 @@ SymbolAssignment *ScriptParser::readProv
 
 SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
   StringRef Op = next();
-  Expr E;
   assert(Op == "=" || Op == "+=");
-  if (consume("ABSOLUTE")) {
-    E = readExpr();
-    E.IsAbsolute = [] { return true; };
-  } else {
-    E = readExpr();
-  }
+  Expr E = readExpr();
   if (Op == "+=") {
     std::string Loc = getCurrentLocation();
     E = [=] { return ScriptBase->getSymbolValue(Loc, Name) + E(); };
@@ -1739,6 +1728,11 @@ Expr ScriptParser::readPrimary() {
 
   // Built-in functions are parsed here.
   // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
+  if (Tok == "ABSOLUTE") {
+    Expr E = readParenExpr();
+    E.IsAbsolute = [] { return true; };
+    return E;
+  }
   if (Tok == "ADDR") {
     StringRef Name = readParenLiteral();
     return {[=] { return ScriptBase->getOutputSection(Location, Name)->Addr; },

Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=297802&r1=297801&r2=297802&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Tue Mar 14 22:33:23 2017
@@ -287,6 +287,7 @@ public:
   bool shouldKeep(InputSectionBase *S);
   void assignOffsets(OutputSectionCommand *Cmd);
   void placeOrphanSections();
+  void processNonSectionCommands();
   void assignAddresses(std::vector<PhdrEntry> &Phdrs);
   int getSectionIndex(StringRef Name);
 };

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=297802&r1=297801&r2=297802&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Mar 14 22:33:23 2017
@@ -270,6 +270,7 @@ template <class ELFT> void Writer<ELFT>:
     } else {
       fixSectionAlignments();
       assignAddresses();
+      Script<ELFT>::X->processNonSectionCommands();
     }
 
     // Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a

Modified: lld/trunk/test/ELF/linkerscript/absolute.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/absolute.s?rev=297802&r1=297801&r2=297802&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/absolute.s (original)
+++ lld/trunk/test/ELF/linkerscript/absolute.s Tue Mar 14 22:33:23 2017
@@ -4,6 +4,11 @@
 # RUN: ld.lld -o %t --script %t.script %t.o
 # RUN: llvm-readobj --symbols %t | FileCheck %s
 
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "PROVIDE(foo = 1 + ABSOLUTE(ADDR(.text)));" > %t.script
+# RUN: ld.lld -o %t --script %t.script %t.o
+# RUN: llvm-readobj --symbols %t | FileCheck --check-prefix=CHECK-RHS %s
+
 # CHECK:        Name: foo
 # CHECK-NEXT:   Value:
 # CHECK-NEXT:   Size:
@@ -13,6 +18,18 @@
 # CHECK-NEXT:   Section: Absolute
 # CHECK-NEXT: }
 
+# CHECK-RHS:        Name: foo
+# CHECK-RHS-NEXT:   Value: 0x201001
+# CHECK-RHS-NEXT:   Size:
+# CHECK-RHS-NEXT:   Binding:
+# CHECK-RHS-NEXT:   Type:
+# CHECK-RHS-NEXT:   Other:
+# CHECK-RHS-NEXT:   Section: Absolute
+# CHECK-RHS-NEXT: }
+
 .text
 .globl _start
 _start:
+ nop
+
+.global foo




More information about the llvm-commits mailing list