<div dir="ltr">I believe this broke msan bots. Can you take a look?<div><br></div><div><a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap/builds/1025">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap/builds/1025</a></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Mar 17, 2017 at 6:05 AM, Rafael Espindola via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rafael<br>
Date: Fri Mar 17 08:05:04 2017<br>
New Revision: 298079<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=298079&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=298079&view=rev</a><br>
Log:<br>
Change our linker script expr representation.<br>
<br>
This fixes pr32031 by representing the expressions results as a<br>
SectionBase and offset. This allows us to use an input section<br>
directly instead of getting lost trying to compute an offset in an<br>
outputsection when not all the information is available yet.<br>
<br>
This also creates a struct to represent the *value* of and expression,<br>
allowing the expression itself to be a simple typedef. I think this is<br>
easier to read and will make it easier to extend the expression<br>
computation to handle more complicated cases.<br>
<br>
Added:<br>
    lld/trunk/test/ELF/<wbr>linkerscript/obj-symbol-value.<wbr>s<br>
Modified:<br>
    lld/trunk/ELF/LinkerScript.cpp<br>
    lld/trunk/ELF/LinkerScript.h<br>
<br>
Modified: lld/trunk/ELF/LinkerScript.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=298079&r1=298078&r2=298079&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/lld/trunk/ELF/<wbr>LinkerScript.cpp?rev=298079&<wbr>r1=298078&r2=298079&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- lld/trunk/ELF/LinkerScript.cpp (original)<br>
+++ lld/trunk/ELF/LinkerScript.cpp Fri Mar 17 08:05:04 2017<br>
@@ -53,6 +53,60 @@ using namespace llvm::support::endian;<br>
 using namespace lld;<br>
 using namespace lld::elf;<br>
<br>
+uint64_t ExprValue::getValue() const {<br>
+  if (Sec)<br>
+    return Sec->getOffset(Val) + Sec->getOutputSection()->Addr;<br>
+  return Val;<br>
+}<br>
+<br>
+static ExprValue add(ExprValue A, ExprValue B) {<br>
+  return {A.Sec, A.ForceAbsolute, A.Val + B.getValue()};<br>
+}<br>
+static ExprValue sub(ExprValue A, ExprValue B) {<br>
+  return {A.Sec, A.Val - B.getValue()};<br>
+}<br>
+static ExprValue mul(ExprValue A, ExprValue B) {<br>
+  return A.getValue() * B.getValue();<br>
+}<br>
+static ExprValue div(ExprValue A, ExprValue B) {<br>
+  if (uint64_t BV = B.getValue())<br>
+    return A.getValue() / BV;<br>
+  error("division by zero");<br>
+  return 0;<br>
+}<br>
+static ExprValue leftShift(ExprValue A, ExprValue B) {<br>
+  return A.getValue() << B.getValue();<br>
+}<br>
+static ExprValue rightShift(ExprValue A, ExprValue B) {<br>
+  return A.getValue() >> B.getValue();<br>
+}<br>
+static ExprValue lessThan(ExprValue A, ExprValue B) {<br>
+  return A.getValue() < B.getValue();<br>
+}<br>
+static ExprValue greaterThan(ExprValue A, ExprValue B) {<br>
+  return A.getValue() > B.getValue();<br>
+}<br>
+static ExprValue greaterThanOrEqual(ExprValue A, ExprValue B) {<br>
+  return A.getValue() >= B.getValue();<br>
+}<br>
+static ExprValue lessThanOrEqual(ExprValue A, ExprValue B) {<br>
+  return A.getValue() <= B.getValue();<br>
+}<br>
+static ExprValue equal(ExprValue A, ExprValue B) {<br>
+  return A.getValue() == B.getValue();<br>
+}<br>
+static ExprValue notEqual(ExprValue A, ExprValue B) {<br>
+  return A.getValue() != B.getValue();<br>
+}<br>
+static ExprValue bitAnd(ExprValue A, ExprValue B) {<br>
+  return A.getValue() & B.getValue();<br>
+}<br>
+static ExprValue bitOr(ExprValue A, ExprValue B) {<br>
+  return A.getValue() | B.getValue();<br>
+}<br>
+static ExprValue bitNot(ExprValue A) { return ~A.getValue(); }<br>
+static ExprValue minus(ExprValue A) { return -A.getValue(); }<br>
+<br>
 LinkerScriptBase *elf::ScriptBase;<br>
 ScriptConfiguration *elf::ScriptConfig;<br>
<br>
@@ -63,8 +117,8 @@ template <class ELFT> static SymbolBody<br>
       Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false,<br>
       /*File*/ nullptr);<br>
   Sym->Binding = STB_GLOBAL;<br>
-  SectionBase *Sec =<br>
-      Cmd->Expression.IsAbsolute() ? nullptr : Cmd->Expression.Section();<br>
+  ExprValue Value = Cmd->Expression();<br>
+  SectionBase *Sec = Value.isAbsolute() ? nullptr : Value.Sec;<br>
   replaceBody<DefinedRegular>(<wbr>Sym, Cmd->Name, /*IsLocal=*/false, Visibility,<br>
                               STT_NOTYPE, 0, 0, Sec, nullptr);<br>
   return Sym->body();<br>
@@ -87,7 +141,8 @@ OutputSection *LinkerScriptBase::getOutp<br>
     if (Sec->Name == Name)<br>
       return Sec;<br>
<br>
-  error(Loc + ": undefined section " + Name);<br>
+  if (ErrorOnMissingSection)<br>
+    error(Loc + ": undefined section " + Name);<br>
   return &FakeSec;<br>
 }<br>
<br>
@@ -105,7 +160,7 @@ uint64_t LinkerScriptBase::<wbr>getOutputSect<br>
 }<br>
<br>
 void LinkerScriptBase::setDot(Expr E, const Twine &Loc, bool InSec) {<br>
-  uint64_t Val = E();<br>
+  uint64_t Val = E().getValue();<br>
   if (Val < Dot) {<br>
     if (InSec)<br>
       error(Loc + ": unable to move location counter backward for: " +<br>
@@ -132,12 +187,15 @@ void LinkerScriptBase::<wbr>assignSymbol(Symb<br>
     return;<br>
<br>
   auto *Sym = cast<DefinedRegular>(Cmd->Sym)<wbr>;<br>
-  Sym->Value = Cmd->Expression();<br>
-  if (!Cmd->Expression.IsAbsolute()<wbr>) {<br>
-    Sym->Section = Cmd->Expression.Section();<br>
-    if (auto *Sec = dyn_cast_or_null<<wbr>OutputSection>(Sym->Section))<br>
-      if (Sec->Flags & SHF_ALLOC)<br>
-        Sym->Value -= Sec->Addr;<br>
+  ExprValue V = Cmd->Expression();<br>
+  if (V.isAbsolute()) {<br>
+    Sym->Value = V.getValue();<br>
+  } else {<br>
+    Sym->Section = V.Sec;<br>
+    if (Sym->Section->Flags & SHF_ALLOC)<br>
+      Sym->Value = V.Val;<br>
+    else<br>
+      Sym->Value = V.getValue();<br>
   }<br>
 }<br>
<br>
@@ -373,7 +431,7 @@ void LinkerScript<ELFT>::<wbr>processCommands<br>
       // is given, input sections are aligned to that value, whether the<br>
       // given value is larger or smaller than the original section alignment.<br>
       if (Cmd->SubalignExpr) {<br>
-        uint32_t Subalign = Cmd->SubalignExpr();<br>
+        uint32_t Subalign = Cmd->SubalignExpr().getValue()<wbr>;<br>
         for (InputSectionBase *S : V)<br>
           S->Alignment = Subalign;<br>
       }<br>
@@ -557,12 +615,12 @@ void LinkerScriptBase::<wbr>assignOffsets(Out<br>
<br>
   if (Cmd->LMAExpr) {<br>
     uint64_t D = Dot;<br>
-    LMAOffset = [=] { return Cmd->LMAExpr() - D; };<br>
+    LMAOffset = [=] { return Cmd->LMAExpr().getValue() - D; };<br>
   }<br>
<br>
   // Handle align (e.g. ".foo : ALIGN(16) { ... }").<br>
   if (Cmd->AlignExpr)<br>
-    Sec->updateAlignment(Cmd-><wbr>AlignExpr());<br>
+    Sec->updateAlignment(Cmd-><wbr>AlignExpr().getValue());<br>
<br>
   // Try and find an appropriate memory region to assign offsets in.<br>
   CurMemRegion = findMemoryRegion(Cmd, Sec);<br>
@@ -776,6 +834,7 @@ void LinkerScriptBase::<wbr>processNonSection<br>
 void LinkerScriptBase::<wbr>assignAddresses(std::vector<<wbr>PhdrEntry> &Phdrs) {<br>
   // Assign addresses as instructed by linker script SECTIONS sub-commands.<br>
   Dot = 0;<br>
+  ErrorOnMissingSection = true;<br>
   switchTo(Aether);<br>
<br>
   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {<br>
@@ -820,7 +879,7 @@ std::vector<PhdrEntry> LinkerScriptBase:<br>
       Phdr.add(Out::ProgramHeaders);<br>
<br>
     if (Cmd.LMAExpr) {<br>
-      Phdr.p_paddr = Cmd.LMAExpr();<br>
+      Phdr.p_paddr = Cmd.LMAExpr().getValue();<br>
       Phdr.HasLMA = true;<br>
     }<br>
   }<br>
@@ -888,7 +947,8 @@ void LinkerScript<ELFT>::<wbr>writeDataBytes(<br>
   auto *Cmd = dyn_cast<OutputSectionCommand><wbr>(Opt.Commands[I].get());<br>
   for (const std::unique_ptr<BaseCommand> &Base : Cmd->Commands)<br>
     if (auto *Data = dyn_cast<BytesDataCommand>(<wbr>Base.get()))<br>
-      writeInt<ELFT>(Buf + Data->Offset, Data->Expression(), Data->Size);<br>
+      writeInt<ELFT>(Buf + Data->Offset, Data->Expression().getValue(),<br>
+                     Data->Size);<br>
 }<br>
<br>
 bool LinkerScriptBase::hasLMA(<wbr>StringRef Name) {<br>
@@ -912,11 +972,15 @@ int LinkerScriptBase::<wbr>getSectionIndex(St<br>
 }<br>
<br>
 template <class ELFT><br>
-uint64_t LinkerScript<ELFT>::<wbr>getSymbolValue(const Twine &Loc, StringRef S) {<br>
+ExprValue LinkerScript<ELFT>::<wbr>getSymbolValue(const Twine &Loc, StringRef S) {<br>
   if (S == ".")<br>
-    return Dot;<br>
-  if (SymbolBody *B = Symtab<ELFT>::X->find(S))<br>
-    return B->getVA();<br>
+    return {CurOutSec, Dot - CurOutSec->Addr};<br>
+  if (SymbolBody *B = Symtab<ELFT>::X->find(S)) {<br>
+    if (auto *D = dyn_cast<DefinedRegular>(B))<br>
+      return {D->Section, D->Value};<br>
+    auto *C = cast<DefinedCommon>(B);<br>
+    return {In<ELFT>::Common, C->Offset};<br>
+  }<br>
   error(Loc + ": symbol not found: " + S);<br>
   return 0;<br>
 }<br>
@@ -925,24 +989,6 @@ template <class ELFT> bool LinkerScript<<br>
   return Symtab<ELFT>::X->find(S) != nullptr;<br>
 }<br>
<br>
-template <class ELFT> bool LinkerScript<ELFT>::<wbr>isAbsolute(StringRef S) {<br>
-  if (S == ".")<br>
-    return false;<br>
-  SymbolBody *Sym = Symtab<ELFT>::X->find(S);<br>
-  auto *DR = dyn_cast_or_null<<wbr>DefinedRegular>(Sym);<br>
-  return DR && !DR->Section;<br>
-}<br>
-<br>
-// Gets section symbol belongs to. Symbol "." doesn't belong to any<br>
-// specific section but isn't absolute at the same time, so we try<br>
-// to find suitable section for it as well.<br>
-template <class ELFT><br>
-OutputSection *LinkerScript<ELFT>::<wbr>getSymbolSection(StringRef S) {<br>
-  if (SymbolBody *Sym = Symtab<ELFT>::X->find(S))<br>
-    return Sym->getOutputSection();<br>
-  return CurOutSec;<br>
-}<br>
-<br>
 // Returns indices of ELF headers containing specific section, identified<br>
 // by Name. Each index is a zero based number of ELF header listed within<br>
 // PHDRS {} script block.<br>
@@ -1256,7 +1302,7 @@ void ScriptParser::readPhdrs() {<br>
         expect("(");<br>
         // Passing 0 for the value of dot is a bit of a hack. It means that<br>
         // we accept expressions like ".|1".<br>
-        PhdrCmd.Flags = readExpr()();<br>
+        PhdrCmd.Flags = readExpr()().getValue();<br>
         expect(")");<br>
       } else<br>
         setError("unexpected header attribute: " + Tok);<br>
@@ -1422,7 +1468,7 @@ Expr ScriptParser::readAssert() {<br>
   StringRef Msg = unquote(next());<br>
   expect(")");<br>
   return [=] {<br>
-    if (!E())<br>
+    if (!E().getValue())<br>
       error(Msg);<br>
     return ScriptBase->getDot();<br>
   };<br>
@@ -1554,7 +1600,7 @@ SymbolAssignment *ScriptParser::readAssi<br>
   Expr E = readExpr();<br>
   if (Op == "+=") {<br>
     std::string Loc = getCurrentLocation();<br>
-    E = [=] { return ScriptBase->getSymbolValue(<wbr>Loc, Name) + E(); };<br>
+    E = [=] { return add(ScriptBase-><wbr>getSymbolValue(Loc, Name), E()); };<br>
   }<br>
   return new SymbolAssignment(Name, E, getCurrentLocation());<br>
 }<br>
@@ -1572,48 +1618,35 @@ Expr ScriptParser::readExpr() {<br>
 }<br>
<br>
 static Expr combine(StringRef Op, Expr L, Expr R) {<br>
-  auto IsAbs = [=] { return L.IsAbsolute() && R.IsAbsolute(); };<br>
-  auto GetOutSec = [=] {<br>
-    SectionBase *S = L.Section();<br>
-    return S ? S : R.Section();<br>
-  };<br>
-<br>
   if (Op == "*")<br>
-    return [=] { return L() * R(); };<br>
+    return [=] { return mul(L(), R()); };<br>
   if (Op == "/") {<br>
-    return [=]() -> uint64_t {<br>
-      uint64_t RHS = R();<br>
-      if (RHS == 0) {<br>
-        error("division by zero");<br>
-        return 0;<br>
-      }<br>
-      return L() / RHS;<br>
-    };<br>
+    return [=] { return div(L(), R()); };<br>
   }<br>
   if (Op == "+")<br>
-    return {[=] { return L() + R(); }, IsAbs, GetOutSec};<br>
+    return [=] { return add(L(), R()); };<br>
   if (Op == "-")<br>
-    return {[=] { return L() - R(); }, IsAbs, GetOutSec};<br>
+    return [=] { return sub(L(), R()); };<br>
   if (Op == "<<")<br>
-    return [=] { return L() << R(); };<br>
+    return [=] { return leftShift(L(), R()); };<br>
   if (Op == ">>")<br>
-    return [=] { return L() >> R(); };<br>
+    return [=] { return rightShift(L(), R()); };<br>
   if (Op == "<")<br>
-    return [=] { return L() < R(); };<br>
+    return [=] { return lessThan(L(), R()); };<br>
   if (Op == ">")<br>
-    return [=] { return L() > R(); };<br>
+    return [=] { return greaterThan(L(), R()); };<br>
   if (Op == ">=")<br>
-    return [=] { return L() >= R(); };<br>
+    return [=] { return greaterThanOrEqual(L(), R()); };<br>
   if (Op == "<=")<br>
-    return [=] { return L() <= R(); };<br>
+    return [=] { return lessThanOrEqual(L(), R()); };<br>
   if (Op == "==")<br>
-    return [=] { return L() == R(); };<br>
+    return [=] { return ::equal(L(), R()); };<br>
   if (Op == "!=")<br>
-    return [=] { return L() != R(); };<br>
+    return [=] { return notEqual(L(), R()); };<br>
   if (Op == "&")<br>
-    return [=] { return L() & R(); };<br>
+    return [=] { return bitAnd(L(), R()); };<br>
   if (Op == "|")<br>
-    return [=] { return L() | R(); };<br>
+    return [=] { return bitOr(L(), R()); };<br>
   llvm_unreachable("invalid operator");<br>
 }<br>
<br>
@@ -1718,25 +1751,28 @@ Expr ScriptParser::readPrimary() {<br>
<br>
   if (Tok == "~") {<br>
     Expr E = readPrimary();<br>
-    return [=] { return ~E(); };<br>
+    return [=] { return bitNot(E()); };<br>
   }<br>
   if (Tok == "-") {<br>
     Expr E = readPrimary();<br>
-    return [=] { return -E(); };<br>
+    return [=] { return minus(E()); };<br>
   }<br>
<br>
   // Built-in functions are parsed here.<br>
   // <a href="https://sourceware.org/binutils/docs/ld/Builtin-Functions.html" rel="noreferrer" target="_blank">https://sourceware.org/<wbr>binutils/docs/ld/Builtin-<wbr>Functions.html</a>.<br>
   if (Tok == "ABSOLUTE") {<br>
-    Expr E = readParenExpr();<br>
-    E.IsAbsolute = [] { return true; };<br>
-    return E;<br>
+    Expr Inner = readParenExpr();<br>
+    return [=] {<br>
+      ExprValue I = Inner();<br>
+      I.ForceAbsolute = true;<br>
+      return I;<br>
+    };<br>
   }<br>
   if (Tok == "ADDR") {<br>
     StringRef Name = readParenLiteral();<br>
-    return {[=] { return ScriptBase->getOutputSection(<wbr>Location, Name)->Addr; },<br>
-            [=] { return false; },<br>
-            [=] { return ScriptBase->getOutputSection(<wbr>Location, Name); }};<br>
+    return [=]() -> ExprValue {<br>
+      return {ScriptBase->getOutputSection(<wbr>Location, Name), 0};<br>
+    };<br>
   }<br>
   if (Tok == "LOADADDR") {<br>
     StringRef Name = readParenLiteral();<br>
@@ -1751,10 +1787,10 @@ Expr ScriptParser::readPrimary() {<br>
     if (consume(",")) {<br>
       Expr E2 = readExpr();<br>
       expect(")");<br>
-      return [=] { return alignTo(E(), E2()); };<br>
+      return [=] { return alignTo(E().getValue(), E2().getValue()); };<br>
     }<br>
     expect(")");<br>
-    return [=] { return alignTo(ScriptBase->getDot(), E()); };<br>
+    return [=] { return alignTo(ScriptBase->getDot(), E().getValue()); };<br>
   }<br>
   if (Tok == "CONSTANT") {<br>
     StringRef Name = readParenLiteral();<br>
@@ -1778,7 +1814,7 @@ Expr ScriptParser::readPrimary() {<br>
     expect(",");<br>
     readExpr();<br>
     expect(")");<br>
-    return [=] { return alignTo(ScriptBase->getDot(), E()); };<br>
+    return [=] { return alignTo(ScriptBase->getDot(), E().getValue()); };<br>
   }<br>
   if (Tok == "DATA_SEGMENT_END") {<br>
     expect("(");<br>
@@ -1817,16 +1853,14 @@ Expr ScriptParser::readPrimary() {<br>
   // Tok is a symbol name.<br>
   if (Tok != "." && !isValidCIdentifier(Tok))<br>
     setError("malformed number: " + Tok);<br>
-  return {[=] { return ScriptBase->getSymbolValue(<wbr>Location, Tok); },<br>
-          [=] { return ScriptBase->isAbsolute(Tok); },<br>
-          [=] { return ScriptBase->getSymbolSection(<wbr>Tok); }};<br>
+  return [=] { return ScriptBase->getSymbolValue(<wbr>Location, Tok); };<br>
 }<br>
<br>
 Expr ScriptParser::readTernary(Expr Cond) {<br>
   Expr L = readExpr();<br>
   expect(":");<br>
   Expr R = readExpr();<br>
-  return [=] { return Cond() ? L() : R(); };<br>
+  return [=] { return Cond().getValue() ? L() : R(); };<br>
 }<br>
<br>
 Expr ScriptParser::readParenExpr() {<br>
<br>
Modified: lld/trunk/ELF/LinkerScript.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=298079&r1=298078&r2=298079&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/lld/trunk/ELF/<wbr>LinkerScript.h?rev=298079&r1=<wbr>298078&r2=298079&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- lld/trunk/ELF/LinkerScript.h (original)<br>
+++ lld/trunk/ELF/LinkerScript.h Fri Mar 17 08:05:04 2017<br>
@@ -38,28 +38,23 @@ class OutputSectionFactory;<br>
 class InputSectionBase;<br>
 class SectionBase;<br>
<br>
+struct ExprValue {<br>
+  SectionBase *Sec;<br>
+  uint64_t Val;<br>
+  bool ForceAbsolute;<br>
+<br>
+  ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val)<br>
+      : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute) {}<br>
+  ExprValue(SectionBase *Sec, uint64_t Val) : ExprValue(Sec, false, Val) {}<br>
+  ExprValue(uint64_t Val) : ExprValue(nullptr, Val) {}<br>
+  bool isAbsolute() const { return ForceAbsolute || Sec == nullptr; }<br>
+  uint64_t getValue() const;<br>
+};<br>
+<br>
 // This represents an expression in the linker script.<br>
 // ScriptParser::readExpr reads an expression and returns an Expr.<br>
-// Later, we evaluate the expression by calling the function<br>
-// with the value of special context variable ".".<br>
-struct Expr {<br>
-  std::function<uint64_t()> Val;<br>
-  std::function<bool()> IsAbsolute;<br>
-<br>
-  // If expression is section-relative the function below is used<br>
-  // to get the output section pointer.<br>
-  std::function<SectionBase *()> Section;<br>
-<br>
-  uint64_t operator()() const { return Val(); }<br>
-  operator bool() const { return (bool)Val; }<br>
-<br>
-  Expr(std::function<uint64_t()> Val, std::function<bool()> IsAbsolute,<br>
-       std::function<SectionBase *()> Section)<br>
-      : Val(Val), IsAbsolute(IsAbsolute), Section(Section) {}<br>
-  template <typename T><br>
-  Expr(T V) : Expr(V, [] { return true; }, [] { return nullptr; }) {}<br>
-  Expr() : Expr(nullptr) {}<br>
-};<br>
+// Later, we evaluate the expression by calling the function.<br>
+typedef std::function<ExprValue()> Expr;<br>
<br>
 // Parses a linker script. Calling this function updates<br>
 // Config and ScriptConfig.<br>
@@ -205,7 +200,6 @@ struct MemoryRegion {<br>
   uint32_t NegFlags;<br>
 };<br>
<br>
-<br>
 // ScriptConfiguration holds linker script parse results.<br>
 struct ScriptConfiguration {<br>
   // Used to assign addresses to sections.<br>
@@ -248,6 +242,7 @@ protected:<br>
   void process(BaseCommand &Base);<br>
<br>
   OutputSection *Aether;<br>
+  bool ErrorOnMissingSection = false;<br>
<br>
   // "ScriptConfig" is a bit too long, so define a short name for it.<br>
   ScriptConfiguration &Opt = *ScriptConfig;<br>
@@ -269,10 +264,8 @@ public:<br>
   uint64_t getOutputSectionSize(StringRef S);<br>
   void discard(ArrayRef<<wbr>InputSectionBase *> V);<br>
<br>
-  virtual uint64_t getSymbolValue(const Twine &Loc, StringRef S) = 0;<br>
+  virtual ExprValue getSymbolValue(const Twine &Loc, StringRef S) = 0;<br>
   virtual bool isDefined(StringRef S) = 0;<br>
-  virtual bool isAbsolute(StringRef S) = 0;<br>
-  virtual OutputSection *getSymbolSection(StringRef S) = 0;<br>
<br>
   std::vector<OutputSection *> *OutputSections;<br>
   void addOrphanSections(<wbr>OutputSectionFactory &Factory);<br>
@@ -303,10 +296,8 @@ public:<br>
   void addSymbol(SymbolAssignment *Cmd);<br>
   void processCommands(<wbr>OutputSectionFactory &Factory);<br>
<br>
-  uint64_t getSymbolValue(const Twine &Loc, StringRef S) override;<br>
+  ExprValue getSymbolValue(const Twine &Loc, StringRef S) override;<br>
   bool isDefined(StringRef S) override;<br>
-  bool isAbsolute(StringRef S) override;<br>
-  OutputSection *getSymbolSection(StringRef S) override;<br>
 };<br>
<br>
 // Variable template is a C++14 feature, so we can't template<br>
<br>
Added: lld/trunk/test/ELF/<wbr>linkerscript/obj-symbol-value.<wbr>s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/obj-symbol-value.s?rev=298079&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/lld/trunk/test/ELF/<wbr>linkerscript/obj-symbol-value.<wbr>s?rev=298079&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- lld/trunk/test/ELF/<wbr>linkerscript/obj-symbol-value.<wbr>s (added)<br>
+++ lld/trunk/test/ELF/<wbr>linkerscript/obj-symbol-value.<wbr>s Fri Mar 17 08:05:04 2017<br>
@@ -0,0 +1,19 @@<br>
+# REQUIRES: x86<br>
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o<br>
+# RUN: echo "SECTIONS { foo = bar; .bar : { *(.bar*) } }" > %t.script<br>
+# RUN: ld.lld %t.o --script %t.script -o %t.so -shared<br>
+# RUN: llvm-readobj -t %t.so | FileCheck %s<br>
+<br>
+# CHECK:     Symbol {<br>
+# CHECK:      Name: bar<br>
+# CHECK-NEXT: Value: 0x[[VAL:.*]]<br>
+# CHECK:      Name: foo<br>
+# CHECK-NEXT: Value: 0x[[VAL]]<br>
+<br>
+.section .bar.1, "a"<br>
+.quad 0<br>
+<br>
+.section .bar.2, "a"<br>
+.quad 0<br>
+.global bar<br>
+bar:<br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>