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

llvm-svn: 297802
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 647725e..5f2c9a1 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -153,11 +153,6 @@
     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 @@
       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::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::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 @@
 
   // 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; },