[lld] r285628 - Delay computation of IsAbsolute.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 31 12:56:37 PDT 2016


Author: rafael
Date: Mon Oct 31 14:56:37 2016
New Revision: 285628

URL: http://llvm.org/viewvc/llvm-project?rev=285628&view=rev
Log:
Delay computation of IsAbsolute.

We parse linker scripts very early, but whether an expression is
absolute or not can depend on a symbol defined in a .o. Given that, we
have to delay the computation of IsAbsolute. We can do that by storing
an AST when parsing or by also making IsAbsolute a function like we do
for the expression value. This patch implements the second option.

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

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=285628&r1=285627&r2=285628&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Mon Oct 31 14:56:37 2016
@@ -64,7 +64,7 @@ template <class ELFT> static void addSyn
 }
 
 template <class ELFT> static void addSymbol(SymbolAssignment *Cmd) {
-  if (Cmd->Expression.IsAbsolute)
+  if (Cmd->Expression.IsAbsolute())
     addRegular<ELFT>(Cmd);
   else
     addSynthetic<ELFT>(Cmd);
@@ -867,6 +867,12 @@ template <class ELFT> bool LinkerScript<
   return Symtab<ELFT>::X->find(S) != nullptr;
 }
 
+template <class ELFT> bool LinkerScript<ELFT>::isAbsolute(StringRef S) {
+  SymbolBody *Sym = Symtab<ELFT>::X->find(S);
+  auto *DR = dyn_cast_or_null<DefinedRegular<ELFT>>(Sym);
+  return DR && !DR->Section;
+}
+
 // Returns indices of ELF headers containing specific section, identified
 // by Name. Each index is a zero based number of ELF header listed within
 // PHDRS {} script block.
@@ -1424,7 +1430,7 @@ SymbolAssignment *ScriptParser::readProv
     Cmd = readProvideHidden(true, true);
   }
   if (Cmd && MakeAbsolute)
-    Cmd->Expression.IsAbsolute = true;
+    Cmd->Expression.IsAbsolute = []() { return true; };
   return Cmd;
 }
 
@@ -1434,6 +1440,12 @@ static uint64_t getSymbolValue(StringRef
   return ScriptBase->getSymbolValue(S);
 }
 
+static bool isAbsolute(StringRef S) {
+  if (S == ".")
+    return false;
+  return ScriptBase->isAbsolute(S);
+}
+
 SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
   StringRef Op = next();
   Expr E;
@@ -1442,7 +1454,7 @@ SymbolAssignment *ScriptParser::readAssi
     // The RHS may be something like "ABSOLUTE(.) & 0xff".
     // Call readExpr1 to read the whole expression.
     E = readExpr1(readParenExpr(), 0);
-    E.IsAbsolute = true;
+    E.IsAbsolute = []() { return true; };
   } else {
     E = readExpr();
   }
@@ -1469,7 +1481,8 @@ static Expr combine(StringRef Op, Expr L
     };
   }
   if (Op == "+")
-    return [=](uint64_t Dot) { return L(Dot) + R(Dot); };
+    return {[=](uint64_t Dot) { return L(Dot) + R(Dot); },
+            [=]() { return L.IsAbsolute() && R.IsAbsolute(); }};
   if (Op == "-")
     return [=](uint64_t Dot) { return L(Dot) - R(Dot); };
   if (Op == "<<")
@@ -1687,7 +1700,8 @@ Expr ScriptParser::readPrimary() {
   // Tok is a symbol name.
   if (Tok != "." && !isValidCIdentifier(Tok))
     setError("malformed number: " + Tok);
-  return [=](uint64_t Dot) { return getSymbolValue(Tok, Dot); };
+  return {[=](uint64_t Dot) { return getSymbolValue(Tok, Dot); },
+          [=]() { return isAbsolute(Tok); }};
 }
 
 Expr ScriptParser::readTernary(Expr Cond) {

Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=285628&r1=285627&r2=285628&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Mon Oct 31 14:56:37 2016
@@ -39,12 +39,16 @@ class InputSectionData;
 // with the value of special context variable ".".
 struct Expr {
   std::function<uint64_t(uint64_t)> Val;
-  bool IsAbsolute;
+  std::function<bool()> IsAbsolute;
   uint64_t operator()(uint64_t Dot) const { return Val(Dot); }
   operator bool() const { return (bool)Val; }
 
   template <typename T>
-  Expr(T Val, bool IsAbsolute) : Val(Val), IsAbsolute(IsAbsolute) {}
+  Expr(T Val, std::function<bool()> IsAbsolute)
+      : Val(Val), IsAbsolute(IsAbsolute) {}
+  template <typename T> Expr(T Val, bool IsAbsolute) : Val(Val) {
+    this->IsAbsolute = [=]() { return IsAbsolute; };
+  }
   template <typename T> Expr(T V) : Expr(V, false) {}
   Expr() : Expr(nullptr) {}
 };
@@ -184,6 +188,7 @@ public:
   virtual uint64_t getHeaderSize() = 0;
   virtual uint64_t getSymbolValue(StringRef S) = 0;
   virtual bool isDefined(StringRef S) = 0;
+  virtual bool isAbsolute(StringRef S) = 0;
 };
 
 // ScriptConfiguration holds linker script parse results.
@@ -231,6 +236,7 @@ public:
   uint64_t getHeaderSize() override;
   uint64_t getSymbolValue(StringRef S) override;
   bool isDefined(StringRef S) override;
+  bool isAbsolute(StringRef S) override;
 
   std::vector<OutputSectionBase<ELFT> *> *OutputSections;
 

Modified: lld/trunk/test/ELF/linkerscript/absolute-expr.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/absolute-expr.s?rev=285628&r1=285627&r2=285628&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/absolute-expr.s (original)
+++ lld/trunk/test/ELF/linkerscript/absolute-expr.s Mon Oct 31 14:56:37 2016
@@ -7,14 +7,27 @@
 # RUN:                    bar3 = SIZEOF (.text); \
 # RUN:                    bar4 = SIZEOF_HEADERS; \
 # RUN:                    bar5 = 0x42; \
+# RUN:                    bar6 = foo + 1; \
 # RUN:                    *(.text) \
 # RUN:                  } \
 # RUN:                };" > %t.script
 # RUN: ld.lld -o %t.so --script %t.script %t.o -shared
 # RUN: llvm-readobj -t %t.so | FileCheck %s
 
+.global foo
+foo = 0x123
+
 # CHECK:      Symbol {
-# CHECK:        Name: bar1
+# CHECK:        Name: foo
+# CHECK-NEXT:   Value: 0x123
+# CHECK-NEXT:   Size: 0
+# CHECK-NEXT:   Binding: Global
+# CHECK-NEXT:   Type: None
+# CHECK-NEXT:   Other: 0
+# CHECK-NEXT:   Section: Absolute (0xFFF1)
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT:   Name: bar1
 # CHECK-NEXT:   Value: 0x4
 # CHECK-NEXT:   Size: 0
 # CHECK-NEXT:   Binding: Global
@@ -58,3 +71,12 @@
 # CHECK-NEXT:   Other: 0
 # CHECK-NEXT:   Section: Absolute
 # CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT:   Name: bar6 (30)
+# CHECK-NEXT:   Value: 0x124
+# CHECK-NEXT:   Size: 0
+# CHECK-NEXT:   Binding: Global (0x1)
+# CHECK-NEXT:   Type: None (0x0)
+# CHECK-NEXT:   Other: 0
+# CHECK-NEXT:   Section: Absolute (0xFFF1)
+# CHECK-NEXT: }




More information about the llvm-commits mailing list